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 Function
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).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.
Define Command Synonym Editor 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 6.3.4 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 Macro
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 Macro
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 Function
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
).
buffer |
An editor buffer. |
check-file-modification | |
A boolean. | |
force-modification | A boolean. |
result | :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:
:buffer-not-locked | The buffer is not locked by the current thread. |
:buffer-not-writable | |
The buffer is not writable, and force-modification is | |
:buffer-out-of-date | |
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 Function
editor:current-buffer
Returns the current buffer.
editor:buffer-name buffer
Returns the name of 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 Function
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.
Notes:
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
Clears any undo information in the buffer 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 6.3.3.1 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.
kind | Insert at < n | Insert at = n | Insert at > n |
---|---|---|---|
| n+len | n | n |
| n+len | n+len | n |
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 Function
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
Deletes the 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 Function
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 lw:precompiled-regexp (the 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 and 28.7 Regular expression syntax in the LispWorks® User Guide and Reference Manual.
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 Function
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 Function
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:set-buffer-name-directory-delimiters Function
editor:set-buffer-name-directory-delimiters &key prefix postfix separator display-p
The function editor:set-buffer-name-directory-delimiters
controls the naming of buffers that are associated with files with the same name.
For a buffer associated with a file, the editor names the buffer using the file's name. Each buffer must have a unique name, so if you open several files with the same name (in different directories) then the editor has to choose different names for these buffers. By default, the editor resolves this situation by changing the name of all such buffers to be the file name followed by enough directory components to make it unique. The format of these unique names is:
filename prefix comp-1 separator comp-2 separator … postfix
where comp-1, comp-2 … are directory components. Note that this feature is new in LispWorks 8.0 and in previous versions the editor just added <number>
after the filename, where number is an increasing integer.
prefix sets the prefix to use. If it is nil
(the default), the prefix is not changed. Otherwise, it must be a string or a character.
postfix sets the postfix to use. If it is nil
(the default), the postfix is not changed. Otherwise, it must be a string or a character.
separator sets the directory separator to use. If it is nil
(the default), the separator is not changed. Otherwise, it must be a string or a character.
Note that if you want any of prefix, postfix and separator to be empty, you need to pass an empty string.
display-p controls whether this name format is used. If it is non-nil, then the naming uses the format above. If it is nil
, the naming uses the pre LispWorks 8.0 format with an integer suffix. If display-p is not supplied, its setting is not changed.
The initial settings are as if editor:set-buffer-name-directory-delimiters
was called like this:
(set-buffer-name-directory-delimiters :prefix "<" :postfix ">" :separator "/" :display-p t)
When editor:set-buffer-name-directory-delimiters
is called and whenever a buffer is created or deleted, the editor checks if it creates or eliminates a clash, and if it does then the editor recomputes the names of all the buffers that are affected.
For example, if you edit a file in the editor (see Find File ) with path /compa-1/compb-1/filename
, then the buffer is named filename
. Suppose you then edit another file /compa-1/compb-2/filename
. Now the first buffer is renamed as filename<compb-1>
, and the second buffer is named filename<compb-2>
. If you close the first buffer, then the second buffer is renamed to filename
because there is no longer a clash.
editor:fast-save-all-buffers Function
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 Function
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 Function
editor:buffer-pathname buffer
Returns the pathname of the file associated with buffer. If no file is associated with buffer, nil
is returned.
editor:set-pathname-load-function Function
editor:set-pathname-load-function &key type load-function load-function-finder
Sets the function to use when loading files with type type.
editor:set-pathname-load-function
affects what the command Load File does, and what loading in the LispWorks IDE using File > Load does. It does not affect what the Common Lisp load function does.
type is a string specifying the pathname-type of a filename.
In the description below, a load function means a function or a fbound symbol that takes one argument, a pathname designator, and "loads" it in some appropriate way.
If load-function-finder is non-nil, it must be a function that takes one argument, a pathname designator, and returns a load function or nil
. If it returns a load function, this function is called to load the file. If it returns nil
, the normal processing is done, which means calling load with the pathname designator without the type.
If load-function-finder is non-nil, load-function is ignored. Otherwise, load-function specifies the load function to use.
If both load-function-finder and load-function are nil
, any previous setting for type is removed.
Each call to editor:set-pathname-load-function
replaces the setting of any previous call with the same type.
For example, the ASDF integration example in (example-edit-file "misc/asdf-integration.lisp")
uses the following call to cause the LispWorks IDE to load files with type "asd"
by calling asdf:load-asd
:
(editor:set-pathname-load-function :type "asd" :load-function 'asdf:load-asd)
Note: editor:set-pathname-load-function
was added in LispWorks 8.0.
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 3.5.3 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 Function
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 Function
editor:points-to-string start end
Returns the string between the points start and end.
editor:*indent-with-tabs* Variable
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* Variable
Contains a list of symbols likely to be found at the beginning of a form (such as apply, funcall, defun, defmethod, defgeneric).
editor:*source-found-action* Variable
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 Function
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.
:must-exist |
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. |
:default |
Defines the default value that is selected if an empty string is input. |
:default-string | Specifies the string that may be edited by the user (with Insert Parse Default). |
:prompt |
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 . |
:help |
Provides a help message that is printed if the user types " ? ". |
editor:prompt-for-file Function
editor:prompt-for-file &key direction must-exist create-directories default default-string prompt help
Prompts for a file name, and returns a pathname.
:direction |
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. |
:create-directories | |
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 |
See above for an explanation of the other arguments.
editor:prompt-for-buffer Function
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 Function
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 Function
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 Function
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 Function
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 the 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 Function
editor:define-editor-variable name value &optional documentation
Defines an editor variable.
name |
Symbol naming the variable. |
value |
The value to assign to the variable. |
mode |
A string naming a mode. |
documentation |
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 Function
editor:define-editor-mode-variable name mode value &optional documentation
Defines an editor variable in the specified mode.
mode |
A string naming a mode. |
name, value |
As for editor:define-editor-variable. |
documentation |
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 Function
editor:editor-variable-documentation editor-variable-name
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 Accessor
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 Function
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 Function
editor:current-window
Returns the 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 Function
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
name |
A symbol. |
if-exists | nil , :overwrite or :error . |
foreground, background | |
CAPI colors or | |
font |
A graphics-ports:font object or nil . |
bold-p, italic-p, underline-p, inverse-p | |
Booleans. | |
documentation |
A string or nil . |
face |
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:
nil |
Return the existing editor:face object as it is (the default). |
:overwrite |
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. |
:error |
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"))
Editor User Guide (Macintosh version) - 01 Dec 2021 19:35:12