NAME

Prima::Edit - standard text editing widget

SYNOPSIS

use Prima qw(Edit Application);
my $e = Prima::Edit->new(
	text         => 'Hello $world',
	syntaxHilite => 1,
);
run Prima;

DESCRIPTION

The class provides text editing capabilities, three types of selection, text wrapping, syntax highlighting, auto indenting, undo and redo function, search and replace methods.

The module declares bt:: package, that contains integer constants for selection block type, used by blockType property.

USAGE

The text is stored line-wise in {lines} array; to access it use get_line method. To access the text chunk-wise, use get_chunk method.

All keyboard events, except the character input and tab key handling, are processed by the accelerator table ( see Prima::Menu ). The default accelItems table defines names, keyboard combinations, and the corresponding actions to the class functions. The class does not provide functionality to change these mappings. To do so, consult "Prima::AccelTable" in Prima::Menu.

Coordinates

The class addresses the text space by (X,Y)-coordinates, where X is visual cluster offset and Y is line number. The addressing can be 'visual' and 'logical', - in logical case Y is number of line of text. The difference can be observed if wordWrap property is set to 1, when a single text string can be shown as several sub-strings, called chunks.

Cluster shaping and word wrapping can play a role here. Consider f.ex. text "offset is zero", that for the sake of the example can wrapped by width and displayed as two lines, "offset" and "is zero". Here, the font substitutes "ff" text with a single ligature glyph. Here, for example, coord("f") will be (0,1) in all coordinates, but coord("z") is different:

Physical

X coordinate is a character offset from character line number Y. These coordinates are identical with and without wordWrap flag. This coordinate is used for direct text manipulation.

Example: coord("z") is (0,10);

Visual

X coordinate is a glyph cluster offset from character line number Y. These coordinates are identical with and without wordWrap flag. This coordinate is used for cursor and selection API.

Example: coord("z") is (0,9);

Logical

Y coordinates is a wrapped line index. chunkMap internal array is addresses in logical coordinates. X coordinate is a glyph cluster offset from the line start. This coordinate is used mostly internally.

Example: coord("z") is (1,3);

API

Events

ParseSyntax TEXT, RESULT_ARRAY_REF

Called when syntax highlighting is required - TEXT is a string to be parsed, and the parsing results to be stored in RESULT_ARRAY_REF, which is a reference to an array of integer pairs, each representing a single-colored text chunk. The first integer in the pairs is the length of a chunk, the second - color value ( cl::XXX constants ).

Properties

autoIndent BOOLEAN

Turns the auto indenting on or off

Default value: 1

blockType INTEGER

Defines type of selection block. Can be one of the following constants:

bt::CUA

Normal block, where the first and the last line of the selection can be partial, and the lines between occupy the whole line. CUA stands for 'common user access'.

Default keys: Shift + arrow keys

See also: cursor_shift_key

bt::Vertical

Rectangular block, where all selected lines are of same offsets and lengths.

Default key: Alt+B

See also: mark_vertical

bt::Horizontal

Rectangular block, where the selection occupies the whole line.

Default key: Alt+L

See also: mark_horizontal

cursor X, Y

Selects visual position of the cursor

cursorX X

Selects visual horizontal position of the cursor

cursorY Y

Selects visual vertical position of the cursor

cursorWrap BOOLEAN

Selects cursor behavior when moved horizontally outside the line. If 0, the cursor is not moved. If 1, the cursor moved to the adjacent line.

See also: cursor_left, cursor_right, word_left, word_right.

insertMode BOOLEAN

Set the typing mode - if 1, the typed text is inserted, if 0, the text overwrites the old text. When insertMode is 0, the cursor shape is thick and covers the whole character; when 1, it is of the default cursor width.

Default toggle key: Insert

hiliteNumbers COLOR

Selects the color for number highlighting

hiliteQStrings COLOR

Selects the color for highlighting the single-quoted strings

hiliteQQStrings COLOR

Selects the color for highlighting the double-quoted strings

hiliteIDs ARRAY

Array of scalar pairs, that define words to be highlighted. The first item in the pair is an array of words; the second item is a color value.

hiliteChars ARRAY

Array of scalar pairs, that define characters to be highlighted. The first item in the pair is a string of characters; the second item is a color value.

hiliteREs ARRAY

Array of scalar pairs, that define character patterns to be highlighted. The first item in the pair is a perl regular expression; the second item is a color value.

Note: these are tricky. Generally, they assume that whatever is captured in (), is highlighted, and that capturing parentheses match from the first character onwards. So for simple matches like (\d+) (digits) or (#.*) this works fine. Things become more interesting if you need to check text after, or especially before the capture. For this you need to make sure that whatever text is matched by a regexp, need not move pos pointer as the regexes are looped over with \G anchor prepended (i.e. starting each time from the position the previous regex left off), and with /gc flags (advancing pos to the match length). Advancing the pos will skip color highlighting on text after the capture but before end of the match - so you'll need look-ahead assertions, (?=pattern) and (?!pattern) (see "Lookaround Assertions" in perlre ).

For example, we have a string ABC123abc , and we want to match 123 followed by abc. This won't work

hiliteREs => [
	'(123)abc',cl::LightRed,
	'(abc)', cl::LightGreen 
]

while this will:

hiliteREs => [
	'(123)(?=abc)',cl::LightRed,
	'(abc)', cl::LightGreen 
]

If you need to look behind, the corresponding assertions (?<=pattern) and (?<!pattern) could be used, but these are even more restrictive in that they only support fixed-width looks-behinds (NB: \K won't work because of \G either). That way, if we want to match 123 that follow ABC, this won't work:

hiliteREs =>  [
	'(ABC)',cl::LightBlue,
	'(?<=[ABC]+)(123)',cl::LightRed,
]

while this will:

hiliteREs =>  [
	'(ABC)',cl::LightBlue,
	'(?<=[ABC]{3})(123)',cl::LightRed,
]
mark MARK [ BLOCK_TYPE ]

Selects block marking state. If MARK is 1, starts the block marking, if 0 - stops the block marking. When MARK is 1, BLOCK_TYPE can be used to set the selection type ( bt::XXX constants ). If BLOCK_TYPE is unset the value of blockType is used.

markers ARRAY

Array of arrays with integer pairs, X and Y, where each represents a visual coordinates in text. Used as anchor storage for fast navigation.

See also: add_marker, delete_marker

modified BOOLEAN

A boolean flag that shows if the text was modified. Can be used externally, to check if the text is to be saved to a file, for example.

offset INTEGER

Horizontal offset of text lines in pixels.

persistentBlock BOOLEAN

Selects whether the selection is canceled as soon as the cursor is moved ( 0 ) or it persists until the selection is explicitly changed ( 1 ).

Default value: 0

readOnly BOOLEAN

If 1, no user input is accepted. Manipulations with text are allowed though.

selection X1, Y1, X2, Y2

Accepts two pair of visual coordinates, (X1,Y1) the beginning and (X2,Y2) the end of new selection, and sets the block according to blockType property.

The selection is null if X1 equals to X2 and Y1 equals to Y2. has_selection method returns 1 if the selection is non-null.

selStart X, Y

Manages the selection start. See selection, X1 and Y1.

selEnd X, Y

Manages the selection end. See selection, X2 and Y2.

syntaxHilite BOOLEAN

Governs the syntax highlighting.

tabIndent INTEGER

Maps tab ( \t ) key to tabIndent amount of space characters.

text TEXT

Provides access to all the text data. The lines are separated by the new line ( \n ) character.

See also: textRef.

textDirection BOOLEAN

If set, indicates RTL text input.

textLigation BOOLEAN

If set, text may be rendered at better quality with ligation and kerning, however that comes with a price that some ligatures may be indivisible and form clusters (f.ex. ff or ffi ligatures). Cursor cannot go inside of such clusters, and thus one can only select them, delete as whole, or press Del/Backspace on the cluster's edge.

textRef TEXT_PTR

Provides access to all the text data. The lines are separated by the new line ( \n ) character. TEXT_PTR is a pointer to text string.

The property is more efficient than text with the large text, because the copying of the text scalar to the stack is eliminated.

See also: text.

topLine INTEGER

Selects the first line of the text drawn.

undoLimit INTEGER

Sets limit on number of stored atomic undo operations. If 0, undo is disabled.

Default value: 1000

wantTabs BOOLEAN

Selects the way the tab ( \t ) character is recognized in the user input. If 1, it is recognized by the Tab key; however, this disallows the toolkit widget tab-driven navigation. If 0, the tab character can be entered by pressing Ctrl+Tab key combination.

Default value: 0

wantReturns BOOLEAN

Selects the way the new line ( \n ) character is recognized in the user input. If 1, it is recognized by the Enter key; however, this disallows the toolkit default button activation. If 0, the new line character can be entered by pressing Ctrl+Enter key combination.

Default value: 1

wordDelimiters STRING

Contains string of character that are used for locating a word break. Default STRING value consists of punctuation marks, space and tab characters, and \xff character.

See also: word_left, word_right

wordWrap BOOLEAN

Selects whether the long lines are wrapped, or can be positioned outside the horizontal widget inferior borders. If 1, syntaxHilite is not used. A line of text can be represented by more than one line of screen text ( chunk ) . To access the text chunk-wise, use get_chunk method.

Methods

add_marker X, Y

Adds visual coordinated X,Y to the markers property.

back_char [ REPEAT = 1 ]

Removes REPEAT times a character left to the cursor. If the cursor is on 0 x-position, removes the new-line character and concatenates the lines.

Default key: Backspace

cancel_block

Removes the selection block

Default key: Alt+U

change_locked

Returns 1 if the logical locking is on, 0 if it is off.

See also lock_change.

copy

Copies the selected text, if any, to the clipboard.

Default key: Ctrl+Insert

copy_block

Copies the selected text and inserts it into the cursor position, according to the blockType value.

Default key: Alt+C

cursor_cend

Moves cursor to the bottom line

Default key: Ctrl+End

cursor_chome

Moves cursor to the top line

Default key: Ctrl+Home

cursor_cpgdn

Default key: Ctrl+PageDown

Moves cursor to the end of text.

cursor_cpgup

Moves cursor to the beginning of text.

Default key: Ctrl+PageUp

cursor_down [ REPEAT = 1 ]

Moves cursor REPEAT times down

Default key: Down

cursor_end

Moves cursor to the end of the line

Default key: End

cursor_home

Moves cursor to the beginning of the line

Default key: Home

cursor_left [ REPEAT = 1 ]

Moves cursor REPEAT times left

Default key: Left

cursor_right [ REPEAT = 1 ]

Moves cursor REPEAT times right

Default key: Right

cursor_up [ REPEAT = 1 ]

Moves cursor REPEAT times up

Default key: Up

cursor_pgdn [ REPEAT = 1 ]

Moves cursor REPEAT pages down

Default key: PageDown

cursor_pgup [ REPEAT = 1 ]

Moves cursor REPEAT pages up

Default key: PageUp

cursor_shift_key [ ACCEL_TABLE_ITEM ]

Performs action of the cursor movement, bound to ACCEL_TABLE_ITEM action ( defined in accelTable or accelItems property ), and extends the selection block along the cursor movement. Not called directly.

cut

Cuts the selected text into the clipboard.

Default key: Shift+Delete

delete_block

Removes the selected text.

Default key: Alt+D

delete_char [ REPEAT = 1 ]

Delete REPEAT characters from the cursor position

Default key: Delete

delete_line LINE_ID, [ LINES = 1 ]

Removes LINES of text at LINE_ID.

delete_current_chunk

Removes the chunk ( or line, if wordWrap is 0 ) at the cursor.

Default key: Ctrl+Y

delete_chunk CHUNK_ID, [ CHUNKS = 1 ]

Removes CHUNKS ( or lines, if wordWrap is 0 ) of text at CHUNK_ID

delete_marker INDEX

Removes marker INDEX in markers list.

delete_to_end

Removes text to the end of the chunk.

Default key: Ctrl+E

delete_text X, Y, TEXT_LENGTH

Removes TEXT_LENGTH characters at X,Y physical coordinates

draw_colorchunk CANVAS, LINE_ID, X, Y, COLOR

Paints the syntax-highlighted chunk taken from LINE_ID line index, at X, Y. COLOR is used if the syntax highlighting information contains cl::Fore as color reference.

end_block

Stops the block selection session.

find SEARCH_STRING, [ X = 0, Y = 0, REPLACE_LINE = '', OPTIONS ]

Tries to find ( and, if REPLACE_LINE is defined, to replace with it ) SEARCH_STRING from (X,Y) physical coordinates. OPTIONS is an integer that consists of the fdo:: constants; the same constants are used in Prima::Dialog::FindDialog, which provides graphic interface to the find and replace facilities of Prima::Edit.

Returns X1, Y, X2, NEW_STRING where X1.Y-X2.Y are physical coordinates of the found string, and NEW_STRING is the replaced version (if any)

fdo::MatchCase

If set, the search is case-sensitive.

fdo::WordsOnly

If set, SEARCH_STRING must constitute the whole word.

fdo::RegularExpression

If set, SEARCH_STRING is a regular expression.

fdo::BackwardSearch

If set, the search direction is backwards.

fdo::ReplacePrompt

Not used in the class, however, used in Prima::Dialog::FindDialog.

See also: examples/editor.pl

get_chunk CHUNK_ID

Returns chunk of text, located at CHUNK_ID. Returns empty string if chunk is nonexistent.

get_chunk_cluster_length CHUNK_ID

Return length of a chunk in clusters

get_chunk_dimension CHUNK_ID

Finds the line number the CHUNK_ID belongs to, return first chunk of that line and how many chunks the line occupies.

get_chunk_width TEXT, FROM, LENGTH, [ RETURN_TEXT_PTR ]

Returns the width in pixels of substr( TEXT, FROM, LENGTH). If FROM is larger than length of TEXT, TEXT is padded with space characters. Tab character in TEXT replaced to tabIndent times space character. If RETURN_TEXT_PTR pointer is specified, the converted TEXT is stored there.

get_line INDEX

Returns line of text, located at INDEX. Returns empty string if line is nonexistent.

get_line_cluster_length LINE_ID

Return length of a line in clusters

get_line_dimension INDEX

Returns two integers, representing the line at INDEX in wordWrap mode: the first value is the corresponding chunk index, the second is how many chunks represent the line.

See also: physical_to_logical.

get_selected_text

Return the text currently selected.

has_selection

Returns boolean value, indicating if the selection block is active.

insert_empty_line LINE_ID, [ REPEAT = 1 ]

Inserts REPEAT empty lines at LINE_ID.

insert_line LINE_ID, @TEXT

Inserts @TEXT strings at LINE_ID

insert_text TEXT, [ HIGHLIGHT = 0 ]

Inserts TEXT at the cursor position. If HIGHLIGHT is set to 1, the selection block is canceled and the newly inserted text is selected.

lock_change BOOLEAN

Increments ( 1 ) or decrements ( 0 ) lock count. Used to defer change notification in multi-change calls. When internal lock count hits zero, Change notification is called.

physical_to_logical X, Y

Maps visual X,Y coordinates to the logical and returns the integer pair. Returns same values when wordWrap is 0.

logical_to_visual X, Y

Maps logical X,Y coordinates to the visual and returns the integer pair.

Returns same values when wordWrap is 0.

visual_to_physical X, Y

Maps visual X,Y coordinates to the physical text offset relative to the Y line

Returns same X when the line does not contain any right-to-left characters or complex glyphs.

physical_to_visual X, Y

Maps test offset X from line Y to the visual X coordinate.

Returns same X when the line does not contain any right-to-left characters or complex glyphs.

mark_horizontal

Starts block marking session with bt::Horizontal block type.

Default key: Alt+L

mark_vertical

Starts block marking session with bt::Vertical block type.

Default key: Alt+B

overtype_block

Copies the selected text and overwrites the text next to the cursor position, according to the blockType value.

Default key: Alt+O

paste

Copies text from the clipboard and inserts it in the cursor position.

Default key: Shift+Insert

realize_panning

Performs deferred widget panning, activated by setting {delayPanning} to 1. The deferred operations are those performed by offset and topLine.

set_line LINE_ID, TEXT, [ OPERATION, FROM, LENGTH ]

Changes line at LINE_ID to new TEXT. Hint scalars OPERATION, FROM and LENGTH used to maintain selection and marking data. OPERATION is an arbitrary string, the ones that are recognized are 'overtype', 'add', and 'delete'. FROM and LENGTH define the range of the change; FROM is a cluster offset and LENGTH is a length of changed text.

split_line

Splits a line in two at the cursor position.

Default key: Enter ( or Ctrl+Enter if wantReturns is 0 )

select_all

Selects all text

start_block [ BLOCK_TYPE ]

Begins the block selection session. The block type if BLOCK_TYPE, if it is specified, or blockType property value otherwise.

update_block

Adjusts the selection inside the block session, extending of shrinking it to the current cursor position.

word_left [ REPEAT = 1 ]

Moves cursor REPEAT words to the left.

word_right [ REPEAT = 1 ]

Moves cursor REPEAT words to the right.

AUTHOR

Dmitry Karasik, <dmitry@karasik.eu.org>.

SEE ALSO

Prima, Prima::Widget, Prima::Dialog::FindDialog, examples/editor.pl