This is Info file jade.info, produced by Makeinfo-1.55 from the input file jade.texi. START-INFO-DIR-ENTRY * Jade: (jade). An editor for X11 and AmigaDOS END-INFO-DIR-ENTRY This is Edition 1.3, last updated 7 October 1994, of `The Jade Manual', for Jade, Version 3.2. Jade is a text editor for X11 (on Unix) and the Amiga. Copyright 1993, 1994 John Harper. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. File: jade.info, Node: Keymaps, Next: Event Loop, Prev: Input Events, Up: Programming Jade Keymaps ======= A "keymap" is a Lisp object defining a mapping between input events (*note Input Events::.) and commands to be executed when the event loop (*note Event Loop::.) receives the input event. - Function: keymapp OBJECT Returns `t' when OBJECT is a keymap. * Menu: * Types of Keymap:: Two different formats of keymap * Creating Keymaps:: Allocating new keymaps * Binding Keys:: Inserting and removing key bindings * Key Lookup:: How a key press is resolved into a command * Prefix Keys:: Chaining events into multiple-event bindings * Standard Keymaps:: Predefined keymaps you can modify File: jade.info, Node: Types of Keymap, Next: Creating Keymaps, Up: Keymaps Types of Keymap --------------- There are two different types of keymap; one for keymaps which contain only a few bindings, the other providing a more efficient method of storing larger numbers of bindings. "Key lists" These are used for keymaps which only contain a few bindings; they are lists whose first element is the symbol `keymap'. All subsequent elements define bindings, they are represented by three-element vectors. The first two are the contents of the cons cell representing the input event, the other element is the command to be invoked. For example, (keymap [120 9 some-command]) Since the event `(120 . 9)' is the key press `Ctrl-x', this keymap binds the command `some-command' to the key press `Ctrl-x'. "Key tables" Key tables are used for keymaps which contain a larger number of bindings. They are vectors of 127 elements, a hash function is used to hash each event contained in the keymap into one of the 127 buckets. Each bucket is a list of key bindings in the same form as a key list (but without the `keymap' symbol). File: jade.info, Node: Creating Keymaps, Next: Binding Keys, Prev: Types of Keymap, Up: Keymaps Creating Keymaps ---------------- Since there are two different types of keymap (lists and tables) there are two different functions for creating them with. - Function: make-keylist Creates and returns a new key list containing no bindings. (make-keylist) => (keymap) - Function: make-keytab This function returns a new key table; it will be totally empty. (make-keytab) => [nil nil ... nil] If you want to produce a new copy of a keymap use the `copy-sequence' function (*note Sequence Functions::.) to duplicate the source keymap. File: jade.info, Node: Binding Keys, Next: Key Lookup, Prev: Creating Keymaps, Up: Keymaps Binding Keys ------------ The `bind-keys' function is used to install new key bindings into a keymap (either a key list or table). - Function: bind-keys KEYMAP &rest BINDINGS This function installs zero or more key bindings into the keymap KEYMAP. Each binding is defined by two elements in the list of BINDINGS, the first defines the name of the input event (or the event itself) and the second defines the command to be associated with the event. For example to bind two keys in the keymap KEYMAP; the event `Ctrl-f' to the command `goto-next-char' and the event `Ctrl-b' to the command `goto-prev-command' the following form would be used, (bind-keys KEYMAP "Ctrl-f" 'goto-next-char "Ctrl-b" 'goto-prev-char) - Function: unbind-keys KEYMAP &rest KEYS This function removes the bindings of the events KEYS (these may be the names of the events or the event objects themselves) from the keymap KEYMAP. (unbind-keys KEYMAP "Ctrl-f" "Ctrl-b") File: jade.info, Node: Key Lookup, Next: Prefix Keys, Prev: Binding Keys, Up: Keymaps Key Lookup ---------- Each time the event loop (*note Event Loop::.) receives an input event from the window system it searches for a binding of that event. The variables `keymap-path' and `next-keymap-path' are used to determine the "keymap environment", this is the list of keymaps which are searched when looking for the binding. - Function: lookup-event-binding EVENT &optional RESET-PATH This function examines the current keymap environment for a binding of the event EVENT (*note Input Events::.). If such a binding is found its command is returned, otherwise `nil' is returned. If the optional RESET-PATH argument is non-`nil' the `next-keymap-path' variable will be set to `nil', otherwise it will be left with its original value. - Variable: keymap-path A buffer-local variable providing the list of keymaps (or variables whose values are keymaps) which will be searched for a binding when the value of the `next-keymap-path' variable is `nil'. keymap-path => (minor-mode-keymap texinfo-keymap global-keymap) - Variable: next-keymap-path This variable is used to create multi-event key bindings. When it has a non-`nil' value it overrides the `keymap-path' variable when a key binding is being searched for. After the value of this variable is used to search for a key binding it is set to `nil'. This means that, unless another prefix key occurred, the next input event received will be resolved through the `keymap-path' variable. When this variable is set the value of the `prefix-arg' variable is set to the current value of the `current-prefix-arg' variable. This is so a prefix argument given to a multi-event command is transmitted through to the command. For more details on multi-event bindings see *Note Prefix Keys::. File: jade.info, Node: Prefix Keys, Next: Standard Keymaps, Prev: Key Lookup, Up: Keymaps Prefix Keys ----------- As briefly noted in the previous section it is possible to create multi-event key bindings. The `next-keymap-path' variable is used to link key presses (known as "prefix keys" since they prefix the actual, command-invoking, binding) to a new keymap environment which will be used to resolve the next key press. This method allows key sequences of an arbitrary length to be used. The best way to explain this is probably with an example. Consider the following, (setq entry-keymap (make-keylist)) (bind-keys entry-keymap "Ctrl-x" '(setq next-keymap-path '(second-keymap))) (setq second-keymap (make-keylist)) (bind-keys second-keymap "Ctrl-j" 'some-command) Two keymaps are created, the first of which, `entry-keymap', would be placed in the `keymap-path' list. When `Ctrl-x' is typed the associated command would be invoked, installing the next piece of the chain, the `second-keymap' into the `next-keymap-path' variable. So, after `Ctrl-x' is typed the keymap environment will be the list of keymaps `(second-keymap)', subsequently typing `Ctrl-j' would then invoke the command `some-command'. File: jade.info, Node: Standard Keymaps, Prev: Prefix Keys, Up: Keymaps Standard Keymaps ---------------- Several keymaps are predefined by Jade. `global-keymap' This keymap is the root of the global keymap structure; all buffers which allow themselves to be edited have this keymap in their `keymap-path'. `ctrl-x-keymap' This is linked to the `global-keymap' via the key `Ctrl-x'. `ctrl-x-4-keymap' The keymap for the global prefix `Ctrl-x 4'. `ctrl-x-5-keymap' The keymap for the global prefix `Ctrl-x 5'. `user-keymap' This keymap is only to be bound by the *user*, not by programmers! It's linked to the global prefix `Ctrl-c' and is intended to allow users to bind unmodified keys (modified keys with the prefix `Ctrl-c' are usually bound to by modes) to commands which don't have bindings by default. File: jade.info, Node: Event Loop, Next: Editing Files, Prev: Keymaps, Up: Programming Jade Event Loop ========== Whenever Jade is not executing a command it is sitting in the "event loop". This is where the editor waits for any input events which the window system sends it, invokes the commands they resolve to and then redraws all the editor windows to reflect the modifications made to any buffers. * Menu: * Event Loop Actions:: What actually happens * Commands:: Commands are Lisp functions which may be called interactively by the user * Event Loop Info:: Information about the event loop * Recursive Edits:: How to call the event loop from Lisp programs * Reading Events:: Reading single events in Lisp * Idle Actions:: What happens when nothing happens File: jade.info, Node: Event Loop Actions, Next: Commands, Up: Event Loop Event Loop Actions ------------------ When Jade appears to be doing nothing it is probably sitting in the event loop waiting for input to arrive. When an input event arrives from the window system it is processed according to its type. If the input event is a keyboard or mouse button event it is converted into a Lisp input event (*note Input Events::.) and the current keymap environment is searched for a binding of that event (*note Key Lookup::.). If a binding of the event is found it defines a command (*note Commands::.) to be invoked, the `call-command' function (*note Calling Commands::.) is used to do this. When no binding of a key or mouse button event exists the hook, `unbound-key-hook', is evaluated; if this returns `nil' and the event is a keyboard event and no prefix keys (*note Prefix Keys::.) preceded it the key is inserted into the current buffer before the cursor. If the event was not a keyboard or mouse button event the event loop will deal with it itself; these events are generally things which should be transparent to Lisp programs (i.e. window exposure notification, etc...). One exception is the event sent when a window should be closed (i.e. hitting the close-window gadget in Intuition, or sending a window the delete-window atom in X), the hook `window-closed-hook' is called. By default this hook is setup to invoke the `close-window' command (as bound to `Ctrl-x 0'). Another function of the event loop is to wait for input from any of the subprocesses currently executing (*note Processes::.); whenever input is pending in a subprocess's standard output channel it is copied to the process objects's output stream. After processing an event or piece of subprocess output the event loop will redisplay any part of any window which needs to be updated; this may be necessary if a window is now displaying a different part of a buffer, or if the part of the buffer it is displaying has been modified. *Note Rendering::. Normally Jade will `sleep' while it's waiting for input, however after every second it spends asleep the event loop will wake up and try to do a sequence of operations; for more details see *Note Idle Actions::. - Hook: unbound-key-hook The hook called when an unbound input event is received. - Hook: window-closed-hook The hook called when an event is received telling Jade to close a window; the current window is the one which should be closed. File: jade.info, Node: Commands, Next: Event Loop Info, Prev: Event Loop Actions, Up: Event Loop Commands -------- A "command" is a Lisp function which may be called interactively, that is, either as a binding of an input event or by name (with the `Meta-x' key sequence). Commands are defined in the same way as functions, using the `defun' special form; the body forms of a command must contain an "interactive declaration". This shows that the function may be called interactively part and tells the `call-command' function how to compute the argument values to apply to the command. * Menu: * Interactive Declarations:: How to define a command * Prefix Arguments:: Arguments to a command from the user * Calling Commands:: The function used to invoke a command * Example Commands:: A definition of a command File: jade.info, Node: Interactive Declarations, Next: Prefix Arguments, Up: Commands Interactive Declarations ........................ When you define a command (using the `defun' special form in the same way you would define a function) the first of its body forms (after the optional documentation string) *must* be an interactive declaration. This form looks like a call to the special form `interactive', in actual fact this special form always returns `nil' and has no side-effects. The only effect of this form is to show the `call-command' function, which invokes commands, that this function definition is actually a command (i.e. it may be called interactively). The second element of the declaration form (after the `interactive' symbol) defines how the argument values applied to the command are computed. The structure of an interactive declaration, then, is: (interactive [CALLING-SPEC]) When a command is defined this is how it is defined with the interactive declaration: (defun some-command (arg1) "Optional documentation string." (interactive ...) ... The CALLING-SPEC form defines the argument values applied to the command when it is called interactively, it may be one of, * `nil' or undefined (i.e. `(interactive)'); no arguments are given to the command, this type of interactive declaration just shows that the function may be called interactively. * A string; zero or more lines (each separated by a newline character), each line defines how to compute one argument value. The first character of each line is a code letter defining exactly how to compute the argument, the rest of the line is an optional prompt string which some code letters show the user when prompting for the argument. The currently available code letters are, `a' Prompt, with completion, for a function object. `b' Prompt, with completion, for an existing buffer object. `B' Prompt, with completion, for a buffer; if it doesn't yet exist it will be created. `c' Prompt for a character. `C' Prompt with completion for a command. `d' The position of the cursor in the current window. `D' Prompt with completion for the name of a directory in the filing system. `e' The event which caused this command to be invoked. `E' The event which caused this command, cooked into a string. `f' Prompt with completion for the name of an existing file. `F' Prompt with completion for the name of a file; it doesn't have to exist. `k' Prompt for a single event. `m' The starting position of the marked block in the current window. `M' The ending position of the current block. `n' Prompt for a number. `N' The prefix argument (*note Prefix Arguments::.) as a number, if no prefix argument exists, prompt for a number. `p' The prefix argument as a number, this will be 1 if no prefix argument has been entered. `P' The raw prefix argument. `s' Prompt for a string. `S' Prompt with completion for a symbol. `t' The symbol `t'. `v' Prompt with completion for a variable. `x' Read one Lisp object. `X' Read a Lisp object, then evaluate it. A null line produces an argument value of `nil'. Any non-alphabetic characters at the beginning of the CALLING-SPEC are used as flags, the currently recognised flags are, `*' If the active buffer is read-only an error will be signalled. `-' After building the argument list the block marked in the current window will be unmarked. * Anything else; the form is evaluated and expected to return a *list* of arguments to apply to the command. Some example interactive declarations, ;; No arguments, but the function may be called ;; as a command. (interactive) ;; One argument, an existing buffer (interactive "bBuffer to kill:") ;; If buffer isn't read-only, three arguments: ;; `nil', a Lisp object and `t'. (interactive "*\nxLisp form:\nt") File: jade.info, Node: Prefix Arguments, Next: Calling Commands, Prev: Interactive Declarations, Up: Commands Prefix Arguments ................ When the you invoke a command it is often useful to be able to specify arguments which the command will act on. "Prefix arguments" are used for this purpose. They are called *prefix* arguments since they are entered before the command is invoked, and therefore prefix the command with an argument. Prefix arguments are usually integers. The easiest way for a command to access these arguments is through its interactive declaration (*note Interactive Declarations::.) and the `N', `p' and `P' code letters. The two variables `prefix-arg' and `current-prefix-arg' are used to store prefix arguments. Whenever a command is invoked the value of `prefix-arg' is moved to `current-prefix-arg' and `prefix-arg' set to `nil'. This allows commands to set the prefix argument of the next command by assigning a value to the `prefix-arg' variable. These variables store an object known as the "raw prefix argument", when a command is called it normally uses the "numeric prefix argument", this is an integer created from the raw argument using the following rules, * If the raw arg is `nil' the numeric value is 1. * If the raw arg is any other symbol the value is -1. * A number is used unchanged. * A cons cell stores the numeric value in its car. The `prefix-numeric-argument' function is used to convert the raw argument into a numeric value. - Function: prefix-numeric-argument RAW-ARG Returns the numeric value of the raw prefix argument RAW-ARG. - Variable: prefix-arg The value of the raw prefix argument used by the next command to be invoked. - Variable: current-prefix-arg The value of the raw prefix argument of the current command. File: jade.info, Node: Calling Commands, Next: Example Commands, Prev: Prefix Arguments, Up: Commands Calling Commands ................ When a command is to be invoked, the `call-command' function is used. This builds a list of argument values to apply to the command (using its interactive declaration) then calls the command. - Function: commandp OBJECT This function returns `t' if its argument may be called interactively. If OBJECT is a function (i.e. a symbol or a lambda-expression) it is a command if it contains an interactive declaration (*note Interactive Declarations::.). The only other object which is a command is a function call form; the use of these types of commands is discouraged but they can be useful sometimes. (commandp 'setq) => nil (commandp 'isearch-forward) => t (commandp '(setq x 20)) => t - Command: call-command COMMAND &optional PREFIX-ARG This function calls the command COMMAND interactively. See the documentation of `commandp' above for what constitutes a command. If the PREFIX-ARGUMENT is non-nil it defines the value of the `current-prefix-arg' variable for this command, normally the value of this variable would be taken from the global `prefix-arg' variable. When called interactively, this function will prompt for a command to invoke. This function is bound to the key sequence `Meta-x'. File: jade.info, Node: Example Commands, Prev: Calling Commands, Up: Commands Example Commands ................ This is a couple of simple commands, taken from the source code of Jade. (defun backward-kill-word (count) "Kill COUNT words backwards." (interactive "p") (kill-area (forward-word (- count)) (cursor-pos))) (defun find-file (name) "Sets the current buffer to that containing the file NAME, if NAME is unspecified it will be prompted for. If the file is not already in memory `open-file' will be used to load it." (interactive "FFind file: ") (goto-buffer (open-file name))) File: jade.info, Node: Event Loop Info, Next: Recursive Edits, Prev: Commands, Up: Event Loop Event Loop Information ---------------------- - Variable: this-command This variable contains the value of the command currently being executed. - Variable: last-command Holds the previously executed command. - Function: current-event Returns the event which caused this command to be invoked. - Function: current-event-string Returns a string which is the `cooked' representation of the current event. - Function: last-event Returns the event which caused the previous command. File: jade.info, Node: Recursive Edits, Next: Reading Events, Prev: Event Loop Info, Up: Event Loop Recursive Edits --------------- Entering a "recursive edit" basically means to recursively call the event loop from a Lisp program, this latest instance of the event loop will work like the normal event loop (the "top level" event loop) until it is exited, at which point the Lisp program will regain control. Recursive edits should be used sparingly since they can be very confusing for the user; they are mainly used to implement interactive user interfaces in the middle of a Lisp program or command. This can be achieved by installing a special set of key bindings for the duration of the recursive edit. When programming with recursive edits *a lot* of care should be used; if proper cautions aren't taken an abnormal exit from a recursive error can wreak havoc. Note that `throw' and `catch' (*note Catch and Throw::.) can be used *through* recursive edits with no problems; the recursive edit will automatically be aborted. - Command: recursive-edit Enter a new level of recursive editing. - Function: recursion-depth This function returns the number of recursive edits currently in progress. When in the top level this will return zero. - Command: top-level Abort all recursive edits, control will be passed straight back to the top level event loop. - Command: abort-recursive-edit &optional EDIT-VALUE This function aborts the outermost recursive edit (but *never* the top level) returning EDIT-VALUE (or `nil') from the instance of the `recursive-edit' function which invoked this recursive edit. When using recursive edits it is important to remember that the buffer and window configuration that existed when the edit was entered may not still exist when the recursive edit terminates. This means that some care has to be taken when installing and removing buffer-local values of variables. For example, the `ask-y-or-n' function, which uses a recursive edit, does something like this: (let ;; First save the old values of the variables to be altered. ;; The variables can't be directly bound to since this doesn't ;; work properly with buffer-local variables :-( ((old-u-k-h unbound-key-hook) (old-k-p keymap-path) (old-buf (current-buffer))) ;; Now install the new values (setq unbound-key-hook (cons #'(lambda () (beep) t) nil) keymap-path '(y-or-n-keymap) status-line-cursor t) ;; This is the important bit; ensure that the old values will ;; be reinstated even if an abnormal exit occurs. Also note ;; that they are always set in the original buffer. (unwind-protect (catch 'ask (recursive-edit)) (with-buffer old-buf (setq keymap-path old-k-p unbound-key-hook old-u-k-h status-line-cursor nil))))) File: jade.info, Node: Reading Events, Next: Idle Actions, Prev: Recursive Edits, Up: Event Loop Reading Events -------------- Most of the time it is unnecessary to read events manually; usually a special-purpose keymap will be sufficient. However it is possible to read single events from a Lisp program. - Function: read-event &optional PROMPT-STRING Read the next input event from the current window and return it. If the optional string PROMPT-STRING is defined it is a one-line message to display while waiting for the event. Note that this function isn't very efficient when used heavily; it uses a recursive edit and the `unbound-key-hook' to read the event. If possible use a keymap instead. File: jade.info, Node: Idle Actions, Prev: Reading Events, Up: Event Loop Idle Actions ------------ When a second goes by with no input events arriving, the editor assumes that is has "idle time" available, and tries to use this period to do non-essential tasks. These tasks include things like garbage collection and auto-saving modified files. Whenever idle time is detected one of the following tasks is performed. They are listed in order of preference; once one of these has been done Jade will again sleep until an input event is received or another second elapses, whichever happens soonest. 1. If prefix keys have been entered and are outstanding their names will be printed in the status line. *Note Prefix Keys::. 2. If any buffers are ready to be auto-saved (i.e. enough time since their last auto-save has elapsed) one of these buffers will be auto-saved. Only one buffer is ever saved in each idle period. *Note Auto-Saving Files::. 3. If the total size of the data objects allocated since the last garbage collection is greater than the value of the `idle-gc-threshold' variable then the garbage collector is invoked. - Variable: idle-garbage-threshold The number of bytes of Lisp data which must have been allocated since the last garbage collection for the garbage collector to be called in an idle period. It is a good idea to set this variable much lower than the value of the `gc-threshold' variable since garbage collections happening while Jade is idle should usually be unnoticeable. *Note Garbage Collection::. 4. If none of the other tasks have been performed the `idle-hook' hook is dispatched. I'm not sure what this hook could be used for but you never know... File: jade.info, Node: Editing Files, Next: Text, Prev: Event Loop, Up: Programming Jade Editing Files ============= The main function of Jade is editing files of text; buffers (*note Buffers::.) are used to contain files to be edited. When the buffer is displayed in a window (*note Windows::.) the user can edit the file interactively using the keyboard and mouse. This chapter documents the Lisp interface to all this; for the user's perspective see *Note Loading and Saving Files::. * Menu: * Reading Files Into Buffers:: How to read a file into a buffer * Writing Buffers:: Functions to write buffers to files * Buffer Date Stamps:: The last-modification time of each file is recorded * Buffer Modification Counts:: Variables storing modification counts * Making Backups:: How backup files can be made * Controlling Auto-Saves:: Functions to control the auto-saving feature File: jade.info, Node: Reading Files Into Buffers, Next: Writing Buffers, Up: Editing Files Reading Files Info Buffers -------------------------- Before a file can be edited it must be read into a buffer, this buffer can then be modified and later saved over the original contents of the file. Note that editing a buffer makes *no* changes to the contents of the file on disk; the buffer will have to be written back to the file on the disk first. *Note Writing Buffers::. - Function: open-file FILE-NAME This function returns a buffer containing the contents of the file called FILE-NAME. If an existing buffer contains the file called FILE-NAME that buffer is returned. Otherwise a new buffer is created and the file read into it. When the file has successfully been read into the new buffer any local variables defined at the end of the file are processed (*note File Variables::.) and the function `init-mode' is used to try to install a major mode for the new buffer. *Note Installing Modes::. If file may not be written to the buffer is marked to be read-only. Note that the hook, `read-file-hook', can be used to read the contents of the file into the buffer if necessary. See the documentation of this hook for more details. - Hook: read-file-hook This hook is called by the `open-file' function when it wants to read a file into a buffer. If the hook returns a non-`nil' value `open-file' assumes that one member of the hook was successful in reading the file, otherwise the file will be read verbatim into the buffer. The hook is called with two arguments: the name of the file and the buffer to read it into respectively. If any members of the hook decide to read the file they're responsible for setting the `buffer-file-name' component of the buffer and the buffer's `buffer-file-modtime' variables to suitable values. See the `gzip.jl' file in the Lisp library directory for an example of how this hook can be used (in this case to automatically decompress gzip'ed files). - Function: read-buffer FILE-OR-NAME &optional BUFFER Replaces all text contained by the buffer by the contents of the file FILE-OR-NAME. This can be either a Lisp file object, in which case bytes will be read until the end of the file is reached, or the name of a file to read. The following commands are used to read a file into a buffer then display that buffer in the current buffer. - Command: find-file FILE-NAME Display a buffer containing the file FILE-NAME in the current window. When called interactively FILE-NAME will be prompted for. - Command: find-alternate-file FILE-NAME Replace the current buffer with one displaying the file FILE-NAME. What actually happens is that the current buffer is killed and a new one created. When called interactively this function will prompt for its argument. - Command: find-file-read-only FILE-NAME Display a buffer containing FILE-NAME in the current window. The buffer will be read-only. This will prompt for its argument when called interactively. There is also a command to insert the contents of a file into a buffer. - Command: insert-file FILE-NAME &optional BUFFER This command inserts the contents of the file FILE-NAME into the buffer BUFFER (or the current buffer). The hook `insert-file-hook' is called with FILE-NAME as an argument to try and insert the file (into the current buffer at the current position). If this hook returns `nil' (i.e. none of the functions in the hook inserted the file) it will be inserted normally. If called interactively, FILE-NAME will be prompted for. - Hook: insert-file-hook Hook used to insert a file (given as the hook's argument) into the current buffer at the current cursor position. - Command: revert-buffer &optional BUFFER Reloads the contents of the buffer from the file it was originally loaded from; if any unsaved modifications will be lost the user is asked for confirmation. File: jade.info, Node: Writing Buffers, Next: Buffer Date Stamps, Prev: Reading Files Into Buffers, Up: Editing Files Writing Buffers --------------- After a buffer containing a file has been edited it must be written back to a file on disk, otherwise the modifications will disappear when Jade is exited! - Function: write-buffer &optional FILE-NAME BUFFER The primitive to save a buffer's contents. The contents of the buffer BUFFER (or the current buffer) is written to the file FILE-NAME (or the `buffer-file-name' component of the buffer). - Function: write-buffer-area START-POS END-POS FILE-NAME &optional BUFFER Writes the region of text from START-POS up to, but not including, END-POS to the file FILE-NAME. - Function: write-file BUFFER &optional FILE-NAME Writes the contents of the buffer BUFFER to a file on disk. If the optional argument FILE-NAME is defined it names the file to write to. Otherwise, the value of the buffer's `buffer-file-name' component is used. The hook `write-file-hook' is used to try and write the file, if this fails (i.e. the hook returns `nil') the buffer is saved normally. A backup may be made of the file to be overwritten (*note Making Backups::.) and the protection-modes of the overwritten file will be preserved if possible. - Hook: write-file-hook This hook is called by the `write-file' function when a buffer is to be saved. If no member of the hook actually writes the buffer to a file (i.e. the hook returns `nil') `write-file' will do it itself in a standard way. The hook function is responsible for creating any required backup file (use the function `backup-file', *note Making Backups::.) and resetting the protection-modes of the new file to their original value. See the file `gzip.jl' in the Lisp library directory for an example, it uses it to compress certain files automatically. Remember to make sure that if a member of the hook writes the buffer it returns a non-`nil' value! The following code fragment defines a function which does what the default action of `write-file' is, (defun write-file-default-action (buffer name) (let ((modes (when (file-exists-p name) (file-modes name)))) (backup-file name) (when (write-buffer name buffer) (when modes (set-file-modes name modes)) t))) The following commands call the `write-file' function to write out a buffer, they also update the various variables containing information about the state of the buffer. It is normally unnecessary to call `write-file' yourself; these commands should suffice. - Command: save-file &optional BUFFER This command writes the buffer to the file that it was loaded from and then updates all the necessary buffer-local variables. If the file on disk has been modified since it was read into the buffer the user is asked if they really want to save it (and risk losing a version of the file). If no modifications have been made to the file since it was last saved it won't be saved again. Any auto-saved version of the file is deleted. - Command: save-file-as NEW-NAME &optional BUFFER This command saves the buffer BUFFER (or the current buffer) to the file called NEW-NAME. The `buffer-file-name' is set to NEW-NAME and all the necessary buffer-local variables are updated. If an auto-saved version of FILE-NAME exists it is deleted. When called interactively NEW-NAME will be prompted for. - Command: save-some-buffers For each buffer which contains unsaved modifications the user is asked whether or not to save the buffer. `t' is returned if no unsaved modifications exist in any buffers (i.e. the user replied `yes' to all files which could be saved). - Command: save-and-quit Calls `save-some-buffers' then quits Jade (after asking the user if any unsaved buffers may be discarded). File: jade.info, Node: Buffer Date Stamps, Next: Buffer Modification Counts, Prev: Writing Buffers, Up: Editing Files Buffer Date Stamps ------------------ When a file is read into a buffer its (the file's) time of last modification is recorded, this can later be used to see if the file (on disk) has been modified since it was loaded into a buffer. - Variable: buffer-file-modtime This buffer-local variable contains the file-modtime of the file stored in the buffer when it (the file) was last read from disk. *Note File Information::. File: jade.info, Node: Buffer Modification Counts, Next: Making Backups, Prev: Buffer Date Stamps, Up: Editing Files Buffer Modification Counts -------------------------- Two buffer-local variables are used to record the modification count (*note Buffer Attributes::.) of a buffer when it is saved. - Variable: last-save-changes A buffer-local variable containing the number of modifications made to the buffer the last time it was saved (either auto-saved or by the user). - Variable: last-user-save-changes This buffer-local variable holds the number of modifications made to the buffer when it was last saved by the user. - Variable: last-save-time A buffer-local variable holding the system time (from the `current-time' function) from when the buffer was last saved (auto-saved or by the user). File: jade.info, Node: Making Backups, Next: Controlling Auto-Saves, Prev: Buffer Modification Counts, Up: Editing Files Making Backups -------------- For details of the variables which control whether and how backup files are made see *Note Backup Files::. - Function: backup-file FILE-NAME When necessary, make a backup of the file FILE-NAME. This should be called when the file FILE-NAME is about to be overwritten. Note that this function doesn't define whether or not the file FILE-NAME will still exist when this function returns. Sometimes it will, sometimes it won't... File: jade.info, Node: Controlling Auto-Saves, Prev: Making Backups, Up: Editing Files Controlling Auto-Saves ---------------------- For the documentation of the variables controlling the making of auto-save files see *Note Auto-Saving Files::. - Function: make-auto-save-name FILE-NAME Returns a string naming the file which should hold the auto-saved version of the file FILE-NAME. (make-auto-save-name "/tmp/foo") => "/tmp/#foo#" - Function: auto-save-function BUFFER This function is called automatically whenever a buffer (BUFFER) needs to be auto-saved. It firstly tries to use the `auto-save-hook' hook to auto-save the file, if this fails (i.e. the hook returns `nil') it is done manually (using the `write-buffer' function). - Hook: auto-save-hook Called by `auto-save-function' (with the buffer as an argument) when a buffer is to be auto-saved. - Command: delete-auto-save-file &optional BUFFER This command deletes the auto-saved version of the buffer, if one exists. - Function: auto-save-file-newer-p FILE-NAME This function returns `t' when there is an auto-saved version of the file called FILE-NAME which is newer than FILE-NAME. - Command: recover-file &optional BUFFER If an auto-saved version of the buffer exists it is read into the buffer, overwriting its current contents. If any changes to the buffer will be lost the user is asked for confirmation. File: jade.info, Node: Text, Next: Writing Modes, Prev: Editing Files, Up: Programming Jade This chapter describes all the functions used for editing and referencing the text stored in a buffer. Note that where a command has a COUNT argument specifying the number of items to process; this argument will normally use the numeric value of the prefix argument when the function is called interactively. * Menu: * Buffer Contents:: Accessing the contents of a buffer * Insertion Functions:: Inserting strings into a buffer * Deletion Functions:: Deleting regions of text * Kill Functions:: Recording regions of text * Transpose Functions:: Swapping two regions of text * Indentation Functions:: Functions for managing indentation * Translation Functions:: Applying a mapping to characters in a buffer * Search and Match Functions:: Regexps and general string matching * Rectangular Editing:: Manipulating rectangular regions * Controlling Undo:: How undo works * Misc Text Functions:: Other stuff File: jade.info, Node: Buffer Contents, Next: Insertion Functions, Up: Text Buffer Contents --------------- - Function: get-char &optional POS BUFFER Returns the character at position POS (or the cursor position) in the specified buffer. - Function: set-char CHARACTER &optional POS BUFFER Sets the character at position POS (or the cursor) in the buffer BUFFER (or the current buffer) to the character CHARACTER, then returns CHARACTER. - Function: copy-area START-POS END-POS &optional BUFFER This function creates and returns a string containing the contents of the buffer BUFFER (or the current buffer) between the two positions START-POS (inclusive) and END-POS (exclusive). - Function: copy-block If a block is marked in the current window returns a string containing the text marked then unmark the block, otherwise returns `nil'. If the marked block is rectangular the `copy-rect' function (*note Rectangular Editing::. is used to get the string. - Function: clear-buffer &optional BUFFER Removes all text from the specified buffer. No precautions are taken against losing any unsaved modifications that the buffer might contain! File: jade.info, Node: Insertion Functions, Next: Deletion Functions, Prev: Buffer Contents, Up: Text Insertion Functions ------------------- Note that the `format' function can be used to provide formatted insertion; simply give it a suitable output stream. *Note Streams::. - Command: insert STRING &optional POS BUFFER Inserts the string STRING into the specified buffer at the cursor position (or POS, if defined). Returns the position of the first character after the end of the inserted text. When called interactively the string to insert is prompted for. - Command: insert-block &optional POS If a block is marked in the current window, the text it contains is inserted at the position POS (or the cursor) and the block is unmarked. If the marked block is rectangular the block is copied and inserted as a rectangle. - Command: yank &optional DONT-YANK-BLOCK Inserts a string before the cursor. If a block is marked in the current buffer and DONT-YANK-BLOCK is `nil' insert the text in the block. Else yank the last killed text. *Note Kill Functions::. When called interactively the raw prefix arg is used as the value of the DONT-YANK-BLOCK argument. - Command: yank-to-mouse Moves the cursor to the current position of the mouse pointer then calls the `yank' function. - Command: open-line COUNT Break the current line at the cursor, creating COUNT new lines. The cursor is left in its original position. - Command: split-line This function inserts a newline character (`\n') at the current cursor position. File: jade.info, Node: Deletion Functions, Next: Kill Functions, Prev: Insertion Functions, Up: Text Deletion Functions ------------------ - Function: delete-area START-POS END-POS &optional BUFFER This function deletes all text starting from the position START-POS up to, but not including, the position END-POS. If BUFFER is defined it specifies the buffer to delete from, usually the current buffer is used. - Function: cut-area START-POS END-POS &optional BUFFER This function is a combination of the `copy-area' and `delete-area' functions; it copies the specified region then deletes it before returning the copy it made. (cut-area START END) == (let ((text (copy-area START END))) (delete-area START END) text) - Command: delete-block Deletes the block marked in the current window (if one exists). This function knows about rectangular blocks. - Function: cut-block Copies the block marked in the current window if one exists, then deletes it before returning the copied string. If the block is rectangular it is copied and cut as a rectangle. - Command: delete-char COUNT Deletes COUNT characters, starting at the cursor position and working forwards. - Command: backspace-char COUNT Deletes the COUNT characters preceding the cursor, if the cursor is past the end of the line, simply move COUNT characters to the left. File: jade.info, Node: Kill Functions, Next: Transpose Functions, Prev: Deletion Functions, Up: Text Kill Functions -------------- "Killing" a piece of text means to delete it then store a copy of it in a special place. This string is later available to other functions, such as `yank' which inserts it into a buffer. - Function: kill-string STRING This function adds the string STRING to the kill buffer. If the last command also killed something STRING is appended to the current value of the kill buffer. The `this-command' variable is set to the value `kill' to flag that the current command did some killing. Returns STRING. - Function: killed-string &optional DEPTH Returns the string in the kill buffer number DEPTH, currently only the last kill is stored so DEPTH must either be zero or undefined. - Command: kill-area START-POS END-POS This command kills a region of text in the current buffer, from START-POS up to, but not including, END-POS. When called interactively the currently marked block (if one exists) is used to provide the two arguments, then the block is unmarked. - Command: copy-area-as-kill START-POS END-POS Similar to `kill-area' except that the region killed is not actually deleted from the buffer. - Command: kill-block Kills the block marked in the current window. - Command: copy-block-as-kill Kills the block marked in this window but doesn't actually delete it from the buffer. - Command: kill-line &optional ARG This command kills lines from the cursor position. ARG is a raw prefix argument (*note Prefix Arguments::.). What gets killed depends on ARG, * When ARG is `nil' it kills from the cursor position to the end of the line, if the cursor is already at the end of the line it kills the newline character. * If the numeric value of ARG is greater than zero it kills from the cursor for that many whole lines. * If the numeric value is less than or equal to zero it kills that number of whole lines *backwards* from the cursor. - Command: kill-whole-line COUNT Kills *all* of the COUNT (an integer) next following lines. - Command: kill-word COUNT Kills COUNT words, starting at the cursor position. When called interactively COUNT is the numeric prefix arg. - Command: backwards-kill-word COUNT Kills the COUNT previous words, starting from the cursor. When called interactively COUNT is the numeric prefix arg. - Command: kill-exp &optional COUNT Kill COUNT expressions from the cursor position. *Note Mode-Specific Expressions::. - Command: backward-kill-exp &optional COUNT Kills COUNT expressions, working backwards from the cursor. *Note Mode-Specific Expressions::. File: jade.info, Node: Transpose Functions, Next: Indentation Functions, Prev: Kill Functions, Up: Text Transpose Functions ------------------- "Transposing" two regions of text in a buffer means to swap their positions. - Function: transpose-items FORWARD-ITEM-FUN BACKWARD-ITEM-FUN COUNT This function transposes the areas defined by the functions FORWARD-ITEM-FUN and BACKWARD-ITEM-FUN (these functions must work in the style of `forward-word' and `backward-word' respectively). What actually happens is that the item before the cursor is dragged forward over the next COUNT items. - Command: transpose-words COUNT Uses `transpose-items' with each item being a word. When called interactively, COUNT is the value of the numeric prefix argument. - Command: transpose-chars COUNT Transposes characters. - Command: transpose-exps COUNT If the major mode in the current buffer has installed functions which define expressions then this command transposes expressions. *Note Mode-Specific Expressions::.