[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter of the manual is a full guide to Jade’s Lisp programming language, including documentation for most of the built-in functions.
1.1 Introduction | Introduction and Lisp conventions | |
1.2 Data Types | Data types and values in Lisp | |
1.3 Numbers | Integers and arithmetic functions | |
1.7 Sequences | Ordered sequences of data values | |
1.8 Symbols | Symbols are uniquely named objects | |
1.9 Evaluation | Evaluating expressions | |
1.10 Control Structures | Special forms. Conditionals, loops, etc… | |
1.11 Variables | Symbols represent named variables | |
1.12 Functions | Functions are the building blocks of Lisp programs | |
1.13 Macros | User-defined control structures | |
1.14 Streams | Data sinks and sources; character streams | |
1.15 Loading | Programs are stored in files | |
1.16 Compiled Lisp | Making programs run faster | |
1.17 Hooks | Hooks allow the extending of Jade | |
1.18 Buffers | Buffers allow editing of files | |
1.19 Windows | Windows receive input and display buffers | |
1.20 Positions | Coordinates in buffers and cursor movement | |
1.21 Marks | Marks represent the position of a character in a file | |
1.22 Glyph Tables | Controlling the glyphs rendered for each ASCII character | |
1.23 Input Events | Objects which represent input events | |
1.24 Keymaps | Mappings between events and commands | |
1.25 Event Loop | The event loop reads input events and invokes commands | |
1.26 Editing Files | Files are edited in buffers | |
1.27 Text | Functions to edit buffers with | |
1.28 Writing Modes | Creating new editing modes | |
1.29 Prompting | Interactively asking the user a question | |
1.30 Files | Manipulating files in the filing system | |
1.31 Processes | Jade can launch and control subprocesses when running under Unix | |
1.32 Miscellaneous Functions | Functions which don’t fit elsewhere in this manual | |
1.33 Debugging | How to debug Lisp programs | |
1.34 Tips | General recommendations for Lisp programmers |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As you have probably gathered by now, Jade is largely controlled by its built in programming language: a dialect of Lisp containing many extensions (non-standard data types and functions) to make it suitable for controlling an editor. Through this language Jade can be customised and extended.
I have attempted to make the “standard” portion of the language (i.e. anything a normal Lisp would have; not related to editing) as compatible with GNU Emacs Lisp as possible. In some areas this rule doesn’t apply, there will usually be a good reason for this. A few functions have been inspired by Common Lisp.
The areas of the language which control the editor are not compatible with Emacs; some functions may be similar but since the two editors are fundamentally different I have not attempted to conform with the Emacs API.
All programs written using only the information in this manual should be compatible with future revisions of Jade.
This following sections explain some of the most important Lisp concepts and the conventions I’ve used in this manual.
1.1.1 nil and t | Boolean values in Lisp | |
1.1.2 The Lisp Reader | Basic program structure | |
1.1.3 Notation | Special glyphs used | |
1.1.4 Descriptions | How functions and variables are documented |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The two boolean values in Lisp are the symbols nil
(FALSE) and
t
(TRUE). Both these symbols always evaluate to themselves (so they
do not have to be quoted), any attempt to change their values is an error.
All of the conditional instructions regard anything which is not
nil
as being TRUE (i.e. not-FALSE). The actual symbol t
should be used where a TRUE boolean value must be explicitly stated to
increase the clarity of the code.
This is not the end of the story; nil
actually has another meaning:
it represents the empty list. This is a consequence of how lists are
constructed in Lisp, a list of zero elements is stored as the symbol
nil
.
To the Lisp system itself there is absolutely no difference between ()
(the notation for a list with zero elements) and nil
(the symbol nil).
When writing code however, the list notation is usually used when the
programmer regards the value as a list and the nil
notation when
its value as a boolean is to be emphasised.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lisp programs and functions are stored internally as normal Lisp data objects, the Lisp Reader is the process used to translate textual descriptions of Lisp objects into the data structures used to represent the objects.
The Lisp Reader is the collection of internal functions accessed by the
read
Lisp function. It reads a character at a time from an input
stream until it has parsed a whole Lisp object.
See section Data Types.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Wherever an example of evaluating a Lisp form is shown it will be formatted like this,
(+ 1 2) ⇒ 3
The glyph ‘⇒’ is used to show the computed value of a form.
When two forms are shown as being exactly equivalent to one another the glyph ‘≡’ is used, for example,
(car some-variable) ≡ (nth 0 some-variable)
Evaluating some forms result in an error being signalled, this is denoted by the ‘error-->’ glyph.
(read-file "/tmp/foo") error--> File error: No such file or directory, /tmp/foo
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The simplest type of descriptions are the descriptions of variables (see section Variables), they look something like,
This imaginary variable contains the number of grains of sand in a one-mile long stretch of an averagely sandy beach.
Hooks (see section Hooks) are also described in this format, the only difference is that ‘Variable:’ is replaced by ‘Hook:’.
Functions (see section Functions) and macros (see section Macros) have more complex descriptions; as well as the name of the thing being described, they also have a list of arguments which the thing will accept. Each argument in the list is named and may be referred to in the body of the description.
Two ‘special’ arguments may be used, ‘&optional’ and &rest
.
They have the same meaning as when used in the lambda-list of a function
definition (see section Lambda Expressions), that is ‘&optional’ means
that all further arguments are optional, and ‘&rest’ means that
zero or more argument values are coalesced into a list to be used
as the value of the following argument.
An example function definition follows.
This function returns a list consisting of the values second (when undefined the number 42 is used), all the items in the list tail and first.
(useless-function 'foo 'bar 'xyz 20) ⇒ (bar xyz 20 foo) (useless-function '50) ⇒ (42 50)
Macros and commands (see section Commands) are defined in the same way with ‘Macro:’ or ‘Command:’ replacing ‘Function:’.
Special forms (see section Special Forms) are described similarly to functions except that the argument list is formatted differently since special forms are, by definition, more flexible in how they treat their arguments. Optional values are enclosed in square brackets (‘[optional-arg]’) and three dots (‘repeated-arg…’) indicate where zero or more arguments are allowed.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The way that data values are represented in Lisp is fundamentally different to more “conventional” languages such as C or Pascal: in Lisp each piece of data (a Lisp Object) has two basic attributes, the actual data and a tag value defining the type of the object. This means that type checking is performed on the actual data itself, not on the “variable” holding the data.
All Lisp objects are a member of one of the primitive types; these are types built into the Lisp system and can represent things like strings, integers, cons cells, vectors, etc…
More complex types of object can be constructed from these primitive types,
for example a vector of three elements could be regarded as a type
triple
if necessary. In general, each separate type provides a
predicate function which returns t
when applied to an object of its
type.
1.2.1 Types Summary | List of the most common types | |
1.2.2 Read Syntax | Some types can be constructed from source code | |
1.2.3 Printed Representation | All types can be printed | |
1.2.4 Equality Predicates | How to test two objects for equality | |
1.2.5 Comparison Predicates | Comparing two objects as scalars | |
1.2.6 Type Predicates | Each type has a predicate defining it | |
1.2.7 Garbage Collection | Reusing memory from stale objects |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each separate data type is documented in its own section, this is a just a table of the more common types.
32-bit signed integers. See section Numbers.
An object containing two other Lisp objects. See section Cons Cells.
A sequence of objects, in Lisp lists are not primitive types, instead they are made by chaining together Cons cells. See section Lists.
A one-dimensional array of objects. See section Vectors.
A vector of characters. See section Strings.
An ordered sequence of objects which can be accessed in constant time, either a vector or a string. See section Sequences.
An ordered sequence of objects, either a list or an array. See section Sequences.
A symbol is a named object; they are used to provide named variables and functions. See section Symbols.
A link to a file in the operating system’s filing system, allows access to the file as a stream. See section Files.
Serial data sinks and sources. See section Streams.
No type, only used in symbols to represent an unset function or variable value.
A “space” in which text can be edited, buffers may be displayed in a window and hence edited by the user. See section Buffers.
A physical window in the underlying window-system, used for input and output.
A pair of integers, used to represent the coordinates of a character in a buffer. See section Positions.
A position in a specified file, this file may either be a buffer in memory or a named file. See section Marks.
An object through which processes may be created and controlled. See section Processes.
A lookup-table which is used to map characters in a buffer to the sequence of glyphs they are rendered as. See section Glyph Tables.
A set of key-sequence-to-command mappings; when installed in a buffer it controls how the editor reacts to all input from the user. See section Keymaps.
An (input-) event from a window.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As previously noted the Lisp reader translates textual descriptions of Lisp objects into the object they describe (source files are simply descriptions of objects). However, not all data types can be created in this way: in fact the only types which can are integers, strings, symbols, cons cells (or lists) and vectors, all others have to be created by calling functions.
Note that comments in a Lisp program are introduced by the semi-colon character (‘;’). Whenever the Lisp reader encounters a semi-colon where it’s looking for the read syntax of a new Lisp object it will discard the rest of the line of input. See section Comment Styles.
The read syntax of an object is the string which when given to the reader as input will produce the object. The read syntax of each type of object is documented in that type’s main section of this manual but here is a small taste of how to write each type.
An integer is simply the number written in either decimal, octal (when the number is preceded by ‘0’) or hexadecimal (when the number is preceded by ‘0x’). An optional minus sign may be the first character in a number. Some examples are,
42 ⇒ 42 0177 ⇒ 127 0xff ⇒ 255 -0x10 ⇒ -16
The read syntax of a string is simply the string with a double-quote character (‘"’) at each end, for more details see Strings.
"This is a string"
A cons cell is written in what is known as dotted pair notation and is just the two objects in the cell separated by a dot and the whole thing in parentheses,
(car . cdr)
The syntax of a list is similar to a cons cell (since this is what lists are made of): no dot is used and there may be zero or more objects,
(object1 object2 object3 …) ("foo" ("bar" "baz") 100)
The second example is a list of three elements, a string, another list and a number.
The read syntax of a vector is very similar to that of a list, simply use square brackets instead of parentheses,
[object1 object2 object3 …]
A symbol’s read syntax is simply its name, for example the read syntax of a symbol called ‘my-symbol’ is,
my-symbol
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The printed representation of an object is the string produced
when the object is printed (with one of the print
functions), this
will usually be very similar to the read syntax of the object
(see section Read Syntax).
Objects which do not have a read syntax do have a printed representation, it will normally be of the form,
#<relevant text>
where the “relevant text” is object-dependent and usually describes the object and its contents. The reader will signal an error if it encounters a description of an object in the format ‘#<…>’.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Returns t
when arg1 and arg2 are the same object. Two
objects are the same object when they occupy the same place in memory and
hence modifying one object would alter the other. The following Lisp
fragments may illustrate this,
(eq "foo" "foo") ;the objects are distinct
⇒ nil
(eq t t) ;the same object -- the symbol t
⇒ t
Note that the result of eq
is undefined when called on two integer
objects with the same value, see eql
.
The function equal
compares the structure of the two objects arg1
and arg2. If they are considered to be equivalent then t
is
returned, otherwise nil
is returned.
(equal "foo" "foo") ⇒ t (equal 42 42) ⇒ t (equal 42 0) ⇒ nil (equal '(x . y) '(x . y)) ⇒ t
This function is a cross between eq
and equal
: if arg1
and arg2 are both numbers then the value of these numbers are compared.
Otherwise it behaves in exactly the same manner as eq
does.
(eql 3 3) ⇒ t (eql 1 2) ⇒ nil (eql "foo" "foo") ⇒ nil (eql 'x 'x) ⇒ t
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions compare their two arguments in a scalar fashion, the arguments may be of any type but the results are only meaningful for numbers, strings (ASCII values of each byte compared until a non-matching pair is found then those two values are compared as numbers) and positions.
Returns t
when arg1 is ‘greater than’ arg2.
Returns t
when arg1 is ‘greater than or equal to’ arg2.
Returns t
when arg1 is ‘less than’ arg2.
Returns t
when arg1 is ‘less than or equal to’ arg2.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each type has a corresponding predicate which defines the objects which are members of that type.
integerp
numberp
null
consp
listp
vectorp
subrp
functionp
sequencep
stringp
symbolp
posp
bufferp
windowp
markp
processp
filep
keymapp
eventp
commandp
The documentation for these functions is with the documentation for the relevant type.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Lisp, data objects are used very freely; a side effect of this is that it is not possible to (easily) know when an object is stale, that is, no references to it exist and it can therefore be reused.
The garbage collector is used to overcome this problem; whenever enough new data objects have been allocated to make it worthwhile, everything stops and the garbage collector works its way through memory deciding which objects are still in use and which are stale. The stale objects are then recorded as being available for reuse and evaluation continues again.
Runs the garbage collector, usually this function doesn’t need to be called manually.
The number of bytes of data which must be allocated before evaluation will pause and the garbage collector called.
Its default value is about 100K.
See section Idle Actions.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Currently Jade is only capable of representing integers, for this it uses signed 32-bit integers: this gives a range of -2147483648 through 0 to 2147483647.
The read syntax of an integer is simply the number written in decimal, octal or hexadecimal. If the integer starts with the string ‘0x’ it is assumed to be hexadecimal or if it starts with a zero it is treated as octal. The first character may be an optional minus or plus sign (this should come before any base-specifier). Examples of valid integer read syntaxes for the number 42 could be ‘42’, ‘0x2a’, ‘052’, ‘+052’, …
An integer’s printed representation is simply the number printed in decimal with a preceding minus sign if it is negative.
This function returns t
if object is a number.
This function returns t
when object is an integer.
1.4 Arithmetic Functions | Adding and substracting… | |
1.5 Bitwise Functions | Using integers as bit-sequences | |
1.6 Numeric Predicates | Comparing numbers | |
1.6.1 Characters | Integers are used to represent characters |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are a number of functions which perform arithmetic operations on numbers, they take a varying number of integer objects as their arguments then return a new integer object as their result.
Note that none of these functions check for overflow.
This functions adds its arguments then returns their sum.
If this function is just given one argument (number1) that number is negated and returned. Otherwise each of numbers is subtracted from a running total starting with the value of number1.
(- 20) ⇒ -20 (- 20 10 5) ⇒ 5
This function multiplies its arguments then returns the result.
This function performs division, a running-total (initialised from number1 is successively divided by each of numbers then the result is returned.
(/ 100 2) ⇒ 50 (/ 200 2 5) ⇒ 20
Returns the remainder from dividing dividend by divisor.
(mod 5 3) ⇒ 2
This function returns the result of adding one to number.
(1+ 42) ⇒ 43
Returns number minus one.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions operate on the bit string which an integer is made of.
This function bit-shifts the integer number count bits to the left, if count is negative number is shifted to the right instead.
(lsh 1 8) ⇒ 256 (lsh 256 -8) ⇒ 1
Similar to lsh
except that an arithmetical shift is done, this means
that the sign of number is always preserved.
(ash 1 8) ⇒ 256 (ash -1 2) ⇒ -4
This function uses a bit-wise logical ‘and’ operation to combine all its arguments (there must be at least one argument).
(logand 15 8) ⇒ 8 (logand 15 7 20) ⇒ 4
Uses a bit-wise logical ‘inclusive-or’ to combine all its arguments (there must always be at least one argument).
(logior 1 2 4) ⇒ 7
Uses a bitwise logical ‘exclusive-or’ to combine all its arguments (there must be at least one).
(logxor 7 3) ⇒ 4
This function inverts all the bits in number.
(lognot 0) ⇒ -1 (lognot 2) ⇒ -3 (lognot -1) ⇒ 0
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For the documentation of the functions >
, <
, >=
and
<=
see Comparison Predicates.
This function returns t
if the two integers number1 and
number2 have the same value.
(= 1 1) ⇒ t (= 1 0) ⇒ nil
This function will return t
if number1 and number2
and not equal to each other.
(/= 1 1) ⇒ nil (/= 1 0) ⇒ t
Returns t
if number is equal to zero.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Jade characters are stored in integers. Their read syntax is a question mark followed by the character itself which may be an escape sequence introduced by a backslash. For details of the available escape sequences see Strings.
?a ⇒ 97 ?\n ⇒ 10 ?\177 ⇒ 127
This function returns t
when character is one of the
alphabetic characters.
(alpha-char-p ?a) ⇒ t
When character is one of the upper-case characters this function
returns t
.
Returns t
when character is lower-case.
This function returns t
when character is one of the decimal
digit characters.
This function returns t
when character is either an alphabetic
character or a decimal digit character.
Returns t
when character is a white-space character (space, tab,
newline or form feed).
This function returns the upper-case equivalent of character. If character is already upper-case or has no upper-case equivalent it is returned unchanged.
(char-upcase ?a) ⇒ 65 ;`A' (char-upcase ?A) ⇒ 65 ;`A' (char-upcase ?!) ⇒ 33 ;`!'
Returns the lower-case equivalent of the character character.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Sequences are ordered groups of objects, there are several primitive types which can be considered sequences, each with its own good and bad points.
A sequence is either an array or a list, where an array is either a vector or a string.
This function returns t
if object is a sequence, nil
otherwise.
1.7.1 Cons Cells | An ordered pair of two objects | |
1.7.2 Lists | Chains of cons cells | |
1.7.3 Vectors | A chunk of memory holding a number of objects | |
1.7.4 Strings | Strings are efficiently-stored vectors | |
1.7.5 Array Functions | Accessing elements in vectors and strings | |
1.7.6 Sequence Functions | These work on any type of sequence |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A cons cell is an ordered pair of two objects, the car and the cdr.
The read syntax of a cons cell is an opening parenthesis followed by the read syntax of the car, a dot, the read syntax of the cdr and a closing parenthesis. For example a cons cell with a car of 10 and a cdr of the string ‘foo’ would be written as,
(10 . "foo")
This function creates a new cons cell. It will have a car of car and a cdr of cdr.
(cons 10 "foo") ⇒ (10 . "foo")
This function returns t
if object is a cons cell and nil
otherwise.
(consp '(1 . 2)) ⇒ t (consp nil) ⇒ nil (consp (cons 1 2)) ⇒ t
In Lisp an atom is any object which is not a cons cell (and is, therefore, atomic).
Returns t
if object is an atom (not a cons cell).
Given a cons cell there are a number of operations which can be performed on it.
This function returns the object which the car of the cons cell cons-cell.
(car (cons 1 2)) ⇒ 1 (car '(1 . 2)) ⇒ 1
This function returns the cdr of the cons cell cons-cell.
(cdr (cons 1 2)) ⇒ 2 (cdr '(1 . 2)) ⇒ 2
This function sets the value of the car in the cons cell cons-cell to new-car. The value returned is new-car.
(setq x (cons 1 2)) ⇒ (1 . 2) (rplaca x 3) ⇒ 3 x ⇒ (3 . 2)
This function is similar to rplacd
except that the cdr slot of
cons-cell is modified.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A list is a sequence of zero or more objects, the main difference between lists and vectors is that lists are more dynamic: they can change size, be split, reversed, concatenated, etc… very easily.
In Lisp lists are not a primitive type; instead singly-linked lists are created by chaining cons cells together (see section Cons Cells).
This functions returns t
when its argument, object, is a
list (i.e. either a cons cell or nil
).
1.7.2.1 List Structure | How lists are built from cons cells | |
1.7.2.2 Building Lists | Dynamically creating lists | |
1.7.2.3 Accessing List Elements | Getting at the elements which make the list | |
1.7.2.4 Modifying Lists | How to alter the contents of a list | |
1.7.2.5 Association Lists | Lists can represent relations | |
1.7.2.6 Infinite Lists | Circular data structures in Lisp |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each element in a list is given its own cons cell and stored in the car of
that cell. The list object is then constructed by making the cdr of a cell
contain the cons cell of the next element (and hence the whole tail of the
list). The cdr of the cell containing the last element in the list is
nil
. A list of zero elements is represented by the symbol nil
.
The read syntax of a list is an opening parenthesis, followed by the read syntax of zero or more space-separated objects, followed by a closing parenthesis. Alternatively, lists can be constructed ‘manually’ using dotted-pair notation.
All of the following examples result in the same list of five elements: the numbers from zero to four.
(0 1 2 3 4) (0 . (1 . (2 . (3 . (4 . nil))))) (0 1 2 . (3 4))
An easy way to visualise lists and how they are constructed is to see each cons cell in the list as a separate box with pointers to its car and cdr,
+-----+-----+ | o | o----> cdr +--|--+-----+ | --> car
Complex box-diagrams can now be drawn to represent lists. For example the
following diagram represents the list (1 2 3 4)
.
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+ | o | o----> | o | o----> | o | o----> | o | o----> nil +--|--+-----+ +--|--+-----+ +--|--+-----+ +--|--+-----+ | | | | --> 1 --> 2 --> 3 --> 4
A more complex example, the list ((1 2) (foo bar))
can be drawn as,
+-----+-----+ +-----+-----+ | o | o---------------------------> | o | o----> nil +--|--+-----+ +--|--+-----+ | | +-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+ | o | o----> | o | o----> nil | o | o----> | o | o----> nil +--|--+-----+ +--|--+-----+ +--|--+-----+ +--|--+-----+ | | | | --> 1 --> 2 --> foo --> bar
Sometimes when manipulating complex list structures it is very helpful to make a diagram of what it is that’s being manipulated.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It has already been shown how you can create lists using the Lisp reader; this method does have a drawback though: the list created is effectively static. If you modify the contents of the list and that list was created when a function was defined the list will remain modified for all future invocations of that function. This is not usually a good idea, consider the following function definition,
(defun bogus-function (x) "Return a list whose first element is nil and whose second element is X." (let ((result '(nil nil))) ;Static list which is filled in each time (rplaca (cdr result) x) ; the function is called result))
This function does in fact do what its documentation claims, but a problem arises when it is called more than once,
(setq x (bogus-function 'foo)) ⇒ (nil foo) (setq y (bogus-function 'bar)) ⇒ (nil bar) ;The first result has been destroyed x ⇒ (nil bar) ;See!
This example is totally contrived — no one would ever write a function like the one in the example but it nicely demonstrates the need for a dynamic method of creating lists.
This function creates a list out of its arguments, if zero arguments are
given the empty list, nil
, is returned.
(list 1 2 3) ⇒ (1 2 3) (list (major-version-number) (minor-version-number)) ⇒ (3 2) (list) ⇒ nil ;Equivalent to `()'
This function creates a list length elements long. If the
initial-value argument is given it defines the value of all elements
in the list, if it is not given they are all nil
.
(make-list 2) ⇒ (nil nil) (make-list 3 t) ⇒ (t t t) (make-list 0) ⇒ nil
This function creates a new list with the elements of each of its arguments
(which must be lists). Unlike the function nconc
this function
preserves all of its arguments.
(append '(1 2 3) '(4 5)) ⇒ (1 2 3 4 5) (append) ⇒ nil
What actually happens is that all arguments but the last are copied then the last argument is linked on to the end of the list (uncopied).
(setq foo '(1 2)) ⇒ (1 2) (setq bar '(3 4)) ⇒ (3 4) (setq baz (append foo bar)) ⇒ (1 2 3 4) (eq (nthcdr 2 baz) bar) ⇒ t
The following diagram shows the final state of the three variables more clearly,
foo--> +-----+-----+ +-----+-----+ | o | o----> | o | | +--|--+-----+ +--|--+-----+ | | o--> 1 o--> 2 bar | | -> baz--> +--|--+-----+ +--|--+-----+ +-----+-----+ +-----+-----+ | o | o----> | o | o----> | o | o----> | o | | +-----+-----+ +-----+-----+ +--|--+-----+ +--|--+-----+ | | --> 3 --> 4
Note how foo
and the first half of baz
use the same
objects for their elements — copying a list only copies its cons cells, its
elements are reused. Also note how the variable bar
actually
references the mid-point of baz
since the last list in an append
call is not copied.
This function returns a new list; it is made from the elements of the list list in reverse order. Note that this function does not alter its argument.
(reverse '(1 2 3 4)) ⇒ (4 3 2 1)
As a postscript to this section, the function used as an example at the beginning could now be written as,
(defun not-so-bogus-function (x) (list nil x))
Also note that the cons
function can be used to create lists by hand
and to add new elements onto the front of a list.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The most powerful method of accessing an element in a list is via a
combination of the car
and cdr
functions. There are other
functions which provide an easier way to get at the elements in a flat
list. These will usually be faster than a string of car
and cdr
operations.
This function returns the element count elements down the list,
therefore to access the first element use a count of zero (or even
better the car
function). If there are too few elements in the list
and no element number count can be found nil
is returned.
(nth 3 '(0 1 2 3 4 5)) ⇒ 3 (nth 0 '(foo bar) ⇒ foo
This function takes the cdr of the list list count times, returning the last cdr taken.
(nthcdr 3 '(0 1 2 3 4 5)) ⇒ (3 4 5) (nthcdr 0 '(foo bar)) ⇒ (foo bar)
This function returns the last element in the list list. If the
list has zero elements nil
is returned.
(last '(1 2 3)) ⇒ 3 (last '()) ⇒ nil
This function scans through the list list until it finds an element
which is equal
to object. The tail of the list (the cons cell
whose car is the matched object) is then returned. If no elements match
object then the empty list nil
is returned.
(member 'c '(a b c d e)) ⇒ (c d e) (member 20 '(1 2)) ⇒ nil
This function is similar to member
except that comparisons are
performed by the eq
function not equal
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The nthcdr
function can be used in conjunction with the rplaca
function to modify an arbitrary element in a list. For example,
(rplaca (nthcdr 2 '(0 1 2 3 4 5)) 'foo) ⇒ foo
sets the third element of the list (0 1 2 3 4 5)
to the symbol
called foo
.
There are also functions which modify the structure of a whole list. These are called destructive operations because they modify the actual structure of a list — no copy is made. This can lead to unpleasant side effects if care is not taken.
This function is the destructive equivalent of the function append
,
it modifies its arguments so that it can return a list which is the
concatenation of the elements in its arguments lists.
Like all the destructive functions this means that the lists given as
arguments are modified (specifically, the cdr of their last cons cell
is made to point to the next list). This can be seen with the
following example (similar to the example in the append
documentation).
(setq foo '(1 2)) ⇒ (1 2) (setq bar '(3 4)) ⇒ (3 4) (setq baz (nconc foo bar)) ⇒ (1 2 3 4) foo ⇒ (1 2 3 4) ;`foo' has been altered! (eq (nthcdr 2 baz) bar) ⇒ t
The following diagram shows the final state of the three variables more clearly,
foo--> bar--> baz--> +-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+ | o | o----> | o | o----> | o | o----> | o | | +--|--+-----+ +--|--+-----+ +--|--+-----+ +--|--+-----+ | | | | --> 1 --> 2 --> 3 --> 4
This function rearranges the cons cells constituting the list list so that the elements are in the reverse order to what they were.
(setq foo '(1 2 3)) ⇒ (1 2 3) (nreverse foo) ⇒ (3 2 1) foo ⇒ (1) ;`foo' wasn't updated when the list ; was altered.
This function destructively removes all elements of the list list
which are equal
to object then returns the modified list.
(delete t '(nil t nil t nil)) ⇒ (nil nil nil)
When this function is used to remove an element from a list which is stored
in a variable that variable must be set to the return value of the
delete
function. Otherwise, if the first element of the list
has to be deleted (because it is equal
to object) the value
of the variable will not change.
(setq foo '(1 2 3)) ⇒ (1 2 3) (delete 1 foo) ⇒ (2 3) foo ⇒ (1 2 3) (setq foo (delete 1 foo)) ⇒ (2 3)
This function is similar to the delete
function, the only difference
is that the eq
function is used to compare object with each
of the elements in list, instead of the equal
function which
is used by delete
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An association list (or alist) is a list mapping key values to to other values. Each element of the alist is a cons cell, the car of which is the key, the cdr is the value that it associates to. For example an alist could look like,
((fred . 20) (bill . 30))
this alist has two keys, fred
and bill
which both associate
to an integer (20 and 30 respectively).
It is possible to make the associated values lists, this looks like,
((fred 20 male) (bill 30 male) (sue 25 female))
in this alist the symbol fred
is associated with the list
(20 male)
.
There are a number of functions which let you interrogate an alist with a given key for its association.
This function scans the association list alist for the first element
whose car is equal
to key, this element is then returned. If
no match of key is found nil
is returned.
(assoc 'two '((one . 1) (two . 2) (three . 3))) ⇒ (two . 2)
Similar to the function assoc
except that the function eq
is
used to compare elements instead of equal
.
It is not usually wise to use assq
when the keys of the alist may not
be symbols — eq
won’t think two objects are equivalent unless they
are the same object!
(assq "foo" '(("bar" . 1) ("foo" . 2))) ⇒ nil (assoc "foo" '(("bar" . 1) ("foo" . 2))) ⇒ ("foo" . 2)
This function searches through alist until it finds an element whose
cdr is equal
to association, that element is then returned.
nil
will be returned if no elements match.
(rassoc 2 '((one . 1) (two . 2) (three . 3))) ⇒ (two . 2)
This function is equivalent to rassoc
except that it uses eq
to make comparisons.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Sometimes it is useful to be able to create ‘infinite’ lists — that is, lists which appear to have no last element — this can easily be done in Lisp by linking the cdr of the last cons cell in the list structure back to the beginning of the list.
----------------------------------- | | --> +-----+-----+ +-----+-----+ | | o | o----> | o | o----- +--|--+-----+ +--|--+-----+ | | --> 1 --> 2
The diagram above represents the infinite list (1 2 1 2 1 2 …)
.
Infinite lists have a major drawback though, many of the standard list manipulation functions can not be used on them. These functions work by moving through the list until they reach the end. If the list has no end the function may never terminate and the only option is to send Jade an interrupt signal (@pxref{Interrupting Jade}).
The only functions which may be used on circular lists are: the cons cell
primitives (cons
, car
, cdr
, rplaca
, rplacd
),
nth
and nthcdr
.
Also note that infinite lists can’t be printed.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A vector is a fixed-size sequence of Lisp objects, each element may be accessed in constant time — unlike lists where the time taken to access an element is proportional to the position of the element.
The read syntax of a vector is an opening square bracket, followed by zero or more space-separated objects, followed by a closing square bracket. For example,
[zero one two three]
In general it is best to use vectors when the number of elements to be stored is known and lists when the sequence must be more dynamic.
This function returns t
if its argument, object, is a vector.
This function creates a new vector containing the arguments given to the function.
(vector 1 2 3) ⇒ [1 2 3] (vector) ⇒ []
Returns a new vector, size elements big. If initial-value is
defined each element of the new vector is set to initial-value, otherwise
they are all nil
.
(make-vector 4) ⇒ [nil nil nil nil] (make-vector 2 t) ⇒ [t t]
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A string is a vector of characters (see section Characters), they are generally used for storing and manipulating pieces of text. Jade puts no restrictions on the values which may be stored in a string — specifically, the null character (‘^@’) may be stored with no problems.
The read syntax of a string is a double quote character, followed by the
contents of the string, the object is terminated by a second double quote
character. For example, "abc"
is the read syntax of the string
‘abc’.
Any backslash characters in the string’s read syntax introduce an escape sequence; one or more of the following characters are treated specially to produce the next actual character in the string.
The following escape sequences are supported (all are shown without their leading backslash ‘\’ character).
A newline character.
A carriage return character.
A form feed character.
A TAB character.
A ‘bell’ character (this is Ctrl-g).
The ‘control’ code of the character c. This is calculated by toggling the seventh bit of the upper-case version of c.
For example,
\^C ;A Ctrl-c character (ASCII value 3) \^@ ;The NUL character (ASCII value 0)
The character whose ASCII value is the octal value ‘012’. After the backslash character the Lisp reader reads up to three octal digits and combines them into one character.
The character whose ASCII value is the hexadecimal value ‘12’, i.e. an ‘x’ character followed by one or two hex digits.
This function returns t
if its argument is a string.
Creates a new string containing length characters, each character is initialised to initial-character (or to spaces if initial-character is not defined).
(make-string 3) ⇒ " " (make-string 2 ?$) ⇒ "$$"
This function concatenates all of its arguments, args, into a single string which is returned. If no arguments are given then the null string (‘’) results.
Each of the args may be a string, a character or a list or vector of characters. Characters are stored in strings modulo 256.
(concat "foo" "bar") ⇒ "foobar" (concat "a" ?b) ⇒ "ab" (concat "foo" [?b ?a ?r]) ⇒ "foobar" (concat) ⇒ ""
This function creates a new string which is a partial copy of the string string. The first character copied is start characters from the beginning of the string. If the end argument is defined it is the index of the character to stop copying at, if it is not defined all characters until the end of the string are copied.
(substring "xxyfoozwx" 3 6) ⇒ "foo" (substring "xyzfoobar" 3) ⇒ "foobar"
This function compares the two strings string1 and string2 — if
they are made from the same characters in the same order then t
is
returned, else nil
.
(string= "one" "one") ⇒ t (string= "one" "two") ⇒ nil
Note that an alternate way to compare strings (or anything!) is to use the
equal
function.
This function returns t
if string1 is ‘less’ than string2
.
This is determined by comparing the two strings a character at a time, the
first pair of characters which do not match each other are then compared
with a normal ‘less-than’ function.
In Jade the standard <
function understands strings so string<
is just a macro calling that function.
(string< "abc" "abd") ⇒ t (string< "abc" "abb") ⇒ nil
Functions are also available which match regular expressions with strings (see section Searching and Matching Functions) and which apply a mapping to each character in a string (see section Translation Functions).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns t
if object is an array.
Returns the element of the array (vector or string) array position
elements from the first element (i.e. the first element is numbered zero).
If no element exists at position in array, nil
is
returned.
(aref [0 1 2 3] 2) ⇒ 2 (aref "abcdef" 3) ⇒ 100 ;`d'
This function sets the element of the array array with an index of position (counting from zero) to value. An error is signalled if element position does not exist. The result of the function is value.
(setq x [0 1 2 3]) ⇒ [0 1 2 3] (aset x 2 'foo) ⇒ foo x ⇒ [0 1 foo 3]
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns the length (an integer) of the sequence sequence.
(length "abc") ⇒ 3 (length '(1 2 3 4)) ⇒ 4 (length [x y]) ⇒ 2
Returns a new copy of the sequence sequence. Where possible (in lists and vectors) only the ‘structure’ of the sequence is newly allocated: the same objects are used for the elements in both sequences.
(copy-sequence "xy") ⇒ "xy" (setq x '("one" "two")) ⇒ ("one" "two") (setq y (copy-sequence x)) ⇒ ("one" "two") (eq x y) ⇒ nil (eq (car x) (car y)) ⇒ t
This function returns the element of sequence position elements from the beginning of the sequence.
This function is a combination of the nth
and aref
functions.
(elt [0 1 2 3] 1) ⇒ 1 (elt '(foo bar) 0) ⇒ foo
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Symbols are objects with a name (usually a unique name), they are one of the most important data structures in Lisp since they are used to provided named variables (see section Variables) and functions (see section Functions).
This function returns t
when its argument is a symbol.
1.8.1 Symbol Syntax | The read syntax of symbols | |
1.8.2 Symbol Attributes | The objects stored in a symbol | |
1.8.3 Obarrays | Vectors used to store symbols | |
1.8.4 Creating Symbols | Allocating new symbols | |
1.8.5 Interning | Putting a symbol into an obarray | |
1.8.6 Property Lists | Each symbol has a set of properties |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The read syntax of a symbol is simply its name; if the name contains any meta-characters (whitespace or any from ‘()[]'";|’) they will have to be entered specially. There are two ways to tell the reader that a meta-character is actually part of the symbol’s name:
xy\(z\) ;the symbol whose name is ‘xy(z)’
xy|(z)| ;the symbol ‘xy(z)’
Here are some example read syntaxes.
setq ; ‘setq’ |setq| ; ‘setq’ \s\e\t\q ; ‘setq’ 1 ; the number 1 \1 ; the symbol ‘1’ |!$%zf78&| ; ‘!$%zf78&’ foo|(bar)| ; ‘foo(bar)’ foo\(bar\) ; ‘foo(bar)’
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
All symbols have four basic attributes, most important is the print name of the symbol. This is a string containing the name of the symbol, after it has been defined (when the symbol is first created) it may not be changed.
This function returns the print name of the symbol symbol.
(symbol-name 'unwind-protect) ⇒ "unwind-protect"
Each symbol also has a value cell storing the value of this symbol when
it is referenced as a variable. Usually this cell is accessed implicitly by
evaluating a variable form but it can also be read via the symbol-value
function(1) (see section Variables).
Similar to the value cell each symbol also has a function cell which
contains the function definition of the symbol (see section Named Functions). The
symbol-function
function can be used to read this cell and the
fset
function to set it.
Lastly, there is the symbol’s property list, this is similar to an alist (see section Association Lists) and provides a method of storing arbitrary extra values in each symbol. See section Property Lists.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An obarray is the structure used to ensure that no two symbols have the same name and to provide quick access to a symbol given its name. An obarray is basically a vector (with a slight wrinkle), each element of the vector is a chain of symbols which share the same hash-value (a bucket). These symbols are chained together through links which are invisible to Lisp programs: if you examine an obarray you will see that each bucket looks as though it has at most one symbol stored in it.
The normal way to reference a symbol is simply to type its name in the program, when the Lisp reader encounters a name of a symbol it looks in the default obarray for a symbol of that name. If the named symbol doesn’t exist it is created and hashed into the obarray — this process is known as interning the symbol, for more details see Interning.
This variable contains the obarray that the read
function uses when
interning symbols. If you change this I hope you know what you’re doing.
This function creates a new obarray with size hash buckets (this should be a prime number for best results).
This is the only correct way of making an obarray.
This function scans the specified obarray (obarray or the value of
the variable obarray
if obarray is undefined) for a symbol
whose name is the string symbol-name. The value returned is the
symbol if it can be found or nil
otherwise.
(find-symbol "setq") ⇒ setq
Returns a list of symbols from the obarray obarray (or the default)
whose print name matches the regular expression regexp. If
predicate is defined and not nil
, each symbol which matches
regexp is applied to the function predicate, if the value
is t
it is considered a match.
The predicate argument is useful for restricting matches to a certain type of symbol, for example only commands.
(apropos "^yank" 'commandp) ⇒ (yank-rectangle yank yank-to-mouse)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is possible to allocate symbols dynamically, this is normally only necessary when the symbol is to be interned in the non-default obarray or the symbol is a temporary object which should not be interned (for example: labels in a compiler?).
This function creates and returns a new, uninterned, symbol whose print name is the string print-name. Its variable and function value cells are void and it will have an empty property list.
(make-symbol "foo") ⇒ foo
This function returns a new, uninterned, symbol which has a unique print name.
(gensym) ⇒ G0001 (gensym) ⇒ G0002
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Interning a symbol means to store it in an obarray so that it can be found in the future: all variables and named-functions are stored in interned symbols.
When a symbol is interned a hash function is applied to its print name to determine which bucket in the obarray it should be stored in. Then it is simply pushed onto the front of that bucket’s chain of symbols.
Normally all interning is done automatically by the Lisp reader. When it
encounters the name of a symbol which it can’t find in the default obarray
(the value of the variable obarray
) it creates a new symbol of that
name and interns it. This means that no two symbols can have the same print
name, and that the read syntax of a particular symbol always produces the
same object (unless the value of obarray
is altered).
(eq 'some-symbol 'some-symbol) ⇒ t
This function uses find-symbol
to search the obarray (or the
standard obarray) for a symbol called symbol-name. If a symbol of
that name is found it is returned, otherwise a new symbol of that name is
created, interned into the obarray, and returned.
(intern "setq") ⇒ setq (intern "my-symbol" my-obarray) ⇒ my-symbol
Interns the symbol symbol into the obarray obarray (or the standard one) then returns the symbol. If symbol is currently interned in an obarray an error is signalled.
(intern-symbol (make-symbol "foo")) ⇒ foo (intern-symbol 'foo) error--> Error: Symbol is already interned, foo
This function removes the symbol symbol from the obarray obarray then returns the symbol.
Beware! this function must be used with extreme caution — once you unintern a symbol there’s no way to recover it.
(unintern 'setq) ;This is extremely stupid ⇒ setq
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each symbol has a property list (or plist), this is a structure which associates an arbitrary Lisp object with a key (usually a symbol). The keys in a plist may not have any duplications (so that each property is only defined once).
The concept of a property list is very similar to an association list (see section Association Lists) but there are two main differences:
((one . 1) (two . 2) (three . 3))
a property list would be,
(one 1 two 2 three 3)
This function searches the property list of the symbol symbol for
a property eq
to property. If such a property is found it
is returned, else the value nil
is returned.
(get 'if 'lisp-indent) ⇒ 2 (get 'set 'lisp-indent) ⇒ nil
put
sets the value of the property property to new-value
in the property list of the symbol symbol. If there is an
existing value for this property it is overwritten. The value returned
is new-value.
(put 'foo 'prop 200) ⇒ 200
Returns the property list of the symbol symbol.
(symbol-plist 'if) ⇒ (lisp-indent 2)
This function sets the property list of the symbol symbol to plist.
(setplist 'foo '(zombie yes)) ⇒ (zombie yes)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
So far I have only discussed a few of the various data types available and how the Lisp reader can convert textual descriptions of these types into Lisp objects. Obviously there has to be a way of actually computing something — it would be difficult to write a useful program otherwise.
What sets Lisp apart from other languages is that in Lisp there is no difference between programs and data: a Lisp program is just a sequence of Lisp objects which will be interpreted when the program is run.
The subsystem which does this interpreting is called the
Lisp evaluator and each expression to be evaluated is called
a form. The evaluator (the function eval
) examines the
structure of the form that is applied to and computes the value of the
form within the current environment.
A form can be any type of data object; the only types which the evaluator treats specially are symbols (which stand for variables) and lists, anything else is returned as-is (and is called a self-evaluating form).
This function computes the value of the form which is its argument, within
the current environment. The computed value is then returned.
eval
is the basic function for interpreting Lisp objects.
1.9.1 Symbol Forms | How variables are accessed | |
1.9.2 List Forms | Subroutine calls | |
1.9.3 Self-Evaluating Forms | Forms which don’t get evaluated | |
1.9.4 Quoting | How to prevent evaluation of forms |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When the evaluator is applied to a symbol the computed value of the form is the object stored in the symbol’s variable slot. Basically this means that to get the value of a variable you simply write its name. For example,
buffer-list ⇒ (#<buffer *jade*> #<buffer programmer.texi>)
this extract from a Lisp session shows the read syntax of a form to
get the value of the variable buffer-list
and the result when
this form is evaluated.
Since forms are evaluated within the current environment the value of a variable is its newest binding, or in the case of buffer-local variables, its value in the current buffer. See section Variables.
If the value of an evaluated symbol is void an error is signalled.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Forms which are lists are used to call a subroutine. The first element of the list is the subroutine which is to be called; all further elements are arguments to be applied to the subroutine.
There are several different types of subroutines available: functions, macros, special forms and autoloads. When the evaluator finds a form which is a list it tries to classify the form into one of these four types. First of all it looks at the first element of the list, if it is a symbol it gets the value from the function slot of the symbol (note that the first element of a list form is never evaluated itself). This value (either the first element or the symbol’s function value) is enough to classify the form into one of the four types.
1.9.2.1 Function Call Forms | ‘Normal’ subroutines | |
1.9.2.2 Macro Call Forms | Source code expansions | |
1.9.2.3 Special Forms | Abnormal control structures | |
1.9.2.4 Autoload Forms | Loading subroutines from files on the fly |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The first element of a function call form is the name of the function, this can be either a symbol (in which case the symbol’s function value is indirected through to get the real function definition) or a lambda expression (see section Lambda Expressions).
Any other elements of the list are forms to be evaluated (in left to right order) and their values become the arguments to the function. The function is applied to these arguments and the result that it returns becomes the value of the form.
For example, consider the form (/ 100 (1+ 4))
. This is a function
call to the function /
. First the 100
form is evaluated: it
returns the value 100
, next the form (1+ 4)
is evaluated. This
is also a function call and computes to a value of 5
which becomes
the second argument to the /
function. Now the /
function is
applied to its arguments of 100
and 5
and it returns the
value 20
which then becomes the value of the form (/ 100 (1+ 4))
.
(/ 100 (1+ 4)) ≡ (/ 100 5) ⇒ 20
Or another example,
(+ (- 10 (1- 7)) (* (1+ 2) 4) ≡ (+ (- 10 6) (* (1+ 2) 4) ≡ (+ 4 (* (1+ 2) 4) ≡ (+ 4 (* 3 4)) ≡ (+ 4 12) ⇒ 16
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Macros are source code expansions, the general idea is that a macro is a function which using the unevaluated arguments applied to it, computes another form (the expansion of the macro and its arguments) which is then evaluated to provide the value of the form. For more details see Macros.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Special forms are built-in functions which the evaluator knows must be handled specially. The main difference between a special form and a function is that the arguments applied to a special form are not automatically evaluated — if necessary the special form will evaluate arguments itself. This will be noted in the documentation of the special form.
Special forms are generally used to provide control structures, for example, all of the conditional constructs are special forms (if all of their arguments, including the forms to be conditionally evaluated, were evaluated automatically this would defeat the object of being conditional!).
The special forms supported by Jade are: and
, catch
, cond
,
defconst
, defmacro
, defun
, defvar
,
error-protect
, function
, if
, let
, let*
,
or
, prog1
, prog2
, progn
, quote
, setq
,
setq-default
, unless
, unwind-protect
, when
,
while
, with-buffer
, with-window
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Not all modules of Jade are needed at once, autoload forms provide a means of marking that a function (or macro) is contained by a specific file of Lisp code. The first time that the function is accessed the autoload form will be evaluated; this loads the file that the function is contained by then re-evaluates the list form.
By then the autoload form will have been overwritten in the symbol’s function slot by the true function (when it was loaded) so the form will execute properly.
An autoload form is a list whose first element is the symbol autoload
,
for full details see Autoloading.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The computed value of any form which is not a symbol or a list will simply be the form itself and the form is said to be a self-evaluating form.
Usually the only forms to be evaluated in this way will be numbers, strings and vectors (since they are the only other data types which have read syntaxes) but the effect is the same for other types of data.
This means that forms you know are self-evaluating do not have to be quoted to be used as constants (like lists and symbols do).
"foo" ⇒ "foo" (eval (current-buffer)) ⇒ #<buffer programmer.texi>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As the above sections explain some types of Lisp object have special meaning to the Lisp evaluator (namely the symbol and list types) this means that if you want to refer to a symbol or a list in a program you can’t (yet) because the evaluator will treat the form as either a variable reference or a function call respectively.
To get around this Lisp uses something called quoting, the
quote
special form simply returns its argument, without evaluating
it. For example,
(quote my-symbol) ⇒ my-symbol
the quote
form prevents the my-symbol
being treated as a
variable — it is effectively ‘hidden’ from the evaluator.
Writing ‘quote’ all the time would be a bit boring so there is a
shortcut: the Lisp reader treats any form x preceded by a single quote
character (‘'’) as the form (quote x)
. So the example
above would normally be written as,
'my-symbol ⇒ my-symbol
This special form returns its single argument without evaluating it. This is used to quote constant objects to prevent them from being evaluated.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Control structures are special forms or macros which control which forms get evaluated, when they get evaluated and the number of times to evaluate them. This includes conditional structures, loops, etc…
The simplest control structures are the sequencing structures; they are used to evaluate a list of forms in left to right order.
1.10.1 Sequencing Structures | Evaluating several forms in sequence | |
1.10.2 Conditional Structures | Making decisions based on truth values | |
1.10.3 Looping Structures | ‘while’ loops | |
1.10.4 Non-Local Exits | Exiting from several levels of evaluation |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each of the special forms in this section simply evaluates its argument forms in left-to-right order. The only difference is the result they return.
The most widely used sequencing special form is progn
: it
evaluates all its argument forms and returns the computed value of the last
one. Many other control structures are said to perform an implicit progn,
this means that they call progn
with a list of forms.
progn
in Lisp is nearly analogous to a begin…end
block
in Pascal; it is used in much the same places — to allow you to
evaluate a sequence of form where only one form was allowed (for example
the true clause of an if
structure).
All of the forms are evaluated sequentially (from left-to-right),
the result of the last evaluated form is the return value of this
structure. If no arguments are given to progn
it returns nil
.
(progn 'one (+ 1 1) "three") ⇒ "three" (progn) ⇒ nil
This special form evaluates its first form then performs an implicit progn on the rest of its arguments. The result of this structure is the computed value of the first form.
(prog1 'one (+ 1 1) "three") ⇒ one
This is similar to prog1
except that the evaluated value of
its second form is returned.
The first form is evaluated, then its second, then it performs an implicit progn on the remaining arguments.
(prog2 'one (+ 1 1) "three") ⇒ 2
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lisp provides a number of conditional constructs, the most complex of
which (cond
) will take a list of conditions, the first of which
is t
then has its associated list of forms evaluated. Theoretically
this is the only conditional special form necessary — the rest could
be implemented as macros.
The if
construct is the nearest thing in Lisp to the if-then-else
construct found in most programming languages.
First the condition form is evaluated, if it returns t
(not
nil
) the true-form is evaluated and its result returned. Otherwise
the result of an implicit progn on the else-forms is returned. If there
are no else-forms nil
is returned.
Note that one of the true-form or the else-forms is completely ignored — it is not evaluated.
(if (special-form-p 'if) "`if' is a special form" "`if' is not a special form") ⇒ "`if' is a special form"
condition is evaluated, if it is t
the result of an implicit progn
on the true-forms is returned, otherwise nil
is returned.
(when t (message "Pointless") 'foo) ⇒ foo
This special forms first evaluates condition, if its computed value is
not nil
its value is returned. Otherwise the else-forms are
evaluated sequentially, the value of the last is returned.
The cond
special form is used to choose between an arbitrary number
of conditions. Each clause is a list; its car is the condition
the list which is the cdr of the clause is the body-forms. This
means that each clause looks something like:
(condition body-forms…)
and a whole cond
form looks like:
(cond (condition-1 body-forms-1…) (condition-2 body-forms-2…) …)
The condition in each clause is evaluated in sequence
(condition-1, then condition-2, …), the first one
which evaluates to a non-nil
has an implicit progn performed on
its body-forms, the value of which is the value returned by the
cond
form.
If the true condition has no body-forms the value returned
by cond
is the value of the condition. If none of the
clauses has a non-nil
condition the value of the cond
is nil
.
Often you want a default clause; one which has its body-forms
to be evaluated if none of the other clauses are true. The way to
do this is to add a clause with a condition of t
and
body-forms of whatever you want the default action to be.
(cond ((stringp buffer-list)) ;Clause with no body-forms ((consp buffer-list) (setq x buffer-list) ;Two body-forms t) (t ;Default clause (error "`buffer-list' is corrupted!"))) ⇒ t
All of the other conditionals can be written in terms of cond
,
(if c t e…) ≡ (cond (c t) (t e…)) (when c t…) ≡ (cond (c t…)) (unless c e…) ≡ (cond (e) (t e…))
There are also a number of special forms which combine conditions together by the normal logical rules.
The first of the forms is evaluated, if it is non-nil
its value
becomes the value of the or
form and no more of forms
are
evaluated. Otherwise this step is repeated for the next member of forms.
If all of the forms have been evaluated and none have a non-nil
value nil
becomes the value of the or
form.
If there are no forms nil
is returned.
(or nil 1 nil (beep)) ;(beep)
won't be evaluated
⇒ 1
The first of the forms is evaluated. If it is nil
no more
of the forms are evaluated and nil
becomes the value of the
and
structure. Otherwise the next member of forms is evaluated
and its value tested. If none of the forms are nil
the computed
value of the last member of forms becomes the value of the and
form.
(and 1 2 nil (beep)) ;(beep)
won't be evaluated
⇒ nil
(and 1 2 3) ;All forms are evaluated
⇒ 3
This function inverts the boolean value of its argument. If object
is non-nil
, nil
is returned, otherwise t
is returned.
(not nil) ⇒ t (not t) ⇒ nil (not 42) ⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jade’s version of Lisp has only one structure for looping — a while loop similar to those found in most programming languages.
The condition form is evaluated. If it is non-nil
an implicit
progn is performed on the body-forms and the whole thing is repeated
again.
This continues until the condition form evaluates to nil
. The
value of any while
structure is nil
.
while
can be recursively defined in terms of when
:
(while c b …) ≡ (when c (progn b … (while c b …)))
;; Step through a list x
(while x
;; Do something with the current element, (car x)
(setq x (cdr x)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A non-local exit is a transfer of control from the current point
of evaluation to a different point (somewhat similar to the much-maligned
goto
statement in some imperative languages).
Non-local exits can either be used explicitly (catch
and throw
)
or implicitly (errors).
1.10.4.1 Catch and Throw | Programmed non-local exits | |
1.10.4.2 Function Exits | Returning values from a function | |
1.10.4.3 Cleanup Forms | Forms which will always be evaluated | |
1.10.4.4 Errors | Signalling that an error occurred |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The catch
and throw
structures are used to perform
explicit transfers of control. First a catch
form is used to
setup a tag, this acts like a label for the C language’s goto
statement. To transfer control a throw
form is then used to
transfer to the named tag. The tag is destroyed and the catch
form exits with the value provided by the throw
.
In a program this looks like,
(catch 'tag ;; Forms which may `throw' back to tag … (throw 'tag value) ;; Control has now passed to the `catch', ;; no more forms in this progn will be evaluated. …) ⇒ value
where tag is the tag to be used (this is normally a symbol) and
value is the result of the catch
form.
When a throw actually happens all catches in scope are searched for
one with a tag which is eq
to the tag in the throw. If more than
one exists the most-recent is chosen. Now that the catch has been located
the environment is ‘wound-back’ to the catch’s position (i.e. local variables
are unbound, cleanup forms removed, unused catches forgotten, etc…)
and all Lisp constructs between the current point of control and
the catch are exited.
For example,
(let ((test 'outer)) (cons (catch 'foo (let ((test 'inner)) (throw 'foo test) (setq test 'unreachable))) ;Never reached test)) ⇒ (inner . outer)
when the throw executes the second binding of test
is unwound and
the first binding comes back into effect. For more details on variable
binding see Local Variables.
Note that catch tags are dynamically scoped, the thrower does not have to be within the same lexical scope (this means you can throw through functions).
This special form defines a catch tag which will be accessible while the body-forms are being evaluated.
tag is evaluated and recorded as the tag for this catch. Next the
body-forms are evaluated as an implicit progn. The value of the
catch
form is either the value of the progn, or, if a throw
happened, the value specified in the throw form.
Before exiting the tag installed by this form is removed.
This function transfers the point of control to the catch form with a
tag which is eq
to tag. The value returned by this catch
form is either catch-value or nil
if catch-value is
undefined.
If there is no catch with a tag of tag an error is signalled and the editor returns to the top-level of evaluation.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is often useful to be able to immediately return control from a function
definition (like the C return
statement). Jade’s version of Lisp has
the return
function for this.
This function transfers control out of the most-recent lambda-expression (i.e. a function or macro definition) so that the result of the lambda- expression is value.
(funcall '(lambda () (return 'x) 'y)) ⇒ x
The 'y
form is never evaluated since control is passed straight from
the (return 'y)
form back to the funcall
form.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is sometimes necessary to be sure that a certain form is always
evaluated, even when a non-local exit would normally bypass that form.
The unwind-protect
special form is used to stop this happening.
The body-form is evaluated, if it exits normally the cleanup-forms
are evaluated sequentially then the value which the body-form
returned becomes the value of the unwind-protect
form. If the
body-form exits abnormally though (i.e. a non-local exit happened)
the cleanup-forms are evaluated anyway and the non-local exit
continues.
One use of this is to ensure that an opened file is always closed, for example,
(catch 'foo
(unwind-protect
(let
((temporary-file (open (tmp-file-name) "w")))
;; Use temporary-file
(write temporary-file "A test\n")
;; Now force a non-local exit
(throw 'foo))
;; This is the cleanup-form it will always
;; be evaluated no matter what happens.
(close temporary-file)))
⇒ nil
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Errors are a type of non-local exit; when a form can not be evaluated properly an error is normally signalled. If an error-handler has been installed for that type of error control is unwound back to the handler and evaluation continues. If there is no suitable handler control is passed back to the event loop of the most-recent recursive edit and a suitable error message is printed.
Signals that an error has happened. error-symbol is a symbol
classifying the type of error, it should have a property error-message
(a string) which is the error message to be printed.
data is a list of objects which are relevant to the error — they will be made available to any error-handler or printed with the error message otherwise.
(signal 'void-value '(some-symbol)) error--> Value as variable is void: some-symbol
This variable is consulted by the function signal
. If its value
is either t
or a list containing the error-symbol to
signal
as one of its elements, the Lisp debugger is entered.
When the debugger exits the error is signalled as normal.
When you expect an error to occur and need to be able to regain control
afterwards the error-protect
form can be used.
error-protect
evaluates the body-form with error
handlers in place.
Each of the error-handlers is a list whose car is a symbol defining the type of error which this handler catches. The cdr of the list is a list of forms to be evaluated sequentially when the handler is invoked.
While the forms of the error handler are being evaluated the variable
error-info
is bound to the value (error-symbol . data)
(these were the arguments to the signal
form which caused the
error).
The special value, the symbol error
, in the car of one of the
error-handlers will catch all types of errors.
(error-protect (signal 'file-error '("File not found" "/tmp/foo")) (file-error error-info) (error (setq x z))) ;Default handler ⇒ (file-error "File not found" "/tmp/foo")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Lisp symbols are used to represent variables. Each symbol contains a slot which is used to contain the value of the symbol when it is used as a symbol.
The normal way to obtain the current value of a variable is simply to evaluate the symbol it lives in (i.e. write the name of the variable in your program).
This function returns the value of the symbol variable in the current environment.
1.11.1 Local Variables | Creating temporary variables | |
1.11.2 Setting Variables | Altering a variable’s value | |
1.11.3 Scope and Extent | Technical jargon | |
1.11.4 Buffer-Local Variables | Variables with distinct values in each buffer. | |
1.11.5 Void Variables | Some variables have no values | |
1.11.6 Constant Variables | Variables which may not be altered | |
1.11.7 Defining Variables | How to define a variable before using it |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A local variable is a variable which has a temporary value while a program is executing, for example, when a function is called the variables which are the names of its arguments are temporarily bound (a binding is a particular instance of a local variable) to the values of the arguments passed to the function. When the function call exits its arguments are unbound and the previous definitions of the variables come back into view.
Even if a variable has more than one binding still ‘active’ only the most recent is visible — there is absolutely no way the previous bindings can be accessed until the bindings are unbound one-by-one.
A nice way of visualising variable binding is to think of each variable as a stack. When the variable is bound to, a new value is pushed onto the stack, when it is unbound the top of the stack is popped. Similarly when the stack is empty the value of the variable is void (see section Void Variables). Assigning a value to the variable (see section Setting Variables) overwrites the top value on the stack with a new value. When the value of the variable is required it is simply read from the top of the stack.
Apart from function calls there are two special forms which perform
variable binding (i.e. creating local variables), let
and let*
.
let
creates new variable bindings as specified by the bindings
argument then evaluates the body-forms in order. The variables
are then unbound to their state before this let
form and the
value of the implicit progn of the body-forms becomes the value
of the let
form.
The bindings argument is a list of the bindings to perform. Each binding is either a symbol, in which case that variable is bound to nil, or a list whose car is a symbol. The cdr of this list is a list of forms which, when evaluated, give the value to bind the variable to.
(setq foo 42) ⇒ 42 (let ((foo (+ 1 2)) bar) ;; Body forms (setq foo (1+ foo)) ;This sets the new binding (cons foo bar)) ⇒ (4 . nil) foo ⇒ 42 ;The original values is back
Note that no variables are bound until all the new values have been
computed (unlike in let*
). For example,
(setq foo 42) ⇒ 42 (let ((foo 100) (bar foo)) (cons foo bar)) ⇒ (100 . 42)
Although foo
is given a new binding this is not actually done
until all the new bindings have been computed, hence bar
is bound to
the old value of foo
.
This special form is exactly the same as let
except for one
important difference: the new bindings are installed as they are
computed.
You can see the difference by comparing the following example with the
last example in the let
documentation (above),
(setq foo 42)
⇒ 42
(let* ;Using let*
this time
((foo 100)
(bar foo))
(cons foo bar))
⇒ (100 . 100)
By the time the binding of bar
is computed the new binding of
foo
has already been installed.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Setting a variable means to overwrite its current value (that is, the value of its most recent binding) with a new one. The old value is irretrievably lost (unlike when a new value is bound to a variable, see section Local Variables).
The special form setq
is the usual method of altering the value of
a variable. Each variable is set to the result of evaluating its
corresponding form. The last value assigned becomes the value of
the setq
form.
(setq x 20 y (+ 2 3)) ⇒ 5
In the above example the variable x
is set to 20
and y
is set to the value of the form (+ 2 3)
(5).
When the variable is marked as being buffer-local (see section Buffer-Local Variables) the current buffer’s instance of the variable is set.
The value of the variable variable (a symbol) is set to new-value and the new-value is returned.
This function is used when the variable is unknown until run-time, and therefore has to be computed from a form.
(set 'foo 20)
≡
(setq foo 20) ;setq
means `set-quoted'
⇒ 20
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Jade’s version of Lisp all variables have indefinite scope and dynamic extent. What this means is that references to variables may occur anywhere in a program (i.e. bindings established in one function are not only accessible within that function, that’s lexical scope) and that references may occur at any point in the time between the binding being created and it being unbound.
The combination of indefinite scope and dynamic extent is often termed dynamic scope.
As an aside, Lisp objects have indefinite extent, meaning that the object will exist for as long as there is a possibility of it being referenced (and possibly longer — until the garbage collector runs).
Note that in Common Lisp only those variables declared ‘special’ have indefinite scope and dynamic extent.
Try not to abuse the dynamic scoping, although it is often very useful to be able to bind a variable in one function and use it in another this can be confusing if not controlled and documented properly.
A quick example of the use of dynamic scope,
(defun foo (x) (let ((foo-var (* x 20))) (bar x) … (defun bar (y) ;; Since this function is called from ;; the functionfoo
it can refer ;; to any bindings whichfoo
can. (setq y (+ y foo-var)) …
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is often very useful to be able to give variables different values for different editor buffers — most major modes need to record some buffer-specific information. Jade allows you to do this by giving a variable buffer-local bindings.
There are two strengths of buffer-local variables: you can either give a variable a buffer-local value in a single buffer, with other buffers treating the variable as normal, or a variable can be marked as being automatically buffer-local, each time the variable is set the current buffer’s value of the variable is updated.
Each buffer maintains an alist of the symbols which have buffer-local
values in the buffer and the actual values themselves, this alist may
be read with the buffer-variables
function.
When the value of a variable is referenced (via the symbol-value
function) the current buffer’s alist of local values is examined for
a binding of the variable being referenced; if one is found that is
the value of the variable, otherwise the default value (the
value stored in the symbol’s value cell) is used.
Setting a variable also searches for a buffer-local binding; if one
exists its value is modified, not the default value. If the
variable has previously been marked as being automatically buffer-local
(by make-variable-buffer-local
) a buffer-local binding is
automatically created if one doesn’t already exist.
Currently there is one main problem with buffer-local variables:
they can’t have temporary values bound to them (or rather, they can
but I guarantee it won’t work how you expect), so for the time
being, don’t try to bind local values (with let
or let*
)
to a buffer-local variable.
This function gives the variable symbol a buffer-local binding in the current buffer. The value of this binding will be the same as the variable’s default value.
If symbol already has a buffer-local value in this buffer nothing happens.
Returns symbol.
This function marks the variable symbol as being automatically buffer-local.
This means that any attempts at setting the value of symbol will actually set the current buffer’s local value (if necessary a new buffer-local binding will be created in the buffer).
Returns symbol.
(make-variable-buffer-local 'buffer-modtime) ⇒ buffer-modtime
This function returns the default value of the variable symbol.
(setq foo 'default) ⇒ default (make-local-variable 'foo) ;Create a value in this buffer ⇒ foo (setq foo 'local) ⇒ local foo ⇒ local (symbol-value 'foo) ⇒ local (default-value 'foo) ⇒ default
Returns t
if the variable symbol has a non-void default
value.
Similar to the setq
special form except that the default value
of each variable is set. In non-buffer-local symbols there is
no difference between setq
and setq-default
.
Sets the default value of the variable symbol to new-value, then returns new-value.
This function removes the buffer-local binding of the variable symbol from the current buffer (if one exists) then returns symbol.
This function removes all the buffer-local bindings associated with the current buffer. Subsequently, any buffer-local variables referenced while this buffer is current will use their default values.
The usual way to define an automatically buffer-local variable is to use
defvar
and make-variable-buffer-local
, for example,
(defvar my-local-variable default-value
"Doc string for my-local-variable
.")
(make-variable-buffer-local 'my-local-variable)
Note that if you want to reference the value of a buffer-local variable
in a buffer other than the current buffer, use the with-buffer
special form (see section The Current Buffer). For example, the form,
(with-buffer other-buffer some-variable)
will produce the value of the variable some-variable in the buffer other-buffer.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A variable which has no value is said to be void, attempting to reference the value of such a symbol will result in an error. It is possible for the most recent binding of a variable to be void even though the inactive bindings may have values.
Returns t
if the symbol variable has a value, nil
if
its value is void.
This function makes the current binding of the symbol variable be void, then returns variable.
(setq foo 42) ⇒ 42 foo ⇒ 42 (boundp 'foo) ⇒ t (makunbound 'foo) ⇒ foo (boundp 'foo) ⇒ nil foo error--> Value as variable is void: foo
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Lisp constants are represented by variables which have been marked as being read-only. Any attempt to alter the value of a constant results in an error.
Two of the most commonly used constants are nil
and t
.
This function defines whether or not the value of the symbol variable
may be modified. If read-write is nil
or undefined the variable
is marked to be constant, otherwise it’s marked to be a normal variable.
The value returned is variable.
Returns t
if the value of the symbol variable may be altered,
nil
otherwise.
Constants may behave a bit strangely when you compile the program they
are used in: the value of the constant is likely to be hardwired into
the compiled functions it is used in, and the constant is unlikely to
be eq
to itself!
The compiler assumes that constant is always the same, whenever it is evaluated. It may even be evaluated more than once. See section Compiled Lisp.
The special form defconst
can be used to define constants,
see Defining Variables.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The special forms defvar
and defconst
allow you to define
the global variables which will be used in a program. This is entirely
optional; it is highly recommended though.
This special form defines a global variable, the symbol variable. If the value of variable is void the form is evaluated and its value is stored as the value of variable (note that the default value is modified, never a buffer-local value).
If the doc-string argument is defined it is a string documenting
variable. This string is then stored as the symbol’s
variable-documentation
property and can be accessed by the
describe-variable
function.
(defvar my-variable '(x y)
"This variable is an example showing the usage of the defvar
special form.")
⇒ my-variable
defconst
defines a constant, the symbol constant. Its value
(in the case of a buffer-local symbol, its default value) is set to the
result of evaluating form. Note that unlike defvar
the value
of the symbol is always set, even if it already has a value.
The doc-string argument, if defined, is the documentation string for the constant.
(defconst the-answer 42 "An example constant.") ⇒ the-answer
See section Constant Variables.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A function is a Lisp object which, when applied to a sequence of argument values, produces a value — the function’s result. It may also produce side-effects. All Lisp functions return results — there is nothing like a procedure in Pascal.
Functions are the main building-block in Lisp programs, each program is usually a system of inter-related functions.
There are two types of function: primitive functions are functions written in the C language, these are sometimes called built-in functions, the object containing the C code itself is called a subr. All other functions are written in Lisp.
Returns t
if object is a function (i.e. it can be used
as the function argument of funcall
.
(functionp 'set) ⇒ t (functionp 'setq) ⇒ nil (functionp #'(lambda (x) (+ x 2))) ⇒ t
1.12.1 Lambda Expressions | Structure of a function object | |
1.12.2 Named Functions | Functions can be named by symbols, | |
1.12.3 Anonymous Functions | Or they can be un-named | |
1.12.4 Predicate Functions | Functions which return boolean values | |
1.12.5 Defining Functions | How to write a function definition | |
1.12.6 Calling Functions | Functions can be called by hand | |
1.12.7 Mapping Functions | Map a function to the elements of a list |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lambda expressions are used to create an object of type function
from other Lisp objects, it is a list whose first element is the
symbol lambda
. All functions written in Lisp (as opposed to the
primitive functions in C) are represented by a lambda expression.
Note that a lambda expression is not an expression, evaluating a
lambda expression will give an error (unless there is a function called
lambda
).
The format of a lambda expression is:
(lambda lambda-list [doc] [interactive-declaration] body-forms… )
Where lambda-list is the argument specification of the function, doc is an optional documentation string, interactive-declaration is only required by editor commands (see section Commands) and the body-forms is the actual function code (when the function is called each form is evaluated in sequence, the last form’s value is the result returned by the function).
The lambda-list is a list, it defines how the argument values applied to the function are bound to local variables which represent the arguments within the function. At its simplest it is simply a list of symbols, each symbol will have the corresponding argument value bound to it. For example, the lambda list,
(lambda (x y) (+ x y))
takes two arguments, x
and y
. When this function is called
with two arguments the first will be bound to x
and the second
to y
(then the function will return their sum).
To complicate matters there are several lambda-list keywords which modify the meaning of symbols in the lambda-list. Each keyword is a symbol whose name begins with an ampersand, they are:
&optional
All the variables following this keyword are considered optional (all
variables before the first keyword are required: an error will be
signalled if a required argument is undefined in a function call). If
an optional argument is undefined it will simply be given the value nil
.
Note that optional arguments must be specified if a later optional argument
is also specified. Use nil
to explicitly show that an optional
argument is undefined.
For example, if a function foo
takes two optional arguments and
you want to call it with only the second argument defined, the first
argument must be specified as nil
to ensure that the correct argument
value is bound to the correct variable.
(defun foo (&optional arg-1 arg-2) … (foo nil arg-2-value) ;Leave the first argument undefined
&rest
The &rest
keyword allows a variable number of arguments to be
applied to a function, all the argument values which have not been
bound to argument variables are simply consed into a list and bound
to the variable after the &rest
keyword. For example, in,
(lambda (x &rest y) …)
the first argument, x
, is required. Any other arguments applied
to this function are made into a list and this list is bound to the
y
variable.
When a function represented by a lambda-list is called the first thing that happens is to bind the argument values to the argument variables. The lambda-list and the list of argument values applied to the function are worked through in parallel. Any required arguments which are left undefined when the end of the argument values has been reached causes an error.
After the arguments have been processed the body-forms are evaluated by an implicit progn, the value of which becomes the value of the function call. Finally, all argument variables are unbound and control passes back to the caller.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Functions are normally associated with symbols, the name of the symbol being the same as the name of its associated function. Each symbol has a special function cell (this is totally separate from the symbol’s value as a variable — variables and functions may have the same name without any problems occurring) which is used to store the function’s definition, either a lambda expression (see section Lambda Expressions) or a subr (C code) object.
The evaluator knows to indirect through the function value of a symbol in any function call (see section Function Call Forms) so the normal way to call a function is simply write its name as the first element in a list, any arguments making up the other elements in the list. See section List Forms.
The functions and special forms which take functions as their arguments
(i.e. funcall
) can also take symbols. For example,
(funcall 'message "An example") ≡ (message "An example")
Returns the value of the function cell in the symbol symbol.
(symbol-function 'symbol-function) ⇒ #<subr symbol-function>
This function returns t
if the symbol symbol has a
non-void value in its function cell, nil
otherwise.
(fboundp 'setq) ⇒ t
Sets the value of the function cell in the symbol symbol to new-value, then returns new-value.
This function is rarely used, see Defining Functions.
This function makes the value of the function cell in symbol void, then returns symbol.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When giving function names as arguments to functions it is useful to give an actual function definition (i.e. a lambda expression) instead of the name of a function.
In Lisp, unlike most other programming languages, functions have no inherent name. As seen in the last section named-functions are created by storing a function in a special slot of a symbol, if you want, a function can have many different names: simply store the function in many different symbols!
So, when you want to pass a function as an argument there is the option
of just writing down its definition. This is especially useful with
functions like mapcar
and delete-if
. For example, the
following form removes all elements from the list which are
even and greater than 20.
(setq list (delete-if #'(lambda (x) (and (zerop (% x 2)) (> x 20))) list))
The lambda expression is very simple, it combines two predicates applied to its argument.
Note that the function definition is quoted by #'
, not the
normal '
. This is a special shortcut for the function
special
form (like '
is a shortcut to quote
). In general,
#'x
is expanded by the Lisp reader to (function x)
.
This special form is nearly identical to the quote
form, it
always returns its argument without evaluating it. The difference is
that the Lisp compiler knows to compile the arg into a byte-code
form (unless arg is a symbol in which case it is not compiled).
What this means is when you have to quote a function, use the #'
syntax.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Lisp, a function which returns a boolean ‘true’ or boolean ‘false’
value is called a predicate. As is the convention in Lisp a
value of nil
means false, anything else means true. The symbol
t
is often used to represent a true value (in fact, sometimes
the symbol t
should be read as any non-nil
value).
Another Lisp convention is that the names of predicate functions should be the concept the predicate is testing for and either ‘p’ or ‘-p’.
The ‘p’ variant is used when the concept name does not contain any hyphens.
For example a predicate to test for the concept const-variable (a
variable which has a constant value, see section Constant Variables) would
be called const-variable-p
. On the other hand a predicate
to test for the concept buffer (a Lisp object which is a buffer)
would be called bufferp
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Named functions are normally defined by the defun
special form.
defun
initialises the function definition of the symbol name
to the lambda expression resulting from the concatenation of the
symbol lambda
, lambda-list and the body-forms. So,
(defun foo (x y) … ≡ (fset 'foo #'(lambda (x y) …
The body-forms may contain a documentation string for the function as its first form and an interactive calling specification as its first (if there is no doc-string) or second form if the function may be called interactively by the user (see section Commands).
An example function definition (actually a command) taken from Jade’s source is,
(defun upcase-word (count) "Makes the next COUNT words from the cursor upper-case." (interactive "p") (let ((pos (forward-word count))) (upcase-area (cursor-pos) pos) (goto-char pos)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Most of the time function calls are done by the evaluator when it detects
a function call form (see section List Forms); when the function to be called
is not known until run-time it is easier to use a special function to
call the function directly than create a custom form to apply to the
eval
function.
Applies the argument values args to the function function, then returns its result.
Note that the argument values args are not evaluated again. This
also means that funcall
can not be used to call macros
or special forms — they would need the unevaluated versions of args,
which are not available to funcall
.
(funcall '+ 1 2 3) ⇒ 6
Similar to funcall
except that the last of its arguments is
a list of arguments which are appended to the other members of
args to form the list of argument values to apply to the
function function.
Constructs a list of arguments to apply to the function function from args.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A mapping function applies a function to each of a collection of
objects. Jade currently has two mapping functions, mapcar
and
mapc
.
Each element in the list list is individually applied to the function function. The values returned are made into a new list which is returned.
The function should be able to be called with one argument.
(mapcar '1+ '(1 2 3 4 5)) ⇒ (2 3 4 5 6)
Similar to mapcar
except that the values returned when each element
is applied to the function function are discarded. The value returned
is list.
This function is generally used where the side effects of calling the function are the important thing, not the results.
The two following functions are also mapping functions of a sort. They
are variants of the delete
function (see section Modifying Lists)
and use predicate functions to classify the elements of the list
which are to be deleted.
This function is a variant of the delete
function. Instead of
comparing each element of list with a specified object, each
element of list is applied to the predicate function predicate.
If it returns t
(i.e. not nil
) then the element is destructively
removed from list.
(delete-if 'stringp '(1 "foo" 2 "bar" 3 "baz")) ⇒ (1 2 3)
This function does the inverse of delete-if
. It applies predicate
to each element of list, if it returns nil
then the element
is destructively removed from the list.
(delete-if-not 'stringp '(1 "foo" 2 "bar" 3 "baz")) ⇒ ("foo" "bar" "baz")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Macros are used to extend the Lisp language, they are basically a function which instead of returning its value, return a new form which will produce the macro call’s value when evaluated.
When a function being compiled calls a macro the macro is expanded immediately and the resultant form is open-coded into the compiler’s output.
1.13.1 Defining Macros | Macros are defined like functions | |
1.13.2 Macro Expansion | How macros are used by the evaluator | |
1.13.3 Compiling Macros | The compiler expands macros at compile- time. |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Macros are defined in the same style as functions, the only difference is the name of the special form used to define them.
A macro object is a list whose car is the symbol macro
, its
cdr is the function which creates the expansion of the macro when
applied to the macro calls unevaluated arguments.
Defines the macro stored in the function cell of the symbol name. lambda-list is the lambda-list specifying the arguments to the macro (see section Lambda Expressions) and body-forms are the forms evaluated when the macro is expanded. The first of body-forms may be a documentation string describing the macro’s use.
Here is a simple macro definition, it is a possible definition for
the when
construct (which might even be useful if when
wasn’t
already defined as a special form…),
(defmacro when (condition &rest body)
"Evaluates condition, if it's non-nil
evaluates the body
forms."
(list 'if condition (cons 'progn body)))
When a form of the type (when c b …)
is evaluated
the macro definition of when
expands to the form
(if c (progn b …))
which is then evaluated to
perform my when-construct.
When you define a macro ensure that the forms which produce the expansion have no side effects; it would fail spectacularly when you attempt to compile your program!
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When a macro call is detected (see section List Forms) the function which is the cdr of the macro’s definition (see section Defining Macros) is applied to the macro call’s arguments. Unlike in a function call, the arguments are not evaluated, the actual forms are the arguments to the macro’s expansion function. This is so these forms can be rearranged by the macro’s expansion function to create the new form which will be evaluated.
There is a function which performs macro expansion, its main use is to let the Lisp compiler expand macro calls at compile time.
If form is a macro call macroexpand
will expand that call
by calling the macro’s expansion function (the cdr of the macro definition).
If this expansion is another macro call the process is repeated until
an expansion is obtained which is not a macro call, this form is
then returned.
The optional environment argument is an alist of macro definitions to use as well as the existing macros; this is mainly used for compiling purposes.
(defmacro when (condition &rest body)
"Evaluates condition, if it's non-nil
evaluates the body
forms."
(list 'if condition (cons 'progn body)))
⇒ when
(macroexpand '(when x (setq foo bar)))
⇒ (if x (progn (setq foo bar)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Although it may seem odd that macros return a form to produce a result and not simply the result this is their most important feature. It allows the expansion and the evaluation of the expansion to happen at different times.
The Lisp compiler makes use of this; when it comes across a macro call
in a form it is compiling it uses the macroexpand
function to
produce the expansion of that form which it then compiles straight into
the object code. Obviously this is good for performance (why evaluate the
expansion every time it is needed when once will do?).
Some rules do need to be observed to make this work properly:
require
function, the compiler will evaluate
any top-level require
forms it sees to bring in any macro
definitions used.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A stream is a Lisp object which is either a data sink (an output stream) or a data source (an input stream). In Jade all streams produce or consume sequences of 8-bit characters.
Streams are very flexible, functions using streams for their input
and output do not need to know what type of stream it is. For example
the Lisp reader (the read
function) takes an input stream as its
one argument, it then reads characters from this stream until it has
parsed a whole object. This stream could be a file, a position in a
buffer, a function or even a string; the read
function can not
tell the difference.
This function returns t
if its argument is a stream.
1.14.1 Input Streams | Types of input stream | |
1.14.2 Output Streams | Types of output stream | |
1.14.3 Input Functions | Functions to read from streams | |
1.14.4 Output Functions | How to output to a stream |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These are the possible types of input stream, for the functions which use them see Input Functions.
file
Characters are read from the file object file, for the functions which manipulate file objects see Files.
mark
The marker mark points to the next character that will be read. Each time a character is read the position that mark points to will be advanced to the following character. See section Marks.
buffer
Reads from the position of the cursor in the buffer buffer. This position is advanced as characters are read.
(buffer . position)
Characters are read from the position position in the buffer buffer. position is advanced to the next character as each character is read.
function
Each time an input character is required the function is called with
no arguments. It should return the character read (an integer) or nil
if for some reason no character is available.
function should also be able to ‘unread’ one character. When this happens the function will be called with one argument — the value of the last character read. The function should arrange it so that the next time it is called it returns this character. A possible implementation could be,
(defvar ms-unread-char nil "If non-nil the character which was pushed back.") (defun my-stream (&optional unread-char) (if unread-char (setq ms-unread-char unread-char) (if ms-unread-char (prog1 ms-unread-char (setq ms-unread-char nil)) ;; Normal case -- read and return a character from somewhere …
nil
Read from the stream stored in the variable standard-input
.
It is also possible to use a string as an input stream. The string to
be read from must be applied to the make-string-input-stream
function
and the result from this function used as the input stream.
Returns an input stream which will supply the characters of the string string in order starting with the character at position start (or from position zero if this argument is undefined).
(read (make-string-input-stream "(1 . 2)")) ⇒ (1 . 2)
The input stream which is used when no other is specified or is nil
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These are the different types of output stream, for the functions which use them see Output Functions.
file
Writes to the file object file. See section Files.
mark
Writes to the position pointed to by the marked mark, then advances the position of the mark.
buffer
Writes to buffer at the position of the cursor in that buffer, which is then advanced.
(buffer . position)
position in the buffer buffer. position is then moved over the written text.
(buffer . t)
Writes to the end of the buffer buffer.
function
The function function is called with one argument, either a string or a character. This should be used as the circumstances dictate. If the function returns a number it is the number of characters actually used, otherwise it is assumed that all the characters were successful.
process
Writes to the standard input of the process object process. If process isn’t running an error is signalled. See section Processes.
t
Appends the character(s) to the end of the status line message.
nil
Write to the stream stored in the variable standard-output
.
It is also possible to store the characters sent to an output stream in a string.
Returns an output stream. It accumulates the text sent to it for the benefit
of the get-output-stream-string
function.
Returns a string consisting of the text sent to the string-output-stream
since the last call to get-output-stream-string (or since this stream
was created by make-string-output-stream
).
(setq stream (make-string-output-stream)) ⇒ ("" . 0) (prin1 keymap-path stream) ⇒ ("(lisp-mode-keymap global-keymap)" . 64) (get-output-stream-string stream) ⇒ "(lisp-mode-keymap global-keymap)"
This variable contains the output stream which is used when no other
is specified (or when the given output stream is nil
).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Read and return the next character from the input stream stream. If
the end of the stream is reached nil
is returned.
This function reads one line of characters from the input stream stream, creates a string containing the line (including the newline character which terminates the line) and returns it.
If the end of stream is reached before any characters can be read nil
is returned, if the end of stream is reached but some characters have
been read (but not the newline) these characters are made into a string
and returned.
Note that unlike the Common Lisp function of the same name, the newline character is not removed from the returned string.
This function is the function which contains the Lisp reader (see section The Lisp Reader). It reads as many characters from the input stream stream as it needs to make the read syntax of a single Lisp object (see section Read Syntax), this object is then returned.
Reads one Lisp object from the string string, the first character is read from position start (or position zero).
(read-from-string string start) ≡ (read (make-string-input-stream string start))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Writes the specified character(s) to the output stream stream. data is either the character or the string to be written. If data is a string the optional argument length may specify how many characters are to be written. The value returned is the number of characters successfully written.
(write standard-output "Testing 1.. 2.. 3..") -| Testing 1.. 2.. 3.. ⇒ 19
This function copies all characters which may be read from input-stream to output-stream. The copying process is not stopped until the end of the input stream is read. Returns the number of characters copied.
Be warned, if you don’t choose the streams carefully you may get a deadlock which only an interrupt signal can break!
Outputs a newline character to the output stream stream, then writes a textual representation of object to the stream.
If possible, this representation will be such that read
can
turn it into an object structurally similar to object. This will
not be possible if object does not have a read syntax.
object is returned.
(print '(1 2 3)) -| -| (1 2 3) ⇒ (1 2 3)
Similar to print
but no initial newline is output.
(prin1 '(1 2 3)) -| (1 2 3) ⇒ (1 2 3) (prin1 '|(xy((z]|) ;A strange symbol -| \(xy\(\(z\] ⇒ \(xy\(\(z\]
Returns a string containing the characters that prin1
would
output when it prints object.
(prin1-to-string '(1 2 3)) ⇒ "(1 2 3)"
Prints a textual representation of object to the output stream
stream. No steps are taken to create output that read
can
parse and no quote characters surround strings.
(princ "foo") -| foo ⇒ "foo" (princ '|(xy((z]|) -| (xy((z] ⇒ \(xy\(\(z\]
Writes to a stream, stream, a string constructed from the format string, template, and the argument values.
If stream is nil
the resulting string will be returned, not
written to a stream.
template is a string which may contain format specifiers, these are a ‘%’ character followed by another character telling how to print the next of the values. The following options are available
Write the printed representation of the value without quoting (as if from
the princ
function).
Write the printed representation with quoting enabled (like the
prin1
function).
Output the value as a decimal number.
Write the value in octal.
In hexadecimal.
Write the character specified by the value.
Print a literal percent character. None of the values are used.
The function works through the template a character at a time. If the character is a format specifier (a ‘%’) it inserts the correct string (as defined above) into the output. Otherwise, the character is simply put into the output stream.
If stream isn’t nil
(i.e. the formatted string is returned) the
value of stream is returned.
(format nil "foo %S bar 0x%x" '(x . y) 255) ⇒ "foo (x . y) bar 0xff" (format standard-output "The %s is %s!" "dog" "purple") -| The dog is purple! ⇒ #<buffer *jade*>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In Lisp, programs (also called modules) are stored in files. Each file is a sequence of Lisp forms (known as top-level forms). Most of the top-level forms in a program will be definitions (i.e. function, macro or variable definitions) since generally each module is a system of related functions and variables.
Before the program can be used it has to be loaded into the editor’s workspace; this involves reading and evaluating each top-level form in the file.
1.15.1 Load Function | The function which loads programs | |
1.15.2 Autoloading | Functions can be loaded on reference | |
1.15.3 Features | Module management functions |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function loads the file containing the program called program; first the file is located then each top-level form contained by the file is read and evaluated in order.
Each directory named by the variable load-path
is searched until
the file containing program is found. In each directory three
different file names are tried,
If none of these gives a result the next directory is searched in the
same way, when all directories in load-path
have been exhausted
and the file still has not been found an error is signalled.
Next the file is opened for reading and Lisp forms are read from it
one at a time, each form is evaluated before the next form is read. When
the end of the file is reached the file has been loaded and this function
returns t
.
The optional arguments to this function are used to modify its behaviour,
When this argument is non-nil
no error is signalled if the file
can not be located. Instead the function returns nil
.
The variable load-path
is not used, program must point to
the file from the current working directory.
When non-nil
no ‘.jlc’ or ‘.jl’ suffixes are applied to
the program argument when locating the file.
If a version of the program whose name ends in ‘.jlc’ is older than a ‘.jl’ version of the same file (i.e. the source code is newer than the compiled version) a warning is displayed and the ‘.jl’ version is used.
(load "foobar") error--> File error: Can't open lisp-file, foobar (load "foobar" t) ⇒ nil
A list of strings, each element is the name of a directory which is prefixed to the name of a program when Lisp program files are being searched for.
load-path ⇒ ("" "/usr/local/lib/jade/3.2/lisp/")
The element ""
means the current directory, note that directory
names should have an ending ‘/’ (or whatever) so that when concatenated
with the name of the file they make a meaningful filename.
The name of the directory in which the standard Lisp files are stored.
lisp-lib-dir ⇒ "/usr/local/lib/jade/3.2/lisp/"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Obviously, not all the features of the editor are always used. Autoloading allows modules to be loaded when they are referenced. This speeds up the initialisation process and may save memory.
Functions which may be autoloaded have a special form in their symbol’s
function cell — an autoload form. This is a list whose first element
is the symbol autoload
. When the function call dispatcher finds
one of these forms it loads the program file specified in the form
then re-evaluates the function call. The true function definition will
have been loaded and therefore the call may proceed as normal.
The structure of an autoload form is:
(autoload program-file [is-command])
program-file is the argument to give to the load
function when
the function is to be loaded. It should be the program containing a definition
of the autoloaded function.
The optional is-command object specifies whether or not the function may be called interactively (i.e. it is an editor command).
Installs an autoload form into the function cell of the symbol symbol.
The form is a cons cell whose car is autoload
and whose cdr is
the argument autoload-defn.
Returns the resulting autoload form.
(autoload 'foo "foos-file") ⇒ (autoload "foos-file") (symbol-function 'foo) ⇒ (autoload "foos-file") (autoload 'bar "bars-file" t) ⇒ (autoload "bars-file" t) (commandp 'bar) ⇒ t
It is not necessary to call the autoload
function manually. Simply
prefix the definitions of all the functions which may be autoloaded (i.e.
the entry points to your module; not all the internal functions!)
with the magic comment ;;;###autoload
. Then the add-autoloads
command can be used to create the necessary calls to the autoload function
in the ‘autoloads.jl’ Lisp file (this file which lives in the Lisp
library directory is loaded when the editor is initialised).
Scans the current buffer for any autoload definitions. Functions with
the comment ;;;###autoload
preceding them have autoload forms
inserted into the ‘autoloads.jl’ file. Simply save this file’s
buffer and the new autoloads will be used the next time Jade is
initialised.
It is also possible to mark arbitrary forms for inclusion in the
‘autoloads.jl’ file: put them on a single line which starts with
the comment ;;;###autoload
call the command.
The unsaved ‘autoloads.jl’ buffer will become the current buffer.
;;;###autoload
(defun foo (bar) ;foo
is to be autoloaded
…
;;;###autoload (setq x y) ;Form to eval on initialisation
Remove all autoload forms from the ‘autoloads.jl’ file which
are marked by the ;;;###autoload
comment in the current buffer.
The unsaved ‘autoloads.jl’ buffer will become the current buffer.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Features correspond to modules of the editor. Each feature is
loaded separately. Each feature has a name, when a certain feature is
required its user asks for it to be present (with the require
function), the feature may then be used as normal.
When a feature is loaded one of the top-level forms evaluated is a call to
the provide
function. This names the feature and installs it into
the list of present features.
A list of the features currently present (that is, loaded). Each feature is represented by a symbol. Usually the print name of the symbol (the name of the feature) is the same as the name of the file it was loaded from, minus any ‘.jl’ or ‘.jlc’ suffix.
features ⇒ (info isearch fill-mode texinfo-mode lisp-mode xc)
Adds feature (a symbol) to the list of features present. A call to this function is normally one of the top-level forms in a module.
;;;; maths.jl -- the maths
module
(provide 'maths)
…
Show that the caller is planning to use the feature feature (a symbol).
This function will check the features
variable to see if feature
is already loaded, if so it will return immediately.
If feature is not present it will be loaded. If file is
non-nil
it specifies the first argument to the load
function,
else the print name of the symbol feature is used.
;;;; physics.jl -- thephysics
module (require 'maths) ;Need themaths
module (provide 'physics) …
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jade contains a rudimentary Lisp compiler; this takes a Lisp form or program and compiles it into a byte-code form. This byte-code form contains a string of byte instructions, a vector of data constants and some other information.
The main reason for compiling your programs is to increase their speed, it is difficult to quantify the speed increase gained — some programs (especially those using a lot of macros) will execute many times quicker than their uncompiled version whereas others may only execute a bit quicker.
1.16.1 Compilation Functions | How to compile Lisp programs | |
1.16.2 Compilation Tips | Getting the most out of the compiler | |
1.16.3 Disassembly | Examining compiled functions |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function compiles the Lisp form form into a byte-code form which is returned.
(compile-form '(setq foo bar)) ⇒ (jade-byte-code "F!" [bar foo] 2)
This function compiles the file called file-name into a file of compiled Lisp forms whose name is file-name with ‘c’ appended to it (i.e. if file-name is ‘foo.jl’ it will be compiled to ‘foo.jlc’).
If an error occurs while the file is being compiled any semi-written file will be deleted.
When called interactively this function will ask for the value of file-name.
Compiles all the Lisp files in the directory called directory which either haven’t been compiled or whose compiled version is older than the source file (Lisp files are those ending in ‘.jl’).
If the optional argument force is non-nil
all Lisp files
will be recompiled whatever the status of their compiled version.
The exclude argument may be a list of filenames, these files will not be compiled.
When this function is called interactively it prompts for the directory.
Uses compile-directory
to compile the library of standard Lisp files.
If force is non-nil
all of these files will be compiled.
The ‘autoloads.jl’ is never compiled since it is often modified and wouldn’t really benefit from compilation anyway.
Interprets the string of byte instructions byte-codes with the vector of constants constants. max-stack defines the maximum number of stack cells required to interpret the code.
This function is never called by hand. The compiler will produce calls to this function when it compiles a form or a function.
(setq x 1 y 3) ⇒ 3 (setq comp (compile-form '(cons x y))) ⇒ (jade-byte-code "K" [x y] 2) (eval comp) ⇒ (1 . 3)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Here are some tips for making compiled code run fast:
For example, the most elegant way of searching a list is to use recursion,
(defun scan-list (list elt) "Search the LIST for an element ELT. Return it if one is found." (if (eq (car list) elt) elt (scan-list (cdr list) elt)))
but this is fairly slow. Instead, iterate through each element,
(defun scan-list (list elt) (while (consp list) (when (eq (car list) elt) (return elt)) (setq list (cdr list))))
member
, memq
, assoc
,
etc… can be used to search lists. Since these are primitives written
in C they will run much faster than an equivalent Lisp function.
So the above scan-list
example can be rewritten as,
(defun scan-list (list elt) (car (memq elt list)))
Also note that the mapcar
and mapc
functions are useful
(and efficient) when using lists.
when
and unless
conditional
structures; they are more efficient than cond
or if
.
I must stress that in some cases constants are not suitable;
they may drastically increase the size of the compiled program (when
the constants are ‘big’ objects, i.e. long lists) or even introduce
subtle bugs (since two references to the same constant may not be
eq
whereas two references to the same variable are always
eq
).
cons
, car
, cdr
, rplaca
, rplacd
, nth
,
nthcdr
, aset
, aref
, length
, eval
, +
,
*
, /
, %
, lognot
, not
, logior
,
logand
, equal
, eq
, =
, /=
, >
,
<
, >=
, <=
, 1+
, 1-
, -
, set
,
fset
, lsh
, zerop
, null
, atom
, consp
,
listp
, numberp
, stringp
, vectorp
, throw
,
fboundp
, boundp
, symbolp
, get
, put
,
signal
, return
, reverse
, nreverse
, assoc
,
assq
, rassoc
, rassq
, last
, mapcar
, mapc
,
member
, memq
, delete
, delq
, delete-if
,
delete-if-not
, copy-sequence
, sequencep
, functionp
,
special-formp
, subrp
, eql
, set-current-buffer
,
current-buffer
, bufferp
, markp
, windowp
.
require
function are evaluated then the unevaluated form
is written as-is to the output file. The reason it is evaluated is so that
any macros defined in the required module are loaded before they are
called by the program being compiled.
if
, cond
, when
, unless
, let
, let*
,
catch
, unwind-protect
, error-protect
, with-buffer
,
with-window
, progn
, prog1
, prog2
, while
,
and
, or
.
then the form is compiled. Otherwise it is just written to the output file in its uncompiled state.
If your program contains a lot of top-level forms which you know will
not be compiled automatically, consider putting them in a progn
block to make the compiler coalesce them into one byte-code form.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is possible to disassemble byte-code forms; originally this was so I could figure out why the compiler wasn’t working but if you’re curious about how the compiler compiles a form it may be of use to you.
Naturally, the output of the disassembler is a listing in Jade’s pseudo-machine language — it won’t take a byte-code form and produce the equivalent Lisp code!
This function disassembles the compile Lisp function function. It
writes a listing to the output stream stream (normally the
value of the standard-output
variable).
When called interactively it will prompt for a function to disassemble.
When reading the output of the disassembler bear in mind that Jade simulates a stack machine for the code to run on. All calculations are performed on the stack, the value left on the stack when the piece of code ends is the value of the byte-code form.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A hook allows you to wedge your own pieces of Lisp code into the editor’s operations. These pieces of code are evaluated via the hook and the result is available to the hook’s caller.
1.17.1 Functions As Hooks | Some hooks are a single function, | |
1.17.2 Normal Hooks | Others may be a list of pieces of code to evaluate. | |
1.17.3 Standard Hooks | A table of the predefined hooks |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Some hooks only allow a single piece of code to be hooked in. Usually a normally-undefined function is used; to install your hook defined a function with the name of the hook. When the hook is to be evaluated the function is called.
Generally the name of the hook’s function will end in -function
.
An alternative scheme is to use a variable to store the hook, its value should be the function to call.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is the standard type of hook, it is a variable whose value is a
list of functions. When the hook is evaluated each of the named functions
will be called in turn until one of them returns a value which is not
nil
. This value becomes the value of the hook and no more of
the functions are called. If all of the functions in the hook return
nil
the value of the hook is nil
.
The names of hooks of this type will normally end in -hook
.
This function adds a new function function to the list of functions installed in the (list) hook hook (a symbol).
If at-end is non-nil
the new function is added at the end of
the hook’s list of functions (and therefore will be called last when the
hook is evaluated), otherwise the new function is added to the front
of the list.
text-mode-hook ⇒ (fill-mode-on) (add-hook 'text-mode-hook 'my-function) ⇒ (my-function fill-mode-on)
This function removes the function function from the list of functions stored in the (list) hook hook (a symbol).
All instances of function are deleted from the hook.
text-mode-hook ⇒ (my-function fill-mode-on) (remove-hook 'text-mode-hook 'my-function) ⇒ (fill-mode-on)
Evaluates the (list) hook hook (a symbol) with argument values args.
Each function stored in the hook is applied to the args in turn until
one returns non-nil
. This non-nil
value becomes the result
of the hook. If all functions return nil
then the result of the
hook is nil
.
Note that most functions which are installed in hooks should always return
nil
to ensure that all the functions in the hook are evaluated.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is a table of the predefined hooks in Jade:
asm-cpp-mode-hook
@xref{Asm mode}.
asm-mode-hook
@xref{Asm mode}.
auto-save-hook
See section Controlling Auto-Saves.
buffer-menu-mode-hook
c-mode-hook
@xref{C mode}.
destroy-window-hook
See section Closing Windows.
gdb-hook
idle-hook
See section Idle Actions.
indented-text-mode-hook
@xref{Indented-Text mode}.
insert-file-hook
See section Reading Files Info Buffers.
kill-buffer-hook
See section Destroying Buffers.
lisp-mode-hook
@xref{Lisp mode}.
make-window-hook
See section Opening Windows.
open-file-hook
See section Reading Files Info Buffers.
read-file-hook
See section Reading Files Info Buffers.
shell-callback-function
shell-mode-hook
texinfo-mode-hook
@xref{Texinfo mode}.
text-mode-hook
@xref{Text mode}.
unbound-key-hook
See section Event Loop.
window-closed-hook
See section Event Loop.
write-file-hook
See section Writing Buffers.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A buffer is a Lisp object containing a ‘space’ in which files (or any pieces of text) may be edited, either directly by the user or by Lisp programs.
Each window (see section Windows) may display any one buffer at any time, the buffer being displayed by the current window is known as the current buffer. This is the buffer which functions will operate on by default.
Returns t
if its argument is a buffer.
1.18.1 Buffer Attributes | Data contained in a buffer object | |
1.18.2 Creating Buffers | How to create empty buffers | |
1.18.3 Modifications to Buffers | Is a buffer modified? | |
1.18.4 Read-Only Buffers | Unmodifiable buffers | |
1.18.5 Destroying Buffers | Deleting a buffer and its contents | |
1.18.6 Special Buffers | Program-controlled buffers | |
1.18.7 The Buffer List | Each window has a list of buffers | |
1.18.8 The Current Buffer | One buffer is the default buffer |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
All buffer objects store a set of basic attributes, some of these are:
Each buffer has a unique name.
Returns the name of the buffer buffer, or of the current buffer if buffer is undefined.
(buffer-name) ⇒ "programmer.texi"
Sets the name of the buffer buffer (or the current buffer) to the string name.
Note that name is not checked for uniqueness, use the
make-buffer-name
function if you want a guaranteed unique name.
Returns a unique version of the string name so that no existing buffer has the same string as its name. If a clash occurs a suffix ‘<N>’ is appended to name, where n is the first number which guarantees the uniqueness of the result.
Returns the existing buffer whose name is name, or nil
if
no such buffer exists.
Since buffers often contain text belonging to files on disk the buffer stores the name of the file its text was read from. See section Editing Files.
Returns the name of the file stored in buffer. If no file is stored in the buffer the null string (‘’) is returned.
(buffer-file-name) ⇒ "man/programmer.texi"
This function sets the file-name of the buffer to the string name.
Searches for an existing buffer containing the file file-name then
returns it, or nil
if no such buffer exists.
The contents of a buffer is the text it holds. This is stored as an array of lines. See section Text.
This is the spacing of tab stops. When the contents of the buffer is being displayed (in a window) this value is used.
A buffer-local variable which holds the size of tab stops in the buffer.
Each buffer has its own glyph table which is used when the buffer is being displayed. See section Buffer Glyph Tables.
Each buffer can have its own value for any variable, these local values are stored in an alist which lives in the buffer object. See section Buffer-Local Variables.
Returns the alist of local variables in the buffer. Each alist element
is structured like, (symbol . local-value)
.
Each modification made to the buffer increments its modification counter. See section Modifications to Buffers.
Returns the number of modifications made to the buffer since it was created.
When a modification is made to a buffer enough information is recorded so that the modification can later be undone. See section Controlling Undo.
All other buffer-specific information is kept in buffer-local variables.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Creates and returns a new buffer object. Its name will be a unique version
of name (created by the make-buffer-name
function).
The buffer will be totally empty and all its attributes will have standard values.
(make-buffer "foo") ⇒ #<buffer foo>
If no buffer called name exists, creates a new buffer of that name
and adds it to the end of each windows buffer-list
. This function
always returns the buffer called name.
For more ways of creating buffers see Editing Files.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each buffer maintains a counter which is incremented each time the contents of the buffer is modified. It also holds the value of this counter when the buffer was last saved, when the two numbers are different the buffer is classed as have being modified.
This function returns t
when the buffer has been modified.
Sets the modified status of the buffer buffer. When status
is nil
the buffer will appear to be unmodified, otherwise it
will look modified.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When a buffer has been marked as being read-only no modifications may be made to its contents (neither by the user nor a Lisp program).
Returns t
when the buffer is read-only.
When read-only is non-nil
the buffer buffer is marked
as being read-only, otherwise it is read-write.
When this variable is non-nil
any buffer may be modified, even if
it is marked as being read-only.
Lisp programs can temporarily bind a non-nil
value to this
variable when they want to edit one of their normally read-only
buffers.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Since all Lisp objects have indefinite extent (i.e. they live until there are no references to them) a buffer will be automatically destroyed when all references to it disappear.
Alternatively one of the following functions can be used to explicitly kill a buffer; the buffer object will still exist but all data associated with it (including the text it contains) will be released.
Removes the buffer buffer (a buffer or the name of a buffer) from all windows (any windows displaying buffer will be changed to display the previous buffer they showed) and destroys the buffer.
The hook kill-buffer-hook
is evaluated before the buffer is killed
with buffer as its argument.
If the buffer contains unsaved modifications the user will be asked if they really want to lose them before the buffer is killed (if the answer is yes).
When called interactively a buffer will be prompted for.
Hook called by kill-buffer
before it does anything. If a function
in the hook doesn’t want the buffer deleted it should signal some
sort of error.
This function may be used to remove all data stored in the buffer object manually. Also, any marks in this buffer are made non-resident.
After applying this function to a buffer the buffer will contain one empty line.
Use this function wisely, there are no safety measures taken to ensure valuable data is not lost.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When a buffer is special it means that it is controlled by a Lisp program, not by the user typing into it (although this can happen as well).
Special buffers are used for things like the ‘*jade*’ or ‘*Info*’ buffers (in fact most of the buffers whose names are surrounded by asterisks are special).
What the special attribute actually does is make sure that the buffer is
never truly killed (kill-buffer
removes it from each window’s
buffer-list
but doesn’t call destroy-buffer
on it) and
modifications don’t cause the ‘+’ flag to appear in the status line.
Returns t
if the buffer is marked as being special.
Sets the value of the special flag in the buffer buffer to the
value of special (nil
means non-special, anything else
means special).
Another type of special buffer exists; the mildly-special buffer.
When this buffer-local variable is set to t
(it is nil
by default) and the buffer is marked as being special, the
kill-buffer
function is allowed to totally destroy the buffer.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each window (see section Windows) has a list of buffers which may be displayed in that window. It is arranged is most-recently-used order, so that the car of the list is the buffer currently being shown in the window, the second element the window previously being shown and so on.
A variable, local to each window, which contains a list of the buffers available in the window. The list is maintained in most-recently-used order.
buffer-list ⇒ (#<buffer programmer.texi> #<buffer *Help*> #<buffer buffers.c> #<buffer buffers.jl> #<buffer edit.c> #<buffer edit.h> #<buffer *jade*> #<buffer lisp.jl> #<buffer *compilation*> #<buffer *Info*>)
Generally each window’s buffer-list
contains the same buffers, each
window has its own value for the variable so it can be kept in the correct
order (each window will probably be displaying different buffers).
This function ensures that the buffer buffer is in each window’s
buffer-list
. If it isn’t it is appended to the end of the list.
Deletes all references to buffer in each window’s buffer-list
.
Puts buffer (or the currently displayed buffer) at the end of the
current window’s buffer-list
then switch to the buffer at the head
of the list.
If all-windows is non-nil
this is done in all windows (the
same buffer will be buried in each window though).
Moves the buffer at the head of the buffer-list
to be last in the
list, the new head of the buffer-list
is displayed in the current
window.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The current buffer is the buffer being displayed in the current window (see section Windows), all functions which take an optional buffer argument will operate on the current buffer if this argument is undefined. Similarly if a window argument to a function is left undefined the current window will be used.
Returns the buffer being displayed by the window window (or the current window).
(current-buffer) ⇒ #<buffer programmer.texi>
The set-current-buffer
function sets the current buffer of a window.
If, when the window is next redisplayed (i.e. after each command), the
current buffer is different to what it was at the last redisplay the new
buffer will be displayed in the window.
Sets the buffer that the window is displaying.
Usually a window’s current buffer will be the buffer which is at the head
of the window’s buffer-list
. The function goto-buffer
can
be used to set both of these at once.
Set the current buffer to buffer which is either a buffer or a string
naming a buffer. The selected buffer is moved to the head of the window’s
buffer-list
.
If buffer is a string and no buffer exists of that name a new one is created.
Often you will want to temporarily switch to a different current buffer,
that is what the with-buffer
special form is for.
Temporarily sets the current buffer to the value of evaluating buffer, then evaluates the forms in sequence. The old value of the current buffer is reinstated and the structure returns the value of the last of the forms to be evaluated.
If the implicit progn evaluating forms is exited abnormally the old value of the current buffer will still be reinstated.
If the window is redisplayed while the forms are being evaluated (i.e. in a recursive edit) the new buffer will be drawn into the window.
(with-buffer new-buffer ;Enter a recursive edit in
(recursive-edit)) ; the buffer new-buffer
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A window is a Lisp object representing a window (a rectangular section of the display) open in the windowing-system you are running Jade in.
Windows have two main functions, firstly to provide a means of seeing the contents of a buffer and secondly to receive input events. For more details about event handling see Event Loop.
A window always displays a buffer and there is always at least one window open. The editor remembers which of the open windows is the current window, this is normally the window it last received an input event from, though it can be set by programs.
For some basic details about using windows see @ref{Using Windows}.
This function returns t
if its argument is a window.
This variable’s value is a list of all the currently open windows. The order of the elements in the list is insignificant.
window-list ⇒ (#<window 20971528 *Info*> #<window 20971524 *jade*>)
1.19.1 Opening Windows | Creating new windows | |
1.19.2 Closing Windows | Deleting windows | |
1.19.3 Iconifying Windows | Temporarily removing windows | |
1.19.4 Displaying Messages | Messages to the user | |
1.19.5 The Current Window | The activated window, used by default | |
1.19.6 Window Font | Each window may use a different font | |
1.19.7 Window Information | Details of a window’s current state | |
1.19.8 Rendering | How buffers are drawn in windows | |
1.19.9 Block Marking | Highlighting a region of a window |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Opens a new window and returns it. If buffer is defined it is the buffer to display in the new window, otherwise the current buffer is displayed.
The x and y arguments are the pixel coordinates of the new window’s top left corner in the display. The width and height arguments are the size of the window in columns and rows of characters respectively.
What happens when the position and size of the window is undefined will depend on the underlying window system, on the Amiga the window will probably be the same as the current window, in X11 the window manager will probably let the user size it interactively.
The new window will have its buffer-list
variable initialised
suitably and it will be added to the head of the window-list
variable.
The make-window
function is the lowest level of creating a new
window, open-window
uses it to open the window.
Creates a new window and returns it, the arguments are similar to
those of the same name in the open-window
function. The window
will display the current buffer.
After the window is created the make-window-hook
will be called
with the window as its argument.
Hook called each time a new window is created. It has one argument, the new window.
This window-local variable is only used on the Amiga version of Jade; it holds the name of the public screen which windows are opened on. By default this is the Workbench screen.
When a window is opened it inherits this value from the current window at the time.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Unlike buffers, window objects don’t have indefinite extent, even when a window is incapable of being referenced the object will not be destroyed by the garbage collector; count the user looking at the window as a reference!
When the window is closed (by the destroy-window
function) the
object loses its ‘window-ness’ and the garbage collector is free to
reclaim its memory.
This function closes the window window (or the current window)
and deletes its entry from the window-list
variable.
If this window is the only one the editor has open the user is asked if it’s okay to lose any modified buffers before the window is closed.
Uses close-window
to close all windows except window (or the
current window).
Closes the window window. After a window object has been closed it is no longer a member of the type ‘window’.
Before closing the window the destroy-window-hook
is evaluated
with the window being destroyed as an argument.
When the last window is closed the editor will exit automatically.
Like the destroy-buffer
function, this function is dangerous
if used carelessly.
Both close-window
and close-other-windows
eventually call
this function.
Hook called by destroy-window
before it does anything. It has
one argument — the window to be destroyed.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you don’t want a window cluttering the display, but don’t want to kill it totally it can be iconified; the window will be displayed as a small icon which can be reactivated when the window is wanted again.
Iconifies the specified window.
Uniconifies the specified window. This may be done automatically if the user needs to be prompted.
Toggles the current window between the iconified and normal states. This command is bound to the key sequence Ctrl-z.
Returns t
when the current window is iconified.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Often it is useful to be able to show the user a short one-line message,
this is what the message
function does.
This function displays the string message in the status line of the current window, then returns message.
If display-now is non-nil
the message is rendered into the
window immediately, otherwise it will not be visible until the next
general redisplay (usually after each command exits).
Note that an alternate way of writing in the status line is to use
the output stream t
. See section Output Streams.
When writing interactive programs it is sometimes useful to be able to render the cursor in the status line. This shows that the next key press will not be subject to normal editing key bindings but to the special user interface (usually explained by a message in the status line).
For example the y-or-n-p
function uses this technique to
show that it needs an answer.
When this window-local variable is non-nil
the window’s cursor is
rendered at the end of the message in the status line, not at the cursor’s
position in the main display.
Another way of alerting the user is to use the beep
function,
This function rings a bell or flashes the current window or screen depending on your system.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The current window is the window that functions operate on by default; every time the event loop receives some input from the user the window which the input event originated in becomes the current window. It is also possible for Lisp programs to set the current window, either permanently or temporarily.
The active window is the window which the windowing system will send any keyboard input to. Since Jade sets the current window to where it receives input from, it is often the case that the current window is the same as the active window. Jade also provides the means to set the active window; in some cases this may be best left to the user though.
This function returns the current window.
(current-window) ⇒ #<window 20971524 programmer.texi>
This function sets the current window to be the window window. If
the optional argument activate is non-nil
this window will
also become the active window.
When using the activate argument bear in mind that it may be confusing for the user if the active window is suddenly changed; only change the active window synchronously with some input from the user.
Temporarily sets the current window to the value of evaluating the form window, then uses an implicit progn to evaluate the forms. The old current window is then reinstated before returning the value of the implicit progn.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each window may use a different font; this font will be used for rendering all text in the window. When windows are created they inherit their font from the current window at the time.
Currently Jade only allows the use of fixed-width fonts; proportional fonts won’t work properly.
This function sets the font used in the window window (or the current window) to the font named by the string font-name.
The format of the string font-name depends on the underlying windowing system:
Simply use the standard name of the font, asterisk characters work like usual (i.e. match zero or more characters).
This is different to the normal Amiga conventions, use the name of the font followed by a dash and then the size of the font. For example to get an 8-point topaz font, use ‘topaz.font-8’.
When this function is called interactively it will prompt for font-name.
Returns the name of the font being used in the specified window.
Note that on an Amiga this will only return the name, and not the size
of the font. For example, if set-font
has been used with an
argument of "topaz.font-8"
, a call to font-name
would
produce "topaz.font"
.
Returns the width (in pixels) of a character in the specified window’s font.
(font-x-size) ⇒ 7
Returns the height in pixels of each character in the window’s font.
(font-y-size) ⇒ 13
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are a number of functions which provide information about the current state of a window.
Returns an integer which is the window system’s ‘handle’ on the window
window (or the current window). Under X11 this is the Window
identifier, on an Amiga it’s a pointer to the window’s struct Window
.
(window-id) ⇒ 20971524
Returns the number of currently-opened windows.
Returns the width of the root window or screen in pixels.
Returns the height in pixels of the root window.
Returns the x coordinate of the current window relative to the root window’s top-left corner.
The y coordinate of the current window relative to the root window’s top-left corner.
Returns the width, in pixels, of the current window.
Returns the height in pixels of the current window.
Only used by Amigas, this returns the height of the current window’s title bar. This will always be zero in X.
Returns the line number of the first line being shown in the current window.
Returns the line number of the last line being shown in the current window.
Returns the column number of the first column being shown in the current window.
Returns the column number of the last column being shown in the current window.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
After each command is executed a full redisplay is done; the display of each window is made to be consistent with the contents of the buffer it is showing.
This function calls the redisplay code, any windows, whose display is inconsistent with what it should be displaying, are updated.
Turns the cursor in the current window on or off (depending on whether
on is non-nil
or not). Normally the cursor is erased while
Lisp programs are executing.
If you use this function be sure to leave the cursor undrawn when you’ve finished.
If possible, this function will arrange it so that the line which the cursor is on (see section The Cursor Position) will be in the centre of the display.
Move count (or 1 by default) screens forwards in the display, Lisp programs shouldn’t need to call this.
Move count screens backwards in the display. Don’t call this from Lisp programs.
This function forces any locally-cached rendering operations to be
drawn into the actual window. This should be called after any use of
the refresh-all
or cursor
functions.
Currently this function only actually does anything in the X11 version of Jade (it calls XFlush()), but to ensure the portability of Lisp programs it should be used anyway.
This window-local variable defines the maximum number of lines which may be scrolled in one go; if more than this number of lines have to be moved when a redisplay happens the whole window will be redrawn.
This window-local variable controls the actual number of lines scrolled when the cursor moves out of the visible part of the window. The number of lines to move the display origin is calculated with the formula:
(/ total-lines-in-window y-scroll-step-ratio)
If the variable’s value is zero then the window will be scrolled by the least number of lines necessary to get the cursor back into the visible part.
Similar to y-scroll-step-ratio
, except that it’s used when the cursor
disappears to the left or the right of the display.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each window may define one block, this is a region of the buffer displayed in the window which is rendered in the opposite colours to normal (i.e. the same as the normal cursor, when the cursor is in a block it’s drawn in the inverse of the block). Blocks are primarily used for marking areas of a buffer which will subsequently be manipulated.
Normally the area of the buffer contained by a block is delimited by two positions; the start and end of the block (these will track changes made to the buffer and adjust themselves, like marks do). It is also possible to mark rectangular blocks; these are also delimited by two positions, but they define the two opposite corners of the rectangular block.
Returns t
if a block is marked in the current window.
Define the beginning and end markers of the block to display in the current window.
Unmark the block displayed in the current window.
Mark count words from pos (or the cursor pos) in the current window.
Mark the whole of the current buffer.
Returns the position of the beginning of the block marked in the
current window. If no block is defined returns nil
.
Returns the position of the end of the block, or nil
if no block
is defined in the current window.
Toggles between marking the beginning, marking the end and totally unmarking the block in the current window.
Returns t
if the block marked in the window is drawn as a rectangle.
Defines whether or not the block drawn in window is drawn as a rectangle
or not. If status is nil
it isn’t.
Toggles between marking normal and rectangular blocks in the current window.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A position is a Lisp object representing the location of one of the characters in the contents of a buffer (see section Buffers). Since Jade stores buffer contents as an array of lines, two index values are needed to reference a single character. A position object contains two integers; the column and line numbers of the character, both these values count upwards from zero (i.e. the first character in a buffer has line and column numbers of zero).
Position objects have no read syntax; they print as,
#<pos column line>
This function returns t
when its argument is a position object.
Creates and returns a new position object, it points to column number column and line number line (both integers).
Creates a new copy of the position object pos.
1.20.1 Position Components | Accessing the members of a position | |
1.20.2 The Cursor Position | Where the cursor is drawn in the display | |
1.20.3 Movement Functions | Position-motion functions | |
1.20.4 Positions and Offsets | Converting between positions and buffer offsets |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As previously noted, each position object has two components; one number defining the column, the other defining the line that the position represents. These components can be accessed individually.
Returns the column which the position object pos points to.
(pos-col (pos 1 2)) ⇒ 1
This function returns the line number which pos points to.
Sets the number of the column which the position object pos points to, to new-col (an integer), then returns col.
(setq x (pos 1 2)) ⇒ #<pos 1 2> (set-pos-col x 3) ⇒ 3 x ⇒ #<pos 3 2>
Similar to set-pos-col
except the line number is modified.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each window displays a cursor, this is rendered as a character in the opposite colour to what it would usually be (i.e. normally a dark rectangle). The cursor is used to show the user where any characters they type will be inserted, each window has a separate cursor position and buffers which are not being displayed ‘remember’ the last position of their cursor.
This function returns a copy of the cursor position in the current window.
(cursor-pos) ⇒ #<pos 14 5638>
Sets the position of the current window’s cursor to the position object pos, then returns pos.
Note that the components of pos are copied, any subsequent modification of pos will not affect the cursor.
If the line number of pos points to a non-existent line the cursor
won’t be moved and nil
will be returned.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section documents the functions which are used to create and modify position objects so that they point to a different position which is related to the original position in some way.
The functions which begin goto-
set the cursor position of the
current window to the new position; the others do not move the
cursor, they simply calculate the new position and return it.
In some cases the position argument itself will be modified and returned, this may cause confusion; if there are existing references to the object they subtle bugs may result. Consider the following,
(setq x (cursor-pos) y (next-char 1 x))
At first glance this looks as though the variable y
will point to
one character after the variable x
does. Since the next-char
function modifies its argument position both variables will
contain the same object, and therefore, point to the same position.
A solution is,
(setq x (cursor-pos) y (next-char 1 (copy-pos x)))
Read each function’s description carefully to see if it alters its arguments!
1.20.3.1 Buffer Extremes | The edges of a buffer | |
1.20.3.2 Character Movement | Moving in terms of characters, | |
1.20.3.3 Word Movement | or maybe words, | |
1.20.3.4 Tab Movement | tabs, | |
1.20.3.5 Line Movement | lines, | |
1.20.3.6 Expression Movement | or even expressions. |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Create and return a new position object pointing to the character after the last character in the buffer.
Set the cursor to the character after the last character in the current buffer.
Create a new position pointing to the first character in the buffer. Currently
this is always the position #<pos 0 0>
and the buffer argument
is ignored.
Set the cursor position to the first character in the buffer.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Alter and return pos (or a copy of the cursor pos) so that it points
count characters (default is one) to the left of its current position.
If the resulting column number is less than zero nil
is returned, else
the position.
(goto-char (pos 20 0)) ⇒ #<pos 20 0> (left-char) ⇒ #<pos 19 0> (setq x (pos 4 1)) ⇒ #<pos 4 1> (left-char 3 x) ⇒ #<pos 1 1> x ⇒ #<pos 1 1>
Move count (or one) characters to the left.
Alter and return pos (or a copy of the cursor pos) so that it points count (or one) characters to the right of its current position. May return a position which points to a character past the end of the line.
Move count (or one) characters to the right.
The following functions results depends on the contents of the buffer they are operating on; they move a certain number of characters, and hence will cross line boundaries.
Alter and return pos (or a copy of the cursor pos) to point to the character count characters in front of its current position.
If count is negative this function will work backwards through the buffer.
Move count characters forwards.
Similar to the next-char
function but will work backwards
when count is positive and forwards when it is negative.
Move count characters backwards.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are two buffer-local variables which control the syntax of words in each buffer.
This buffer-local variable contains a regular expression which will match each character allowed to be in a word.
The standard value is ‘[a-zA-Z0-9]’, i.e. all alphanumeric characters.
A buffer-local variable. Holds a regular expression which will match anything not in a word.
The normal value is ‘[^a-zA-Z0-9]|$’, i.e. anything which is not alphanumeric or the end of a line.
The following functions use these variables when deciding what is and what isn’t a word.
Return the position of the first character after the end of the word at position pos (or the cursor). count is the number of words to move, negative values mean go backwards.
If move is non-nil
then the cursor is moved to the result.
Note that pos is not altered.
Similar to forward-word
except that it works backwards. In fact,
all this function does is call forward-word
with count
negated.
Returns the position of the first character of the word at pos (or the cursor position).
This function returns t
if pos (or the cursor) is in a word.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Alter and return pos (or a copy of the cursor position) so that it
points count (default is one) tab stops to the left of its
current position. Returns nil
if that position is before the start
of the line.
size is optionally the number of glyphs in each tab, or the value
of the tab-size
variable.
Note that the position returned is not the position of a character but of a glyph (see section Glyph Positions).
(prev-tab 1 (pos 20 0)) ⇒ #<pos 16 0>
Move count tab stops to the left.
Alter and return pos (or a copy of the cursor position) so that it points count tab stops to the right of its current position.
size is optionally the number of glyphs in each tab, or the value
of the tab-size
variable.
Note that the position returned is not the position of a character but of a glyph (see section Glyph Positions).
Move count tab stops to the right.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Alter and return pos (or a copy of the cursor position) so that it points count (or one) lines forwards, the column component is not changed.
If count is negative (i.e. go backwards) and the resulting line
number is less than zero nil
is returned.
(next-line 2 (pos 1 1)) ⇒ #<pos 1 3> (next-line -1 (pos 1 1)) ⇒ #<pos 1 0>
Move count lines downwards, the column number of the cursor is adjusted so that its glyph position is as close to its previous glyph position as possible.
Similar to next-line but goes backwards (or forwards with a negative count).
Move count lines backwards, adjusting the column number of the cursor as necessary.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Some major modes provide functions to move backwards and forwards over expressions written in a buffer in the programming language that the mode supports (see section Mode-Specific Expressions), for example the Lisp mode defines the syntax of Lisp forms written in a buffer.
This function moves the cursor over count expressions, as defined in the current buffer. If the buffer has no expression definitions an error is signalled.
Moves backwards over count (or one) expressions, leaving the cursor at the beginning of the expression. If the buffer has no expression definition functions an error is signalled.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Although Jade stores the position of a character as a pair of two numbers many other programs define the position of a character as its offset from the beginning of the buffer or file it is in. The following functions may be used to convert between these two types of positions in a specified buffer.
This function returns the offset of the character at the position pos (or the cursor position by default) in the specified buffer. This will be an integer, the first character in a buffer is represented by an offset of zero.
(pos-to-offset (pos 0 0)) ⇒ 0 (pos-to-offset) ⇒ 195654
Creates a new position object which contains the position of the character offset characters from the start of the specified buffer.
(offset-to-pos 0) ⇒ #<pos 0 0> (offset-to-pos 195654) ⇒ #<pos 14 5974>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A mark is a Lisp object which points to a character in a file (or buffer), as the buffer the file is stored in is modified the position the mark points to is also modified so that the mark will always point to the same character.
The character that a mark points to does not have to be loaded into the editor all the time either; if the file the character is in is not resident in a buffer the mark will simply contain the character’s position and the file’s name. When a file is loaded any marks pointing to the file are altered so that they point straight to the buffer containing the file.
This function returns t
if its argument is a mark.
1.21.1 Mark Components | Marks contain two values; position and file | |
1.21.2 Mark Relocation | How the position of a mark is updated as its buffer is modified | |
1.21.3 Mark Residency | Marks may point to files which have not been loaded | |
1.21.4 Creating Marks | Functions to allocate new mark objects | |
1.21.5 Altering Marks | Setting the components of a mark | |
1.21.6 Moving to Marks | Moving the cursor to the character a mark points to |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each mark object has two main components; the position of the character pointed to by the mark (a position object) and the file which the character is contained by.
The file is the most complex component, it can be either a string naming the file or a buffer. When the file component is a string the mark is said to be non-resident since none of the editor buffers contain the character which the mark points to.
Returns the position object contained in the marker mark, no copy is made: if you modify the position returned it will be reflected in the position of the mark.
Note that if you later modify the buffer the mark is resident in the
position previously returned by mark-pos
may be altered by
the mark relocation process. See section Mark Relocation.
Returns the file component of mark. This will be either the name of the file or the buffer itself depending on whether the mark is resident or not. See section Mark Residency.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An important feature of marks is that they always point to the same character, even when the buffer has been modified, changing the position of the character (i.e. if some text is deleted from somewhere before the character its position will probably change).
Every time a buffer is modified each mark which points to a character in that buffer is examined and then, if necessary, the position it points to is changed to take account of the buffer’s new state.
Basically, what happens is that each mark will try to point at the same character all the time. If some text is inserted at the position of the mark the mark’s position will be advanced to the end of the insertion and hence the original character.
The only time the mark will not point at the same character is when the character is deleted from the buffer. In this case the mark will point to the start of the deletion.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As I have already explained, a mark does not necessarily have to point at a character loaded into a buffer; it can also point at a character in a file on disk somewhere. When this happens the mark is said to be non-resident.
This function returns t
when the character pointed to by the marker
mark is resident in one of the editor’s buffers.
When the function mark-file
(see section Mark Components) is applied
to a non-resident mark it returns the full name of the file, for example,
(setq x (make-mark (pos 0 20) "/tmp/foo.c")) ⇒ #<mark "/tmp/foo.c" #<pos 1 21>> (mark-resident-p x) ⇒ nil (mark-file x) ⇒ "/tmp/foo.c"
When a file is loaded into a buffer all existing non-resident marks are examined to see if they point to that file. If so that mark has its file component set to the buffer that the file was loaded into.
Similarly, when a buffer is deleted any marks pointing to characters in that buffer are made non-resident: their file component is set to the name of the file.
When the function which moves the cursor to the position of a specific
mark (goto-mark
, see section Moving to Marks) is called with a
non-resident mark it will try to load the file into a buffer.
The following code fragment can be used to ensure that a mark mark is resident,
(or (mark-resident-p mark) (open-file (mark-file mark)) (error "Can't make mark resident, %S" mark))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function allocates a new mark object and fills it in according to the supplied arguments.
It will point at a character at position pos, or the position of the cursor in the current window. Note that a copy of pos is made.
The buffer-or-filename argument specifies the file component of the
mark. If buffer-or-filename is a buffer (nil
or undefined means
the current buffer) the mark will use it and therefore will be resident
(see section Mark Residency).
Alternatively, buffer-or-filename can be a string naming the file explicitly. If the file is already loaded into a buffer that buffer will be used and the mark will be resident. Otherwise the mark will be non-resident and the string will be used as the file component.
With no arguments this function will produce a resident mark pointing at the cursor in the current buffer.
(make-mark) ⇒ #<mark #<buffer programmer.texi> #<pos 46 6152>> (make-mark (buffer-start) "/tmp/foo") ⇒ #<mark "/tmp/foo" #<pos 0 0>> (make-mark (pos 0 3)) ⇒ #<mark #<buffer programmer.texi> #<pos 0 3>>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If you just want to set the position of a mark you can modify its position component (see section Mark Components). Alternately the following function may be used. When you need to set the file a mark points to the only method is to use this function.
This function sets either or both of the position and file components of the mark object mark, then returns mark.
If pos is a position object the position component of mark will be set to it (a copy of it actually).
If the buffer-or-filename argument is non-nil
the file component
of mark will be set. This argument can be a buffer object or a string
naming a file. If a named file is already in a buffer that buffer will be
used instead.
(setq x (make-mark)) ⇒ #<mark #<buffer programmer.texi> #<pos 46 6186>> (set-mark x (buffer-start)) ⇒ #<mark #<buffer programmer.texi> #<pos 0 0>> (set-mark x nil "/tmp/foo") ⇒ #<mark "/tmp/foo" #<pos 0 0>>
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function switches to the buffer containing mark (if necessary) and then moves the cursor to the character that the mark points to.
If the mark is not currently resident an attempt will be made to load the mark’s file into a new buffer and use that.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A glyph table is a Lisp object used to define a mapping between the characters which may occur in a buffer (anything with a numeric value between 0 and 255 inclusive) and the sequences of glyphs which are drawn into a window to represent these characters.
A glyph is a image which, when rendered into the display, takes up one character position. Each character in a buffer is rendered as a sequence of 1 or more glyphs.
This function returns t
when its argument is a glyph table.
1.22.1 Glyph Table Basics | How a glyph table defines mappings | |
1.22.2 Glyph Positions | The position of a character and its glyph sequence may be different | |
1.22.3 Creating Glyph Tables | Making new glyph tables | |
1.22.4 Buffer Glyph Tables | Each buffer may use a separate glyph table for its display |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A glyph table is basically an array that has 256 elements; each element represents one character and contains between zero and four glyphs — the glyphs which will be printed for the character.
A special case exists for the tab character; when an element in the table contains zero glyphs, enough spaces will be printed to fill in to the next tab stop.
This function returns a string containing the glyphs in the element of the glyph table glyph-table for the character character.
(get-glyph (default-glyph-table) ?a) ⇒ "a" (get-glyph (default-glyph-table) ?\t) ⇒ "" ;TAB is special (get-glyph (default-glyph-table) ?\000) ⇒ "^@" ;the NUL character
This function sets the sequence of glyphs used to render the character character in the glyph table glyph-table to the characters in the string glyph-string.
An error is signalled if there are more than four characters in glyph-string.
All buffers which use glyph-table for their rendering will be totally redrawn at the next redisplay.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Position objects are usually used to refer to the position of a character in a buffer, this position (sometimes called the character position may not be the same as the position of the sequence of glyphs printed to represent the character. When a position object is used to refer to the position of a glyph it is called a glyph position.
For example, consider a line in a buffer containing the string ‘a\tb’ (where ‘\t’ represents a tab character). When this is rendered in a buffer the glyphs which will actually be drawn are,
a b
That is, an ‘a’ glyph, followed by seven (assuming tab-size
is
set to 8) ‘ ’ glyphs, and lastly a ‘b’ glyph.
The character position of the ‘b’ character in the buffer is
#<pos 2 line>
, where line is the line’s number.
Now the confusing bit: the glyph position of the ‘b’ glyph
is #<pos 8 line>
since it is actually the ninth glyph to
be drawn.
The good news is that most of the time you can forget about glyph positions, they only need to be considered when you’re thinking about how the buffer will look when rendered in the window. For example, Lisp programs which indent source code will definitely need to use glyph positions.
Two functions are provided for converting between character and glyph positions and vice versa.
Return a new position object containing the glyph position of the character at character position pos (or the cursor position) in the specified buffer.
This function returns a new position object containing the character position of the glyph printed at glyph position pos in the specified buffer.
If the glyph position pos is not the position of the first in a sequence of glyphs representing a single character the position of the next character will be returned.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function creates a new glyph table, containing glyph sequences defined by the source argument.
If source is a glyph table it will be copied, if it’s a buffer
that buffer’s glyph table will be copied or if source is
nil
a copy of the default glyph table will be made.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each buffer may define its own glyph table that will be used to provide the character-to-glyph mappings for that buffer.
Returns the glyph table installed in the buffer.
Sets the glyph table being used in the buffer to glyph-table.
By default, each buffer uses the default glyph table. This is a glyph table set up when the editor initialise itself. The mappings it provides are very generic, for more details see @ref{Character Images}.
This function returns the default glyph table.
Redefining some of the mappings in the default glyph table is an easy way to affect rendering operations, for example if I want the UK pound sign character (ASCII value is octal 243) to be printed as itself and not the usual escape sequence I can do the following,
(set-glyph (default-glyph-table) ?243 "\243")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An input event is a Lisp object representing an action initiated by the user, i.e. a key press, pressing a mouse button and similar things.
Note that input events are often referred to as key presses, this isn’t really accurate but since most input events are key presses the term sort of stuck. Anyway, wherever the phrase ‘key press’ occurs in this manual it could be replaced by ‘input event’.
Each input event is represented by a cons cell (see section Cons Cells) containing two integers, these integers encode the actual input event. The encoding is opaque; the only way to access an event meaningfully is via the functions provided.
This function returns t
if its argument is an input event.
Each event has a textual name, for the actual format of these names see @ref{Key Names}.
Functions are available to convert between the name of an event and the actual event itself, and vice versa.
Create and return a new input event whose name is event-name.
(lookup-event "Ctrl-x") ⇒ (120 . 9) (lookup-event "Ctrl-Meta-LMB-Click1") ⇒ (1 . 58)
This function returns a string naming the input event event.
(event-name (lookup-event "Ctrl-x")) ⇒ "Ctrl-x"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A keymap is a Lisp object defining a mapping between input events (see section Input Events) and commands to be executed when the event loop (see section Event Loop) receives the input event.
Returns t
when object is a keymap.
1.24.1 Types of Keymap | Two different formats of keymap | |
1.24.2 Creating Keymaps | Allocating new keymaps | |
1.24.3 Binding Keys | Inserting and removing key bindings | |
1.24.4 Key Lookup | How a key press is resolved into a command | |
1.24.5 Prefix Keys | Chaining events into multiple-event bindings | |
1.24.6 Standard Keymaps | Predefined keymaps you can modify |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
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 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).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Since there are two different types of keymap (lists and tables) there are two different functions for creating them with.
Creates and returns a new key list containing no bindings.
(make-keylist) ⇒ (keymap)
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 (see section Sequence Functions) to duplicate the source keymap.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The bind-keys
function is used to install new key bindings
into a keymap (either a key list or table).
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)
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")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each time the event loop (see section 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.
This function examines the current keymap environment for a binding of
the event event (see section 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.
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)
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 Prefix Keys.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
1.25.1 Event Loop Actions | What actually happens | |
1.25.2 Commands | Commands are Lisp functions which may be called interactively by the user | |
1.25.3 Event Loop Information | Information about the event loop | |
1.25.4 Recursive Edits | How to call the event loop from Lisp programs | |
1.25.5 Reading Events | Reading single events in Lisp | |
1.25.6 Idle Actions | What happens when nothing happens |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 (see section Input Events) and the current keymap
environment is searched for a binding of that event (see section Key Lookup).
If a binding of the event is found it defines a command (see section Commands)
to be invoked, the call-command
function (see section 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 (see section 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 (see section 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. See section 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 Idle Actions.
The hook called when an unbound input event is received.
The hook called when an event is received telling Jade to close a window; the current window is the one which should be closed.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
1.25.2.1 Interactive Declarations | How to define a command | |
1.25.2.2 Prefix Arguments | Arguments to a command from the user | |
1.25.2.3 Calling Commands | The function used to invoke a command | |
1.25.2.4 Example Commands | A definition of a command |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
The currently available code letters are,
Prompt, with completion, for a function object.
Prompt, with completion, for an existing buffer object.
Prompt, with completion, for a buffer; if it doesn’t yet exist it will be created.
Prompt for a character.
Prompt with completion for a command.
The position of the cursor in the current window.
Prompt with completion for the name of a directory in the filing system.
The event which caused this command to be invoked.
The event which caused this command, cooked into a string.
Prompt with completion for the name of an existing file.
Prompt with completion for the name of a file; it doesn’t have to exist.
Prompt for a single event.
The starting position of the marked block in the current window.
The ending position of the current block.
Prompt for a number.
The prefix argument (see section Prefix Arguments) as a number, if no prefix argument exists, prompt for a number.
The prefix argument as a number, this will be 1 if no prefix argument has been entered.
The raw prefix argument.
Prompt for a string.
Prompt with completion for a symbol.
The symbol t
.
Prompt with completion for a variable.
Read one Lisp object.
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.
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 andt
. (interactive "*\nxLisp form:\nt")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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 (see section 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,
nil
the numeric value is 1.
The prefix-numeric-argument
function is used to convert the
raw argument into a numeric value.
Returns the numeric value of the raw prefix argument raw-arg.
The value of the raw prefix argument used by the next command to be invoked.
The value of the raw prefix argument of the current command.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
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
(see section 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
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.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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)))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This variable contains the value of the command currently being executed.
Holds the previously executed command.
Returns the event which caused this command to be invoked.
Returns a string which is the ‘cooked’ representation of the current event.
Returns the event which caused the previous command.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
(see section Catch and Throw) can
be used through recursive edits with no problems; the recursive
edit will automatically be aborted.
Enter a new level of recursive editing.
This function returns the number of recursive edits currently in progress. When in the top level this will return zero.
Abort all recursive edits, control will be passed straight back to the top level event loop.
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)))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
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.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
idle-gc-threshold
variable
then the garbage collector is invoked.
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.
See section Garbage Collection.
idle-hook
hook
is dispatched. I’m not sure what this hook could be used for but you
never know…
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The main function of Jade is editing files of text; buffers (see section Buffers) are used to contain files to be edited. When the buffer is displayed in a window (see section 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 @ref{Loading and Saving Files}.
1.26.1 Reading Files Info Buffers | How to read a file into a buffer | |
1.26.2 Writing Buffers | Functions to write buffers to files | |
1.26.3 Buffer Date Stamps | The last-modification time of each file is recorded | |
1.26.4 Buffer Modification Counts | Variables storing modification counts | |
1.26.5 Making Backups | How backup files can be made | |
1.26.6 Controlling Auto-Saves | Functions to control the auto-saving feature |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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. See section Writing Buffers.
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
(@pxref{File Variables}) and the function init-mode
is used to try
to install a major mode for the new buffer. See section 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.
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).
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.
Display a buffer containing the file file-name in the current window.
When called interactively file-name will be prompted for.
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.
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.
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 used to insert a file (given as the hook’s argument) into the current buffer at the current cursor position.
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.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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!
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).
Writes the region of text from start-pos up to, but not including, end-pos to the file 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 (see section Making Backups) and the protection-modes of the overwritten file will be preserved if possible.
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
, see section 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.
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.
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.
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).
Calls save-some-buffers
then quits Jade (after asking the user if any
unsaved buffers may be discarded).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
This buffer-local variable contains the file-modtime of the file stored in the buffer when it (the file) was last read from disk.
See section File Information.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Two buffer-local variables are used to record the modification count (see section Buffer Attributes) of a buffer when it is saved.
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).
This buffer-local variable holds the number of modifications made to the buffer when it was last saved by the user.
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).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For details of the variables which control whether and how backup files are made see @ref{Backup Files}.
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…
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For the documentation of the variables controlling the making of auto-save files see @ref{Auto-Saving Files}.
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#"
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).
Called by auto-save-function
(with the buffer as an argument)
when a buffer is to be auto-saved.
This command deletes the auto-saved version of the buffer, if one exists.
This function returns t
when there is an auto-saved version of
the file called file-name which is newer than file-name.
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.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
1.27.1 Buffer Contents | Accessing the contents of a buffer | |
1.27.2 Insertion Functions | Inserting strings into a buffer | |
1.27.3 Deletion Functions | Deleting regions of text | |
1.27.4 Kill Functions | Recording regions of text | |
1.27.5 Transpose Functions | Swapping two regions of text | |
1.27.6 Indentation Functions | Functions for managing indentation | |
1.27.7 Translation Functions | Applying a mapping to characters in a buffer | |
1.27.8 Searching and Matching Functions | Regexps and general string matching | |
1.27.9 Rectangular Editing | Manipulating rectangular regions | |
1.27.10 Controlling Undo | How undo works | |
1.27.11 Miscellaneous Text Functions | Other stuff |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Returns the character at position pos (or the cursor position) in the specified 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.
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).
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
(see section Rectangular Editing is used to get the string.
Removes all text from the specified buffer. No precautions are taken against losing any unsaved modifications that the buffer might contain!
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Note that the format
function can be used to provide
formatted insertion; simply give it a suitable output stream.
See section Streams.
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.
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.
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. See section Kill Functions.
When called interactively the raw prefix arg is used as the value of the dont-yank-block argument.
Moves the cursor to the current position of the mouse pointer then calls the
yank
function.
Break the current line at the cursor, creating count new lines. The cursor is left in its original position.
This function inserts a newline character (‘\n’) at the current cursor position.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
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)
Deletes the block marked in the current window (if one exists). This function knows about rectangular blocks.
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.
Deletes count characters, starting at the cursor position and working forwards.
Deletes the count characters preceding the cursor, if the cursor is past the end of the line, simply move count characters to the left.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
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.
Returns the string in the kill buffer number depth, currently only the last kill is stored so depth must either be zero or undefined.
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.
Similar to kill-area
except that the region killed is not
actually deleted from the buffer.
Kills the block marked in the current window.
Kills the block marked in this window but doesn’t actually delete it from the buffer.
This command kills lines from the cursor position. arg is a raw prefix argument (see section Prefix Arguments). What gets killed depends on arg,
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.
Kills all of the count (an integer) next following lines.
Kills count words, starting at the cursor position.
When called interactively count is the numeric prefix arg.
Kills the count previous words, starting from the cursor.
When called interactively count is the numeric prefix arg.
Kill count expressions from the cursor position. See section Mode-Specific Expressions.
Kills count expressions, working backwards from the cursor. See section Mode-Specific Expressions.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Transposing two regions of text in a buffer means to swap their positions.
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.
Uses transpose-items
with each item being a word.
When called interactively, count is the value of the numeric prefix argument.
Transposes characters.
If the major mode in the current buffer has installed functions which define expressions then this command transposes expressions. See section Mode-Specific Expressions.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns the glyph position (see section Glyph Positions) of the first character in the line pointed to by pos (or the cursor) which is not a TAB or SPC character.
Sets the indentation of the line pointed to by pos to the column pointed to by pos by putting the optimal sequence of TAB and SPC characters at the start of the line.
If the only-spaces argument is non-nil
no TAB characters
will be used.
This function inserts enough TAB and SPC characters to move the cursor to glyph column column.
If the only-spaces argument is non-nil
no TAB characters are used.
Note that column counts from zero.
When called interactively the column argument is either the numeric value of the prefix argument or, if no prefix argument has been entered, the result of prompting for a number.
This command inserts enough spaces at the cursor position to move the cursor to the next tab stop.
Some major modes provide their own method of indentation (for example Lisp mode will indent Lisp programs in the proper style), see Mode-Specific Indentation.
If the current buffer has a method for indentation installed, use it to indent the current line to its correct depth.
Insert a newline character, then indent the new line; if no function for indenting lines has been installed in this buffer a single TAB character is inserted.
Uses the buffer’s indentation method to indent all lines in the specified region to their correct depth.
When called interactively the currently-marked block is used to get the values of the two arguments, the block is then unmarked.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function applies the mapping translation-table to each character in the region starting at the position start-pos up to, but not including, end-pos.
translation-table is a string, each character represents the mapping for an ASCII character of that character’s position in the string. If the string is less than 256 characters in length any undefined characters will remain unchanged (i.e. a translation-table of ‘’ would leave the region unaltered).
This function uses a similar method to that used in the translate-area
function. Instead of applying the mapping to a region of a buffer it
applies it to the string string. string is returned (after
being modified).
Note that the string really is modified, no copy is made!
(translate-string "abc" upcase-table) ⇒ "ABC"
This is a 256-character long string which may be used as a translation table
to convert from lower-case to upper-case with the functions
translate-string
and translate-area
.
Similar to upcase-table
except that it is used to convert from
upper-case to lower-case.
The following functions use the translation functions and the two translation tables described above.
Makes all alphabetic characters in the specified region of text upper-case.
When called interactively uses the block marks for its arguments; note that this won’t work properly with rectangular blocks.
Similar to upcase-area
but makes all alphabetic characters lower-case.
For the next count words starting at the cursor position, make their alphabetic characters upper-case.
Does the opposite of upcase-word
, makes words lower-case!
The first character of this word (normally the one under the cursor) is made upper-case, the rest lower.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The most powerful of the searching and matching functions are those using regular expressions, for details of the regexp syntax used by Jade see @ref{Regular Expressions}.
Note that the regexp matcher does not work across lines, at the moment no regexp may span more than one line. Also the regexp routines choke on NUL bytes; hopefully I’ll correct these problems soon…
1.27.8.1 Searching Buffers | Scanning buffers for something | |
1.27.8.2 String Matching | Matching regexps to text | |
1.27.8.3 Replacing Strings | Replacing a found string or regexp with something else | |
1.27.8.4 Regexp Functions | General regexp utility functions |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns the position of the next substring in the buffer matching the regular expression string regexp. It starts searching at pos, or the cursor position if pos is undefined.
If no match of the regexp occurs before the end of the buffer nil
is returned.
If the ignore-case argument is non-nil
then the case of
matched strings is ignored (note that character ranges are still
case-significant).
Similar to find-next-regexp
except this searches in the opposite
direction, from pos (or the cursor) to the start of the
buffer.
Scans forwards from pos (or the cursor), in buffer (or the current
buffer), looking for a match with the string string. Returns the
position of the next match or nil
.
Note that matches can’t span more than one line.
A backwards-searching version of find-next-string
.
Search forwards for an occurrence of the character character and
returns its position, or nil
if no occurrence exists.
This function searches backwards for an occurrence of the character character.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Returns t
if the regular expression regexp matches the text
at position pos in the buffer buffer (or the current buffer).
Only the text from pos to the end of the line is matched against.
This function returns t
if the regular expression regexp
matches the string string.
Note that the match is unanchored so if you want test for a match of the whole of string use the ‘^’ and ‘$’ regexp meta-characters. For example,
(regexp-match "(a|b)+" "fooabababar") ⇒ t (regexp-match "^(a|b)+$" "fooabababar") ⇒ nil (regexp-match "^(a|b)+$" "ababbabba") ⇒ t
When the ignore-case argument is non-nil
the case of strings
being matched is insignificant (except in character ranges).
This function matches the regular expression regexp against the string string, if the match is successful a string is created by expanding the template string template.
For details of what meta-characters are allowed in template see @ref{Regular Expressions}.
(regexp-expand "^([a-z]+):([0-9]+)$" "foobar:42" "The \\1 is \\2.") ⇒ "The foobar is 42."
This function is similar to regexp-match
, instead of explicitly
supplying the string to match against it is one whole line of the specified
buffer, the line pointed to by line-pos (or the line that the cursor
is on).
t
is returned if the match is successful.
As regexp-match-line
is similar to regexp-match
, this function
is similar to regexp-expand
.
The whole of the line at the position line-pos (or the cursor) is matched with the regular expression regexp. If the match is successful the template is used to expand a string which is returned.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If a substring of the buffer at pos (or the cursor) matches the regular expression regexp the text that matched is replaced with the result of expanding the template string template.
For details about templates see @ref{Regular Expressions}.
nil
is returned if the match failed, and therefore no replacement
occurred.
If a substring of the buffer at pos (or the cursor) matches the string old-string it is replaced by the string new-string.
If the match fails nil
is returned, otherwise some non-nil
value.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is often useful to construct regular expressions by concatenating several strings together; the problem with doing this is you may not know if a string contains any characters which the regexp compiler reacts specially to (i.e. ‘*’, ‘|’, …). Obviously these characters should be protected by a backslash, the following function will do this for you.
This function returns a new version of the string string, any characters in string which are regexp meta-characters are quoted with a backslash.
If the string contains no meta-characters the original string is returned, without being copied.
(regexp-quote "foo*bar+baz") ⇒ "foo\\*bar\\+baz"
Note that in the above example the backslashes in the returned string are only single backslashes; the print functions print a single backslash character as ‘\\’ so they can be read back in.
This function is usually used when a part of a regexp being constructed is unknown at compile time, often provided by the user.
As the section describing regexp syntax notes, the strings that parenthesised expressions match are recorded, the following two functions allow Lisp programs to access the positions of these strings.
This function returns the position which the parenthesised expression number expression-index started at in the last successful regexp match.
If expression-index is nil
or zero the start of the whole string
matched is returned instead.
The returned value will either be a position object if the last match was
in a buffer, or an integer if the last match was in a string (i.e.
regexp-match
).
(regexp-match "foo(bar)" "xyzfoobarsaalsd") ⇒ t (match-start) ⇒ 3 (match-start 1) ⇒ 6
Return the position which the parenthesised expression number expression-index ended at in the last successful regexp match.
If expression-index is nil
or zero the end of the whole match
is returned instead.
The returned value will either be a position object if the last match was
in a buffer, or an integer if the last match was in a string (i.e.
regexp-match
).
(regexp-match "foo(bar)" "xyzfoobarsaalsd") ⇒ t (match-end) ⇒ 9 (match-end 1) ⇒ 9
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions are used to manipulate rectangular regions of buffers. Two position objects are used to define a rectangle, these represent opposite corners of the rectangle. Note that the corner on the right hand side of the rectangle specifies the column after the last column included in the rectangle.
This function deletes a rectangle, defined by start-pos and end-pos, from the specified buffer.
Returns a string containing the rectangle of text defined by the two positions start-pos and end-pos. Any TAB characters are expanded to SPC characters, newline characters mark the end of each line in the rectangle.
A combination of the copy-rect
and delete-rect
functions;
it makes a copy of the rectangle’s contents which is returned after the
rectangle is deleted from the buffer.
Inserts the string string into the buffer at the specified position, treating string as a rectangle of text. This means that each successive line of string (separated by newline characters) is inserted at the same column in successive lines.
If the end of the buffer is reached and there is still some of the string left to insert extra lines are created at the end of the buffer.
This function is similar to the yank
function
(see section Insertion Functions), except that it uses the insert-rect
function to insert the piece of text.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For the description of one part of controlling the undo feature, the maximum size of the undo-list, see @ref{Undo}.
A buffer-local variable which, when set to nil
, stops any
undo-information being recorded for the buffer.
When a buffer is created, this variable is always set to t
.
This buffer-local variable stores the actual list of undo-information; each element defines one modification to the buffer.
Don’t try to be clever and access the contents of this list; the structure may well change in future revisions of Jade.
The only thing you’re allowed to do is set it to nil
, this clears
all undo-information for the buffer.
Undo every change to the contents of the buffer back to the previous command. Successive calls to this command work backwards through the buffer’s undo-list.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns t
if the line pointed to by pos (or
by the cursor) consists totally of TAB or SPC characters.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Modes are used to customise individual buffers so that the text it
contains can be edited in a special way. Each buffer has a single
Major mode, tailoring the buffer to the type of file contained
in it (i.e. C source code uses c-mode
). @xref{Editing Modes}.
Minor modes provide individual features which may be enabled and disabled individually, each buffer may have any number of minor modes enabled at once. @xref{Minor Modes}.
1.28.1 Writing Major Modes | How to define a new major mode | |
1.28.2 Installing Modes | Functions and variables used to install major modes in buffers | |
1.28.3 Writing Minor Modes | Minor modes are totally different to major modes | |
1.28.4 Mode-Specific Indentation | Each major mode may define its own method of indentation, | |
1.28.5 Mode-Specific Expressions | expression handling, | |
1.28.6 Mode-Specific Comments | and comment insertion. |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each major mode must define a command whose name ends in ‘-mode’
(i.e. c-mode
, lisp-mode
, etc…). This command is
called when the major mode is to be installed in the current buffer. It’s
first action must be to check for an already installed mode and
remove it. The following code fragment does this,
(when major-mode-kill (funcall major-mode-kill))
All major modes must do this!
Now the major mode is free to install itself; generally this will entail
setting the buffer-local values of the mode-name
, major-mode
,
major-mode-kill
and keymap-path
variables. For example
the lisp-mode
sets these variables as follows,
(setq mode-name "Lisp" major-mode 'lisp-mode major-mode-kill 'lisp-mode-kill keymap-path (cons 'lisp-mode-keymap keymap-path))
Note how the major mode’s own keymap (with all the mode’s local key bindings
installed in it) is consed onto the front of the keymap-path
; this
ensures that mode-local bindings take precedence over bindings in the
global keymaps.
After installing itself a major mode should call a hook (generally called
x-mode-hook
where x is the name of the mode) to
allow customisation of the mode itself.
The major-mode-kill
variable holds a function to be called when the
major mode is to be removed from the current buffer; basically it should
remove its keymap and set all the mode-local variables to nil
.
For example the lisp-mode-kill
function does the following to
negate the effects of the code fragment above,
(setq keymap-path (delq 'lisp-mode-keymap keymap-path) major-mode nil major-mode-kill nil mode-name nil)
This buffer-local variable contains the symbol whose function definition
was used to install the buffer’s major mode (i.e. c-mode
, etc…).
When it is nil
the buffer uses the ‘generic’ mode; this is simply
the bog standard editor.
This buffer-local variable contains the function which should be called to remove the buffer’s currently installed major-mode.
Note that the kill-buffer
function calls this (if it’s non-nil
)
just before destroying a buffer; so if necessary, an error signalled
within this function will prevent a buffer being killed.
A buffer-local variable containing the ‘pretty’ name of the buffer’s major mode, a string which will be printed in the status line.
Many modes bind commands to keys with the prefix Ctrl-c, to save
each mode creating a new root keymap the buffer-local variable
ctrl-c-keymap
exists.
This buffer-local variable can be used by major modes to hang their keymap for the Ctrl-c prefix from. Simply set this variable to the keymap your mode wants to be installed after a Ctrl-c prefix.
The definitions for many different types of modes can be found in Jade’s lisp directory.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Before a major mode can be used to edit a buffer with it must be installed
in that buffer. The most straightforward method of doing this is simply
to invoke the mode’s command which does this (i.e. c-mode
).
It could be a bit annoying to have to this every time a new buffer is
created so the mode-alist
variable allows major modes to be
installed automatically, when the buffer is opened.
This function attempts to install a major mode into buffer. If the
major-mode
variable is non-nil
it defines the function to
call to install the mode; this function will be called.
Otherwise the mode-alist
variable is searched; each regular
expression is matched against a string, when a match occurs the associated
function is called to install the mode.
The string matched against is defined by the first of the following
choices which is not nil
or undefined.
Note that each match is case-insensitive.
An association list (see section Association Lists) defining regular expressions which associate with a particular major mode.
When the init-mode
function matches a regular expression to the
string it is using to find the mode for the buffer the associated mode
is installed.
For example, mode-alist
could be,
(("\\.(c|h)$|^c(|-mode)$" . c-mode) ("\\.jl$|^lisp(|-mode)$" . lisp-mode) ("\\.(text|doc|txt|article|letter)$" . text-mode) ("^(text(|-mode)|(.*/|)draft)$" . text-mode) ("^indented-text(|-mode)$" . indented-text-mode) ("\\.[s]$|^asm(|-mode)$" . asm-mode) ("\\.[S]$|^asm-cpp(|-mode)$" . asm-cpp-mode) ("\\.texi(|nfo)|^texinfo(|-mode)$" . texinfo-mode))
This function removes the major mode currently installed in the specified buffer.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Minor modes are generally harder to write properly than major modes since they have to peacefully coexist with all the other minor modes which may also be enabled in a buffer.
Generally each minor mode maintains a buffer-local variable saying whether or not it’s installed in the buffer. The minor mode’s function usually toggles the mode on or off depending on the state of this variable.
There are two functions which must be used to install and remove a
minor mode — add-minor-mode
and remove-minor-mode
, see their
documentation for details.
Each buffer has a keymap containing the bindings of all the minor modes
enabled in the buffer (the variable minor-mode-keymap
). These bindings
have to be added when the mode is enabled and removed when it
is disabled.
This buffer-local variable is a list of all the minor modes enabled in a buffer.
This buffer-local variable contains a list of strings, each string names one of the minor modes currently enabled in the buffer.
A buffer-local keymap to be used by minor-modes. This is only created
the first time a minor mode calls add-minor-mode
in the buffer.
This function installs a minor mode (the symbol mode) into the current buffer. All minor modes should call this before doing anything drastic.
name is the string to be displayed in the status line as the name of this minor mode.
When no-keymap is nil
or undefined this function ensures
that the minor-mode-keymap
variable has a valid value in this buffer.
Removes a minor mode from the current buffer, the mode and
name arguments must have the same value as the arguments given
to add-minor-mode
when the mode was enabled.
The following code fragment is an example minor mode taken from Jade’s source code.
(provide 'fill-mode) (defvar fill-column 72 "Position at which the text filling commands break lines.") (defvar fill-mode-p nil) (make-variable-buffer-local 'fill-mode-p) ;;;###autoload (defun fill-mode () "Minor mode for automatically filling lines, i.e. word-wrapping. This makes the SPC key checks if the cursor is past the fill-column. If so, the next line is started." (interactive) (if fill-mode-p (progn (setq fill-mode-p nil) (remove-minor-mode 'fill-mode "Fill") (unbind-keys minor-mode-keymap "SPC")) (add-minor-mode 'fill-mode "Fill") (setq fill-mode-p t) (bind-keys minor-mode-keymap "SPC" 'fill-mode-spc))) (defun fill-mode-spc () (interactive) (when (> (pos-col (cursor-pos)) fill-column) (let ((pos (cursor-pos))) (set-pos-col pos (1+ fill-column)) (setq pos (unless (word-start pos) (forward-word -1 pos))) (insert "\n" pos) (let ((end (left-char 1 (copy-pos pos)))) (when (equal (get-char end) ?\ ) (delete-area end pos))))) (insert " "))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Some major modes provide functions which manage the indentation of the buffer they are installed in. These modes are usually those which are designed for a particular programming language; for example C mode understands how to indent C source and Lisp mode knows about Lisp code.
To simplify matters there is a unified interface to the indentation process; each major mode simply sets the value of a buffer-local variable to the function used to indent a line in that buffer. This variable is then referenced by the functions which provide indentation.
This buffer-local variable should contain a function when the buffer’s major mode provides special indentation.
The function should take one optional argument, the position of the line
to indent. If the value of this argument is nil
the current line
should be indented. The function should set the indentation of the
line to the correct depth then return the glyph position
(see section Glyph Positions) of the first non-whitespace character.
For example Lisp mode sets this variable to lisp-indent-line
, this
function is defined as,
(defun lisp-indent-line (&optional pos) (set-indent-pos (lisp-indent-pos (or pos (cursor-pos)))))
Where the function lisp-indent-pos
calculates the proper indentation
for the line pointed to by its argument.
For the functions dealing with indentation see Indentation Functions.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Most programming use the concept of an expression, Jade allows major modes to define two functions which define the syntax of an expression in a particular programming language. Commands exist which use these functions to allow the manipulation of expressions as entities in a buffer, much like words.
This buffer-local variable contains a function which calculates the position of the end of an expression in that language.
The lambda-list of the function (i.e. its arguments) must be
(&optional count pos)
. count is the number
of expressions to move forwards over (default is one), pos is
the position to start from (default is the cursor position).
The function should return the position of the character following the end of count expressions starting from pos.
Similar to mode-forward-exp
but works backwards from the character
after the expression (at pos) to the start of the previous count
expressions.
These functions can often be quite complex but their structure is usually the same; these two examples are taken from the Lisp mode,
(defun lisp-forward-sexp (&optional number pos) "Return the position of the NUMBER'th next s-expression from POS." (unless number (setq number 1)) (while (> number 0) ;; Movepos
over one expression … (setq number (1- number))) pos) (defun lisp-backward-sexp (&optional number orig-pos) "Return the position of the NUMBER'th previous s-expression from ORIG-POS." (unless number (setq number 1)) (unless orig-pos (setq orig-pos (cursor-pos))) (let ((pos (copy-pos orig-pos))) (while (> number 0) ;; Movepos
backwards over one expression … (setq number (1- number))) pos))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you wish to enter a comment in a piece of source code Jade has
a command to do this (insert-comment
); each major mode which wishes
to allow comments (created by this command) must give the following
variable a suitable function.
This buffer-local variable contains the function to call when a comment
is to be entered, basically the insert-comment
command just calls
this function.
This function moves the cursor to a suitable position for inserting a comment in the current line.
Buffer-local variable containing the canonical column number which
comments should begin at (used by the find-comment-pos
function).
If the line extends past this column the next tab stop after the end of
the line is used instead.
The following function is an example of what is needed in the
mode-comment-fun
variable; it is used by the C mode.
(defun c-insert-comment () (interactive) (find-comment-pos) (insert "/* */") (goto-left-char 3))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The most common way to ask the user for a response is to encode the question in the command’s interactive declaration (see section Interactive Declarations), sometimes this is inconvenient; functions are available which have the same effect as the code letters in an interactive declaration.
The following two functions don’t have an equivalent code for the interactive declaration.
This function prompts the user for a single key response to the string question asking a question which can be answered yes or no.
Returns t
when question is answered with a y and
nil
when n is typed.
Similar to y-or-n-p
but the answer must be either the word ‘yes’
or the word no
entered in full. This function should be used when
a mistyped answer could be catastrophic (i.e. losing changes to a buffer).
Returns t
for ‘yes’, nil
for anything else.
The following functions are the functions used by the call-command
function to resolve interactive arguments.
Note that these function don’t return the string entered (except for
prompt-for-string
) — they return some Lisp object which the
string entered represents somehow.
Prompts for the name of a file. prompt is the string to display
at the head of the prompt, when existing is non-nil
only
files which actually exist are allowed to be entered. The start
argument may be a string defining the starting contents of the prompt.
Prompts for the name of a directory, all arguments are similar to
in the prompt-for-file
function.
This function prompts for a buffer object, if existing is non-nil
the buffer selected must exist, otherwise the buffer will be created if
it doesn’t already exist. default is the value to return if the
user enters the null string, if nil
the current buffer is returned.
Note that this returns the actual buffer, not its name as a string.
Prompt for a symbol, prompt is displayed at the head of the prompt
buffer. If the predicate argument is defined it is a predicate
function; only symbols which when applied to the function predicate
return non-nil
will be allowed to be entered.
Prompt for and return a Lisp object.
Prompts for a function.
(prompt-for-function prompt) ≡ (prompt-for-symbol prompt 'functionp)
Prompts for a variable (a symbol whose value is not void).
(prompt-for-variable prompt) ≡ (prompt-for-symbol prompt 'boundp)
Prompts for a command (a function which may be called interactively).
(prompt-for-command prompt) ≡ (prompt-for-symbol prompt 'commandp)
Prompt for a string, whatever string is entered is returned as-is.
Prompts for a number which is then returned.
The following function is useful when a number of options have to be chosen between, for example the menu command in Info-mode uses this function.
Returns a selected choice from the list of options (strings) option-list. prompt is the title displayed, start the optional starting choice.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Jade allows you to manipulate files in the operating system’s filing system; a special type of Lisp object, a file object, is used to represent files which have been opened for reading or writing (through the streams mechanism, see section Streams).
Names of files are represented by strings, the syntax of file names is defined by the underlying operating system: Jade simply treats it as a string.
1.30.1 File Names | Files are named by a string | |
1.30.2 File Objects | Lisp objects representing files | |
1.30.3 File Information | Predicates on files | |
1.30.4 Manipulating Files | Deleting, renaming and copying files | |
1.30.5 Reading Directories | Getting a list of the files in a directory | |
1.30.6 Reading and Writing Files | Accessing the contents of a file in one go |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A file name is a string identifying an individual file (or directory) in the filing system (i.e. the disk). The exact syntax of file names depends on the operating system.
This function returns the directory part of the file name string file-name. This is the substring of file-name defining the directory containing the file.
(file-name-directory "/tmp/foo") ⇒ "/tmp/" (file-name-directory "foo") ⇒ "" (file-name-directory "foo/bar/") ⇒ "/foo/bar/"
Returns the substring of the file name file-name which is not the directory part.
(file-name-nondirectory "/tmp/foo") ⇒ "foo" (file-name-nondirectory "foo") ⇒ "foo" (file-name-nondirectory "foo/bar/") ⇒ ""
This function returns a file name constructed by concatenating each of the parts of the file name together. Each part is separated by the necessary string (i.e. ‘/’ on Unix) when necessary. Note that each part may contain more than one component of the file name.
(file-name-concat "/tmp" "foo" "bar") ⇒ "/tmp/foo/bar" (file-name-concat "/tmp/" "foo/" "bar") ⇒ "/tmp/foo/bar" (file-name-concat "/tmp/foo" "bar") ⇒ "/tmp/foo/bar"
This function expands the string file-name into a valid file name. Currently it only checks for a leading tilde character (‘~’) when running on Unix, if one is found it’s expanded to the user’s home directory.
When the optional argument make-absolute is non-nil
file-name
is altered so that it is not relative to the current working directory.
Generally this involves prefixing it by the absolute name of the current
directory.
(expand-file-name "~/src") ⇒ "/home/jsh/src" (expand-file-name "foo.c" t) ⇒ "/var/src/jade/foo.c"
This function returns the name of a file which, when created, may be used for temporary storage. Each time this function is called a unique name is computed.
(tmp-file-name) ⇒ "/tmp/00088aaa" (tmp-file-name) ⇒ "/tmp/00088baa"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A file object is a Lisp object which represents a file in the filing system. Any file object may be used as a stream (either input or output) to access the contents of the file serially, Streams.
1.30.2.1 Creating File Objects | Opening files | |
1.30.2.2 Destroying File Objects | Closing files | |
1.30.2.3 File Object Predicates | Predicates for file objects | |
1.30.2.4 Functions on File Objects | Functions operating on file objects |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function opens the file called file-name (see section File Names) and returns the file’s object.
The mode-string argument is a string defining the access modes used
to open the file with; this string is passed as-is to the C library’s
fopen()
function. Usually one of the following strings is used,
Open an existing file for reading only.
Open the file for writing only, if the file exists it is truncated to zero length. Otherwise a new file is created.
Open the file for appending to, i.e. writing to the end of the file. If the file doesn’t exist it is created.
Other options exist; consult a C library manual for details.
When the file-object argument is defined it should be a file object, the file it points to will be closed and the new file will be opened on this object.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The easiest way to close a file is simply to eliminate all references to it, subsequently the garbage collector will close it for you. It is better to close files explicitly though since only a limited number of files may be opened concurrently.
This function closes the file pointed to by the file object file-object.
Until a new file is opened on file-object any read/write accesses to it are illegal and an error will be signalled.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns t
when its argument is a file object.
Returns t
when the file object file-object is currently
bound to a physical file (i.e. the close
function hasn’t been
called on it yet).
This function returns t
when the current position of the file
object file-object is the end of the file (i.e. when reading
a character from the file would return nil
).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function flushes any buffered output to the file object file-object to disk.
Note that when using a file which was opened with the ‘+’ option it’s necessary to call this function when switching from reading to writing or vice versa.
Returns the name of the file which the file object file-object is currently bound to.
This function reads lines from the file object file-object until
a line matching the regular expression regexp is found. The matching
line is returned, or nil
if the end of the file is reached.
When the ignore-case option is non-nil
all regexp matching
is done case-insignificantly (except for matching ranges).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A number of functions exist which when given the name of a file return some information about that file.
Returns t
when a file file-name exists.
Returns t
when the file file-name is a ‘normal’ file. This means
that it isn’t a directory, device, symbolic link or whatever.
Returns t
when the file file-name is a directory.
Returns t
when the file file-name is a symbolic link.
Returns t
when the file file-name is readable.
Returns t
when the file file-name is writable.
Returns t
when the ownership of the file file-name is
the same as that of any files written by the editor.
Note that currently this always returns t
in the Amiga version.
Returns the number of hard links pointing to the file file-name. If file-name has only one name the number will be one.
Note that this always returns one in the Amiga version of Jade.
This function returns the access permissions of the file file-name. This will be an integer whose format is undefined; it differs from operating system to operating system.
This function sets the access permissions of the file file-name to
the integer modes (as returned by the file-modes
function).
Returns the system time at the last modification to the file file-name, this will be an integer. See section System Time.
This function returns t
if the file file-name1 was modified
more recently than the file file-name2 was.
(file-newer-than-file-p file1 file2) ≡ (> (file-modtime file1) (file-modtime file2))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function deletes the file called file-name. When called interactively file-name is prompted for.
This function attempts to change the name of the file new-name to new-name.
This won’t work from one file system to another or if a file called new-name already exists, in these cases an error is signalled.
This prompts for its arguments when called interactively.
Creates a new copy of the file file-name with the name destination-name.
The access modes of the new file will be the same as those of the original file.
The arguments are prompted for when this function is called interactively.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns a list of the names of all files in the directory whose file name is directory-name. The names in the list will be relative to the directory directory-name, any directories in the list will have a ‘/’ character appended to them.
(directory-files "/tmp/foo" ⇒ ("bar" "subdir/" "xyz" "." "..")
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns a string containing the contents of the file called file-name.
This function creates or overwrites the file called file-name with the string contents as its contents.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When running on a Unix-style operating system (i.e. the X11 version) Jade allows you to launch and control an arbitrary number of subprocesses. These subprocesses can run either synchronously or asynchronously in respect to the editor; data can be sent to the stdin channel and any output from the process is automatically written to a programmer-defined Lisp stream.
Currently there is no way to manipulate subprocesses in the Amiga version of Jade (sorry!).
1.31.1 Process Objects | Lisp objects associated with subprocesses | |
1.31.2 Asynchronous Processes | Subprocesses running in parallel with Jade | |
1.31.3 Synchronous Processes | Subprocesses which Jade runs serially | |
1.31.4 Process I/O | Input and output with subprocesses | |
1.31.5 Process States | Suspending subprocesses | |
1.31.6 Signalling Processes | Sending signals to subprocesses | |
1.31.7 Process Information | Information stored in a process object | |
1.31.8 Interactive Processes | Shell mode lets the user interact with a subprocess |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A process object is a type of Lisp object used to provide a link between a ‘physical’ process running in the operating system and Jade’s Lisp system. Each process object consists of a number of components (references to other Lisp objects); these components are used when the object is used to run a subprocess.
Process objects which aren’t currently being used to run a subprocess store the exit value of the last subprocess which was run on that object.
This function returns t
when its argument is a process object.
The programmer-accessible components of a process object are,
A normal Lisp output stream (see section Output Streams), all data which the
subprocess outputs to its stdout
channel is copied to this
output stream. See section Process I/O.
A Lisp function, called each time the state of the subprocess being run on the object changes. See section Process States.
The name of the program (a string) to execute when the subprocess is created.
A list of strings defining the arguments which the program executed is given.
When a subprocess is started its current working directory is set to the directory named by this component of its process object.
Asynchronous subprocesses (see section Asynchronous Processes) use this component to decide how to connect to the I/O channels of the subprocess. Current options include pseudo-terminals and pipes.
This functions creates and returns a new process object. No subprocess will be started.
The optional arguments are used to define the values of the components of the new process object, any undefined components will be set to default or null values.
For each component of a process object two functions exist; one to read the component’s value in a specific process object, the other to set the component’s value.
Returns the value of the program name component of the process object process.
Sets the value of the program name component of the process object process to the string prog-name, then returns prog-name.
Returns the value of the program arguments component of the process object process.
Sets the value of the program arguments component of the process object process to the list arg-list, then returns arg-list.
Returns the value of the directory component of the process object process.
Sets the value of the directory component of the process object process to the string directory, then returns directory.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
An asynchronous process is one that runs in parallel with the editor,
basically this means that once the subprocess has been started (by the
start-process
function) Jade will carry on as normal.
The event loop checks for output from asynchronous processes, any found is copied to the process’ output stream, and calls the the process’ state change function when necessary (see section Process States).
When using asynchronous processes you have a choice as to the Unix
mechanism used to connect the stdin
, stdout
and stderr
streams of the subprocess to Jade’s process (note that whatever the choice
stdout
and stderr
always go to the same place).
The two options currently available are pipes or pseudo-terminals; in general pseudo-terminals should only be used to provide a direct interface between the user and a process (i.e. the ‘*shell*’ buffer) since they allow job control to work properly. At other times pipes will be more efficient and are used by default.
This function starts an asynchronous subprocess running on the process
object process-object. If process-object is undefined a
new process object is created (by calling the function make-process
with all arguments undefined).
The function always returns the process object which the subprocess
has been started on. If for some reason the subprocess can’t be created
an error of type process-error
is signalled.
The optional argument program is a string defining the name of the
program to execute, it will be searched for in all the directories
in the PATH
environment variable. The args are strings
to pass to the subprocess as its arguments.
When defined, the optional arguments overrule the values of the related components of the process object.
The following example runs the ls
program asynchronously, its output
is inserted into the current buffer.
(let ((process (make-process (current-buffer)))) (start-process process "ls" "-s"))
Note that when Jade terminates it kills all of its asynchronous subprocesses which are still running without warning.
Returns the value of the connection type component of the process object
process. See the documentation of the set-process-connection-type
function for the values this may take.
Sets the value of the connection type component of the process object process to symbol, then returns symbol.
symbol should be one of the following symbols,
pty
Use pseudo-terminals to connect to subprocesses running asynchronously on this process object.
pipe
Use standard Unix pipes to connect, this is the default value of this component.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When a synchronous process is started Jade waits for it to
terminated before continuing; they are usually used when a Lisp program
must invoke an external program as part of its function, i.e. the
auto-compression feature runs the compression program gzip
synchronously when it needs to compress a buffer.
Unlike asynchronous processes their is no choice between pipes and
pseudo-terminals for connecting to a subprocess. Instead, it is possible
to link the stdin
channel of a synchronous process to a named
file.
This function starts a process running on the process object
process-object. If process-object is undefined a new process object
is created by calling the make-process
function.
If defined, the string input-file-name names the file to connect to the standard input of the subprocess, otherwise the subprocess’ input comes from the null device (‘/dev/null’).
The optional arguments program and args define the name of the
program to invoke and any arguments to pass to it. The program will be searched
for in all directories listed in the PATH
environment variable.
If any of the optional parameters are unspecified they should have been set in the process-object prior to calling this function.
After successfully creating the new subprocess, this function simply copies
any output from the process to the output stream defined by the output stream
component of the process object. When the subprocess exits its exit-value
is returned (an integer). Note that the exit-value is the value returned
by the process-exit-value
function, see Process Information.
If, for some reason, the new subprocess can’t be created an error of type
process-error
is signalled.
The following function definition is taken from the ‘gzip.jl’ file,
it shows how the run-process
function can be used to uncompress
a file into a buffer.
;; Uncompress FILE-NAME into the current buffer (defun gzip-uncompress (file-name) (let ((proc (make-process (current-buffer)))) (message (concat "Uncompressing `" file-name "'") t) ;; gunzip can do .Z files as well (unless (zerop (run-process proc nil "gunzip" "-c" file-name)) (signal 'file-error (list "Can't gunzip file" file-name)))))
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is only possible for lisp programs to explicitly send input data
to asynchronous processes (by the time it’s possible to call a function
to send data to a synchronous process, the process will already have
terminated!). Simply use the process object which an asynchronous process
is running on as a normal Lisp input stream, any strings or characters
written to the stream will immediately be copied to the stdin
channel
of the subprocess.
With synchronous processes, the only control over input data possible is
by giving the run-process
function the name of a file containing
the subprocess’ input data.
Output data from subprocesses is handled the same way by both asynchronous and synchronous processes: it is simply copied to the stream defined by the output stream component of the subprocess’ process object.
Returns the value of the output stream component of the process object process.
Sets the value of the output stream component of the process object process to the stream stream, then returns stream.
See section Streams.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each process object has a state associated with it; this depends on the status of the subprocess currently running on the process object (or not as the case may be).
The possible states are,
This state means that the subprocess using this process object is currently running, i.e. it hasn’t been stopped.
Means that the subprocess has been temporarily suspended from running.
This means that the process object is free to have a new subprocess created on it.
Predicates exist which test whether a given process object is in one of these states.
Returns t
when process-object is in the running state.
Returns t
when process-object is in the stopped state.
Returns t
when process-object is not in the unused
state.
The following two functions are used to stop and then subsequently continue a process running.
This function suspends execution of the subprocess running on the process object process-object.
If whole-group is non-nil
all subprocesses in the
process group of process-object are stopped.
Use this function to continue a subprocess executing after it has been
stopped (by the stop-process
function).
If whole-group is non-nil
all subprocesses in the
process group of process-object are continued.
The state change function component of a process object defines a function which will be called each time the state of the process object changes. If your program needs to be informed when an asynchronous process terminates this function is the way to do it.
Returns the value of the state change function component of the process object process.
Sets the value of the state change function component of the process object process to the function function, then returns function.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If the process object process-object is being used to run an asynchronous subprocess send the signal numbered signal-number to it.
When the optional argument whole-group is non-nil
the
signal is also sent to all processes in the process group of the subprocess.
The following functions use the signal-process
function to send some
common signals to processes.
Sends the SIGINT
signal to process-object.
(interrupt-process process-object whole-group)
≡
(signal-process process-object SIGINT
whole-group)
Sends the SIGKILL
signal to the process-object.
(kill-process process-object whole-group)
≡
(signal-process process-object SIGKILL
whole-group)
Note that the functions stop-process
and continue-process
also send signals to the subprocess.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns the operating-system identifier associated with the subprocess currently running on the process object process-object.
Returns the integer representing the return code of the last subprocess to be run on process-object.
If no subprocess has been run on process-object, process-object
is currently in the running state or the last subprocess exited abnormally
(i.e. from a terminal signal) nil
is returned.
This function returns the integer that was the exit status of the last subprocess which was run on the process object process-object.
Note that the exit status is not the value given to the exit
function in a C program, use the process-exit-value
to access this
value.
If no process has been run on process-object, or the process is currently
in the running state nil
is returned.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The Shell mode is usually used to run a shell process in a buffer (with
the shell
command, @pxref{Shell}) but in actual fact it is
capable of running (nearly) any type of interactive process. For
example the gdb interface (@pxref{Debugging Programs}) uses the Shell
mode to handle its user interaction.
The following buffer-local variables control the Shell mode.
This variable defines the name of the program to execute. By default it is the user’s shell.
A list of arguments which should be given to the process when it is started.
This regular expression must match the prompt that the process emits each time it waits for input. Its standard value of ‘^[^]#$%>)]*[]#$%>)] *’ will need to be tailored to the program that you are executing.
Every time the state of the subprocess changes (see section Process States) this function is called in the context of the process’ buffer.
All output from the subprocess is copied to this output stream. If it is
nil
all output goes to the end of the process’ buffer.
Note that this variable is only referenced when the process is started.
To use the Shell mode to create an interface with a program simply use the following steps.
buffer-file-name
attribute of the buffer defines the
working directory of the subprocess.
shell-mode
function.
mode-name
and major-mode
if
necessary and install your own keymaps.
Remember that commands essential to the Shell mode (and hence your
program) are contained in the two keymaps shell-keymap
and
shell-ctrl-c-keymap
. If you need to bind your own commands to
either of these prefixes make copies of these keymaps (using the
function copy-sequence
) and bind to the copies.
For example the gdb interface installs its own key bindings from the Ctrl-c prefix by doing the following in its initialisation.
(defvar gdb-ctrl-c-keymap (copy-sequence shell-ctrl-c-keymap)) (bind-keys gdb-ctrl-c-keymap ;; Gdb mode `Ctrl-c' prefix bindings follow …
This function installs the Shell mode and starts a subprocess running in the current buffer.
The variables shell-program
, shell-program-args
,
shell-prompt-regexp
, shell-callback-function
and
shell-output-stream
control the program executed and how it will
execute.
The process object created is stored in the buffer-local variable
shell-process
.
This buffer-local variable contains the process object which the Shell
mode started running in this buffer. If it is nil
no such process
exists.
The root keymap of the Shell mode.
The keymap containing the key bindings of the commands in Shell mode with a prefix of Ctrl-c.
See the Lisp program ‘gdb.jl’ for an example of how to use the Shell mode as the user interface with an external program.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section of the manual documents functions and features which don’t comfortably fit elsewhere in this manual.
1.32.1 System Information | Getting details about the host | |
1.32.2 User Information | The name of the user | |
1.32.3 Environment Variables | Reading and writing the environment | |
1.32.4 System Time | Getting the current time | |
1.32.5 Revision Information | How to check Jade’s revision numbers |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns t
when Jade is running on the X11 window system.
This function returns t
when Jade is running on a variant of the Unix
operating system.
This function returns t
when Jade is running on an Amiga.
This function returns a string naming the host that Jade is running on. When possible this will include the name of the domain as well.
In the Amiga version of Jade the environment variable HOSTNAME
is
assumed to contain the host’s name.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns a string containing the login name of the user.
In the Amiga version this is taken from the environment variable
USERNAME
.
(user-login-name) ⇒ "jsh"
This function returns a string containing the ‘real’ name of the user; the format of the string will depend on the host system.
In the Amiga version this is taken from the REALNAME
environment
variable.
(user-real-name) ⇒ "John Harper"
This function returns the name of the user’s home directory terminated by a slash character (‘/’).
The first place this is looked for is in the HOME
environment
variable; if this variable doesn’t exist we either use the ‘SYS:’
logical device in AmigaDOS or consult the passwd file when in Unix.
(user-home-directory) ⇒ "/home/jsh/"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns the value (a string) of the environment variable
called variable-name. If the specified variable doesn’t exist nil
is returned.
(getenv "OSTYPE") ⇒ "Linux"
This function sets the value of the environment variable called
variable-name to new-value. new-value can either be
a string containing the new contents of the variable or nil
, in which
case the environment variable is deleted.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
No matter what operating system Jade is running on it always an integer to store a time value. Generally this will be the number of seconds since some previous date.
The only thing a Lisp program is allowed to assume about a time value is that as time passes the time value increases. This means that it’s possible to compare two time values and know which is the newer.
Returns an integer denoting the current time.
(current-time) ⇒ 780935736
This function returns a string stating the current time and date in a fixed format. An example of the format is,
Fri Sep 30 15:20:56 1994
Each field will always be in the same place, for example,
Thu Sep 1 12:13:14 1994
(current-time-string) ⇒ "Fri Sep 30 15:20:56 1994"
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This function returns a number defining the major version of the editor.
(major-version-number) ⇒ 3
Returns a number defining the minor version of the editor.
(minor-version-number) ⇒ 2
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When you have written a Lisp program you will have to debug it (unless all your programs work first time?). There are two main classes of errors; syntax errors and semantic errors.
Syntax errors occur when the text you’ve typed out to represent your program is not a valid representation of a Lisp object (since a program is simply an ordered set of Lisp objects). When you try to load your program the Lisp reader will find the syntax error and tell you about, unfortunately though it probably won’t be able to tell you exactly where the error is.
The most common source of syntax errors is too few or too many parentheses; the Ctrl-Meta-f and Ctrl-Meta-b commands can be used to show the structure of the program as the Lisp reader sees it.
Semantic errors are what we normally call bugs — errors in logic, the program is syntactically correct but doesn’t do what you want it to. For these types of errors Jade provides a simple debugger which allows you to single step through the Lisp forms of your program as they are being evaluated.
There are several ways to enter the Lisp debugger; functions can be marked so that they cause the debugger to be entered when they are called, breakpoints can be written in functions or it can be called explicitly with a form to step through.
This command marks the symbol symbol so that each time the function stored in the function cell of symbol is called the debugger is entered immediately.
When called interactively symbol is prompted for.
The opposite of trace
— unmarks the symbol.
This function causes the debugger to be entered immediately. By putting the
form (break)
at suitable points in your program simple breakpoints
can be created.
This function invokes the debugger to step through the form form.
When called interactively form is prompted for.
Whenever the Lisp debugger is entered the form waiting to be evaluated is printed at the bottom of the buffer, at this point the special debugger commands available are,
Step into the current form; this means that in a list form the debugger is used to evaluated each argument in turn.
Ignore the current form; makes the current form immediately return nil
.
Continue evaluating forms normally until the next form at the current level is entered, then re-enter the debugger.
Continue execution normally. Note that this command is the one to use when an error has been trapped.
Print a backtrace of the current Lisp call stack, note that calls of primitive functions aren’t currently recorded in this stack.
Prompt for a Lisp form, evaluate it and return this value as the result of the current form.
After the form has been evaluated (i.e. after you’ve typed one of the commands above) the value of the form is printed in the buffer, prefixed by the string ‘=> ’.
Note that it is also possible to make certain types of errors invoke the debugger immediately they are signalled, see Errors.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section of the manual gives advice about programming in Jade.
Obviously there is no need to religiously follow every single one, but following these tips will make your programs easier to read and (hopefully) more efficient overall.
For advice on getting the most out of the compiler, see Compilation Tips.
1.34.1 Comment Styles | Differrent types of comments | |
1.34.2 Program Layout | How I lay out the programs I write | |
1.34.3 General Tips | Do’s and Don’t’s of Jade programming |
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As already described, single-line comments in Lisp are introduced by a semi-colon (‘;’) character. By convention a different number of semi-colons is used to introduce different types of comments,
A comment referring to the line of Lisp code that it occurs on, comments of this type are usually indented to the same depth, on the right of the Lisp code. When editing in Lisp mode the command Meta-; can be used to insert a comment of this type.
For example,
(defconst op-call 0x08) ;call (stk[n] stk[n-1] ... stk[0]) ; pops n values, replacing the ; function with the result. (defconst op-push 0x10) ;pushes constant # n
Comments starting with two semi-colons are written on a line of their own and indented to the same depth as the next line of Lisp code. They describe the following lines of code.
For example,
;; Be sure to remove any partially written dst-file. (let ((fname (concat file-name ?c))) (when (file-exists-p fname) (delete-file fname)))
Comments of this type are also placed before a function definition to describe the function. This saves wasting memory with a documentation string in a module’s internal functions.
For example,
;; Compile a form which occurred at the `top-level' into a ;; byte code form. ;; defuns, defmacros, defvars, etc... are treated specially. ;; require forms are evaluated before being output uncompiled; ;; this is so any macros are brought in before they're used. (defun comp-compile-top-form (form) …
This type of comment always starts in the first column of the line, they are used to make general comments about a program and don’t refer to any function or piece of code in particular.
For example,
;;; Notes: ;;; ;;; Instruction Encoding ;;; ==================== ;;; Instructions which get an argument (with opcodes of zero up to …
Each program should have a comment of this type as its first line, the body of the comment is the name of the file, two dashes and a brief description of what the program does. They always start in the first column.
For example,
;;;; compiler.jl -- Simple compiler for Lisp files/forms
If you adhere to these standards the indentation functions provide by the Lisp mode will indent your comments to the correct depth.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The layout that I have used for all the Lisp programs included with Jade is as follows, obviously this isn’t ideal but it seems ok.
require
forms needed followed by a provide
form for
this module. The require
forms should be before the
provide
in case the required modules aren’t available.
defvar
then initialised with
the bind-keys
function.
For example,
(defvar debug-buffer (make-buffer "*debugger*") "Buffer to use for the Lisp debugger.") (set-buffer-special debug-buffer t) (add-buffer debug-buffer) (defvar debug-ctrl-c-keymap (make-keylist) "Keymap for debugger's ctrl-c prefix.") (bind-keys debug-ctrl-c-keymap "Ctrl-s" 'debug-step …
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following are some general items of advice; you don’t have to follow them but they are the result of experience!
When you write a program all the symbols it creates should be prefixed
by a name derived from the name of the program in some way. For example,
in the program ‘isearch.jl’ all functions and variable names are
prefixed by the string ‘isearch-’, giving isearch-cancel
and so on. Note that the prefix doesn’t have to be the exact name of the
file, the program ‘buffer-menu.jl’ uses the prefix ‘bm-’.
The entry points to a module (i.e. the names of the commands it provides) should not have a prefix, simply give them a descriptive name (but try not to make it too long!).
Don’t bother giving local variables these prefixes unless they are used by several functions in the program.
recursive-edit
function as little as possible; it can be
very confusing for the user! When at all possible use keymaps to
create user interfaces.
error
or signal
,
don’t just print a message or call beep
.
require
a file
that a macro is defined in before using the macro definition.
memq
and assq
types of functions can be used to search some types of list structures
very quickly.
[Top] | [Contents] | [Index] | [ ? ] |
Actually buffer-local variables complicate matters but you’ll learn about that later.
[Top] | [Contents] | [Index] | [ ? ] |
This document was generated on January 9, 2023 using texi2html 5.0.
The buttons in the navigation panels have the following meaning:
Button | Name | Go to | From 1.2.3 go to |
---|---|---|---|
[ << ] | FastBack | Beginning of this chapter or previous chapter | 1 |
[ < ] | Back | Previous section in reading order | 1.2.2 |
[ Up ] | Up | Up section | 1.2 |
[ > ] | Forward | Next section in reading order | 1.2.4 |
[ >> ] | FastForward | Next chapter | 2 |
[Top] | Top | Cover (top) of document | |
[Contents] | Contents | Table of contents | |
[Index] | Index | Index | |
[ ? ] | About | About (help) |
where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:
This document was generated on January 9, 2023 using texi2html 5.0.