Class editor describes a graphical object that can be used to edit long textual descriptions. PCE editors have similar design and user-interface as GNU-Emacs. New functionality may added by means of class key_binding.
WHY A PCE EDITOR?
Many applications manipulate large text fields. For many applications, editing text is one of the most important activities. Unfortunately, there is not much of a standard as far as editors is concerned. For this reason, the best option would be to allow the user to run an editor of his/her choice. Unfortunately no good interfacing protocol is available that allows us to manage the text in the editor from inside PCE and read a considerable amount of status information from the editor.
Therefore, PCE defines it's own editor. The basic user interface of the editor is based on the widely accepted GNU-EMACS editor and can be extended and modified to improve compatibility to other editors.
Class editor is a
subclass of device because it is implemented as a compound graphical
object, consisting of the following parts.
text_image object Graphical that displays the text itself scroll_bar object Allows you to scroll the text vertically text_cursor object Graphical that displays the caret text_margin object Optional annotation margin text_buffer object Storage and low-level manipulation
The editor uses the following vocabulary:
<-caret
Current position of the insertion-point, indicated using a
text_cursor
object. For proportional fonts, this is a triangle with a vertical
line-segment. For fixed fonts, this is a static block.
<-mark
Unvisible point that, together with the editor<-caret,
describes the REGION. Many operations work on a REGION of the entire
text (deleting, formatting, etc.).
<-caret
and the editor<-mark.
\C-u digit ... M-<digit> ...
and reset after the completion of the next interactive command. The
interpretation is command dependent, but most commands interpret the
argument as do this command so many times.
The UI of PCE editors is based on GNU-EMACS. Many of the basic function of GNU-EMACS are available. Like GNU-EMACS, the PCE editors can be programmed. Unlike GNU-EMACS however, this is not done by programming EMACS-LISP, but by adding methods to the editor (or class editor) and linking these methods to key-strokes.
As the basic functionality is rich and can be expanded/redefined, it should not be very difficult to transform the PCE-editor into an editor that is largely compatible to most available editors.
PCE-editors can be operated both mouse-driven and keyboard-driven, although the latter is the principal way of manipulating a text.
-exact_case-indent_increment
->append.
Backward compatibility only.
<-defaults bound to the
built-in key_binding
object named editor. This implies that bindings created
using editor->key_binding
are local to the editor.
<-caret
is the current insertion point. In ranges from 0 up to and
including editor<-size.
Zero implies insert at the beginning; editor<-size
implies append at the end.
The method editor->caret
is invoked explicitly from all internal methods that manipulate the
caret and this method may thus be redefined to keep track of the users
caret-movements.
The editor<-mark
is a mark that moves with inserts and, together with the editor<-caret,
defines the region. The region can be in various modes as described by editor<-mark_status.
To get the caret from an event, see text_image<-index.
The location of the caret is visualised by a text_cursor
object that can be requested using editor<-text_cursor.
dabbrev_origin to dabbrev_pos.
See also editor->show_caret
for hiding the caret on read-only editors.
BUG: In the original design, methods were fixed and methods
either implemented behaviour intended for user interaction or methods
intended for program interaction. The editor->editable
flag only affected interactive methods. Some of this distinction still
remains. It is adviced to set editable to @on
before modifying a read-only editor
object from the program to avoid confusion.
->report.
When defined, editor->report
will execute this message with arguments given below:
@receiver: The editor (or view) @arg1 idem @arg2 The type (status/warning/inform/error) @arg3 String representing the message itself
See visual->report
for a general discussion on the reporting system.
Defaults: @nil
->switch_case_mode
sets editor<-exact case according to the
argument:
@default toggle editor <-exact_case> 0 editor ->exact_case: @on<= 0 editor <-exact_case: @off
Defaults: @off (Resource determined).
<->right_margin
while inserting text.
editor->auto_fill_mode
may be used to set editor<-fill_mode
interactively:
@default: toggle editor <-fill_mode> 0 editor ->fill_mode: @on<= 0 editor ->fill_mode: @off
<->focus_function
variable is used to process commands that start a kind of sub-mode,
such as entering a numeric argument, doing incremental search, doing a
dabbrev expansion, etc.
An interactive behaviour that uses such a sub-loop sets this variable
to the selector that handles the loop. As a consequence, editor->typed
will invoke this method on each subsequent character typed until
<->focus_function
to @nil. If
the method invoked via editor<->focus_function
succeeds, editor->typed
assumes the character is handled.
By convention, the method that is invoked by the focus function has the same name than the method that set the focus preceded by an underscore:
quoted_insert ->
_quoted_insert
text_image ->tab_stopsSet vector of tab-stops text_image ->wrapControl line-wrapping
Direct access may also be used to attach event-handling to the
editor. For example, if a popup is attached to the editor as a whole it
might contradict with the editor<-scroll_bar.
Associating the popup with the
editor<-image
ensures it only operates in the text area.
This group of commands is intended for editing source-code.
Defaults: 4 (Resource defined)
->label.
See also editor<->show_label.->fill, editor->justify_paragraph,
editor->fill_mode,
etc. The method editor->set_fill_column
may be used to set both methods interactively (Dope compatibility):
@default Report current margins > 0 Set editor ->right_margin< 0 Set editor ->left_margin to the absolute value.
Defaults: 0
<-style,
and editor->style.
When the editor->margin_width
is set to a value > 0 and there is no editor<-margin,
a margin is created.
Defaults: @nil (no margin)
-caret
->mark,
the old mark is pushed into the ring. The maximum size of the ring is
hard-coded to 16. The command editor->set_mark
with a prefix argument cycles throught the saved marks.<-selection_style.
Region commands are effective if the mark is in this state.
->exchange_point_and_mark
(C-x C-x). The regions is made inactive with the command editor->keyboard_quit
(C-g).
->select_line.
See also editor->caret
and editor->selection.
<->modified
attribute of the associated text_buffer changes and this message is not @nil,
this message is executed with the following arguments:
@receiver Editor or view @arg1 New value of editor <->modified
Inherits description from: editor-left_margin
->width
to 0 before the editor is displayed effectively removes it.
->isearch_forward
and
editor->isearch_backward
to resp. forward and backward.
->isearch_forward
and
editor->isearch_backward.
Used to return when the search is canceled.
<-selected_fragment_style.
There is no default user-interface for selecting fragments. text_buffer<-find_fragment
and text_margin<-fragment
may be useful methods for defining a user-interface.
-selected_fragment
@see text_margin-styles @see class fragment<-ex
of the current editor<-font.,
height in font<-height.
The methods editor->_size, graphical->area
and graphical->set
may still be used to handle the pixel size directly.
<-style
onto style objects
that determine the actual appearance of a fragment. This separates
semantical information represented by the fragment from visualisation as
achieved in the editor. Setting the style to
@nil deletes
the visual appearance of fragments with this name.
The following skeleton illustrates this. E is an editor. The final code fragment creates a fragment to turn the current selection into a title.
:- pce_global(@title_style,
new(style(font :=
font(helvetica, bold, 16)))).
...
send(E, style, title, @title_style),
...
...
get(E, selection, point(Start, End)),
Length is End - Start,
new(F, fragment(E, Start, Length, title)),
...
<-ex
units of the current editor<-font.
Mainly used for handling source-code. When editor->tab_stops
is defined the value of this variable is ignored.<-text_buffer
stores the text. Class editor
delegates messages not understood to the editor<-text_buffer.
A text_buffer can have multiple editors operating on it simultaneously.
The text_buffer
object associated to an editor may be changed anytime.->dabbrev_expandindex
[editor<-caret]
will have editor<-indentation column.
When layout characters are deleted, at least a single space remains.
Useful for realising automatic indentation and alignment of comments in syntax driven editors.
<-left_margin
is used. See also editor->align,
align_region and editor->indent_line.->align_line
to all lines in the current region (mark, caret).<-left_margin
is not zero, editor->align
the last line to editor<-left_margin.
Then append the text. If editor<-auto_newline
is @on, append
a newline too. Set the editor->caret
at the end of the buffer.
editor->print editor->insert’s
the text at the editor<-caret,
followed by a newline character if editor<-auto_newline
equals @on.
Bugs: Messy. New code should use the editor->align
and editor->format
methods.
->format
and string->format
(argument specification).->insert_self_fill
detected a long line. The default implementation fills from the start of
the current line to the end of the paragraph, using the left-margin from
the current indentation.
This method is intended for redefinition in language mode to perform more mode-dependent filling such as breaking long comments, log argument lists, etc.
-fill_modetimes the indicated unit backwards. The
definition of words, sentences and paragraphs depends on the syntax_table
object associate to the editor<-text_buffer.
See also text_buffer<-scan.->kill
and editor->yank
for details on killing and yanking (cut/copy) text.->capitalise_word/editor->upcase_word
and editor->downcase_word
group, but affects the word before rather than after the editor<-caret.
Saves keystrokes when used to correct typos while entering text.<-caret
up to the end of this word. editor->capitalise_word
maps the first letter to uppercase and the remainder to lowercase.->clear.
Deletes the selection and sets the editor<-caret
to 0.<-column->compute.
Next verifies that the editor<-caret
is in the window and moves the window if necessary. Finally update the
editor<-text_cursor, editor<-margin
and editor<-scroll_bar.|event_id\C-x or \C-c as
Emacs prefix keys or CUA-mode Cut/Copy commands. The rules for this are
based on cua.el, a GNU-Emacs mode merging CUA
and Emacs by Kim F. Storm (storm@cua.dk):
<-mark_status),
map them to copy or cut.
.25
seconds, use map them to their Emacs prefix behaviour.
According to Kim this results in pretty normal behaviour for both
Emacs and CUA users. CUA users expect the bevahiour on the selection
only. Emacs users have some trouble with
\C-c or \C-x commands that act on the region,
but luckily these conflicts are acceptable.
The underlying behaviour is implemented by key_binding->typed.
->delete, editor->grab
and editor->kill
operate on characters in the range [from, to) (i.e. to
minus from characters). If to <
from, the arguments are first swapped. The commands may or
may not delete the range and may or may not add the deleted text to the
kill-buffer @text_kill_ring:
editor ->deleteJust deletes the text editor ->killeditor ->delete and add the deleted text to the kill ringeditor ->grabAdd the text to the kill-ring without deleting it.
See also @text_kill_ring and editor->yank.
->delete_horizontal_space
and editor->just_one_space.->just_one_space.<-mark
... editor<-caret)
to the specified case. editor->capitalise_region
will map any first letter of a word to uppercase and any other letter to
lowercase.
This method may be used to indicate a related position. For example if the user types a closing-bracket this method may be used to indicate the matching opening bracket.
Defaults: The default time to restore the caret is 0.5
seconds.
->event
succeeds. This allows for redefining event-handling on any of the parts
of the editor.
->typed.
->active
status.
->event
to this object and return the result thereof.
<-mark
with editor<-caret.
Note that commands operating on the region (the text between the two) do
not care which of the two has the lowest index.
<-left_margin
and editor<-right_margin.
If justify equals @on, editor->fill
inserts spaces such that the right_margin will be straight.
Bugs: Only works properly with fixed-width fonts,
->fill_region.->fill
the specified text. The margins default to
editor<-left_margin
and editor<-right_margin.
<-cut_buffer
as a plain string. Respects editor<-exact_case.
If the string is found it is selected, otherwise a warning is editor->report’ed.<-caret
location. See string->format
for a description on the format specification. See also editor->appendf.times the indicated unit forwards. The
definition of words, sentences and paragraphs depends on the
syntax_table
object associate to the editor<-text_buffer.
See also
text_buffer<-scan.<-scroll_bar, editor<-image
and editor<-margin.
The minimum size is defined to be 50x20 pixels.->gosmacs_transpose
this requires a single keystroke. Using
editor->transpose_chars
this requires 3 keystrokes.-size<-indent_increment.->indent_region.<-indent_increment.<-indent_increment.->undent_region.arg
times editor<-indent_increment.
This group of methods is compatible to the Dope editor and allows for
manipulating the indentation when editing source-code. See also editor->align_line.
The margin specifies the with of the text_margin
object attached to the right side used for annotations. The default is
0, attaching no annotation margin. See also editor->margin.
<-cut_buffer.
Move caret to the end.times times.
The editor->insert
method calls editor->insert_self_fill
if editor<-auto_fill_mode equals @on.
The editor->insert_self_fill
calls editor->auto_fill
if -after the insertion-, the text extends the editor<-right_margin.
Normally this fills the remainder of the paragraph. By redefining editor->auto_fill,
more specialised handling of long lines can be implemented.
<-exact_case)
and indicate the first hit using the selection on each
subsequent letter typed by the user. While searching, the following keys
have special meaning:
keyboard_quit Abort and revert to where search started isearch_backward isearch_forward Revert direction or search for next backward_delete_char Remove the last character from the target ESCAPE Terminate search \C-w Extend target to current word
->fill
the specified unit of text. The justify argument of editor->fill
is set to @on,
creating a straight right margin.|code<-bindings
using key_binding->function
to this object. The key_binding remains local to the receiving editor.
The method editor<-key_binding
requests the current binding (local or global) using key_binding<-function.->kill
the current region. Otherwise
editor->grab
the region.<-label_text.
The font of the label is dictated by editor.label_font.
See also editor<->show_label.->normalise.->clear Clear the editor `text_buffer ->insert_file` Insert the file contents <-file Assign the file variable ->caret: 0 Put the caret `home` `text_buffer ->modified: @off` Clear modified `text_buffer ->reset_undo` Clear undo info ->editable: Bool
If file->access
succeeds, editor->editable: @on
is invoked on the editor, otherwise editor->editable: @off.
<-text_buffer
if it is being freed. By default, this method will simply send object->free
to the editor, or its associated view
object.
This method may be redefined, but should either free the editor, or associate another (new) text_buffer object with the editor.
See also text_buffer->unlink.
-margin, editor<-margin_width
<-mark
... editor<-caret)
or [editor<-caret
.. editor<-mark)
if the caret is before the mark. The old position of the mark is pushed
in editor<-mark_ring.
If the mark is
active, it can be used for region-commands.
See also editor->set_mark, editor<-mark_ring
and editor->selection.
times newline characters. editor->newline
inserts before the caret,
editor->open_line after
the caret, so the caret remains at the same line.<-column
is used. Normally the column is maintained by class key_binding.
from resides will be the
first line displayed. See also editor->line_to_top_of_window
and
editor->recenter.
Defaults: Both arguments default to editor<-caret
<-caret
to the editor<-mark.
In most cases editor->exchange_point_and_mark
is to be preferred. See also editor->set_mark.
->line_number.->line_to_top_of_window,
but centers the current line on the window rather than making it the
first line.<-error_message
is not @nil,
execute it using the following arguments:
@receiver The editor <-master of the editor@arg1 The editor @arg2 the kind@arg3 The message
See visual->report
for a discussion on the reporting mechanism.
<-file
or named file. If no file is specified and editor<-file
is
@nil, this
method fails. If the file to save in exists, a backup is created using file->backup.
Next, the contents of the editor is saved into the named file. If a file
was specified, editor<-file
will be filled with the argument file.
<-file
if it is editor<-modified or the argument
is not
@default. If
the operation succeeds, the editor<-modified
flag is cleared. Diagnostics are reported using editor->report.
one_line versions of this method, the default is to scroll
a single line. For editor->scroll_up/editor->scroll_down
the default is a screenful minus a line.See text_buffer<-scan.
<-scroll_bar.
Normally there is no reason to deal with this method yourself. We
document it here to explain the three scrolling models used by the
editor.
If the text_buffer<-size
(i.e. the number of characters held by the
editor) is large, It determines the position and size of the scrollbar
based on character offsets.
If the size gets medium, it counts physical lines, i.e.
the number of newline characters.
If the size gets small, it computes the line-layout, including
line-heigth using the current editor<-wrap
setting. This mode provides relyable precise scrolling, but quickly gets
too costly for real-time usage.
Inherits description from: editor<-length
<-selected_fragment.
See also editor->margin_width, editor->selection_style
and class style.
->normalise
on the same range to make the selection or as much as possible thereof
visible. If to is equal to
from, no selection is visible and the editor is not
normalised.
The selection is determined by editor<-mark
and editor<-caret.
It can be in three modes as described with editor<->mark_status.
See also editor<-selected, editor<-selection, editor<-selection_start
and editor<-selection_end.
Defaults: The first argument (from) defaults to
the current start of the selection; the second (to) to the
current end of the selection.
-left_margin
<-mark
at editor<-caret,
starting an active selection, also called region. With an argument this
command cycles through the list marks in the editor<-mark_ring.
Programmatic access to the mark is provided by editor->mark.
->editable.<-start
and editor<-view).
This method is used by
editor->electric_caret..
<-label_text,
one is created. Otherwise the graphical<->displayed
attribute of the label_text is used to control the visibility of the
label. The method editor->geometry
is invoked to realise the proper layout of the components of the editor
object.<-caret)
using editor->electric_caret.-size->sort-styles
-exact_case
<-text_buffer|event_id->event
to handle typing. Handles editor<-focus_function
and/or invokes key_binding->typed
on editor<-bindings.
->event.->downcase_region-size<-wrap<-element
of
@text_kill_ring. Text is inserted in the kill-ring using editor->kill
or
editor->grab.
index. Interprets editor<-tab_stops.
When set, the editor<-caret
is moved as close as possible to the indicated column. See also editor->align.<-editor.
Improves the transparency between class editor
and class view.->dabbrev_expand.
The mode argument describes the stage of the expansion:
towards the start of the buffer and then to the end.
This method should return a list if candidates, each starting with target.
-size<-caret.
If regex is specified, regex->match
is executed from the start of the line and the column for the end of the
match is returned. If the regex does not match at all, 0 is returned.
This method is commonly used in combination with editor->align
for language dependent automatic indentation and alignment.
|event_id -> action=name|code->key_binding<-length, editor<-start
and editor<-view
are used by the related
scroll_bar object
to determine the visible part of the text. The method
editor->scroll_vertical
is called from the editor<-scroll_bar.<-caret
is returned.index. If index is omitted, editor<-caret
is used as default. The line-numbers returned refers to the physical
line number. In other words, the returned number is the number of LF
(Line-Feed) characters from the start of the buffer to index
plus one.
This numbering is conventionally used by programming languages.
-margin|view<-device
yields an instance of class view.
Otherwise return the editor itself. Used when the editor executes a code
object. See editor<-error_message
and editor<-modified_message.
See also visual<-master.
<-line,
moves caret to next line. Fails after reading the last line of text.
When reading the whole buffer in this fashion, don't forget to set editor->caret:
0 before starting. See also file<-read_line.<-x
is the start of the selection and
device<-y
is the end of the selection (not including: 50,51 represents a selection
holding one characters). The device<-x
is guaranteed to be smaller than device<-y.
The selection is determined by the editor<-mark
and editor<-caret.
<-caret.
See also editor<-mark
and
editor<-selection.<-mark.
See also editor<-caret
and editor<-selection.
Inherits description from: editor-selection_end
-size->tab_stops
-sizecharacter,
breaking long-lines at the character level. If none is
used, text exceeding the left-margin is simply discarded. Finally,
word makes the editor break lines at the start of a word.
See also text_image->wrap.
editor->wrap
chooses between the two views on a text-file realised by class editor.
The default mode is intended for editing source code or other
traditional line-based text documents, generally using a fixed-width font
object. Using‘editor->wrap:
word’, the editor treats the file as a sequence of paragraphs
separated by newlines. The latter is the common view for most modern
GUIs for textareas.
In addition to wrapping, a number of commands are influenced by editor<-wrap
to use screen-lines rather then physical lines if
editor<-wrap
= word. This is only the case if the method is not passed a
numerical argument.
->end_of_line, editor->beginning_of_line
->kill_line
->cursor_up, editor->cursor_down
->scroll_vertical
(handling the scroll_bar
object).