Stk.Textbuffer
Text buffer sharable by several views.
A textbuffer holds a (Utf-8) string and associated tags in a Rope.t
. The buffer also maintains cursors, updating their position when text is modified.
A widget wanting to display the buffer contents must register by providing functions to call when buffer is modified (text or tags).
A history is kept for undoing/redoing actions.
val create : ?source_language:string -> ?word_char_re:Pcre.regexp -> unit -> t
Create a new text buffer. Options arguments:
source_langage
: sets a source language by name.word_char_re
: regular expression of word characters. Default is default_word_char_re
.val lines : t -> Rope.range array
lines t
returns an array with the range of each line of t
.
val line_count : t -> int
line_count t
returns the number of lines in t
.
val size : t -> int
size t
returns the number of utf8 characters in t
.
val modified : t -> bool
Get the modified flag of t
. This flag is set to true
when t
is modified. The history keeps track of this flag, so undoing or redoing can change this flag.
val set_modified : t -> bool -> unit
set_modified t b
sets modified flag of t
to b
. A typical use is to set the flag to false
after saving the contents of buffer to a file.
val set_map_in : t -> (Stdlib.Uchar.t -> Stdlib.Uchar.t) option -> unit
set_map_in t f
sets a function (or removes it) used to map inserted contents. When such a function is set, it is applied on strings passed to insertion functions (insert
, insert_at_cursor
, set_text
, ...
val set_map_out : t -> (Stdlib.Uchar.t -> Stdlib.Uchar.t) option -> unit
val pp : Stdlib.Format.formatter -> t -> unit
Pretty-print contents of text buffer.
This module has its own Logs
source "stk.textbuffer"
. See Log
.
include Log.LOG
include Logs.LOG
All position and offset are 0-based and expressed in UTF8 characters (not bytes).
type line_offset = {
line : int;
line number
*)bol : int;
offset of beginning of line
*)offset : int;
offset from the beginning of line
*)}
A line_offset
defines a line number and a character position on this line.
val line_offset : line:int -> bol:int -> offset:int -> line_offset
val pp_line_offset : Stdlib.Format.formatter -> line_offset -> unit
val compare_line_offset : line_offset -> line_offset -> int
val order_line_offsets :
line_offset ->
line_offset ->
line_offset * line_offset
order_line_offsets lo1 lo2
returns (lo1, lo2)
if lo1
is before or equal to lo2
, else returns (lo2, lo1)
.
type line_range = {
lstart : line_offset;
left of first char
*)lstop : line_offset;
right of last char
*)}
Range accross lines, defined by two line_offset
positions.
val line_range : start:line_offset -> stop:line_offset -> line_range
line_range ~start ~stop
creates a line_range
from start
to stop
characters.
val pp_line_range : Stdlib.Format.formatter -> line_range -> unit
Pretty-prints a line range.
val range_of_line_range : line_range -> Rope.range
range_of_line_range lr
converts lr
to a Rope.range
.
val line_of_offset : t -> int -> int
line_of_offset t o
returns the line number of t
corresponding to offset o
.
val line_char_of_offset : t -> int -> int * int
line_char_of_offset t o
returns the pair (line, char)
corresponding to offset o
.
val offset_of_line_char : t -> line:int -> char:int -> int
offset_of_line_char t ~line ~char
returns the absolute offset in t
corresponding to line
and character char
.
val line_offset_of_offset : t -> int -> line_offset
line_offset_of_offset t o
returns a line_offset
position from the given absolute offset o
.
val line_range_of_range : t -> Rope.range -> line_range
val line_ranges_of_ranges : t -> Rope.range list -> line_range list
line_ranges_of_ranges t ranges
returns a list of line_range
from a list of Rope.range
. Returnd ranges are merged when possible.
A text buffer can handle several cursors. Some cursors can be associated to a widget. In this case, they will be removed when the widget is unregistered, and changes of these cursors will be signaled only to this widget.
Cursor positions are automatically updated after each change (insertion, deletion) in the buffer.
Cursor gravity defines how a cursor moves when text is inserted at its position. `Left
gravity means that the cursor stays at the same position, `Right
means that the cursor moves to the right of the inserted text, as when user types text.
val pp_cursor : Stdlib.Format.formatter -> cursor -> unit
Pretty-prints a cursor (with its position).
A map with cursors as keys. This is useful for views on a text buffer (like Textview.textview
widget).
val create_cursor :
?widget:Stk.Oid.Map.key ->
?gravity:cursor_gravity ->
?line:int ->
?char:int ->
?offset:int ->
t ->
cursor
create_cursor t
creates a new cursor in buffer. Optional arguments are:
widget
: indicates a widget id. Changes regarding this cursor will be signaled only to this widget.gravity
: the gravity of the cursor. Default is `Right
.line
, char
and offset
: indicate position of cursor. If offset
is given, it is used. Else line
and char
are used, with default value 0
for each.Get last used cursor field of textbuffer. This can be useful for editors handling several cursors.
remove_cursor t c
removes cursor c
from t
. This cursor cannot be used anymore.
create_insert_cursor t
creates a new cursor in t
. If last_used_cursor
of t
is not None
and is a valid cursor, then this cursor is duplicated, setting gravity of new cursor to `Right
. Else a new cursor is created at offset 0
. Optonal argument widget
indicates a widget id. Changes regarding this cursor will be signaled only to this widget.
val dup_cursor :
t ->
?widget:Stk.Oid.Map.key ->
?gravity:cursor_gravity ->
cursor ->
cursor option
dup_cursor t c
returns a new cursor, if c
is a valid cursor. The new cursor is at the same position than c
. The cursor can be associated to widget
id, if provided. gravity
argument allows to force the gravity of new cursor rather than having the same as c
.
cursor_offset t c
returns absolute offset of c
, or 0
if cursor is invalid.
val cursor_line_offset : t -> cursor -> line_offset
cursor_line_offset t c
returns position of c
as a line_offset
.
All these functions returns the new absolute offset of the cursor, or None if the cursor is invalid.
move_cursor t c
moves the cursor c
according to optional parameters:
offset
: move cursor to absolute offset
.line
and char
: if offset
is not provided, then move cursor to the given line
(default is 0
) and char
(default is 0
).move_cursor_to_cursor t ~src ~dst
moves cursor src
at the same position as dst
. Returns the new absolute offset of the cursor, or None if src
or dst
is invalid.
Moves cursor to the start of the current line of the cursor.
Moves cursor to the end of the current line of the cursor.
line_forward_cursor t c n
moves cursor n
lines forward. If possible, keep the same char position on line.
Same as line_forward_cursor
but moves backward.
forward_cursor t c n
moves c
n
characters forward.
backward_cursor t c n
moves c
n
characters backward.
forward_cursor_to_word_end t c
moves c
to the next word end.
backward_cursor_to_word_start t c
moves c
to the previous word start.
val create_region :
?start_gravity:cursor_gravity ->
start:int ->
?stop_gravity:cursor_gravity ->
stop:int ->
t ->
region
create_region ~start ~stop t
creates a new region defined by two cursors at the given absolute positions. start_gravity
(default is `Left
) and stop_gravity
(default is `Right
) can be used to specify different gravities for cursors.
type Events.ev +=
| Delete_range : ((line_range * string) -> unit) Events.ev
| Insert_text : ((line_range * string) -> unit) Events.ev
| Cursor_moved : ((cursor * line_offset) -> unit) Events.ev
| Modified_changed : (bool -> unit) Events.ev
| Source_language_changed : (string option -> unit) Events.ev
Textbuffer events:
Delete (range, string)
: A range
was deleted which corresponds to string
.Insert_text (range, string)
: A string
was inserted, now at range
.Cursor_moved (c, line_offset)
: The given cursor moved to a new position.Modified_changed bool
: The modified status changed to the given boolean.Source_language_changed lang
: the source language changed to Some name
, or None
for no language.val connect : t -> 'a Events.ev -> 'a -> Events.callback_id
connect t ev cb
connects callback cb
to be called when event ev
is triggered by t
.
val disconnect : t -> Events.callback_id -> unit
disconnect t id
disconnect callback with id
from t
.
val to_string : ?start:int -> ?size:int -> t -> string
to_string t
returns contents of t
as a string. Optional arguments:
start
indicates a start position (default is 0
).size
indicates a size of string to get (default is to get the contents of t
until the end, i.e. size t - start
.val chars :
?start:int ->
?size:int ->
t ->
(Stdlib.Uchar.t * (Stk.Rope.TagSet.t * Stk.Rope.Tag.t option)) list
Same as to_string
but returns a list of characters with their associated tags: for each character, a pair (tag set,
language tag option)
.
val get_line : t -> int -> Rope.range
get_line t n
returns the range of line n
in t
.
val line_chars :
t ->
int ->
(Stdlib.Uchar.t * (Stk.Rope.TagSet.t * Stk.Rope.Tag.t option)) list
Same as chars
but returns chars for the given line.
val line_to_string : t -> int -> string
line_to_string t n
returns line n
as a string.
val insert_at_cursor :
t ->
cursor ->
?readonly:(Stk.Rope.TagSet.t option -> Stk.Rope.TagSet.t option -> bool) ->
?tags:Texttag.T.t list ->
string ->
unit
insert_at_cursor t c s
inserts the string s
at the position of the cursor c
. Optional arguments:
readonly
: a function taking tags of characters before and after the insertion position and returning whether can be inserted here. Can be used to define readonly ranges in a buffer based on tags.tags
: tags associated to each inserted character.val insert :
t ->
?readonly:(Stk.Rope.TagSet.t option -> Stk.Rope.TagSet.t option -> bool) ->
?tags:Texttag.TSet.id list ->
int ->
string ->
unit
insert t offset s
is the same as insert_at_cursor
but inserts at the given offset.
val set_text : t -> string -> unit
set_text t s
replaces contents of buffer with string s
.
val delete :
?readonly:(Stk.Rope.TagSet.t -> bool) ->
?start:int ->
?size:int ->
t ->
string
delete t
deletes contents from t
. Options arguments:
readonly
: a function taking the tags of a character and returning whether this character can be deleted. Only characters which are not readonly will be deleted.start
: start of range to delete. Default is 0
.size
: size of range to delete. Default is size t - start
.The function returns the deleted text.
Tags are associated to each character of the underlying rope used by a text buffer. The text buffer does not associate properties to these tags. The theme of the Textview
displaying a text buffer associated properties (color, font, ...) to tags.
val add_tag : t -> Texttag.T.t -> ?start:int -> ?size:int -> unit -> unit
add_tag t tag ()
adds the given tag
to contents of t
. Optional arguments:
start
: indicates the start of range to tag (default is 0
).size
: indicate the size of range to tag (default is size t - start
).val remove_tag : t -> Texttag.T.t -> ?start:int -> ?size:int -> unit -> unit
remove_tag t tag ()
removes the given tag
from contents of t
. Optional arguments:
start
: indicates the start of range to tag (default is 0
).size
: indicate the size of range to tag (default is size t - start
).A text buffer can be given a source language, using its name. The name if used as key for language lexers registered in Higlo
library. Higlo lexeme are mapped to Texttag.Lang
tags. These tags are given properties in the Texttag.Theme
used in Textview
, so that each lexeme can be styled.
val source_language : t -> string option
Returns the source language of the buffer, if any.
val set_source_language : t -> string option -> unit
Sets the source language of the buffer, or None
for no language.
A regular expression is used in buffer to determine what is a Word character. This is used by functions acting on words in the buffer.
A word is defined by default by this regular PCRE expression: "(*UCP)\\w"
, with iflags
contains `UTF8
, as buffer contains UTF8 strings.
val set_word_char_re : t -> Pcre.regexp -> unit
Sets the word character regular expression of t
.
val set_word_char_re_string : t -> string -> unit
Same as set_word_char_re
but regular expression is given as string. It is compiled to a regular expression with the `UTF8
flag.
A textbuffer keeps tracks of changes in a history, allowing undo/redo.
val max_undo_levels : t -> int
Get max undo levels.
val set_max_undo_levels : t -> int -> unit
set_max_undo_levels t n
sets max undo levels of t
to n
.
val reset_history : t -> unit
reset_history t
clears the list of stored changes in t
.
val begin_action : t -> unit
Begins a action. An action will be considered will be considered as one change (as a list of changes) in the history.
val end_action : t -> unit
Ends the current action. All the changes of the action are added to the history as a single change.
val undo : t -> unit
Undo last change.
val redo : t -> unit
Redo last undone change.
type change =
| Del of line_range * string
Deletion of range, string deleted
*)| Ins of line_range * string
Insertion of string at range
*)| Group of change list
list of changes
*)A change in the buffer.
val pp_change : Stdlib.Format.formatter -> change -> unit
val register_widget :
t ->
widget:Widget.widget ->
on_change:(change -> unit) ->
on_cursor_change:(cursor -> prev:line_offset -> now:line_offset -> unit) ->
on_tag_change:(line_range list -> unit) ->
cursor option
register_widget t ~widget ~on_change ~on_cursor_change ~on_tag_change
registers the given widget
as view on t
. on_change
will be called when contents of the textbuffer changes. on_cursor_change
will be called when a cursor not associated to a widget or associated to this widget
moves. on_tag_change
will be called when tags of a part of the contents changed. If the widget is already registered, then returns None
, else returns Some c
where c
is a new cursor created with create_insert_cursor ~widget t
.
val unregister_widget : t -> Widget.widget -> unit
unregister_widget t widget
unregisters the given widget
from the views of t
. Cursor of this widget are removed (and not usable any more).