Trailing-Edge
-
PDP-10 Archives
-
mit_emacs_170_teco_1220
-
info/conv.info
There are no other files named conv.info in the archive.
-*-Text-*-
File: CONV Node: Top Up: (DIR) Next: Init
Programming in TECO for EMACS
* Menu:
* Init Files: Init INIT files and what they can do.
* Syntax: Syntax Syntax library source files to be compiled by
the EMACS library compiler in the PURIFY library.
Description of TECO mode, good for editing
source code for libraries.
* Libraries: Lib Other conventions for Libraries and sources.
* Ivory: (Ivory)Top The IVORY library has an alternative
compressor and purifier mechanism.
* Programming: Prog Conventions for TECO programs to be operated
in the EMACS enviromnment.
* Buffers:: Data structures for EMACS buffers.
* Windows:: Data structures for two window mode.
* Complete:: How to read names with completion.
* Variables: Vars Named variable (QFoo, etc) conventions.
* Major Modes: Major How to define new major modes.
* Submodes:: How to define submodes.
* Prefix:: Prefix characters, such as C-X.
* Hooks:: Variables which EMACS will call at specific times.
* Novice:: Setting up restricted subsets for beginners.
* Dump:: Dumping EMACS environments.
* Build:: Building and dumping a new EMACS.
* Wall Charts:: Making wall charts.
* Abstracts:: Making abstracts of libraries (for documentation)
and source listings and source indexes of
TECO code (good for studying the code).
* Q-registers: Qregs Conventions for use of Q-registers.
* FS ^R PREV: FS^RPREV Conventions for setting/examining FS ^R PREV.
* Debugging: Debug Debugging aids in EMACS.
* TDEBUG: (TDEBUG) TDEBUG is a package for stepping and
breakpoints in TECO code.
File: CONV Node: Init, Up: Top, Previous: Top, Next: Syntax
INIT Files.
This is not a full description of how to write init files,
because such a description has to include a full course on TECO
programming. People who want to learn to program in TECO should
follow this course of action: find a DEC TECO manual and read it
(much of that will apply to this TECO as well, though many individual
commands are different or missing in DEC TECO), look through the
TECORD file, then read this file. After that, you can read some EMACS
source code and init files using TECORD and this file as a reference.
Each user can have his own file of TECO commands for EMACS to
execute each time he starts it up. EMACS looks for the file
<hsname>;<user> EMACS and then for <hsname>;* EMACS, where <hsname>
stands for the user's home directory. If neither file exists, the
file EMACS;* EMACS (the default init file) is used instead.
On Twenex, the init file is called EMACS.INIT in your login directory,
and the default init file is EMACS:EMACS.INIT.
You can cause an EMACS to read another user's init file by giving it
that user's name as its XUNAME; just do <user>^S in DDT immediately
before starting the EMACS. To avoid running your own init file,
specify a name like FOO which has no init file.
Setting up the default character definitions and named variables
need not be done in an init file, since that is done before the EMACS
environment is dumped out. As a result, your init file need only
define those commands which you wish to change. Use MM Load Lib to
load any additional libraries (or the :EJ command, for libraries which
have no & Setup <library> Library function). To obtain a function as a
value so you can put it on a character, simply use M.M <name> . The
U command can define a character, as in for example U..^RX which puts
its argument on Meta-X. The character is specified in the same manner
as in an EVARS file; *Note EVARS: (EMACS)Init. Use M.V to create and
assign a variable, or better yet M.C to give it some documentation as
well. *Note Vars: Vars, for details of how to use M.V and M.C.
When the init file is started, all q-registers not used by EMACS
(and described herein) will probably be zero. One exception is Q1,
which contains the version number of EMACS :EJ (on ITS, [PURE] >), as
a string. The default init file types this out as the "EMACS version
number".
If you have no init file, EMACS runs the default init file, which is
the init file on the EMACS directory. This does various things such
as processing a command line from the superior, loading LISPT if
necessary, printing the EMACS version number and offering help, ...
Most people will find that they wish to perform the actions of the
default init file after their own peculiar initializations.
To do this, just end your own init file with
ER EMACS;* EMACS @Y ET@ > :M(HFX*)
(On Twenex, do ER EMACS;EMACS INIT or ER EMACS:EMACS.INIT instead)
This practice is recommended because some of the things in the default
init file are important for the proper functioning of EMACS.
The above sample of code calls the default init file with an empty
buffer. If you call it with text in the buffer, that text is used
instead of the job's command line arguments.
To prevent the default init file from printing its help message,
create the variable Inhibit Help Message and make it nonzero.
If you have enough of your own functions to have a private library of
them, you need not have both the library and an init file to load the
library. You can just call your library <user> EMACS and give it a
~Filename~ of INIT and a & Setup INIT Library function to perform the
other initialization. The & Setup INIT Library function should end by
reading in the default init file, just as an ordinary init file
should, but the calling convention is slightly different:
:I..9 ER EMACS;* EMACS @Y ET@ > :M(HFX*)
File: CONV Node: Syntax, Up: Top, Previous: Init, Next: Lib
Syntactic Conventions for EMACS Library Source Files
The fundamental basis of EMACS is the library, which contains a set
of functions written in TECO, together with their names and
documentation. There is one standard library which contains the main
body of EMACS, and there are other libraries that are loaded sometimes
automatically or by request. For more information on how to use
libraries, *Note Use: (EMACS)Libraries. This node describes how to
write library source files, and the next node describes how to compile
them.
A source file of EMACS functions contains one function on each page.
Each function has a name and documentation as well as its definition.
These source files are processed by a compressor which deletes spaces
and comments and performs other syntactic transformations before they
are run. You can also ask to compress and install a single function,
for testing, by pointing at it and using MM Compile.
Every function definition should end with a CRLF, after which may
come a ^L and the next function definition. Function definitions are
separated only by CRLF ^L CRLF. A ^L in the middle of the line is
just part of a function. If you want to put CRLF ^L CRLF inside a
function, use CRLF ^]^Q^L CRLF.
The Function Name
Every function's definition begins with the function name, which is
preceded by a ! and followed by :!. You must not ever put a :!, even
with spaces in between, in a source file except to end a function
name. The function name must be the first thing on a page except for a
CRLF which must follow the previous formfeed on pages after the first.
The name conventions are that subroutine names start with "& " and
names of commands intended to be put on characters start with "^R ".
This is to keep them from limiting the user's ability to abbreviate
the names of commands he wishes to type. Another convention is that
"#" begins the names of commands which form a dispatch table. For
example, in INFO, the command M causes # INFO M to be run. If you
define a command named # INFO +, that will automatically give you an
INFO command called +.
The Function Documentation
After the function name comes a space, an !, and then the function
class. Then, after another space, the rest of the line is the "brief"
documentation which is used when only a single line is wanted. It
should be a complete sentence. The function class should be the
character C for a command which users should call by name, S for a
command intended to be used as a subroutine, and ^R for a command
intended to be placed on a character. The function class does not
restrict how the function can actually be used; some of the
documentation commands filter commands to be described by class.
The function may have only the brief documentation. In this case,
the brief documentation should be followed by an !. Otherwise, the
lines following the brief documentation are the full documentation,
which ends with the first !. The ! must be at the end of its line,
and should not be an excuse to omit punctuation for the last sentence,
since it will not be seen by the user. To put an ! in the text of the
documentation, use control-^.
If you wish to refer to one or two character commands in the
documentation, you should not just put in the characters of the
command, since that would make the documentation wrong for users who
move their commands around. The thing to do instead is to put in the
full name of the function which you are referring to, surrounded by
characters. When the documentation is printed out, this is replaced
by the name of the character which is connected to the function, if
there is one. If there isn't one, the function's name is used
instead. For example, you could use ^R Exit to refer to the command
to exit from a recursive edit, which in the standard environment can
be invoked with either Control-Altmode or C-M-C, and when the
documentation is printed it will say "Control-Altmode" or
"Control-Meta-C". The construct cannot be used in the brief
documentation because only the command which prints the full
documentation knows how to process it.
For even more flexibility in the documentation of a function, if the
string between the characters starts with an Altmode, it is
considered a TECO program to be executed, rather than a function name
to be looked up. It does not undergo the same syntactic preprocessing
that the function definitions do;; spaces are represented as spaces,
not as underlines, etc. The TECO program can either print text out or
insert it in the buffer (from which M-X Describe will print it out).
When this TECO program is run, it receives the name of the function as
a postcomma argument (a string pointer) or the numeric code for the
character being described as a precomma argument, or both. A string
containing the command character sequence being described can be
passed as a precomma argument instead of a number.
The Function Definition
After the line ending with !, the next line contains the beginning
of the function definition proper. Usually, a blank line is put there
to improve readability. You must remember that the definition will
not be used as written, but will be processed syntactically first: all
spaces and tabs, except those following a ^Q, will be deleted. all
_'s not following a ^Q will be turned into spaces. !* is taken to
start a comment and everything from there up to and including the
following ! is deleted (again, a ^Q will prevent this). Double CRLFs
are converted to single ones. Normally, you should use ^]^Q to do
such quoting, since that is safe in all contexts. Inside search
commands and file commands a ^Q by itself is enough.
TECO Mode
The major mode TECO Mode is useful for editing EMACS source files.
Comments are defined to start with !* and end with !. Tab is set to
the command ^R Indent Nested, which normally moves the current line to
be under the previous line. With an argument, it takes the argument
to be the number of levels "up" to go, where up means a lesser amount
of indentation. Thus, Tab with an argument of 2 or more is good for
the first line after the end of a conditional or iteration. In
addition, unindented lines and lines containing only comments are
ignored. In addition, Meta-' is defined to move forward over a TECO
conditional, and Meta-" to move back. These commands ignore quotes
that are inside comments.
File: CONV Node: Lib, Up: Top, Previous: Syntax, Next: Prog
Library File Conventions
The command Generate Library, in the library PURIFY, is used to
generate :EJ'able libraries from source files following the syntactic
conventions. The operation has two logical subparts: compression,
which removes spaces and comments, and extracts the documentation into
separately named functions; and purification, which converts the
intermediate form into a :EJ'able library. It is possible to divide
the source for a large library into several subfiles, which will be
compressed separately but purified together. This saves time if only
some of the subfiles are modified, since the compressed versions are
saved in separate files and reused if more recent than the sources.
Generate Library handles such multi-file sources automatically if all
the source files' names are given to it.
One of the source files going into a library should define a
"function" named ~Filename~. The "definition" of this function should
be some kind of identification for the file. It should usually be the
same as the first filename of the library. The documentation for
~Filename~ should describe the purpose of the library as a whole. It
should NOT have a function class ("S", "C" or "^R") at the front.
Generate Library automatically creates a ~Directory~ object which
contains a list of all the functions in the file. A library should
never contain two functions with the same name (~Filename~ is an
exception: see below).
Sometimes it is desirable to merge several library sources into one
:EJ file. If you always like to use, say, TAGS :EJ, and have a
private library, you may save space and increase speed by including
the source of TAGS when generating your private library. This,
however, means that you need to be able to override the ~Filename~
function which comes from the source of TAGS. Generate Library solves
this problem by deleting all but the first ~Filename~. Your private
source file must come first, and contain a ~Filename~, to override the
one in the TAGS source.
Libraries intended to be accessed via the Run Library command should
contain a function named <ENTRY>, which will be the default entry
point, so that the user need not specify the entry point name. In
addition, they MUST have a ~FILENAME~ which is identical to the actual
first name of the file, so that Run Library can tell whether the
library is already loaded.
If a library contains a function named & Setup <libname> Library,
where <libname> is the library's ~Filename~ name, then whenever the
library is loaded with MM Load Library that function will be called.
It can be used to connect some of the library's functions to
characters, for example. If it is used for that purpose, then it
should allow the user to override it by setting up a named variable.
For example, the TAGS library has an & Setup TAGS Library function,
which defines Meta-. as a command. However, if the variable TAGS
Setup Hook is nonzero, & Setup TAGS Library executes that variable
instead of its default actions. Thus, a user's init file can specify
where the TAGS commands should go if TAGS is ever loaded, by defining
TAGS Setup Hook.
If you wish, you can put a function called & Kill <libname> Library
in the library. If the library is killed with the Kill Libraries
command, this function will be called. A string pointer to the
library in core will be passed to it as an argument. The & Kill
function might try to remove pointers into the library from important
places where they were put by the & Setup <libname> Library function.
It is probably not worth while looking for characters which have been
connected to functions in the library, since this is painful and slow,
and the worst that can happen is that those commands will cause errors
when used. However, if pointers into the library were placed in
important FS flags, it may be essential to remove them if TECO is to
continue functioning properly.
It is a good idea for an & Kill <libname> library function to
execute the value of <libname> Kill Hook if it exists and is nonzero.
In addition to the names of functions, there are several names that
(usually or always) be found in libraries. For every function FOO, an
object named ~DOC~ FOO is available, that contains FOO's
documentation. In addition, ~DIRECTORY~ contains a list (one per
line) of all the functions that the file wishes to advertise that it
contains. Special things such as described in this section, and all
commands with ~ in their names, are not included.
~INVERT~ is supposed to be a function that is the inverse of the
loader function. That is, <object in file>,<pointer to file> fed to
the ~INVERT~ function should return a string containing the name of
the object. You should not have to be aware of ~INVERT~, because it
will be provided automatically, and called by & Macro Name when
necessary.
The BARE library, which contains "definitions" for the sake of
documentation of the built-in functions used to define some command
characters, has a different loader function and so must be generated
in a special way. The command MM BARE Library
Generatesource-file-name will generate and write out the BARE
library. The difference in the loader function is simply that if a
function's definition is three characters long or fewer then it is
treated as the name of a command character (as in .^RA for C-A) and
that character's initial raw-TECO definition is returned instead. If
the function's definition as found in the ordinary way is longer than
three characters, it really is the definition. This way,
documentation strings act normally but the command names themselves
can return the raw TECO commands as their definitions. BARE has a
~INVERT~ function which knows how to find the names of raw TECO
commands as well as strings in the library. However, & Macro Name has
to know specially that such commands, which are positive numbers
rather than strings, should be passed to the BARE library to invert.
File: CONV Node: Prog, Up: Top, Previous: Lib, Next: Buffers
Programming Conventions
For good programming practise, every CRLF that is not
part of a string argument should be followed by an indentation
to a position that indicates the current depth in iterations
and conditionals. Use of the Tab command will make this easy.
Since the FS S ERROR flag is normally set in EMACS, searches that
are followed by ";" must always be given the ":" modifier; otherwise,
they will cause errors when they fail, before noticing the ";". This
is because, if FS S ERROR is not set, a user who types an iteration
in the minibuffer and omits the ";" is likely to cause himself extreme
lossage. The Tab TECO command is disabled in the EMACS environment,
and is a no-op. Use 9I or I^]^Q<tab> to insert a tab.
Calling Subroutines
Use named subroutines whenever convenient. The subroutine
should usually have documentation beginning with "S "
so that users doing a "List Commands" will not see it, and
a name beginning with "& " so that it will not interfere with the
user's attempt to abbreviate command names.
Call the subroutine with M( M.M&_Subroutine) (note the
_ is used to get a space). MM&_Subroutine would work, but
functions are not supposed to depend on having no-dot q-regs
set up.
Use M.A to run a function in a specific library, loading the library
temporarily if necessary. For example: M(M.A DIRED& DIRED Enter)
calls the function & DIRED Enter in the DIRED library. M.A is
analogous to M.M. Both M.A and M.M accept a variable named MM Foo as
a definition of the function named Foo, and this takes precedence over
an actual definition of Foo in a loaded library.
^R Mode
The normal EMACS command level is precisely the TECO ^R command,
with characters redefined to run EMACS functions or user-supplied
functions. All of the information in TECORD on the ^R command,
facilities available for functions which are definitions of
characters, and what values should be returned by such functions, are
very important for anyone who writes functions which are to be placed
on characters.
The Mark
The mark is kept in TECO's "Ring buffer of point". It's value can
be obtained with :^V with no argument; <arg>:^V will push a new value
of the mark. ^V with no colon can be used to pop the mark (read TECO
ORDER for details). One consequence of this scheme is that there is
always a mark somewhere. Note that the C-W EMACS command POPS the
mark, rather than leaving a useless mark at point.
Recursive Editing Levels
A recursive editing level is implemented by the TECO command ^R.
Commands that call ^R on data that the user is likely not to regard
as "the thing he is editing" should do 0[..F before the ^R, to turn
off auto-saving, and inhibit window, buffer or file switching (either
of which would cause garbage results if allowed to proceed). See the
& Check Top Level subroutine. They should also bind the default
filenames to GAZONK .DEL, which will prevent the user from screwing
himself with a C-X C-W.
No non-dotted Q-regs should be reserved by functions, except for
user interfaces like MM. Also, avoid using double-dot Q-regs except
as defined in TECORD. All temporary Q-regs should be pushed and
popped. All functions should return with ^\ if possible, except for
those like M.A which need to leave something on the stack to be popped
later.
Numeric Arguments
The TECO commands ^X and ^Y refer to the values of the precomma and
postcomma arguments. (A function invoked with a character command
gets only a postcomma argument). If there was no argument, the
default value (zero or one, depending) is returned. To find out
whether there was an argument, use F^XF^Y.
F^XF^Y"N succeeds if there was an explicit argument (C-U or
otherwise). This makes it convenient to use the function as a
subroutine, since then one can give it any argument to mean
"C-U", and no argument to mean "no C-U". F^XF^Y can also be used to
check individually for precomma arguments or postcomma arguments.
The Mode Line
Anything that changes information which is displayed in the mode
line should do 1FS MODE CHANGE so that FS MODE MACRO will eventually
be run to update q-register ..J and thus the mode line.
Printing in the Echo Area
The @FT command can be used to print in the echo area. To clear the
echo area, do :I*^PC FS ECHO DISP. The echo area is normally
cleared after each command which uses it. If you want to print in the
echo area and prevent the message from being erased after the command,
you must set FS ECHO ACTIVE to zero after printing the message.
Reading Input
Commands that read input should do M.I before actually doing the FI
to read a character of input. M.I is in charge of prompting. It also
supplies a definition for FS HELP MAC that will handle the Help
character if it is typed at that time. The user may redefine .I if he
wishes to eliminate prompting, but even so he should still define all
his functions to use M.I so that other users will receive the behavior
they want. For more info on using M.I, do M-X Describe& Prepare for
Input.
M.I is useful for input read a character at a time. Other ways of
reading input are & Read Line, which reads a line terminated by a
Return, and & Minibuffer, which reads input allowing the user to edit
it in the minibuffer. See the code of those two functions for calling
conventions.
The TECO command F^K allows a function to take a string argument if
called with M-X, or read a line if invoked with a character command.
Do 1,F^KFoo:_ to read the argument in whichever fashion is
appropriate, prompting with "Foo: " if the argument is read from the
terminal, and return a pointer to the string containing the value.
This can be followed with a [1 command to store the string in
q-register 1.
File: CONV Node: Buffers, Up: Top, Previous: Prog, Next: Windows
EMACS Buffer Data Structures
An EMACS buffer is not the same thing as a TECO buffer object. A
TECO buffer an anonymous object which is a string stored in a special
way, so that it can be edited by the TECO program. It contains text,
the cursor location, and virtual boundaries, plus flags for modified
and read-only, and that is all. Selection is controlled by the
q-register ..O: whichever buffer object is put in ..O, that buffer
is the one edited by all TECO commands. An EMACS buffer is a more
complicated structure and a TECO buffer is just part of it.
All information about EMACS buffers is stored in a qvector called
the buffer table, which lives in q-register .B. This table contains a
sequence of variable-length entries, each describing one buffer. The
first word in each entry is its length in words; the next 12 have fixed
meanings; the remained describe the EMACS buffer's local variables, 2
words per variable. The index in words of the start of a buffer's
entry is called the buffer's index. The index of a buffer is needed
to access the components of the buffer's entry; but it can't be
expected to stay fixed while other buffers are selected, since a
buffer earlier in the table might have to make its entry larger to
create new local variables. Therefore, to remember one buffer for a
while, you must always use its name, not its index. Killing a buffer
that is not selected can change the current buffer's index! It knows
how to change the value of QBuffer Index if this happens.
An EMACS buffer has, among other things, a name, a TECO buffer, a
major mode, and visited filenames.
It also has a buffer number which identifies it uniquely from all
other buffers ever created earlier or later in the same EMACS. This
number is not the same as the buffer index. It is computed when the
buffer is created (by incrementing QNext Buffer Number) and
remembered while the buffer exists.
A buffer also has some "TECO-default filenames". These are not the
same in meaning to the visited filenames, though often they are equal.
When the buffer is selected, these names are made the TECO filename
defaults. When the buffer is deselected, the TECO filename defaults
are remembered here for the next selection.
Format of a Buffer Table Entry
Each fixed word in the buffer table entry has a symbolic name. These
names are just comments, so the numeric offset must be used as well,
but the name helps clarify the code and makes it easier to identify
places that need to be changed if the entry format is changed.
For example, to refer to the name of a buffer whose buffer index is in
Q1, you would write Q:.B(Q1+1!*Bufnam!)
Word 0: the length of this entry, in words.
Word 1!*bufnam!: the name of this buffer, a string.
Word 2!*bufvis!: the filenames visited in the buffer, a string, or 0.
Word 3!*bufmod!: the name of the major mode the buffer is in, a string, such as "LISP".
This may not be accurate for the buffer which is selected.
Word 4!*bufbuf!: the TECO buffer used to hold the text.
Word 5!*buftdf!: the TECO-default filenames remembered for this buffer.
They are 0 in a buffer that has never been selected.
This is not accurate for the buffer which is selected.
Word 6!*bufwin!: the FS WINDOW associated with the buffer.
This is not accurate for the buffer which is selected.
Word 7!*bufnum!: the buffer's buffer number.
Word 8!*bufdat!: the creation date of last file visited or saved.
This is used to give the warnings about files changed
on disk since they were visited.
Word 9!*bufver!: the version number of the last file read or written.
Word 10!*bufsav!: controlls auto-save for this buffer. Zero if no
auto saving. If 1, auto save as the visited file name.
Otherwise it should be a string which contains the names to
save as.
Word 11!*bufsiz!: the size of the buffer at the time of the last visit
or real save or auto save.
Word 12!*bufnwr!: the read protection flag for the buffer.
Positive means the buffer can be changed but the file cannot
be saved unless you insist. Negative means the buffer cannot
be changed.
Word 13!*buflcl!: the beginning of the local variables of the buffer.
Words 13,14: these describe one local variable of this buffer.
Word 13 is the string which is the variable's name.
Word 14 is the value. When the buffer is selected, this is
the global value. When the buffer is not selected, this is
the local value. The TECO command F^G is used for swapping
the local and global values of variables.
Words 15,16: the next local variable, etc.
The Current Buffer
The index of the current buffer is kept in QBuffer Index. All
information about it could be obtained from that through the buffer
table. However, the most important information is kept redundantly in
variables to be convenient to access. The name of the buffer is kept
in QBuffer Name, and the visited filenames are in QBuffer
Filenames, which will be zero if no file is visited. The current
major mode is in QMode, but looking at the name of the mode is
usually the wrong way to do something. The TECO buffer of the current
EMACS buffer can normally be found in ..O.
Switching between EMACS buffers officially is slow. For specific
temporary purposes, it is often enough to put an EMACS buffer's TECO
buffer object into Q..O temporarily so that the text of the buffer can
be manipulated. This is how Kill Some Buffers lets you examine a
buffer that you might want to kill.
Special Purpose Buffers
Often an EMACS subsystem will need to store data permanently.
Sometimes it is convenient to create a special EMACS buffer for this.
For example, TAGS keeps the tag table in a buffer called *TAGS*. This
allows the EMACS file visiting operations to be used as subroutines by
Visit Tag Table. It also allows the tag table to be selected by the
EMACS user when he wants to examine it.
Since M-. needs to look at the tag table, for efficiency a redundant
pointer to the TECO buffer object of the *TAGS* buffer is kept in a
variable. This saves M-. from having to search for the *TAGS* buffer
in the buffer table.
The convention for such special purpose buffers is that their names
start and end with stars.
The Previous Buffer
QPrevious Buffer contains the name of the buffer selected before
the current one. C-X B will use this as the default buffer to select.
Searching the Buffer Table
To refer to a buffer given its name or its buffer number, it is
necessary to search the buffer table, which contains the entries of
the buffers in order of creation. The subroutine & Find Buffer does
this. & Find File searches for a buffer visiting a given filename.
In either case, the buffer index is returned.
File: CONV Node: Windows, Up: Top, Previous: Buffers, Next: Complete
Data Structures for Two Window Mode
TECO can only deal with a single display window. When EMACS is in
two window mode, TECO is just displaying one buffer in a small window.
Only one EMACS buffer is selected, as always. Various information
about the buffer in the other window is remembered in a special set of
variables. Some information is kept which overrides what is
remembered in the buffer table, so that it is possible to select the
same buffer in both windows with different values of point, for
example.
When in two window mode, each window has several variables
describing its contents. Some of them are set up only when the window
is not selected; some are always valid. For window one, these are:
Window 1 Buffer the name of the EMACS buffer in window 1.
Window 1 Window the FS WINDOW setting for window 1. Valid only when
the window is not selected.
Window 1 Point the value of point in window 1. Valid only when the
window is not selected.
Window 1 Size the height of the window, in lines.
Window two has a similar set of variables. These variables stay
around when two window mode is left, so that if it is used again
things can be as they were before. To get information about either
window 1 or window 2, deciding which one at run time, put either
character (1 or 2) in a q-register such as Q1 and look at
QWindow_1_Buffer, etc.
In addition, there are these variables:
Other Window Buffer
the TECO buffer object of the EMACS buffer in the
other window.
Total Size the total size of the two windows plus the line
between them.
Default Size the setting of FS LINES in one window mode, saved
here while in two window mode.
To tell whether two window mode is in effect, see if QWindow 2
Size exists. If it does, two windows are being shown. This variable
can be killed with no loss of information when reentering one window
mode because its value can be deduced from QWindow 1 Size together
with QTotal Size. When two window mode is in effect, to tell which
window is selected, use FS TOPLINE. Window 1 is selected if it is
zero.
Redisplay of both windows when EMACS is continued is done by putting
& Multi-Window Refresh in FS REFRESH. This uses the variable QOther
Window Buffer to redisplay without having to do an EMACS buffer
switch.
File: CONV Node: Complete, Up: Top, Previous: Windows, Next: Vars
Completion
Completion is the feature whereby, when a command name is being read
in, Altmode and Space cause the appearance of characters determined by
the ones already read. It is possible to provide completion when
reading something other than a command name. Here is how.
The basic way to read something with completion is to use the F
command with the 8 bit set in its precomma argument. For example,
8,F Command:_
reads a command name with completion and returns it as a string.
To read something other than a command name, you must supply a table
of allowed strings. This table has the same form as the variable
table (that which lives in Q..Q): it is a qvector whose first element
is a number, the number of elements per entry, and whose following
elements are any number of entries. The first element of each entry
should be the string which is the name of the entry.
For completion's sake, it does not matter how long the entries are,
since only the name of each entry is used. The table can have one
element per entry, if its only purpose is completion. It can have
more than one element per entry if you wish. For example, the actual
variable table itself, which has three elements per entry, can be used
for completion of variable names.
Specify the table to be used for completion by putting it in the
variable CRL List before doing the F, and setting the 2 bit in the
argument to the F. Thus,
Q..Q[CRL_List
12.,F Variable_to_frobnicate:_
To allow the user to specify names which are not in the table, turn
on the 20. bit in the precomma argument. If this bit is set, the user
can type any string at all, followed by Return, and it will be
accepted. Only if the user types Altmode will it be rejected.
Normally, Return also rejects any string which is not in the table.
If you like, you can use Linefeed to specify names not in the table,
and make Return continue to insist on an existing name. To do this,
set the variable CRL Non-match Method to 4. (The normal behavior is
obtained with the value 2).
The 40. bit in the precomma arg says that Return should be allowed
as the first character typed. An empty string is returned as the
specified name.
You can additionally restrict completion to those names which start
with a prefix, at the same time making the prefix invisible to the
user (he does not have to type it, and does not see it echo). For
example, suppose your library LOSER uses variables with names such as
LOSER Object FOO to represent LOSER's definition of the object FOO.
Then you can read the name of a LOSER object with completion by doing
:I*LOSER_Object[CRL_Prefix
Q..Q[CRL_List
12.,F LOSER_Object:_
Then only variables with names starting with LOSER Object will be
considered. The user can type F and complete it to FOO; he does not
see the "LOSER Object" as part of the string, and just "FOO" is
returned.
You should set the variable CRL Name Type to a string which
describes what sort of name is being read. It is used as part of the
message printed if the user asks for help while typing the name.
The value of CRL Help is printed as additional help, after the
standard completion help, if that variable is not zero.
The hook CRL Name Lister allows you to customize the display done
if the user types "?" to list the possible completions of what he has
typed. It is called at two different times, with arguments to allow
it to distinguish the reason it was called.
For each possible completion, the CRL Name Lister is called once,
with a postcomma arg which is an index into the table in CRL List.
That table is also in Q.1 at the time. The function should insert
information about that name into the buffer beginning at point, and
include a CRLF at the end.
The function CRL Name Lister is called again after all the possible
completions have been processed. This time it will receive 1 as a
precomma arg. The text previously inserted in the temporary buffer
for all the alternatives is still there. The function might take the
opportunity to sort the list of names, or insert a heading.
File: CONV Node: Vars, Up: Top, Previous: Complete, Next: Major
Named Variable Conventions
EMACS makes extensive use of named variables, and provides features
for creating, destroying, editing, and listing them.
The basic way of getting the value of a named variable that already
exists is to do Q<name>. See TECORD for details. If you are
not sure whether a variable exists, you can do <default> FO..Q <name>
which will return the value if the variable exists, or <default> if
the variable does not exist. :FO can be used to tell whether a
variable exists. Any TECO command that can use a q-register, except
for ^], can also use an existing named variable if it is given the
name of the variable, surrounded by Altmodes, as the q-reg name.
Although TECO allows unambiguous abbreviations of the name to be used,
it is unwise to use abbreviations in a program.
To create a variable, do M.V<name>. Unlike Q and FO, M.V
deliberately does not handle abbreviations. It does discard leading
and trailing spaces (in a library source file, spaces and tabs are
deleted anyway, and to get a real space you must use "_"). If the
variable already exists, nothing will happen, but its value will be
returned. If it does not exist, it will be created with a value of 0,
and 0 will be returned.
<value>M.V<name> can also be used. This creates the variable if it
doesn't exist, but also in any case sets its value to <value>. The
value returned by the M.V will be <value>.
To give a variable a comment, use M.C<name><comment>. This sets
the variable's comment to <comment>, creating the variable first if
necessary. <value>M.C<name><comment> will set the variable to
<value> if it creates the variable. It will not change the value if
the variable already exists. This is NOT the same as what M.V does!
What M.C does is good for defaulting variables which are options,
whereas what M.V does is good for setting a variable for internal use
while making sure that it exists. M.C's value is the value of the
variable.
Sometimes it is more efficient for changing a variable's value to
redefine some command characters, instead of having one definition
which always checks the value of the variable. Do this by providing a
function to be run whenever the variable's value is changed. This function
is supplied by making it the variable's comment. Whenever the comment
begins with a "!" it is taken to be a function to be run in this manner.
The function is given the variable's new value as an argument. For
example, the comment could be "!! FS^rmdly" to copy the variable's
value into the FS ^R MDLY flag. This is (approximately) what is used
for the variable Auto Save Interval.
If you want a variable to be presented for editing by MM Edit
Options, you should give the variable a comment which starts with a
"*". If the variable is to have a function to run when it changes, and
so the comment must start with a "!", then the variable is an option
if the comment starts with "!*". NOTE: if you are not careful, the
TECO code to set up such a variable will contain "!*" which will be
taken as the beginning of a comment. Leaving a space (which will be
removed by compression) between the "!" and the "*" will prevent such
lossage. See where the file EINIT sets up such variables if this
isn't clear.
You can examine the value, and comment if any, of a variable by
doing MM Describe<name>, just as you would ask for the documentation
of a function.
Overriding Command Definitions
You can override the library definition of a function by defining
a variable named "MM " followed by the function name. M.M checks for
such a variable before looking the name up in the loaded libraries.
MM Compile installs the compiled function in just this way. A few such
MM variables are present in the default environment. This is to make
calling certain key subroutines more efficient; M.M takes less time
finding the variable than searching the libraries.
Listing and Killing Variables
To see a list of all existing variables, do MM List Variables with
a null string argument. Each variable's name and value (abbreviated
if too long) will be shown. A list of variables whose names contain
<string> can be seen by doing MM List Variables<string>.
To destroy a variable, do M(M.M Kill Variable)<name> to run
MM Kill Variable. This is necessary only in special situations.
Local Variables
Variables can be local to an individual buffer. To make a variable
local to the current buffer, do <value>M.L<name>. From then on,
setting the variable when the current buffer is selected will not
affect its global value, which other buffers will continue to see,
nor will changing that global value affect the local value. Each
buffer in which the variable is made local has its own value for the
variable, while all other buffers share one global value.
Doing M.L has the side-effect of creating the variable globally
with the value of 0 if it did not already exist globally. Local
variables will be created automatically when a file is visited which
contains a local modes specification at the end. They are also the
way in which major modes perform their redefinitions.
Not only variables, but q-registers as well, and command
character definitions, can be made local. To make a q-register
local, use the Make Local Q-register command, with the q-register name
as a string argument: M(M.M Make Local Q-reg)A makes QA local, and
M(M.M Make Local Q-reg).^RF makes the definition of Control-F local.
You can also make a TECO FS flag local by specifying "FS" followed by
the name of the flag as the "q-register" name. For example, M(M.M
Make Local Q-register)FSCTLMTA. Inside Major Mode functions, this
function is available as M.Q.
Temporary and Permanent Locals
There are two types of local variables: permanent ones and temporary
ones. The permanent ones have to be the first on the list; they
remain forever local in the buffer that has them. All others are
temporary; these disappear when you switch major modes. The locals
created by major modes are temporary, which is how one major mode gets
undone when a new one is selected. Other locals created by local mode
lists and by random use of M.L are also temporary.
The initial buffer is given a set of permanent local variables when
the EMACS environment is built. The way permanent locals are told
from temporary ones is that the number of permanent ones is kept in
the variable QInitial Local Count, and the first that many locals
are permanent.
When a new buffer is created, some or all of the locals of the
previously selected buffer are copied into it. If Default Major Mode
is empty, they are all copied (thus, the major mode is copied). If
Default Major Mode specifies a mode, then only the permanent locals
are copied into the new buffer. The value of Initial Local Count is
used to tell how many there are. Some of these locals are
reinitialized, however; and you can reinitialize others in the Buffer
Creation Hook.
To add a new permanent local to a buffer, use 2,M.L<varname>. This
adds a local at the front of the list instead of at the end, and
increments the value of Initial Local Count (which requires making IT
into a permanent local as well, if it isn't one already, but that
happens automatically).
To increase the set of permanent local variables of all buffers, you
can simply create a few locals in your init file with M.L and then
increase QInitial Local Count. This will give the initial buffer
extra locals, and all other buffers will get them through the copying.
To do this for all users at your site, you can modify & Load Essential
Environment at the end where it creates the standard set, to create a
few extra.
You can also cause each buffer to get extra permanent locals when it
is created, in the Buffer Creation Hook, by using 2,M.L inside it.
File: CONV Node: Major, Up: Top, Previous: Vars, Next: Submodes
Defining Major Modes.
Each major mode is embodied by a command, such as MM TECO Mode or
MM Lisp Mode. A major mode can be created simply by defining an
appropriate command. However, major mode commands must work in a
particular way.
Major modes make all their redefinitions by creating local
variables. This is how each buffer can have its own major mode.
Buffer switching does not consciously "switch" modes; it just swaps the
local variables, which has that effect.
The first thing which each major mode command must do is eliminate
the local variables, if any, made by the previous major mode. This is
done by calling M(M.M &_Init_Buffer_Locals). All local variables of
the current buffer, except those made when the buffer was created, are
killed, and the global values reassert themselves. In addition, &
Init Buffer Locals leaves Q.Q bound to the Make Local Q-register
command until the major mode command returns with .
Then, the major mode function should create any local variables and
local q-registers that it wants. Supplying a 1, argument to M.L
causes M.L to run much faster, assuming that the specified variable is
not already local. Example: 1,(:I*;) M.L Comment_Start. This is
recommended for cuatious use by major mode commands. Command
characters can be redefined by using M.Q, since character definitions
count as q-registers. Example: M.M ^R_Indent_for_Lisp M.Q ^^I makes
the Tab character local to the current buffer, and redefines it for
Lisp. The "1," argument can be used with M.Q also.
Many major modes have their own values of the delimiter dispatch
table Q..D. They construct these values by making Q..D a local
q-register, copying the value of Q..D that is lying around with
:I..D..D, and then changing the necessary entries with the
command MM & Alter ..D. This is so that any other changes to ..D made
by the user will not be discarded. A new ..D should be constructed
only the first time a mode is entered. It should be saved in a
variable such as Text ..D or Lisp ..D, and retrieved from there when
the mode is entered again. This way, if the user changes ..D with the
command Edit ..D, his changes remain in effect whenever he is in that
mode. He can also define the variable in advance in his initfile if
he knows that, whenever he is in a certain mode, he wants his ..D to
be just so.
Finally, the major mode function should do
1M(M.M &_Set_Mode_Line <mode name> ^\
& Set Mode Line makes the new mode appear in the mode line, and the 1
as argument tells it to do everything else appropriate for finishing
up the change of major mode: Setting the variable QMode, running
the value of <Mode> Mode Hook if it is defined.
Exiting with ^\ causes the binding of Q.Q, left by & Init Buffer
Locals, to be popped, as well as any other bindings made by the major
mode function.
File: CONV Node: Submodes, Up: Top, Previous: Major, Next: Prefix
Submodes and ..F
A submode is just a command which rebinds commands or variables and
then calls ^R recursively on the same buffer. A submode's name
usually starts with the word "Edit", as in "Edit Picture". Submodes
are to be distinguished from commands such as Edit ..D which call ^R
recursively on some other text.
For submodes to indicate that they are active, the variable Submode
is provided. Binding QSubmode to FOO causes [FOO] to appear in the
mode line after the name of the major mode. However, you must call
& Set Mode Line yourself before entering ^R, and you must do an FN
command to cause & Set Mode Line to be called on the way out (even if
you come out via a throw or an MM Top Level). Usually, the Edit FOO
submode will put FOO in the Submode variable.
Submodes need not bind ..F to zero. Because the buffer is not
bound, it works reasonably well to switch files, buffers or windows
inside a submode. However, you stay inside the submode when you
switch, which you may not like. Someday there may be a different
implementation of Submodes which makes them local to a buffer. In
fact, submodes are not fully worked out at this time.
File: CONV Node: Prefix, Up: Top, Previous: Submodes, Next: Hooks
Defining Prefix Characters.
An EMACS environment can contain any number of prefix characters,
although EMACS normally contains only one - C-X.
To define a prefix character, you must choose a place to put the
dispatch table for it. This can be a q-register or a variable. Call
MM Make Prefix Character<q-reg name> which returns a string which is
a definition of a prefix character which will look in the specified
q-register for the dispatch table. Then put this string into the
desired character's definition. Normally, dispatch tables are made 96
characters long. If you want Rubout to be available as a subcommand,
you must make it 128 characters long, which you can do by providing
128 as an argument to Make Prefix Character.
For example, a prefix character C-Y can be defined to dispatch
through q-register .Y by doing
M(M.M Make Prefix Character).Y U.Y
After this, you can define individual subcommands by doing things like
M.MFOO U:.Y(A) which puts MM FOO on C-Y A.
To use a variable to hold the dispatch table, first create the
variable using M.V. Then create the prefix chararacter definition by
calling MM Make Prefix Character, supplying the variable name
surrounded by quoted altmodes in place of a q-register name. For
example,
M.V My Prefix Table
M(M.M Make Prefix Character)My Prefix Table U.Y
The altmodes are quoted by characters so that they become part of
the argument to Make Prefix Character.
How Prefix Characters Dispatch.
All prefix characters made by Make Prefix Character, including the
initially present C-X, do their work by calling the contents of
q-register .P, providing the dispatch table as an argument. .P reads
the input character, extracts the definition of the subcommand, and
returns it. The prefix character itself then calls whatever .value P
returns. You are free to redefine .P to get different behavior, as
long as you respect the interface conventions. Take a look at the
source code for & Prefix Character Driver, which is the default
contents of .P.
Making Self-documentation Work for Prefix Characters.
In order for Where Is and Apropos to list all the ways a command can
be reached as a subcommand of a prefix character, all prefix
characters must be listed in QPrefix Char List. The value of this
variable is a string containing one line for each prefix character.
first on the line comes the way this prefix character should be named
when a command character is printed out (for example, "Control-X").
This is followed by two spaces (two, so that single spaces can be part
of the string to be printed) and a TECO expression which evaluates to
the dispatch table. For the default EMACS Control-X command, the
value of the string is "Control-X Q.X<crlf>".
File: CONV Node: Hooks, Up: Top, Previous: Prefix, Next: Novice
Hooks Provided by EMACS
EMACS offers several hooks in the form of variables whose values
will be executed, if nonzero, at specific times.
Buffer Creation Hook
This variable is executed when a new EMACS buffer is made by Select
Buffer, just after that buffer has been selected. If you wish to use
this to create local variables, you should see under "Temporary and
Permanent Locals" in *Note Locals: Vars.
The Buffer Creation Hook is not run when a buffer is created by
Append to Buffer. This is obviously wrong, but since the buffer thus
created is never actually selected, there is no easy way to fix this.
However, if the buffer is eventually selected, the Buffer Creation
Hook will be run then.
Buffer Selection Hook
This variable is executed whenever a buffer has just been selected.
It is most likely to be useful when made local to a particular buffer.
Buffer Deselection Hook
This variable is executed whenever a buffer is just about to be
deselected. It is most likely to be useful when made local to a
particular buffer.
Visit File Hook
This variable is executed whenever a file has been visited. All the
normal actions of visiting are already complete. It is also called
when the name of the visited file is changed by the commands Write
File and Set Visited Filename. In that case (change of name but the
text is not newly read in) an argument of 1 will be passed to the
function in Visit File Hook. In the case of actual visiting, the
argument will be zero.
Exit Hook
This variable is executed by the function & Exit EMACS, which is
called when EMACS is about to be exited other than momentarily. This
is in addition to auto saving and possibly a real save. A useful
thing to put in this hook might be MM Save All Files, if you want
that.
Exit to Superior Hook
This variable is executed by ^R Return to Superior after it calls
& Exit EMACS, but before it actually returns to the superior.
Return from Superior Hook
This variable is executed by ^R Return to Superior after EMACS is
continued by the superior.
Exit to Inferior Hook
This variable is executed by various Twenex-only commands that
invoke inferior forks, before they do so.
Return from Inferior Hook
This variable is executed by various Twenex-only commands that
invoke inferior forks, on return from the inferior fork. These
commands all run Exit to Inferior Hook before invoking the inferior.
Not all commands which invoke inferior forks run the two hooks. If
the fork is expected to return almost immediately, then the hooks are
not used. If the fork is expected to run indefinitely then the hooks
are executed.
Compile Command
This variable is executed to perform the compilation of the visited
file. It can find the filename in q-register 1, and it MUST exit with
.
After Compilation Hook
This variable is executed by M-X Compile after the compiler returns
to EMACS. The Return from Superior Hook or Return from Inferior Hook
is NOT executed. This hook only applies if Compile Command has not
been specified.
Set Mode Line Hook
This variable is executed by & Set Mode Line. When it is called,
the buffer contains the first part mode line as it is going to appear,
everything up to just before the closeparen. The Set Mode Line Hook
can insert text in the buffer to get it into the mode line at that
point. The purpose of this variable is to allow libraries which have
state variables to display them in the mode line. So that several
libraries can do this without interfering with each other, each
library should append its own hook to the variable Set Mode Line Hook
instead of setting it.
When Set Mode Line Hook is called, the currently selected TECO
buffer (which normally belongs to the selected EMACS buffer) can be
found in Q8.
<libname> Setup Hook
Each library's & Setup <libname> Library function should check for
the existence of a <libname> Setup Hook variable, using 0FO..Q. If
the variable exists and is nonzero, the setup function should execute
the variable INSTEAD of its normal actions.
<Mode> Mode Hook
Each major mode executes a mode hook variable after making its
normal redefinitions, but before updating the mode line. Mode hooks
can create additional local variables or local q-registers (including
local character command redefinitions).
Hooks on Variables
Each variable can have a hook to be executed when it is set. The
hook is stored in the variable's comment: if the comment starts with
an exclamation mark, then it is executed when the variable changes,
and the new value is supplied as an argument. The hook does not need
to change the actual value of the variable; that is done
automatically after the hook is finished. Unfortunately there is no
way for the hook to change the value of the variable.
Sometimes you want the hook for each of two variables to change the
other. To avoid an infinite recursion in hooks, bind F[VARMAC to
zero in each hook before setting the other variable.
If you want the variable to be an option also, the exclamation mark
can be followed with a star, followed by the real comment.
File: CONV Node: Novice, Up: Top, Previous: Hooks, Next: Dump
Creating Restricted EMACS Subsets for Beginners.
When dealing with large communities of beginning users, it is
sometimes desirable to give them limited subsets of EMACS, in which
commands that they are unlikely to want to use and might be confusing
to them are not allowed. This could be done simply with an init file
that redefined those commands to be undefined; however, this would
prevent the beginners from learning to use those commands. The NOVICE
library solves this problem by allowing the user to read about,
experiment and eventually re-enable the commands that were initially
disabled for him.
To set up a limited EMACS subset with NOVICE, the biggest piece of
work is to decide which commands you want to allow. Then you must
create the user's command profile, a file which says which commands
are enabled for him. This file contains 512 characters, one for each
EMACS command character, and each character of the file should be an
"E" to enable the EMACS command or a "D" to disable it. The file
should be named <hsname>;<uname> EPRFIL on ITS, or <user>EMACS.PROFILE
on Twenex.
Finally, you must make the user's init file load and invoke the
NOVICE library. This can be done with
M(M.M Load Library)NOVICE
M(M.M & Load Disable Profile)
Alternatively, the default init file at your site could do the work:
FS :EJPAGE[1 !* Remember what libraries we have.!
M(M.M Load Library)NOVICE !* Load this library.!
M(M.M & Load Disable Profile)"E !* try to process profile.!
Q1FS:EJ PAGE' !* If there is none, flush NOVICE.!
]1 !* restore q-reg 1.!
This discards the NOVICE library if it says that it does not find a
profile file for this user.
One way to create a profile file is to edit it with NOVICE. Load
NOVICE and then use the command Disable Command to turn off some
commands. This creates or modifies a profile file for you
automatically. To turn commands back on, try using them and answer
the questions appropriately. This also edits your profile. When you
are done, give a copy of that profile to the user you made it for.
You will probably want to delete the original!
File: CONV Node: Dump, Up: Top, Previous: Novice, Next: Build
Dumping an EMACS Environment.
Dumping an EMACS environment so that it can be loaded and run again
is no simple feat. Since the environment, when dumped (with @EJ),
contains absolute pointers into the main EMACS library, we must make
sure that when the environment is run again the same version of that
library will be at the same place in the address space. This is
accomplished by the Dump Environment command in the PURIFY library.
The Dump Environment command in the PURIFY library has the ability
to dump out an EMACS environment so that, when loaded, it will reload
the same libraries that were loaded at dumping time - the same
versions, even, if multiple versions of the libraries are maintained.
Before calling Dump Environment, you must decide which of the loaded
libraries are to be reloaded by the dump file. Given such a library,
called (say) "Mumble", you must set up a variable QMumble Library
Filename containing the filename to be used to reload that library.
This filename can contain a version number, if you are interested in
loading the same version as the dumped environment was made with (this
is necessary if any pointers to functions in that library exist in
q-registers or character definitions, etc.).
Only libraries for which such variables are created will be reloaded
by the dumped environment. Not all loaded libraries must be included,
but any which are not included must all have been loaded after the
ones which are included.
In addition, before calling Dump Environment you must specify the
TECO commands to be executed when the dump file is reloaded. This is
done by creating a variable named QMM & Startup Mumble, where Mumble
stands for the contents of QEditor Name. For EMACS, it is called
QMM & Startup EMACS. The QMM & Startup Mumble variable is killed
by Dump Environment, since it will be no use afterward. Actually, if
you wish, you can have a command named just & Startup Mumble in one of
the libraries to be reloaded by the dump file, instead.
The contents of q-register ..L when Dump Environment is called are
NOT used to initialize the dump file when it is reloaded. However,
they do persist in ..L when the reloaded dumped environment is
running, and if that job is stopped and restarted again, the ..L will
be used.
EMACS actually happens to make MM & Startup EMACS the same as ..L,
despite all the emphasis above on allowing them to be different. ..L
and & Startup EMACS both point to the function & Toplevel ^R, which
simply enters the TECO real-time editing mode. The user's init file
is executed after entering real-time editing. When the outermost
level of ^R mode is entered, the hook variable *Initialization* is
executed if it is nonzero, and also set to zero. Thus, it is only
done the first time the top level ^R is entered. When EMACS is
dumped, *Initialization* contains the TECO code to find, read and
execute the user's init file. The code to implement this is in the
TECO init file for EMACS, and in & Recursive ^R Set Mode.
If your EMACS init file takes a long time to run, you can use Dump
Environment yourself after running the init file. The QEMACS Library
Filename variable remains set up, so you need not worry about getting
the right version of it. You must create similar variables for any
other libraries you want loaded when the dump is restarted (Load
Library can make them for you automatically). Just provide a suitable
variable MM & Startup EMACS (or make that variable a copy of Q..L and
supply *Initialization*), and call Dump Environment.
If you do this, it is best not to call the default init file
from your own init file, but instead call it from the & Startup or the
*Initialization* variable. This way, various actions will be
performed when the dump is started, based on the terminal type, user
name and command string that you have at that time, rather than being
done when you build the dump, based on the terminal type, user name
and command line at the time the dump was built.
File: CONV Node: Build, Up: Top, Previous: Dump, Next: Wall Charts
How to Build and Dump a New EMACS
Before building a new dumped EMACS, you may wish to Generate
up-to-date versions of the essential libraries. This can be done by
M-X RunEINIT? Generate
However, there is no need to do this if the new versions of functions
to be changed are present in the patch files (see below).
The visible procedure for building a new EMACS is simply to do
EMACS
:NTECO
which runs NTECO using EMACS's TECO init file. On Twenex, simply run
TECO while connected to EMACS:. This leaves you in the
TECO top-level loop, typing TECO command strings, and should display
an EMACS-style mode line. Then, to dump the EMACS, type
MMRunPURIFYDump<filename>
which will dump the environment you have built. Then kill the job.
How Building and Dumping Work
Building a new EMACS environment has three phases: loading
libraries, creating the "essential environment" necessary for EMACS
functions to work at all, and making the default set of command
bindings. Two other minor operations are the loading of the patch
file, and the purification of variable names. The first phase is
straightforward: it simply loads the latest version of EMACS :EJ, and
also the EINIT library which contains the code for performing the rest
of the initialization.
Loading the essential environment is done by the & Load Essential
Environment command in EINIT. This sets up things like q-registers
.M, .L, .V, .A, etc. as well as the option variables which many
commands assume the existence of. Part of loading the essential
environment is loading the patch file EMACS;PATnnn >, which contains
corrected versions of functions changed since EMACS :EJ was generated.
nnn stands for the version number of EMACS; thus, different versions
can coexist with different patch files. The format of PATnnn is just
that of a library source file, with a function on each page. It is
read in and MM TCompile is done on each page of it. Thus, the
function definitions in the patch file exist as impure strings which
override the definitions in the library. Another file named
EMACS;PATCH > is also loaded. This file is intended to have site
specific changes, which are not generally expected to become obsolete
in the next version, wheras PATnnn's fixes will all be incorporated
therein.
Loading the default EMACS environment is done by & Load Default
Environment in EINIT. This is what defines C-N to run ^R Down Real.
The reason why it and & Load Essential Environment are not combined is
so that other command environments which use the EMACS execution
environment can be easily built. Building such an environment would
involve calling & Load Essential Environment, and then using something
else instead of & Load Default Environment. Also, loading the patch
files requires using the essential environment, and must precede
loading the default environment so that the command character
definitions use the patched versions of functions instead of the
original versions.
At the end of building the environment, the variable names are
purified. In order to save a few hundred words of impure core for all
users, the predefined variables' names and their comments are made to
live inside EMACS :EJ instead of in impure string space. The
necessary strings are created in the library by the special file VARS,
which is included in the generation of the library. It inserts the
strings into the EMACS :EJ file inside of another string, so that they
are conveniently out of the way. Then, the Purify Variables command
in EINIT is used to look at each variable and replace its impure name
with the corresponding pure string, if there is one.
How Stand-alone RMAIL and INFO are Built and Dumped.
Stand-alone INFO differs from an EMACS in that, on start-up, instead
of running the user's or the default init file, a particular procedure
(that of entering ^R-mode and then running MM INFO) is followed.
INFO is built by an EMACS init file which calls Dump Environment,
setting Editor Name to INFO and providing an appropriate MM & Startup
INFO function to be used to start up the dump file when it is reloaded.
On the practical level, the EMACS init file for INFO actually
dumps the INFO, instead of returning and letting the user dump it.
Stand-alone RMAIL differs from INFO because it is presumed that since
users will be doing things such as editing replies from Rmail, he probably
wants his EMACS init run. Therefore the program TS RMAIL actually just
loads an EMACS into itself, passing it the JCL string 2,MMRMAIL. The
argument of 2, is merely used to instruct Rmail to kill the job upon exit,
instead of returning into Emacs. The MM RMAIL command in Emacs just runs
the Rmail library, which by convention on ITS is kept in EMACS;[RMAI] >.
Effectively users could just as well enter EMACS themselves and run Rmail.
TS RMAIL is only there because many people seem to prefer thinking of it
as a different program.
The TRMAIL command is a version of RMAIL that runs in a bare Teco ^R
environment. It exists purely because RMAIL used to run that way
itself, and some RMAIL users who are not EMACS users want it that way.
TRMAIL must be dumped by a TECO init file to avoid getting the Emacs
character command definitions in the dumped library. The file
AI:EMACS1;RMAIL TECO must be loaded into a bare teco and executed to
do this.
New versions of stand-alone TRMAIL and INFO must be made for each new
TECO or EMACS version, just like new versions of the EMACS dump file.
The stand-alone TRMAIL and INFO always load up the current version of
the RMAIL and INFO libraries, rather than the version which was
current when they were dumped, so new TRMAIL and INFO dump files do not
generally need to be made when new versions of those libraries are
installed.
File: CONV Node: Wall Charts, Up: Top, Previous: Build, Next: Abstracts
Making Wall Charts
Wall Charts are made by M-X RunABSTRWall Chart<prefix chars>
with an empty buffer. This produces a wall chart in the buffer,
describing the environment as it exists. <prefix chars> is a list of
names of prefix characters, each of which should get a page describing
all of its subcommands. The prefix characters are named as if you
were accessing their definitions as q-registers, such as ".X" for
C-X. The names should be separated by Altmodes. Two Altmodes end the
list of prefix character names.
A vertically compressed and horizontally expanded wall chart that
packs two or three columns to a page can be made from the standard
wall chart using the function Wide Wall Chart, also in ABSTR. Start
with the standard wall chart in the buffer, then call the function.
When it is done, the buffer contains the wide chart instead.
Writing the Documentation Files EMACS CHART and EMACS DOC.
These two files are produced from the self-documentation strings
within EMACS by the functions in the library ABSTR. Simply doing
M-X RunEINIT? Document
will update them according to the current environment. Make sure that
you do this as a user who does not have an init file! Otherwise, the
files will reflect your command definitions rather than the default.
File: CONV Node: Abstracts, Up: Top, Previous: Wall Charts, Next: Qregs
Library Abstracts, Source Listings and Source Indexes
Library Abstracts are a form of automatically generated
documentation files for libraries. Source listings and indices are
files useful in hardcopy form for studying code. This node tells
about making all three.
An abstract of a library is a file of the documentation of all the
commands in the library. Abstracts are useful for documentation of
the library. They can follow the order of the functions in the library
itself or can be alphabetized.
To make an abstract, load the ABSTR library and then call either
Abstract Library or Alphabetical Abstract. Abstract File makes an
abstract using the order functions appear in the library sources;
usually this order is a logical classification of the functions if the
sources are arranged carefully. It takes three arguments; a name
prefix, a documentation prefix, and the library name. The name prefix
and documentation prefix are used as filters; only functions whose
name and documentation start with those prefixes are included in the
abstract. The prefixes can be null.
Alphabetical Abstract takes just a library filename as its argument,
and abstracts all functions in the library. The functions are first
sorted by documentation class (S, C or ^R) and then alphabetically
within each class.
Listings of TECO Code
There are two ways to make a listing of TECO code.
One is the function @ TECO, in the PURIFY library. This function
takes the library file name as a string argument and writes an XGP
listing as <working dir>;<library name> XGP. You can supply a font
name as a second string argument and a number of lines per page as a
numeric argument.
If you don't have an XGP or anything that can print XGP files, you
can use instead two functions in the TMACS library. Load the TECO
source file into EMACS, then do M-X Run LibraryTMACSUncontrolify.
This replaces each control character with an "^" and a letter.
Then do M-X Run LibraryTMACSSave Trees. This combines consecutive
short pages together so that the listing uses fewer pages. Otherwise,
each function would come out on a separate page of the listing, which
would be very wasteful for the many small functions that often exist.
After Save Trees, the listing is now in the buffer.
Source Indexes
A source index describes the contents of several TECO source files.
It is sorted alphabetically by function name and says which file each
function is in. It is useful for studying listings of those source
files.
To make a source index, create a buffer and put in it the names of
the source files, one filename per line. Then load ABSTR and call
Make Source Index. When it is finished, the buffer contains the
source index.
File: CONV Node: Qregs, Up: Top, Previous: Abstracts, Next: FS^RPREV
Usage of Q-registers in EMACS and Functions Intended for EMACS
EMACS makes no use of non-dot q-regs except as saved and restored
local variables, unless the user explicitly requests such use with
(say) C-X X, except for M and R, and even those are not depended on by
the EMACS functions. User functions may use non-dot q-regs freely,
but those intended for general use should not do so except as local
variables (pushed and popped).
User functions should not use single or double dot q-regs except as
listed here. If it is really essential, you should ask RMS to
allocate another single-dot q-reg for a specific use. Normally, a
named variable is just as good.
.A MM & Autoload. This function loads a library temporarily
and returns a pointer to a specified function in it.
For example, M.A DIREDClean Dir loads the DIRED
library and returns a pointer to the Clean Dir function
in it. FS :EJPAGE is pushed and left on the stack,
so that the library will be flushed when the function
which invoked M.A exits and unwinds the stack.
.B The buffer table. This is a q-vector which is
subdivided into a section for each EMACS named buffer.
The details of the format are described in a comment
at the front of the EMACS source file BUFFER.
.C Set Variable Comment.
Like .V, but creates a comment for the variable.
<val>M.C <var> <comment> creates <var> if necessary,
giving it the comment <comment> and the value <val>.
<val> defaults to 0. If the comment starts with
"*", then the variable is an "option"
and MM Alter Options will let the user edit it.
.F The "normal" (top-level) contents of ..F.
When .F and ..F are not the same, EMACS knows that
it is not safe to switch buffers, windows or files.
.F should not be zero; that would lose. See ..F.
.H The horizontal position "goal" for ^N and ^P
commands. If it is a small positive number, it
is a temporary goal, which will be reset by
each ^N or ^P not following another such. The
other possible values in .H are 1000000. plus a
small number, which indicates a semipermanent goal
that was established by ^R Set Goal Column and
which it alone can alter.
.I & Prepare for Input. Do M.I before doing an
FI to read input. The second argument, if any
is the character to prompt with (default is in Q..0).
The first argument is bit-decoded: 1 means that
the control and meta prefix characters should be
noticed, and 2 suppresses prompting and echoing
(acts as if the characater being read is an independent
command).
.L Make Local Variable. Do M.L <var> to make <var>
into a local variable of the current buffer.
If it already is local, nothing is changed. If
<var> didn't exist at all, 0M.V <var> is implied.
The global value of <var> is not changed; the local
<var> starts off with that same value as well.
If M.L is given a numeric argument, it becomes
the new value of the (local) <var>.
.M & Macro Get. M.M<name> returns a pointer to
the function <name>. Normally, an error will
occur if the name is undefined or ambiguous,
but if 1, is given as argument, instead of an error,
the value 0 or 1 will be returned. Independently,
a pointer to a file can be given as an argument,
and the function will be looked for in that file.
.N The ring buffer of minibuffer commands. All commands
that use the minibuffer and execute its contents
normally push their commands onto this ring,
so you can run them again easily. Q.N is a q-vector
whose 0th element is the most recent minibuffer.
.P M.P is the driver for prefix commands such as C-X
which read another character and dispatch on it.
Whatever you put in .P should work like what is
usually put there: & Prefix Character Driver.
See Make Prefix Character.
.Q Inside major mode functions, this contains the
function Make Local Q-register.
.V Named Variable maker. (Teco "altmode" Q-regs)
.W Is a flag that determines whether the word commands
refer to LISP atoms. It holds either a null string
(if they do not) or an "@" (if they do).
.X Is the dispatch table for the C-X prefix command.
It is a qvector 128 elements long, indexed by
subcommand. This is only in the default environment.
If you build a completely separate environment, .X
is available.
..F normally holds the auto-filing secretary function.
Auto-saving is turned off by zeroing FS ^R MDLY,
not by changing ..F. Normally, .F contains the
same thing as ..F. Functions which call ^R recursively
should bind ..F to 0, thus inhibiting auto-saving.
Also, the fact that .F and ..F will then be different
will serve as an indication that it is not safe to
switch buffers, files or windows. If you use a
modified version of the secretary function, you must
store it in both ..F and .F for proper operation.
To turn off the secretary function globally, you should
not simply set .F and ..F to zero, because then the
functions that bind ..F to zero will not make it
different from .F. You must make a null string and
put it in .F and ..F.
..K A qvector used to hold strings of deleted text
by the ^R Kill ... and ^R Un-kill commands.
The elements are the strings, in the order they
were killed. The beginning may be filled with zeros,
if there are not enough remembered killed strings
to use the whole qvector.
..M holds the keyboard macro call stack.
See the file KBDMAC.
..U holds the data base for the Undo command.
It is a qvector containing these 5 objects which
describe the most recent undoable change.
:..U(0) is the buffer in which the change was made.
:..U(1) is the text that was deleted.
:..U(2) is the number of characters which preceded
that text.
:..U(3) is the number which followed that text.
:..U(4) is a string like "kill" or "sort" which says
what sort of operation made the change.
File: CONV Node: FS^RPREV, Up: Top, Previous: Qregs, Next: Debug
FS ^R LAST / FS ^R PREV Convention
Some commands set FS ^R LAST to a special value not in
the range of 9-bit characters, to make it possible to test
whether the previous command was in a certain class without
having to know which characters various functions are on.
These are the values used:
512+27 is set at times in minibuffering, when the
(1033 octal) most recent character was an altmode but a
following altmode should not exit.
1001 (decimal) is set by deleting commands.
This allows multiple consecutive deletions
to be combined in the ..K ring.
1002 is set by the vertical-motion commands
so that repeated vertical motion commands
can use the same horizontal position as a goal.
1003 signals that it is OK for m-Y (^R Un-kill Pop)
to work even though the current region is not
on the kill-ring. This is used by commands like
Fill Region which save the region then do a simple
but possibly dangerous transformation to it.
File: CONV Node: Debug, Up: Top, Previous: FS^RPREV
Debugging
For debugging, make use of the function TCompile, which compresses
the definition of the function you are pointing at and makes it
available to M.M. This makes it possible to test a new version of a
function without purifying the whole file containing it. Insert a ^R
command into the definition to make a "breakpoint" which will allow
you to look around. Exiting the ^R will cause execution of the
function to resume. To test-compile the function and put it on a
character, use the fact that TCompile returns the definition as its
value; thus, do MM TcompileU.N to set C-N's definition.
The default EMACS error handler runs MM Backtrace after every
error, if the first character you type is "?". Inside the backtrace
you can examine the functions on the call stack, look at the buffer
being edited, and resume execution either at the place it stopped or
elsewhere. To find out the details of how, type "?" while inside
Backtrace. If QDebug is nonzero, you can type "?" to get a
backtrace after a quit as well as after an error.
*note TDEBUG: (TDEBUG)Top, for info on the superb TDEBUG package
which allows you to step through the execution of a function,
and examine the macro and q-register pdls.
Tag Table:
File: CONV Node: Top35
File: CONV Node: Init1665
File: CONV Node: Syntax5602
File: CONV Node: Lib12218
File: CONV Node: Prog18380
File: CONV Node: Buffers24348
File: CONV Node: Windows31266
File: CONV Node: Complete33712
File: CONV Node: Vars37986
File: CONV Node: Major46077
File: CONV Node: Submodes49076
File: CONV Node: Prefix50339
File: CONV Node: Hooks53236
File: CONV Node: Novice58568
File: CONV Node: Dump60839
File: CONV Node: Build64999
File: CONV Node: Wall Charts70990
File: CONV Node: Abstracts72391
File: CONV Node: Qregs75261
File: CONV Node: FS^RPREV81375
File: CONV Node: Debug82430
End Tag Table