The editor functions described in this section can be combined and provided with arguments to create new commands.
Existing editor commands can also be used in the creation of new commands. Every editor command documented in this manual is named by a string command which can be used to invoke the command interactively, but there is also associated with this a standard Lisp function (the "command function") named by a symbol exported from the editor package. You can use this symbol to call the command programmatically. For example, the editor command Forward Character is referred to by editor:forward-character-command
.
The first argument of any command function is the prefix argument p, and this must therefore be included in any programmatic call, even if the prefix argument is ignored. Some commands have additional optional arguments. For example to insert 42 #\! characters, you would call
(editor:self-insert-command 42 #\!)
Details of these optional arguments are provided in the command descriptions throughout this manual.
See editor:defcommand for the details of how to create new commands.
Note: code which modifies the contents of a capi:editor-pane
(for example a displayed editor buffer) must be run only in the interface process of that pane.
The following sections describe editor functions that are not interactive editor commands.
All editor commands and some other editor functions expect to be called within a dynamic context that includes settings for the current buffer and current window. This happens automatically when using the editor interactively.
You can set up the context in a CAPI application by using the function capi:call-editor
(see the
CAPI User Guide and Reference Manual
).
You can also use the following function to call editor commands and functions.
editor:process-character char window
Processes char in a dynamic context where the current window is window and the current buffer is the buffer currently displayed in window.
The char can be one of the following:
(
function .
args)
, which causes function to be called with args. The items in args are not evaluated.nil
as its argument (like a command function would be if there is no prefix argument).system:gesture-spec
object, which is treated as if it has been typed on the keyboard.There is no return value. The processing may happen in another thread, so may not have competed before this function returns.
defcommand name lambda-list command-doc function-doc &body forms => command-function
Defines a new editor command. name is a usually string naming the new editor command which can invoked in the editor via Extended Command, and command-function is a symbol naming the new command function which can be called programmatically. The command-function symbol is interned in the current package.
lambda-list is the lambda list of the new command, which must have at least one argument which is usually denoted p, the prefix argument.
command-doc and function-doc should be strings giving detailed and brief descriptions of the new command respectively.
forms is the Lisp code for the command.
The name of the command must be a string, while the name of the associated command function must be a symbol. There are two ways in which name can be supplied. Most simply, name is given as a string, and the string is taken to be the name of the editor command. The symbol naming the command function is computed from that string: spaces are replaced with hyphens and alphabetic characters are uppercased, but otherwise the symbol name contains the same characters as the string with -COMMAND
appended.
If a specific function name, different to the one defcommand
derives itself, is required, then this can be supplied explicitly. To do this, name should be a list: its first element is the string used as the name of the command, while its second and last element is the symbol used to name the Lisp command function.
For example the following code defines an editor command, Move Five
, which moves the cursor forward in an editor buffer by five characters.
(editor:defcommand "Move Five" (p)
"Moves the current point forward five characters.
Any prefix argument is ignored."
"Moves five characters forward."
(editor:forward-character-command 5))
=>
MOVE-FIVE-COMMAND
The prefix argument p is not used, and is there simply because the lambda-list must have at least one element.
Use Meta+X Move Five
to invoke the command.
As another example this command changes all the text in a writable buffer to be uppercase:
(editor:defcommand "Uppercase Buffer" (p)
"Uppercase the buffer contents" ""
(declare (ignore p))
(let* ((buffer (editor:current-buffer))
(point (editor:buffer-point buffer))
(start (editor:buffers-start buffer))
(end (editor:buffers-end buffer)))
(editor:set-current-mark start)
(editor:move-point point end)
(editor:uppercase-region-command nil)))
Having defined your new command, you can invoke it immediately by Meta+X Uppercase Buffer
.
You could also call it programmatically:
(uppercase-buffer-command nil)
If you anticipate frequent interactive use of Uppercase Buffer
you will want to bind it to a key. You can do this interactively for the current session using Bind Key. Also you can put something like this in your initialization file to establish the key binding for each new session:
(editor:bind-key "Uppercase Buffer" #("Control-x" "Meta-u"))
Then, entering Ctrl+X Meta+U
will invoke the command.
Arguments: new-name,
command-name
Key sequence: None
The command Define Command Synonym
prompts for a string and an existing command name, and makes the string be a synonym for the existing command name.
Each buffer that you manipulate interactively using editor commands is an object of type editor:buffer
that can be used directly when programming the editor. Buffers contain an arbitrary number of editor:point
objects, which are used when examining or modifying the text in a buffer (see Points).
Each buffer contains a lock that is used to prevent more than one thread from modifying the text, text properties or points within the buffer simultaneously. All of the exported editor functions (editor:insert-string, editor:move-point etc) claim this lock implicitly and are therefore atomic with respect to other such functions.
In situations where you want to make several changes as one atomic operation, use one of the macros editor:with-buffer-locked or editor:with-point-locked to lock the buffer for the duration of the operation. For example, if you want to delete the next character and replace it by a space:
(editor:with-buffer-locked ((editor:current-buffer))
(editor:delete-next-character-command nil)
(editor:insert-character (editor:current-point)
#\Space))
In addition, you sometimes want to examine the text in a buffer without changing it, but ensure that no other thread can modify it in the meantime. This can be achieved by locking the buffer using editor:with-buffer-locked or editor:with-point-locked and passing the for-modification argument as nil
. For example, if you are computing the beginning and end of some portion of the text in a buffer and then performing some operation on that text, you may want to lock the buffer to ensure that no other threads can modify the text while your are processing it.
editor:with-buffer-locked (buffer &key for-modification check-file-modification block-interrupts) &body body => values
Evaluates body while holding the lock in buffer. At most one thread can lock a buffer at a time and the macro waits until it can claim the lock.
If for-modification is non-nil (the default), the contents of buffer can be modified by body. If for-modification is nil
, the contents of buffer cannot be modified until body returns and trying to do so from within body will signal an error. If the buffer is read-only and for-modification is non-nil, then an editor:editor-error
is signaled. The status of the lock can be changed to for-modification (see editor:change-buffer-lock-for-modification). If the buffer is read-only, an editor:editor-error occurs if for-modification is t
.
The macro editor:with-buffer-locked
can be used recursively, but if the outermost use passed nil
as the value of for-modification, then inner uses cannot pass non-nil as the value of for-modification, unless editor:change-buffer-lock-for-modification is used to change the lock status.
If check-file-modification is non-nil (the default) and the buffer is associated with a file and has not already been modified, then the modification time of the file is compared to the time that the file was last read. If the file is newer than the buffer, then the user is asked if they want to re-read the file into the buffer, and if they do then the file is re-read and the operations aborts. Otherwise, there is no check for the file being newer than the buffer.
If block-interrupts is non-nil, the body is evaluated with interrupts blocked. This is useful if the buffer may be modified by an interrupt function, or some interrupt function may end up waiting for another thread that may wait for the buffer lock, which would cause a deadlock. The default is not to block interrupts.
Note that using a non-nil value for block-interrupts is not the same as using the without-interrupts
or without-preemption
macros. It just stops the current thread from calling interrupt functions, so other threads might run while the body is being evaluated.
The values returned are those of body.
editor:with-point-locked (point &key for-modification check-file-modification block-interrupts errorp) &body body => values
Evaluates body while holding the lock in the buffer that is associated with point. In addition, the macro checks that point is valid and this check is atomic with respect to calls to the function editor:delete-point. The values of for-modification, check-file-modification and block-interrupts have the same meanings as for editor:with-buffer-locked.
The value of errorp determines the behavior when point is not valid. If errorp is non-nil, an error is signaled, otherwise nil
is returned without evaluating body. The point may be invalid because it does not reference any buffer (that is, it has been deleted), or because its buffer was changed by another thread while the current thread was attempting to lock the buffer.
The values returned are those of body, or nil
when errorp is nil
and point is not valid.
editor:change-buffer-lock-for-modification
editor:change-buffer-lock-for-modification buffer &key check-file-modification force-modification => result
Changes the status of the lock in the buffer buffer to allow modification of the text. buffer must already be locked for non-modification by the current thread (that is, it must be dynamically within a editor:with-buffer-locked or editor:with-point-locked form with for-modification nil
).
An editor buffer.
:buffer-not-locked
, :buffer-out-of-date
or :buffer-not-writable
.
If check-file-modification is non-nil, the same test as described for editor:with-buffer-locked is performed, and if the file has been modified then :buffer-out-of-date
is returned without changing anything (it does not prompt the user to re-read the file).
The default value of check-file-modification is t
.
force-modification controls what happens if the buffer is read-only. If force-modification is nil
, the function returns :buffer-not-writable
and does nothing. If it is non-nil, the status is changed. The buffer remains read-only.
result is nil
if the status of the locking was changed to for-modification, or if the status of the buffer lock was already for-modification. Otherwise, result is a keyword indicating why the status could not be changed. When result is non-nil, the status of the locking remains unchanged.
The returned value can be be one of:
The buffer is not locked by the current thread.
The buffer is not writable, and force-modification is nil
.
The file that is associated with the buffer was modified after it was read into the editor, the buffer is not modified, and check-file-modification is non-nil.
Contains a list of all the buffers in the editor.
editor:current-buffer
editor:buffer-name buffer
editor:window-buffer window
Returns the buffer currently associated with window.
editor:buffers-start buffer
Returns the starting point of buffer.
editor:buffers-end buffer
Returns the end point of buffer.
editor:buffer-point buffer
Returns the current point in buffer.
editor:use-buffer buffer &body forms
Makes buffer the current buffer during the evaluation of forms.
editor:buffer-from-name name
Returns the buffer called name (which should be a string). If there is no buffer with that name, nil
is returned.
make-buffer name &key modes contents temporary base-name name-pattern
Creates or returns an existing buffer.
name should be a string or nil
.
modes should be a list of strings naming modes. The first mode must be a major mode, and the rest minor modes. The default value of modes is the value of default-modes.
base-name should be a string or nil
. If name and temporary are both nil
then base-name must be a string.
contents should be a string, nil
or t
(default value nil
).
temporary is a boolean (default value nil
).
name-pattern should be a string (default value "~a<~a>"
).
When name is non-nil, it is the name of the buffer. If there is already a buffer with this name which is not temporary and the temporary argument is nil
, make-buffer
returns that buffer. Before doing so, it sets its contents to contents unless contents is t
. When contents is nil
, the buffer is made empty.
If name is nil
or temporary is non-nil or a buffer with the name cannot be found, then a new buffer is made and returned. The buffer's contents is set to contents if contents is a string, and otherwise the buffer is made empty. The name of the buffer is set to name if name is non-nil.
If temporary is nil
, the buffer is added to the internal tables of the editor. If name is non-nil, it is used. Otherwise make-buffer
tries to use base-name. If there is already a buffer with this name, it constructs another name by
(format nil name-pattern base-name n)
with different integers n until it constructs an unused name, which it uses as the buffer's name.
If temporary is non-nil, the buffer is not added to the internal tables. It is also marked as temporary, which mainly means that it does not have auto-save and backup files, and avoids calling general hooks when it is modified.
Using :temporary t
gives you a buffer that is 'yours', that is the editor does not do anything with it except in response to explicit calls from your code. Except when actually editing files, this is the most useful way of using buffers in most cases.
capi:editor-pane
with the :buffer :temp
initarg uses
(make-buffer ... :temporary t)
editor:goto-buffer buffer in-same-window
Makes buffer the current buffer. If buffer is currently being shown in a window then the cursor is moved there. If buffer is not currently in a window and in-same-window is non-nil then it is shown in the current window, otherwise a new window is created for it.
editor:clear-undo buffer
Locations within a buffer are recorded as editor:point
objects. Each point remembers a character position within the buffer and all of the editor functions that manipulate the text of a buffer locate the text using one or more point objects (sometimes the current point).
A point's kind controls what happens to the point when text in the buffer is inserted or deleted.
:temporary
points are for cases where you need read-only access to the buffer. They are like GNU Emacs "points". They have a lower overhead than the other kinds of point and do not need to be explicitly deleted, but do not use them in cases where you make a point, insert or delete text and then use the point again, since they do not move when the text is changed. Also, do not use them in cases where more than one thread can modify their buffer without locking the buffer first (see Buffer locking)
:before-insert
and :after-insert
points are for cases where you need to make a point, insert or delete text and still use the point afterwards. They are like GNU Emacs "markers". The difference between these two kinds is what happens when text is inserted. For a point at position n from the start of the buffer, inserting len characters will leave the point at either position n or n+len according to the following table.
When text is deleted, :before-insert
and :after-insert
points are treated the same: points <= the start of the deletion remain unchanged, points >= the end of the deletion are moved with the text and points within the deleted region are automatically deleted and cannot be used again.
All points with kind other than :temporary
are stored within the data structures of the editor buffer so they can be updated when the text changes. A point can be removed from the buffer by editor:delete-point, and point objects are also destroyed if their buffer is killed.
editor:point-kind point
Returns the kind of the point, which is :temporary
, :before-insert
or :after-insert
.
editor:current-point
Returns the current point. See also editor:buffer-point.
editor:current-mark &optional pop-p no-error-p
Returns the current mark. If pop-p is t
, the mark ring is rotated so that the previous mark becomes the current mark. If no mark is set and no-error-p is t
, nil
is returned; otherwise an error is signaled. The default for both of these optional arguments is nil
.
editor:set-current-mark point
Sets the current mark to be point.
editor:point< point1 point2
Returns non-nil if point1 is before point2 in the buffer.
editor:point<= point1 point2
Returns non-nil if point1 is before or at the same offset as point2 in the buffer.
editor:point> point1 point2
Returns non-nil if point1 is after point2 in the buffer.
editor:point>= point1 point2
Returns non-nil if point1 is after or at the same offset as point2 in the buffer.
editor:copy-point point &optional kind new-point
Makes and returns a copy of point. The argument kind can take the value :before
, :after
, or :temporary
. If new-point is supplied, the copied point is bound to that as well as being returned.
editor:delete-point point
This should be done to any non-temporary point which is no longer needed.
editor:move-point point new-position
Moves point to new-position, which should itself be a point.
editor:start-line-p point
Returns t
if point is immediately before the first character in a line, and nil
otherwise.
editor:end-line-p point
Returns t
if point is immediately after the last character in a line, and nil
otherwise.
editor:same-line-p point1 point2
Returns t
if point1 and point2 are on the same line, and nil
otherwise.
editor:save-excursion &rest body
Saves the location of the point and the mark and restores them after completion of body. This restoration is accomplished even when there is an abnormal exit from body.
editor:with-point point-bindings &rest body
point-bindings is a list of bindings, each of the form (
var
point [
kind])
. Each variable var is bound to a new point which is a copy of the point point though possibly with a different kind, if kind is supplied. If kind is not supplied, then the new point has kind :temporary
.
The forms of body are evaluated within the scope of the point bindings, and then the points in each variable var are deleted, as if by editor:delete-point. Each point var is deleted even if there was an error when evaluating body.
The main reason for using with-point
to create non-temporary points is to allow body to modify the buffer while keeping these points up to date for later use within body.
editor:regular-expression-search
regular-expression-search point pattern &key forwardp prompt limit to-end brackets-limits => match-len, brackets-limits-vector
Search for pattern starting from point.
point must be an editor:point
object or nil
, meaning the result of calling editor:current-point.
pattern can be a string, a "precompiled" pattern (result of lw:precompile-regexp
), or nil
.
forwardp is a boolean (default value t
) specifying the direction to search.
prompt is a string used to prompt for a pattern when pattern is nil
.
limit should be nil
or an editor:point
specifying a limit for the search.
to-end is a boolean (default value t
), specifying whether to move the point to the end of the match when searching forward.
brackets-limits is a boolean specifying whether regular-expression-search
should return a vector of brackets-limits.
regular-expression-search
performs a search starting from point for the pattern, in the direction specified by forwardp, up to to limit if specified, or the buffer's end (when forwardp is non-nil) or the buffer's start (when forwardp is nil
). If it succeeds, it then moves the point, either to the end of that match when both forwardp and to-end are non-nil (the default), or to the beginning of the match.
When pattern is non-nil it must be either a string or a precompiled pattern created with lw:precompile-regexp
. If pattern is a string, regular-expression-search
"precompiles" it before searching, so using a precompiled pattern is more efficient when using the same pattern repeatedly.
If pattern is nil
, regular-expression-search
first prompts for a pattern in the echo area, using the prompt. If pattern is non-nil, prompt is ignored.
Return values: If regular-expression-search
is successful, it returns the length of the string that it matched, and if brackets-limits is non-nil, a second value which is a vector of the limits of the matches of each \(
and \)
pair in the pattern. The meaning of the vector is described in the manual entry for lw:find-regexp-in-string
in the
LispWorks User Guide and Reference Manual
.
Compatibility note: regular-expression-search
was exported but not documented in LispWorks 6.1 and earlier versions. brackets-limits was introduced in LispWorks 7.0.
See also:
lw:find-regexp-in-string
, lw:regexp-find-symbols
and lw:precompile-regexp
in the
LispWorks User Guide and Reference Manual
Regular expression syntax
editor:message string &rest args
A message is printed in the Echo Area. The argument string must be a string, which may contain formatting characters to be interpreted by format
. The argument args consists of arguments to be printed within the string.
editor:clear-echo-area &optional string force
Clears the Echo Area. The argument string is then printed in the Echo Area. If force is non-nil, the Echo Area is cleared immediately, with no delay. Otherwise, there may be a delay for the user to read any existing message.
Many editor commands and functions signal an error on failure (using editor:editor-error
as described below). This causes the current operation to be aborted.
In many cases, the user will not want the operation to abort completely if one of the editor commands it uses is not successful. For example, the operation may involve a search, but some aspects of the operation should continue even if the search is not successful. To achieve this, the user can catch the editor:editor-error
using a macro such as handler-case
.
For example, one part of an application might involve moving forward 5 forms. If the current point cannot be moved forward five forms, generally the Editor would signal an error. However, this error can be caught. The following trivial example shows how a new message could be printed in this situation, replacing the system message.
(editor:defcommand "Five Forms" (p)
"Tries to move the current point forward five forms, printing out an appropriate message on failure."
"Tries to move the current point forward five forms."
(handler-case
(editor:forward-form-command 5)
(editor:editor-error (condition)
(editor:message "could not move forward five"))))
editor:editor-error string &rest args
By default this prints a message in the Echo Area, sounds a beep, and exits to the top level of LispWorks, aborting the current operation. The argument string must be a string, which is interpreted as a control string by format
. As with editor:message, args can consist of arguments to be processed within the control string.
The behavior is affected by break-on-editor-error.
editor:find-file-buffer pathname &optional check-function
Returns a buffer associated with the file pathname, reading the file into a new buffer if necessary. The second value returned is T
if a new buffer is created, and nil
otherwise. If the file already exists in a buffer, its consistency is first checked by means of check-function. If no value is supplied for check-function, editor:check-disk-version-consistent is used.
editor:fast-save-all-buffers &optional ask
Saves all modified buffers which are associated with a file. If ask is non-nil then confirmation is asked for before saving each buffer. If ask is not set, all buffers are saved without further prompting.
Unlike the editor command Save All Files this function can be run without any window interaction. It is thus suitable for use in code which does not intend to allow the user to leave any buffers unsaved, and from the console if it is necessary to save buffers without re-entering the full window system.
editor:check-disk-version-consistent
editor:check-disk-version-consistent pathname buffer
Checks that the date of the file pathname is not more recent than the last time buffer was saved. If pathname is more recent, the user is prompted on how to proceed. Returns t
if there is no need to read the file from disk and nil
if it should be read from disk.
editor:buffer-pathname buffer
Returns the pathname of the file associated with buffer. If no file is associated with buffer, nil
is returned.
In an application which writes editor buffers to file, you can do this to set the external format of a given buffer:
(setf (editor:buffer-external-format buffer) ef-spec)
You can also set a global default external format for editor buffers:
(setf (editor:variable-value 'editor:output-format-default
:global)
ef-spec )
Then ef-spec will be used when a buffer itself does not have an external format.
See Unicode and other file encodings for a full description of the editor's file encodings interface.
editor:insert-string point string &optional start end
Inserts string at point in the current buffer. The arguments start and end specify the indices within string of the substring to be inserted. The default values for start and end are 0 and (length
string)
respectively.
editor:kill-ring-string &optional index
Returns either the topmost string on the kill ring, or the string at index places below the top when index is supplied.
The editor kill ring stores the strings copied by the editor, in order to allow using them later.
editor:points-to-string start end
Controls whether indentation commands such as Indent and Indent Form insert whitespace using #\Space
or #\Tab
characters when changing the indentation of a line.
The initial value is nil
, meaning that only the #\Space
character is inserted.
A true value for editor:*indent-with-tabs* causes the indentation commands to insert #\Tab
characters according to the value of spaces-for-tab and then pad with #\Space
characters as needed.
editor:*find-likely-function-ignores*
Contains a list of symbols likely to be found at the beginning of a form (such as apply
, funcall
, defun
, defmethod
, defgeneric
).
This variable determines how definitions found by the commands Find Source, Find Source for Dspec and Find Tag are shown. The value should be a list of length 2.
The first element controls the positioning of the definition: when t
, show it at the top of the editor window; when a non-negative fixnum, position it that many lines from the top; and when nil
, position it at the center of the window.
The second element can be :highlight
, meaning highlight the definition, or nil
, meaning do not highlight it.
The initial value of *source-found-action*
is (nil :highlight)
.
editor:line-end point
Moves point to be located immediately before the next newline character, or the end of the buffer if there are no following newline characters.
editor:line-start point
Moves point to be located immediately after the previous newline character, or the start of the buffer if there are no previous newline characters.
editor:character-offset point n
Moves point forward n characters. If n is negative, point moves back n characters.
editor:word-offset point n
Moves point forward n words. If n is negative, point moves back n words.
editor:line-offset point n &optional to-offset
Moves point n lines forward, to a location to-offset characters into the line. If n is negative, point moves back n lines. If to-offset is nil
(its default value), an attempt is made to retain the current offset. An error is signaled if there are not n further lines in the buffer.
editor:form-offset point n &optional form depth
Moves point forward n Lisp forms. If n is negative, point moves back n forms. If form is t
(its default value) then atoms are counted as forms, otherwise they are ignored. Before point is moved forward n forms, it first jumps out depth levels. The default value for depth is 0.
The following functions can be used to prompt for some kind of input, which is generally typed into the Echo Area.
The following keyword arguments are common to a number of prompting functions.
Specifies whether the value that is input by the user must be an existing value or not. If :must-exist
is non-nil, the user is prompted again if a non-existent value is input.
Defines the default value that is selected if an empty string is input.
Specifies the string that may be edited by the user (with Insert Parse Default).
Defines the prompt that is written in the Echo Area. Most prompting functions have a default prompt that is used if no value is supplied for :prompt
.
Provides a help message that is printed if the user types "?
".
editor:prompt-for-file &key direction must-exist create-directories default default-string prompt help
Prompts for a file name, and returns a pathname.
You can specify direction :input (when expecting to read the file) or direction :output (when expecting to write the file). This controls the default value of must-exist, which is false for direction :output and true otherwise.
If create-directories is true, then the user is prompted to create any missing directories in the path she enters. The default is false for direction :output and true otherwise.
See above for an explanation of the other arguments.
editor:prompt-for-buffer &key prompt must-exist default default-string help
Prompts for a buffer name, and returns the buffer. See above for an explanation of the keywords.
The default value of must-exist is t
. If must-exist is nil
and the buffer does not exist, it is created.
editor:prompt-for-integer &key prompt must-exist default help
Prompts for an integer. See above for an explanation of the keywords.
editor:prompt-for-string &key prompt default default-string clear-echo-area help
Prompts for a string. No checking is done on the input. The keyword clear-echo-area controls whether or not the echo area is cleared (that is, whether the text being replaced is visible or not). The default for this keyword is t
. See above for an explanation of the remaining keywords.
editor:prompt-for-variable &key must-exist prompt default default-string help
Prompts for an editor variable. See above for an explanation of the keywords. The default value of must-exist is t
.
editor:complete-in-place complete-func &key extract-func skip-func insert-func
Performs a non-focus completion at the editor current point.
complete-func should be a function designator with signature:
complete-func string &optional user-arg => result
string should be a string to complete. user-arg is the second return value of extract-func, if this is not nil
. result should be a list of items to be displayed in the list panel of the non-focus window.
extract-func must be a function designator with signature
extract-func point => string, user-arg
point should be a Point object
extract-func needs to move point to the beginning of the text that will be replaced if the user confirms. It should return two values: string is the string to complete, and user-arg can be any Lisp object. string is passed to the function complete-func, and if user-arg is non-nil it is also passed.
The default value of extract-func is a function which searches backwards until it finds a non-alphanumeric character, or the beginning of the buffer. It then moves its point argument forward to the next character. The function returns its first value string the string between this and the original location of the point, and it returns nil
as the second value user-arg.
skip-func, if supplied, must be a function designator with signature
skip-func point
point should be a Point object
point will be used as the end of the region to replace by the completion. At the call to skip-func, the point is located at the same place as the point that was passed to extract-func (after it moved). skip-func needs to move point forward to the end of the text that should be replaced when the user wants to do the completion. If skip-func is not supplied, the end point is set to the current point.
insert-func, if supplied, must be a function designator with signature
insert-func result string user-arg => string-to-use
result is the item selected by the user, string is the original string that was returned by extract-func, and user-arg is the second value returned by extract-func (regardless of whether this value is nil
). It must return a string, string-to-use, which is inserted as the the completion.
If insert-func is not supplied, the completion item is inserted. If it is not a string it is first converted by prin1-to-string
.
When editor:complete-in-place
is called, it makes a copy of the current point and passes it to extract-func. It then copies this point and positions it either using skip-func or the current point. These two points define the text to be replaced. editor:complete-in-place
then calls complete-func, and use the result to raise a non-focus window next to the current point. The interaction of this window is as described in
CAPI User Guide and Reference Manual
.
Note: editor:complete-with-non-focus
is a deprecated synonym for editor:complete-in-place
.
editor:define-editor-variable name value &optional documentation
Symbol naming the variable.
The value to assign to the variable.
A string naming a mode.
A documentation string.
The macro editor:define-editor-variable
defines a global editor variable. There is only one global value, so repeated uses of editor:define-editor-variable
overwrite each other.
editor:define-editor-variable
gives a readable value of defining a variable, and is recognized by the LispWorks source code location system. However variables can also be defined dynamically by calling (setf editor:variable-value)
. Variable values may be accessed by editor:variable-value.
A variable has only one string of documentation associated with it. editor:variable-value overwrites the existing documentation string, if there is any. You can see the documentation by the command Describe Editor Variable. It can can be accessed programmatically by editor:editor-variable-documentation.
Note: for backwards compatibility name can also be a string, which is converted to a symbol by uppercasing, replacing #\Space
by #\-
, and interning in the EDITOR package. This may lead to clashes and so you should use a symbol for name, not a string.
editor:define-editor-mode-variable
editor:define-editor-mode-variable name mode value &optional documentation
Defines an editor variable in the specified mode.
A string naming a mode.
As for editor:define-editor-variable.
As for editor:define-editor-variable, except that editor:define-editor-mode-variable
installs the documentation only if the editor variable does not already have any documentation.
editor:define-editor-mode-variable
defines a variable in the specified mode. There is one value per variable per mode.
editor:define-editor-mode-variable
gives a readable value of defining a variable in a mode, and is recognized by the LispWorks source code location system. However mode variables can also be defined dynamically by calling (setf editor:variable-value)
. Mode variable values may be accessed by editor:variable-value.
editor:editor-variable-documentation
editor:editor-variable-documentation editor-variable-name
A symbol naming an editor variable.
Returns the documentation associated with the editor variable, if any.
Note: For backwards compatibility a string editor-variable-name is also accepted, as described for editor:define-editor-variable.
editor:variable-value name &optional kind where
The reader returns the value of the editor variable name, where name is a symbol. An error is signaled if the variable is undefined. The argument kind can take the value :current
, :buffer
, :global
or :mode
. The default value of kind is :current
.
When kind is :current
the argument where should be nil
(the default, meaning the current buffer) or an editor buffer object or the name of a buffer. The variable value for the specified buffer is returned or (if there is no current buffer) then the global variable value is returned.
kind can also be :buffer
, and then where should be an editor buffer object.
For example, the code given below will, by default, return the value :ask-user
.
(editor:variable-value
'editor:add-newline-at-eof-on-writing-file)
The value of variables may also be altered using the setter of this function. For example, the code given below will allow buffers to be saved to file without any prompt for a missing newline.
(setf
(editor:variable-value
'editor:add-newline-at-eof-on-writing-file)
nil)
editor:variable-value-if-bound
editor:variable-value-if-bound name &optional kind where
Returns the value of the variable name. If the variable is not bound, nil
is returned. The arguments are as for editor:variable-value.
editor:buffer-value buffer name &optional errorp
Accesses the value of the editor variable name in the buffer specified by buffer.
name should be a symbol and buffer should be a point object or a buffer object.
If the editor variable is undefined and errorp is true, an error is signaled. If the variable is undefined and errorp is false, nil
is returned. The default value of errorp is nil
.
editor:current-window
editor:redisplay
Redisplays any window that appears to need it. In general, the contents of a window may not be redisplayed until there is an event to provoke it.
Note: editor:redisplay
will update a modified editor buffer only when that buffer is the editor:current-buffer. Take care to call editor:redisplay
in an appropriate context.
editor:window-text-pane window
Returns the capi:editor-pane
associated with an editor window.
An instance of the system class editor:face describes the "face" of some text. It specifies the colors of the text and background, the font, and whether the text is bold, italic or underlined.
A editor:face is created by calling editor:make-face. It is used by various interface functions, for example hcl:code-coverage-set-editor-colors
and hcl:write-string-with-properties
. Note that in general you can use a face name, that is associated with a editor:face by editor:make-face, instead of the actual editor:face object.
editor:make-face name &key if-exists foreground background font bold-p italic-p underline-p inverse-p documentation => face
A symbol.
nil
, :overwrite
or :error
.
A graphics-ports:font
object or nil
.
bold-p, italic-p, underline-p, inverse-p
A string or nil
.
A editor:face object.
The function editor:make-face returns a editor:face , either new or existing, and may associate it with name. editor:face objects are used by some interface function such as hcl:code-coverage-set-editor-colors
and hcl:write-string-with-properties
.
If name is non-nil, editor:make-face first checks if a editor:face with this name already exists. If it exists, then if-exists controls what happens:
Return the existing editor:face object as it is (the default).
Reset the existing editor:face to default values and set its slots using the supplied keywords. The existing face is returned. This also causes Editor windows to update, and where this face is used the display will change accordingly.
Signal an error.
If there is no existing editor:face, either because name is nil
or because it has not been made yet, editor:make-face creates a new editor:face from the supplied keywords. If name is non-nil, the editor:face is associated with name, so future calls to editor:make-face with the same name will find it and name can be used in interface functions.
None of the keywords is required, and they all default to nil
. For foreground, background and font, nil
means use the default value, that is the color or font that the text would have drawn if the face was not applied.
foreground and background specify the colors to use. When they are non-nil, they must be a CAPI color. See the chapter "The Color System" in the CAPI User Guide and Reference Manual for description of colors.
font specifies the font to use. It must be a graphics-ports:font
object, typically the result of graphics-ports:find-best-font
. See "Portable font descriptions" in the "Drawing - Graphics Ports" chapter in the
CAPI User Guide and Reference Manual
for details. Note that the editor does not work properly with fonts of different height.
bold-p, italic-p and underline-p specify whether the text should be bold, italic or underlined respectively.
inverse-p specifies that the foreground and background colors are swapped, which causes the text to be drawn in the current background color using the current foreground color as the background. The effective background color is either the background argument if it is non-nil, or the default otherwise, and the same for the effective foreground color.
documentation is stored in the editor:face, and can be retrieved by calling cl:documentation
with editor:face as the doc-type argument. cl:documentation
can be called either with a editor:face object or with name.
The following simple example creates a new editor command called Current Line
.
(editor:defcommand "Current Line" (p)
"Computes the line number of the current point and
prints it in the Echo Area"
"Prints the line number of the current point"
(let* ((cpoint (editor:current-point))
(svpoint (editor:copy-point cpoint))
(count 0))
(editor:beginning-of-buffer-command nil)
(loop
(if (editor:point> cpoint svpoint)
(return))
(unless (editor:next-line-command nil)
(return))
(incf count))
(editor:move-point cpoint svpoint)
(editor:message "Current Line Number: ~S " count)))
This example creates a new editor command called Goto Line
which moves the current point to the specified line number.
(editor:defcommand "Goto Line" (p)
"Moves the current point to a specified line number.
The number can either be supplied via the prefix
argument, or, if this is nil, it is prompted for."
"Moves the current point to a specified line number."
(let ((line-number
(or p (editor:prompt-for-integer
:prompt "Line number: "
:help "Type in the number of the line to
go to"))))
(editor:beginning-of-buffer-command nil)
(editor:next-line-command line-number)))
The following example illustrates how text might be copied between buffers. First, string is set to all the text in from-buf
. This text is then copied to the end of to-buf
.
(defun copy-string (from-buf to-buf)
(let ((string (editor:points-to-string
(editor:buffers-start from-buf)
(editor:buffers-end from-buf))))
(editor:insert-string (editor:buffers-end to-buf) string)))
To test this example, two buffers named t1
and t2
should be created. Then, to copy all the text from t1
to the end of t2
:
(copy-string (editor:buffer-from-name "t1")
(editor:buffer-from-name "t2"))
LispWorks Editor User Guide (Macintosh version) - 17 Aug 2017