1
0
mirror of https://github.com/PDP-10/its.git synced 2026-03-05 02:54:55 +00:00

Generate some EMACS libraries with IVORY.

Except IVORY, there's also WORDAB and TMACS.  IVORY needs go be
generated with itself, so include the :EJ for bootstrapping.
This commit is contained in:
Lars Brinkhoff
2016-12-08 14:38:38 +01:00
committed by Eric Swenson
parent 6b0bad5dc8
commit d68aae0339
9 changed files with 3909 additions and 0 deletions

BIN
bin/emacs/ivory.:ej Executable file

Binary file not shown.

View File

@@ -237,6 +237,16 @@ respond "&" "mmrun\033purify\033dump\033ts 126\033\033"
respond "&" "\003"
respond "*" ":kill\r"
# BABYL, BABYLM, CACHE, FIXLIB, IVORY, MKDUMP, OUTLINE-MODE, PL1,
# TEACH-C100, TMACS and WORDAB are generated with IVORY.
respond "*" ":emacs\r"
respond "EMACS Editor" "\033xload\033ivory\r"
respond "\n" "\033xgenerate\033emacs;ivory\033emacs1;ivory\r"
respond ":EJ" "\033xgenerate\033emacs;wordab\033emacs1;wordab\r"
respond ":EJ" "\033xgenerate\033emacs;tmacs\033emacs1;tmacs\033tmucs\r"
respond ":EJ" "\030\003"
respond "*" ":kill\r"
respond "*" ":midas sysbin;_syseng;dump\r"
respond "WHICH MACHINE?" "DB\r"
expect ":KILL"

321
doc/info/ivory.6 Executable file
View File

@@ -0,0 +1,321 @@
-*-Text-*-

Node: Top, Next: CommandAbstract, Up: (CONV)Top
The IVORY library is a alternative to the PURIFY library for
aiding the construction and maintenance of EMACS libraries. It
was originally developed so that source library code could be
executed without compressing, to aid debugging. This
necessitated certain changes from PURIFY's syntactic conventions,
especially regarding what whitespace can be compressed out.
Since its inception, though, it has grown to include various
features that aid in creating and editing library sources, e.g.
facilities for automatically generating some library setup
routines. This INFO node will briefly explain the differences
from PURIFY regarding syntax and give an abstract of the various
commands. Several of these commands are essentially the same as
their counterparts in PURIFY; they are in IVORY too just to allow
IVORY to be a substitute -- i.e. these commands are editing aids
and unrelated to compressing and purifying libraries. The IVORY
user should first familiarize himself with the general EMACS
source library conventions described in the CONV INFO file.
If you decide to use IVORY and want to receive messages about
changes to IVORY, you should place yourself on the IVORY@MIT-MC
mailing list. If you need assistance with this, send a message
to BUG-IVORY@MIT-MC asking someone to put you on the IVORY
mailing list.
And BUG-IVORY@MIT-MC is also where you should send bug
messages.
A special hack has been implemented to allow PURIFY format
libraries to be compressed in with IVORY libraries. For a library
FOO, if variable PURIFY Library FOO exists and is non-zero, the
library will be treated as a PURIFY library. IVORY knows about a
number of common PURIFY libraries already -- see M-X Generate Library.
Some syntax notes, differences from PURIFY:
Only comments and surrounding whitespace are compressed out.
PURIFY compresses out spaces and tabs; the user must force them by
using underscores and quoting. However IVORY cannot do this, as that
prevents uncompressed code from being executable. Thus IVORY will not
be able to compress out many spaces; only those surrounding comments
are clearly recognizable as compressable. Typically, these
uncompressed spaces increase code size by 5% to 12%.
Putting comments within string arguments is discouraged: it makes
the uncompressed code have different (undoubtedly wrong) semantics
from compressed code.
A macro may have multiple names. These must precede the macro
documentation string. They may be on separate lines if desired.
FF-CRLFs (formfeed carriage-return linefeed) separate functions in
the source file. PURIFY uses CRLF-FF-CRLF, but again that can force
incorrect semantics for executed source code. (In particular, for
strings which are M.M'd -- similar to documentation strings.) As with
PURIFY, to force FF-CRLF into a function, quote the FF with Control-Q
or Control-] Control-Q. E.g. ^]^Q^L^M^J.
Blank macros are ok, e.g. for formatting/commenting source files.
These macros must ONLY contain comments. No macro names, no code...
We remove all comments and surrounding whitespace BEFORE checking
the major syntax, and thus you may have comments, e.g. before a macro
name.
Unlike PURIFY, comments may contain :!, or : Space !, since
comments are removed before looking for :!s, and spaces are not
removed. However, having :!s in comments is discouraged -- : Space !
is recommended; this is so that simple commands may be written that
understand a little about source file structure, in particular
recognizing where names are.
As with PURIFY, to force a ! into command documentation, use a
Control-^ -- the compressor converts it to an !.
Suggested style, for fewer chances of weird bugs executing source
code: don't put apostrophes, double-quotes, or angle-brackets ('"<>)
into comments, or else balance them. Teco will not recognize that
these are in comments if it is scanning looking for them. To avoid
worrying about them, leave them out of comments. E.g. avoid:
!* If positive, don't do it.!
since Teco might find that ' as the end of a conditional. Note
though, that you may have to worry about a related problem -- even in
compressed code: If you have a string argument with one of these
characters in it, it is best to balance that character inside a
teco-label outside that command. E.g.:
qFoo Option"g
:i*The Foo option doesn't yet work. It will soon. fsErr'
will not work when the conditional is skipped -- Teco will think that
the conditional ends with "doesn" and will thus start executing "t
yet...". Correct code is:
qFoo Option"g
!"! :i*The Foo option doesn't yet work. It will soon. fsErr'
IVORY will do some automatic & Setup ... Library function creating
when you generate a library. Some of this is complicated, and the
user is referred to the description of the commands. But basically:
if you compress together several source libraries, and some of these
have their own & Setup... functions, these functions will
automatically be called by the main & Setup... function. Furthermore,
this main & Setup... will contain M.C commands to create and default
certain variables, called "declared variables". These are variables
listed at the beginning of various functions, in a "call" to & Declare
Load-Time Defaults, e.g.:
!Foo:! !C Do something...!
m(m.m& Declare Load-Time Defaults)
Foo Option, * Controls the action of M-X Foo: 5
Foo State,: 0

.....
When the library containing this function is generated, the Foo
function will NOT contain any call to & Declare Load-Time Defaults;
that will have been removed, and instead, the & Setup... function will
contain:
5M.CFoo Option* Controls the action of M-X Foo
0M.CFoo State
However, a & Declare Load-Time Defaults function does exist, so
that if this function's source is executed, the variables will be
created if necessary. Note that the "call" to declare these variables
must come before any code in the function -- this makes finding it
easier and more reliable. (Comments may precede it, since they are
removed before looking for it.)
Note that the & Setup... will not contain redundant M.Cs. Also,
the compressor will check each declaration it finds to ensure that all
declarations of the same variable actually are the same declaration --
same value, same comment.
Each variable declaration is of the form:
<w> <variable name> "," <w> <comment> ":" <w> <value>
<w> is any horizontal or vertical whitespace.
<comment> is a string. Quote any ":"s with the
2-character sequence Control-] Control-Q.
Quote any Altmodes or Control-]s with just a
Control-].
<value> may be either a number or string surrounded by
delimiters. Quotes should be avoided as
delimiters, so that the & Setup... code is
safer; we suggest you quote with the "|"
character as a rule. Quote Altmodes or Control-]s
with a Control-].
Sample specification:
Test Foo, * foo fah: 123
Test Oof, * fah foo: |hello there|
Test Num, Random string variable: |123|
Random Hook, 0 or a Teco program: sets random seed:
| m(m.m& Random Hook) |
Note that comments or string values may be more than one line long.
The & Setup... routine will have some automatically generated
documentation too: it will record information about the
generation of this library: who generated, on what machine, the
date, the exact source files. This information can be helpful to
maintainers who FTP an ITS library to a Twenex, where they would
like to have the version number of the library match the source
version; after they FTP it over, they can then describe & Setup...
and find out the proper version.
A final note: loading IVORY defines an incorrect-looking
subroutine, & File PURIFY Loaded, which is a signal to the M-X Teco
Mode command that "PURIFY has been loaded". This means that if you
have IVORY loaded, going into Teco mode will not then try to outsmart
you by loading PURIFY. IVORY contains all the Teco-editing functions
that Teco mode wants.
IVORY's source is on MIT-MC in EAK;IVORY > and is maintained by
Earl Killian <EAK at MIT-MC>, John Pershing <JPershing at BBNA>, and
Eugene Ciccarelli <ECC at MIT-AI>.
If you want to receive mail about IVORY (e.g. announcements of
new features or proposed changes), you should be on the mailing
list IVORY at MIT-MC. Reports of bugs should be mailed to
BUG-IVORY at MIT-MC.

Node: CommandAbstract, Previous: Top, Up: Top
Commands in file IVORY:
1Generate
C Make one :EJ file from just one source file.
Takes one string argument which is the source filename. If no string
argument is given, it defaults to the buffer filenames.
Generate Library
C Make one :EJ file from several source files.
Takes desired name for :EJ file as first string argument, followed by
the names of the input files. A null string argument
(altmode-altmode) ends the argument list.
The input files are all compressed and purified together. You are
told as each is compressed etc. However, if $Silent Running$ is
non-0 nothing is printed. (Good for ^Z ^Ping.)
Filename defaulting is sticky; input FN2's default to >; the output
FN2 to :EJ.
The defaults are restored after the macro is finished.
~FILENAME~ is taken from first file's ~FILENAME~. It must have one.
Other ~FILENAME~s are turned into "& Compressed foo Library:"s.
All "hidden" & SetUps (i.e. not of same name as object ~FILENAME~)
will be accumulated, and code to call them will be inserted at the
beginning of the first file's &Setup. If that file has no &Setup,
one will be created.
Also, the &Setup documentation will have a record (as part of its
documentation string) telling who generated the object, when, and
from what source files.
All "hidden" & Kills (i.e. not of same name as object ~FILENAME~) will
be accumulated and called from the main &Kill in a similar manner.
Note that all source libraries are always compressed, no COMPRS files
are created, and the destination library is always created.
For a given FN1, if variable PURIFY Library FN1 is non-zero, then
the file is assumed to be a PURIFY library.
No Key Test Load
C Test Load with Test Load Sets Keys bound to 0.
Thus Test Load will not offer to set any keys. Useful if running Test
Load over an entire library with many ^R commands.
Numeric arguments are passed along to Text Load.
Key Test Load
C Test Load with Test Load Sets Keys bound to 1.
Thus Test Load will offer to set keys.
Numeric arguments are passed along to Test Load.
Test Load
C Load any modified macros into MM-variables and ^R-keys.
A library source is in the buffer.
Compares each macro (compressed) with M.M-found version; if
different, puts the new macro (uncompressed) in an MM-variable.
If Test Load Sets Keys is non-0 (the default) and if the macro is an
^R one, user is asked which key to put it on. Rubout means do not
put it on any key. (any better?)
If a positive NUMARG is given, compressed macros are put into
MM-variables when differences are found. Negative NUMARG means
make uncompressed, without checking difference.
If a pre-comma ARG is given, the library is searched for a & Setup...
macro, which if found is macroed.
Flush Test Functions
C  mode on all (TEST) function names, then kill.
This is for killing sets of impure test functions created by
M-X Test Load.
String argument, if non-null, prunes the list.
The user is put into a recursive  mode on the list of all
MM-variable names which contain "(TEST)" and the string argument
if any.
The user may then trim the list further.
When the  is exited, those names that are left are killed.
Compress File
C Generate a PURIFY style COMPRS file from a source file.
STRARG1 is the COMPRS file.
STRARG2 is the source file. Filename defaulting is sticky left to
right.
(The second filename of the COMPRS file MUST be COMPRS.)
This command is useful for creating COMPRS files so people using the
standard EMACS purify package can GEN them into their libraries.
One tricky thing: it always leaves ^Ls on their own lines, even if
not there to begin with, since PURIFY will change CRLF ^L to ^L,
and CRLF CRLF ^L to CRLF ^L.
TecDoc
C Look up information on Teco commands.
String arg is command, e.g. MM TecdocF^B or MM TecdocFS HPOS.
Represent a control character with a "^" not followed by a space.
Spaces elsewhere are ignored.
For speed (of another TecDoc) it keeps TECORD in an EMACS buffer,
named *TECORD*. If you are worried about space, kill that buffer.
Giving TecDoc a numeric argument will inhibit use of the buffer.
The format of INFO;TECORD is understood. Type "?" for help.
List TECO FS Flags
C List names of all TECO FS flags.
^R Commands in file IVORY:
^R Ivory-Bound This Page
^R Even if already bounded.
Thus calling this always results in the same thing, unlike the normal
EMACS ^R Mark Page, which moves forward a page if already
bounded.
Uses IVORY-style definition of what a page is, i.e.:
<not-C-Q><C-L><CRLF>.
^R Forward TECO Conditional
^R Move past the ' matching the following ".
This ignores "s or 's inside comments.
^R Backward TECO Conditional
^R Move back past the " matching the preceding '.
This ignores "s or 's inside comments.
^R TQuote
^R Quote with ^] all altmodes and ^]'s in the region.
This is to aid quoting inside a string argument to a Teco command.

Local Modes:
Fill Column:65
End:

347
doc/info/tmacs.12 Executable file
View File

@@ -0,0 +1,347 @@
-*-TEXT-*-
This file describes the TMACS library, source in MC:EMACS1;TMACS >
and MC:EMACS1;TMUCS >. (TMUCS has some less frequently used
functions. Some users generate TMACS but not TMUCS into their
environments.)

Node: Top, Next: M-X Commands, Up: (EMACS)
TMACS is a library containing EMACS commands of various sorts, which
may be of occasional (or perhaps frequent) interest to the EMACS
community. This file describes each of the functions in TMACS, starting
here with the ones that are probably of most general interest. These are
summarized here; for full details see the next node.
M-X Type Mailing List<mailing list name><cr>
This command shows you who is on any ITS mailing list.
It will work from one ITS machine to another -- e.g. if you are on
AI, you can see MC's TMACS mailing list by doing:
M-X Type Mailing ListTMACS@MC<cr>
^R Select Buffer
This function is designed as a replacement for the standard List
Buffers on C-X C-B. This version will not only list the buffers,
but lets you select buffers in a recursive edit level on this list.
M-X Graph Buffer<cr> or ^R Buffer Graph
This function (called either by M-X or put on a key) shows you a
schematic picture of the buffer in the echo area, e.g.:
|----B-----==[==--]---Z------------------------------------------|
1 2 3 4 5 6 7 8 9
This shows the region, the window, any narrowing that has occured.
M-X =Abbrev<abbrev><full function name><cr>
This allows you to create abbreviations for function names that
you call via M-X. E.g. to make M-X LLL<cr> be an abbreviation for
M-X List Loaded Libraries<cr>, just do:
M-X =AbbrevLLLList Loaded Libraries<cr>
This works nicely with completion -- if you type M-X LLL you see:
M-X LLL = List Loaded Libraries giving you confirmation (though
you could just type M-X LLL<cr> and not bother to see it).
^R Draw Vertical Line
Draws a vertical line on the screen (but not modifying the
buffer), allowing you to line up things visually. Only works on
ITS machines.
* Menu:
* M-X Commands:: The functions in TMACS generally run by M-X.
* Character Commands:: The functions in TMACS generally put on keys.
* Subroutines:: Subroutines of interest to TECO programmers.
* Mail:: If you wish to get news about TMACS or complain.

Node: M-X Commands, Next: Character Commands, Up: Top
Commands in file TMACS:
Type Mailing List
C Prints an entry in ITS mailing list file.
This works on any ITS machine. (.MAIL.;NAMES > has the ITS mailing
lists.)
For instance, M-X Type Mailing Listbug-random-program<cr> will show
you who is on the bug-random-program mailing list on your machine.
If string argument is of form <name>@<site>, <site>:.MAIL.;NAMES is
used. Only final @ indicates site, so you can do something like:
M-X Type Mailing List$BUG-@@AI$
A numeric ARG limits depth of recursion on EQV-LIST members. (Default
depth is 3.)
<name>@<site> entries in EQV-LIST are not followed.
Prints "Done." when done, since it sometimes is slow.
Giving a pre-comma numeric argument inhibits done-printing, for
use as a subroutine.
Graph Buffer
C Call ^R Buffer Graph to show schematic of buffer.
=Abbrev
C Define or delete M-X abbreviations.
M-X =Abbrev$IF$Insert File$ will define M-X IF = Insert File$
to be M-X Insert File$, evaluated by name each time
M-X IF$ is used. Thus if a new Insert File is created or loaded,
that one will be used. This works nicely with command-completion.
C-U 0 M-X =Abbrev$IF$ and
C-U - M-X =Abbrev$IF$ will remove definition for M-X IF$.
Lock File
C Lock current buffer's file.
"Lock" the file in the current buffer by creating FN1 *LOCKED*.
Will complain if FN1 *LOCKED* already exists, and will tell who has it
locked (since FN1 *LOCKED* contains that person's xuname).
Fails the critical-race test.
This assumes that others will cooperate and use M-X Lock File$ and the
matching M-X Unlock File$.
Unlock File
C "Unlock" file in buffer locked by M-X Lock File.
Flush Variables
C Kill some variables specified by search string.
Kill variables whose name contains the string argument.
String argument actually is a TECO search string, and so you can flush
variables containing "foo" OR "bar" by using the string argument
"foobar".
The list to be flushed is typed, asking Y, N, or ^R?
N means abort, ^R allows editing of the list.
List unused ^R characters
C Unused C-, M-, and C-M- characters.
If numeric argument then list unused prefix commands.
0
C Does nothing, returns nothing...
...but is good for something:
If you want to give some Teco commands from the bottom of the screen,
you can call ^R Extended Command (or any such "Meta-X") and give the
Teco commands as the "string argument".
UnSAILify
C Turn SAIL file into readable form.
M-X UnSAILify interchanges underscore and backarrow; this is good for
mail.
1 M-X UnSAILify goes further and fixes lossage caused by image FTPing
a SAIL file.
Uncontrolify
C Turn control chars into uparrowed chars.
This is good for listing a file with control characters in it on a
line printer which would not show control characters well.
String argument is a string of characters NOT to change.
TABs are turned into spaces. CRLF pairs are left alone.
Abort Recursive Edit
C Abnormal exit from recursive editing command.
The recursive edit is exited and the command that invoked
it is aborted.
For a normal exit, you should use ^R Exit, NOT this command.
The command can put a string in Abort Resumption Message
to tell the user how to resume the command after aborting it.
If the option variable Less Asking is non-0, it won't
print any message or ask for confirmation.
Revert File
C Undo changes to a file.
Reads back the file being edited from disk
(or the most recent save file, if that isn't the same thing).
A numeric argument means ignore the Auto Save files.
A nonzero pre-comma argument waives confirmation.
If the option variable Less Asking is non-0, it won't ask
for confirmation either.
Save Trees
C Compress a listing with form feeds.
Replaces some ^L's in buffer by 4 blank lines, in an attempt
to fill all pages. Page length is an optional numeric
argument.
SRMail
C Summarize new mail and call RMAIL.
If there is no new mail, and the variable SRMAIL No New Mail Query
Exit is non-0, asks whether to exit or read mail.
Any string argument is passed to RMAIL.
Summarizing happens only if there is no string argument, i.e. you're
reading your mail in the normal way.
Nowhere Links
C Enters recursive ^R on links to nonexistant files
String argument is directory name (should end with semicolon).

Node: Character Commands, Next: Subroutines, Previous: M-X Commands, Up: Top
^R Commands in file TMACS:
^R Select Buffer
^R Display information about all buffers.
A recursive edit level is entered on a list of all buffers.
On exit the buffer on the current line is selected.
Point is initially on line of current buffer and space will exit (like
^R Exit), so this is very much like List Buffers but
combines listing with selecting in a way that does not involve
much typing or redisplay. * means modified, - means modified and
not auto-saved, . means current buffer, and $ means readonly.
D will mark buffer for deletion on exit,
S will mark buffer for saving on exit,
U will unmark buffer, and
~ will clear modified flags of buffer.
^R Buffer Graph
^R Show a scale schematic of buffer in echo area.
(You can also use M-X Graph Buffer<cr>.)
Draws something like the following in the echo area:
|----B-----==[==--]---Z------------------------------------------|
1 2 3 4 5 6 7 8 9
The |--...--| indicates the whole buffer, numbers approx tenths.
=== indicates the region.
B indicates the virtual buffer beginning.
Z indicates the virtual buffer end.
[---] indicates the window.
^R Draw Vertical Line
^R Draws from current hpos, not inserting.
Line drawn only in current window, and column printed at base of line.
This only works on ITS machines.
If any ARG given, is displacement from current hpos. E.g. -1 means
draw line through position one column left.
If C-U is specified, together with an ARG then ARG is an absolute
column. E.g. M-3 C-U as argument makes line in column 3. But
M-3 as argument makes line in column 3+current_column.
^R Auto Fill Comments
^R Refill the comment and its continuations.
To handle comment starts (or parts of them) that are repeated, e.g.
";;; " in Lisp, or perhaps "/*** " in Pl1, it will treat a duplicated
last character of the comment start or begin as part of the comment
beginning when merging comment lines.
^R Change Case Letter
^R Next <argument> letters, moving past.
Numeric argument negative means move left.
Fast, does not move gap.
^R Get Macro Name
^R Inserts macro name for char typed.
MARK is set before inserted name.
Handles bit and char prefixes, e.g. Meta-, ^X, unless:
Given a numeric argument, gets the name of a prefixer (e.g. metizer).
Impure-strings that are uncompressed macros are handled if their names
are present at the beginning of the macro.
Some characters run standard builtin functions whose names are found
in the BARE library. These work fine. Others which are not found
just insert their key names, e.g. Meta-O.
^R Argument
^R Put on digits, minus, and comma to get arguments
^R Break Line
^R Fill if too long, even out of Auto Fill mode.
Cursor may be anywhere within line.
Line will be broken (space inserted at margin) repeatedly until it
fits within the margins.
Uses ^R Auto-Fill Space.
^R Uppercase Last Word
^R Uppercase word(s) before point.
^R Lowercase Last Word
^R Lowercase word(s) before point.
^R Uppercase Last Initial
^R Capitalize word(s) before point.
^R Really Underline Word
^R Underline words using backspaces.
Numeric argument is number of words to underline.
Canonicalizes the underlining if the option Canonicalize Underlines
is non-0. (Multics-style canonicalization.)
If 0, it puts _<BS><letter> so that scopes don't show only the _.
^R Remove Word Underline
^R Removes underlining from NUMARG words.
^R Comma-Arg
^R Give pre- and post-comma arguments to a command.
Numeric argument becomes the pre-comma argument.
Any digits you type after this become post-comma arguments. They are
terminated by a non-digit, which is the ^R command called. If
there are no post-comma digits typed, there is only a pre-comma
argument.
Example (assuming this is on M-, and meta-digits are autoarguments):
Typing the following characters: M-1 2 3 M-, 4 5 6 M-X calls M-X
with arguments of 123,456 so you get "123,456 M-X".
Leaves ..0 set to char after the post-comma argument.

Node: Subroutines, Next: Mail, Previous: Character Commands, Up: Top
Subroutines in file TMACS:
^^ TMACS Error Handler
S Q..P: handles TECO errors.
If first character typed is "?" then Backtrace is called.
A space makes us exit, with no action.
If option TMACS Error Dispatch is non-0, some other characters may
be typed, in any order, ending with a space (no further action) or
"?" (enter Backtrace):
B Display the offending buffer.
D Directory Lister is run.
W Who caused this? -- type function's name.
Typing HELP character describes the error handler.
Quits are not handled at all unless QDebug is nonzero. That is so a
quit will cause the buffer and modeline to be restored and
redisplayed immediately.
A QRP error (q-register PDL overflow) will cause
automatic parital unwinding of the q-register PDL if you
type anything but Space. You can thus enter Backtrace etc.
& Set ..D
S Create a new ..D with chars in arg as break characters.
& Get 9-Bit Character Name
S Inserts pretty name for 9-bit ARG.
Example: 415. MM & Get 9-Bit$ inserts "Meta-CR".
An arg of "2," means say "^M" instead of "CR", etc, and ^B instead of
an alpha on TV's.
& Kill Prefixed Variable Names
S Kill some variables.
String argument is prefix for variable name. E.g. doing m(m.m& Kill
Prefixed Variable Names)Cache  will kill all variables whose
names start with "Cache ".
& Insert Prefixed Variable Names
S Insert some variable names.
String argument is prefix for variable name. One variable name to a
line.
E.g. m(m.m& Insert Prefixed Variable Names)MM  will insert the names
of all variables whose names start with "MM ".
Also see & Kill Prefixed Variable Names, and & List Prefixed Variable
Names.
# RMAIL R
S Edit and then send a reply to current message.
With 1st arg of 1, continues editing an outgoing message.
With 1st arg of 2, sends a (non-reply) message - different
initialization.
Uses its own buffer, *REPLY*, with Text and Auto Fill modes.
This must be put into $MM # RMAIL R$ to work.
& Temporarily _<BS> No Break
S Set so _ and BS are not breaks.
Pushes a ..N so definitions for _ and <BS> revert when caller exits.

Node: Mail, Previous: Subroutines, Up: Top
If you wish to be informed of changes to TMACS, asked about various
EMACS ideas being bandied about, or kept up-to-date on news about TMACS
commands, you can place yourself on the TMACS mailing list, which lives on
MIT-MC.
If you wish to make any suggestions about TMACS, or comments etc., you
can mail them to TMACS@MIT-MC. People on the TMACS mailing list get both
information and bug-reports. It is thus a more verbose (though not
terribly so) mailing list than INFO-EMACS.
The primary maintainers of TMACS are ECC@MIT-AI and EAK@MIT-MC, if you
want to be more selective in your suggestions.

584
doc/info/wordab.182 Executable file
View File

@@ -0,0 +1,584 @@
-*-Text-*-
This file documents the EMACS Word Abbrev Mode.

Node: Top, Next: Intro, Up: (EMACS)Top
Word Abbrev Mode allows the EMACS user to abbreviate text with a
single "word", with EMACS expanding the abbreviation automatically as
soon as you have finished the abbreviation, with control over
capitalization of the expanded string.
Abbrevs are also useful for correcting commonly misspelled or
mistyped words (e.g. "thier" could expand to "their"), and for
uppercasing words like "EMACS" (abbrev "emacs" could expand to
"EMACS").
To use this mode, load the WORDAB library and then do MM Word
Abbrev Mode$$:
MM Load Library$WORDAB$$
MM Word Abbrev Mode$$
0 MM Word Abbrev Mode$$ turns the mode off.
For example, in writing this doumentation I could have defined
"wam" to be an abbreviation for "word abbrev mode". After only
typing the letters "wam", I see just that, "wam", but if I then
finish the word by typing space or period or any of the text
break-characters, the "wam" is replaced by (and redisplays as) "word
abbrev mode". If I capitalize the abbrev, "Wam", the expansion is
capitalized: "Word abbrev mode". If I capitalize the whole abbrev,
WAM", each word in the expansion is capitalized: "Word Abbrev Mode".
In this particular example, though, I would define "wam" to expand to
"Word Abbrev Mode" since it is always to be capitalized.
Thus, I can type "I am in wam now" and end up with "I
am in Word Abbrev Mode now".
Word Abbrev Mode can interface with other modes, e.g. Text, LISP,
TECO, Auto Fill, PL1. Those modes (or the user) may redefine what
functions are to be called by characters; that will not interfere
with Word Abbrev Mode.
* Menu:
* Intro:: An introduction to Word Abbrev Mode.
* Kinds:: There are two kinds of abbrevs:
Global word abbrevs are active in all modes.
Mode word abbrevs are active in one mode.
* Defining:: You can add or delete abbrevs as you
think of them, define many at once
from a list, file a list of abbrev
definitions, and edit the current
definitions.
* Listing:: MM List Word Abbrevs$ lists currently
defined abbrevs.
* Unexpanding:: Correcting an expansion that you
didn't want.
* Expansions:: Expansions can be capitalized; prefixes and
suffixes can be "glued" on.
* Entry/Exit:: MM Word Abbrev Mode, user hooks.
* Other Modes:: Word Abbrev Mode tries to interface
gracefully to other modes without interfering.
Text break characters like space, return,
!@#$%^&*()-_+=,.<>/? etc. cause expansion of
abbreviations, unless otherwise specified.
In addition, they will do whatever they would
do if you weren't in Word Abbrev Mode.

Node: Intro, Next: Kinds, Previous: Top, Up: Top
Word Abbrev Mode is useful for abbreviating commonly-used or long words
or expressions, both to save typing and to avoid mispellings. The mode is
designed to appeal both to fast and slow typists. It is also designed to be
used in modes other than Text; for instance, LISP programmers could define
abbreviations for long function names.
There are two kinds of word abbreviations: mode and global. A mode word
abbrev will cause expansion in only one mode, while a global word abbrev will
cause expansion in all modes. If some abbrev is both a mode word abbrev for
the current mode and a global word abbrev, the mode word abbrev expansion
takes precedence.
For instance, you might want an abbrev "foo" for "find outer otter" in
TEXT mode, an abbrev "foo" for "FINAGLE-OPPOSING-OPINIONS" in LISP, and an
abbrev "foo" for "meta-syntactic variable" in any other mode (the global word
abbrev).
MM Word Abbrev Mode$ will enter Word Abbrev Mode and set up some
characters for handling abbreviations and expansions:
^X ^A:
Add a new mode abbrev, which will expand into the word
before point. Type the abbrev followed by a return. (You
can edit a little with rubout.) The abbrev must not contain
any break characters (just letters and digits). If you give
^X ^A an non-0 argument, N, the abbrev will expand into the
N words before point. A 0 argument means expand into the
text between MARK and point. A negative argument means kill
the abbrev typed -- it will no longer cause any expansions.
^X +:
Add a new global abbrev, which will expand into the word before
point. ^X + interprets its argument in the same way ^X ^A does.
^X U:
"Unexpand" -- change the last expansion that occurred back to its
abbreviation. Thus, if you typed something that you didn't want to
expand, but which did, type ^X U. E.g. if you type "foo." and it
expands to "fooooo.", typing ^X U will restore "foo.".
If you know ahead of time that "foo." will expand, and you don't want
it to, you can quote the text break character which terminates "foo"
with ^Q (type "foo^Q.").
Meta-':
If you have an abbrev "com" for "committee", and wish to write
"intercommittee.", you can separate the prefix "inter" from the
abbrev "com" by meta-', which will mark the end of the prefix with a
hyphen, so you have "inter-". Then type "com", getting "inter-com";
when "com." expands, it will note that a prefix has been marked, and
glue it on to the expansion, eliminating the hyphen, ending with
"intercommittee." as desired. Thus, you just type "inter", meta-',
"com.".
Listing Word Abbreviations:
MM List Word Abbrevs$ will list the abbreviations currently in use, both
global and mode, which might include:
ab: (Text) 3 "abbrev"
which identifies "ab" as a mode abbrev for "abbrev" in Text mode,
used 3 times. You might also see something like:
aw: 2 "always"
which identifies "aw" as a global abbrev for "always", used twice.
Changing Word Abbreviations:
You can redefine any abbrev simply by using ^X ^A or ^X + to define the
same abbrev. However, if you want to do a fair amount of redefining and/or
killing at once, you can use MM Edit Word Abbrevs$, which will put you into a
recursive ^R mode editing the abbrev definition list (the same format as MM
List Word Abbrevs prints). This can be useful for changing several abbrevs
from mode to global word abbrevs, for instance (editing out the "(...)" mode
specifications).
Some people like to define word abbrevs from a command:
MM Make Word Abbrev$foo$find outer otter$TEXT$ makes "foo" expand
to "find outer otter" in TEXT mode. Using "*" in place of "TEXT"
causes "foo" to expand in all modes.
Saving Word Abbreviations:
After adding or redefining word abbrevs, you can save the
definition list by using MM Write Word Abbrev File$<filename>$. (If
you don't specify a filename, the last one you specified, or WORDAB DEFNS
if none, is used.)
Later, e.g. in a new EMACS, you can define those same word
abbrevs by MM Read Word Abbrev File$<filename>$.
**********
Now that you've finished the introduction, I suggest that you
try Word Abbrev Mode out a bit, rather than reading more of this
INFO just now. Later, after you've got a feel for the mode, and
perhaps have some questions, you can come back to INFO and get more
details from the other nodes. To try it out, just do:
MM Load Library$WORDAB$
MM Word Abbrev Mode$

Node: Kinds, Next: Defining, Previous: Intro, Up: Top
There are two kinds of abbrevs: mode and global. Mode word abbrevs are
effective in only one mode, global word abbrevs in all modes. Abbrevs are
defined by EMACS variables:
$X <abbrev> <modename> Abbrev$ for a mode abbrev, and
$X <abbrev> * Abbrev$ for a global abbrev.
The variable contains the expansion string. Thus if the variable
$X longt Text Abbrev$ contains the string "Long Winded Thesis Title", then
in Text mode "longt" will expand to "Long Winded Thesis Title". If the
variable $X hufpuf * Abbrev$ contains the string "Much Longer Thesis
Title Which Can't Even Fit On A TR Cover's Side", then in any mode (unless
overridden by a mode abbrev) "hufpuf" will expand to....
The variable's "comment" (all variables can have comments
describing what they are for) is used to meter the usage of the
abbrev: the "comment" is a string representing the number of times
the abbrev has expanded. (E.g. it might be the string "4".) This
usage-count is shown by MM List Word Abbrevs$ and saved by MM Write
Word Abbrev File$, so that when the saved word abbrev definitions are
used to define abbrevs, the usage-counts start off where they were
before.
The command Sort Word Abbrevs will reorder a word abbrev
definition list (in the buffer) so that the most frequently used
abbrevs are listed first, rather than in alphabetical order.
Since abbrevs are just variables, you can make any abbrev local to a
buffer or file, or use MM Variable Apropos$ to list just those abbrevs that
contain some pattern (e.g. to list just the Text mode abbrevs, you could do:
MM Variable Apropos$ Text Abbrev$, just the globals: MM Variable Ap$* Ab$).

Node: Defining, Next: Listing, Previous: Kinds, Up: Top
Word abbrevs can be defined one at a time (adding them as you
think of them), or many at a time (from a definition list). Word
abbrev definitions, being EMACS variables, will stay around even if
you're not in Word Abbrev Mode at the moment.
Word abbrevs can be killed either singly, by editing the current
definition list, or by MM Kill All Word abbrevs$.
Here is a summary of the word abbrev defining commands. "+n"
refers to an explicit argument which is positive, "-n" an explicit
argument which is negative:
^X ^A: Define a mode abbrev for the word before point.
+n ^X ^A: Define a mode abbrev for the n words before point.
-n ^X ^A: Kill specified abbrev.
^X +: Define a global abbrev for the word before point.
+n ^X +: Define a global abbrev for the n words before point.
-n ^X +: Kill specified abbrev.
MM Define Word Abbrevs: Define word abbrevs from list in buffer.
MM Make Word Abbrev: Define one word abbrev from command's arguments.
MM Edit Word Abbrevs: Edit word abbrev definitions in a ^R mode.
MM Kill All Word Abbrevs: No word abbrevs are defined after this.
* Menu: More details about (re)defining word abbrevs.
* Add One:: ^X ^A will define an abbrev that expands only
in one mode (a mode abbrev). ^X + will
define an abbrev that expands in all modes (a
global abbrev). MM Make Word Abbrev is a
command to define one abbrev.
* Kill One:: ^X ^A with a negative argument will kill a
mode abbrev. ^X + with a negative argument
will kill a global abbrev.
* Define Many:: MM Define Word Abbrevs$ will add many abbrev
definitions from a list in the buffer.
* Edit:: MM Edit Word Abbrevs$ allows editing of the
current word abbrevs in a recursive ^R mode.
* Local Definitions:: Word abbrevs can be made local to a buffer or file.

Node: Add One, Next: Kill One, Up: Defining
^X ^A (^R Add Mode Word Abbrev) and ^X + (^R Add Global Word
Abbrev) define one abbrev, which will expand to n words before point,
or the region. The argument specification determines the expansion
string:
No argument given: expansion string starts with word before
point and continues to point.
Positive argument n given: expansion string starts with nth
word before point, and continues to point.
Zero argument given: expansion string is the region (between
pont and MARK).
There is one exception to the above expansion string specification:
If FS ^R Mark$ is set, the expansion string is all text
between point and FS ^R Mark$. Note that the standard EMACS
environment does not set FS ^R Mark$. FS ^R Mark$ is a Teco
mark, and is volatile: after setting it, it stays defined
only as long as you do not edit (i.e. you can only move).
^X ^A and ^X + will print the specified expansion string at the
bottom of the screen, unless it is too long, in which case the first
and last several letters of the expansion are printed. E.g. you
might see:
Text Abbrev for "this is the expansion":
or Global Abbrev for "here is another...":
Type the abbrev for that expansion, followed by a return. You
can edit a little with rubout, control-U (to erase everything typed),
and control-G (to abort the abbrev definition). The abbrev must not
contain any break characters (just letters and digits -- it must be a
"word").
If you are causing an existing abbrev to be redefined, you will
be told of the old expansion, and asked for confirmation: type "yes"
followed by return if you want to change the abbrev. Anything else
followed by return means no change.
If the abbrev is already defined as you are now specifying, you
will be told. The usage-count for the abbrev is left as it was, so
this becomes a no-op.
MM Make Word Abbrev$foo$find outer otter$TEXT$
will define "foo" to expand automatically to "find outer otter" when
in TEXT mode. If the third string argument is null, the current mode
is used. If the third string argument is "*", a global abbrev is
defined:
MM Make Word Abbrev$foo$find outer otter$$ -- for current mode,
MM Make Word Abbrev$foo$find outer otter$*$ -- for global.

Node: Kill One, Next: Define Many, Previous: Add One, Up: Defining
^X ^A (^R Add Mode Word Abbrev) and ^X + (^R Add Global Word
Abbrev) can also be used to kill a single word abbrev (mode or
global, respectively). Just give them a negative argument, and type
the abbrev to kill.
The character-commands ^R Kill Mode Word Abbrev, and ^R Kill
Global Word Abbrev exist, but are not attached to any characters or
^X-commands by default. If you want to avoid specifying negative
arguments to ^X ^A and ^X +, you should attach these commands to
characters. For instance, if you wanted to put the kill-mode-abbrev
command on Control-Meta-W and kill-global-abbrev on Meta-W, you
should go into mini-buffer and type:
m.m ^R Kill Mode Word Abbrev$ u...^RW
m.m ^R Kill Global Word Abbrev$ u..^RW $$
(The "..^R" means "Meta-", and the "...^R" means "Control-Meta-", in
Teco.)

Node: Define Many, Next: Edit, Previous: Kill One, Up: Defining
MM Read Word Abbrev File$<filename>$ will define all abbrevs
listed in the specified file. If no filename is given, it defaults
to the last one used by Read Word Abbrev File or Write Word Abbrev
File. The format of the file is the same as what MM List Word
Abbrevs$ prints, and is described below.
MM Write Word Abbrev File$<filename>$ will write a file with the
definitions of all current abbrevs. The filename defaults like that
for MM Read Word Abbrev File.
If you want a lower-level handle:
MM Define Word Abbrevs$ will define abbrevs from a definition
list in the buffer.
MM Insert Word Abbrevs$ will insert into the buffer a definition
list for the current abbrevs.
The format for word abbrev definition lists is:
<deflist> ::= null | <1def> CRLF <deflist>
<1def> ::= <abbrev> : <white> <optionals> <white> " <expansion> "
<optionals> ::= <optmode> <white> <optcount>
<optmode> ::= null | ( <modename> )
<optcount> ::= null | <usage-count>
<White> refers to spaces and tabs. There can be no colons in an
abbrev, though there can be quotes in the expansion. If <optmode> is
null, then the abbrev is to be global; otherwise it is for the mode named.

Node: Edit, Next: Local Definitions, Previous: Define Many, Up: Defining
MM Edit Word Abbrevs$ will place you in a recursive ^R mode,
editing the current word abbrev definition list. When that ^R mode
is exited (via C-M-C, or ^C^C), the current word abbrevs will be
redefined by the edited definition list: any abbrevs that have been
deleted from the list are killed, new ones added to the list are
defined, and old ones changed are modified.
In effect, after exiting the Edit Word Abbrev ^R mode, all
previously-defined word abbrevs are killed, and the edited list is
used to define new abbrevs.
Typing ^G will abort the Edit Word Abbrev ^R mode, without
killing or redefining any abbrevs.

Node: Local Definitions, Previous: Edit, Up: Defining
Word abbrevs can be made local to one buffer, or one file, since
the abbrevs are implemented as EMACS variables.
To have an abbrev local to a file, the last page of the file must
contain a "Local Modes" specification. For full documentation on how
files can have local variables and modes, see the INFO documentation
on EMACS, under the "Local Modes" section. As an example, consider a
TJ6 source file. At the end of the file, following a form-feed (^L),
you might have:
.comment Local Modes:
.comment Mode:Text
.comment Mode:Auto Fill
.comment X foo * Abbrev:this is an abbrev
.comment X oof * Abbrev:this is too
.comment End:
The ".comment"s force TJ6 to ignore these lines, while the "Local
Modes:" and "End:" tell EMACS that these are local mode and variable
specifications. These lines say that a buffer containing this file
should be put into Text and Auto Fill modes, that "foo" is a global
abbrev for "this is an abbrev", and that "oof" is a global abbrev for
"this is too".

Node: Listing, Next: Unexpanding, Previous: Defining, Up: Top
MM List Word Abbrevs$ will list all currently defined word
abbrevs. An abbrev "foo" that expands to "this is an abbrev" in TEXT
mode and has been expanded 3 times, will be listed by:
foo: (Text) 3 "this is an abbrev"
An abbrev "gfoo" which expands to "this is a global abbrev" in
all modes, expanded 11 times, will be listed by:
gfoo: 11 "this is a global abbrev"
Abbrevs that are local to a buffer other than the currently
selected one are not listed.

Node: Unexpanding, Next: Expansions, Previous: Listing, Up: Top
If you discover that a word expanded when you didn't mean it to
be an abbrev, you can "unexpand" it to its original word by ^X U (the
^R-command ^R Unexpand Last Word). You can unexpand even if you have
typed past the end of the expansion. However, unexpand is not a
stack mechanism: only the last expansion can be unexpanded.
As an example, assume that "v" expands to "very". You mean to
type the phrase "the velocity v is..." but at that point you see
"the velocity very is". Type ^X U, and you have "the velocity v is",
with the cursor after "is" where you want it.
Any line break or new-comment starting that happened because of
the expansion is undone, leaving you with the abbrev as originally
typed. E.g. if "mev" expands to "million electron volts", and you
are typing a LISP program:
(defun foo (a b) ;mev subr is used.
The "mev" is a subroutine name, so you want precisely "mev", but get:
(defun foo (a b) ;million
;electron
;volts subr
;is used.
So, with the cursor after "used.", type ^X U, and get back to:
(defun foo (a b) ;mev subr
;is used.
The cursor is still after "used.", as desired.

Node: Expansions, Next: Entry/Exit, Previous: Unexpanding, Up: Top
There are three expand functions: ^R Expand And Self-Insert,
^R Expand And Call Old Character, and ^R Expand Only. All three
check the word (if any) before point, expanding it if it is an
abbrev. They differ in what action they take after trying to expand:
^R Expand Only (C-M-Space) will do nothing after expanding,
allowing you to type a suffix for instance.
^R Expand And Call Old Char will do whatever the character did
outside of Word Abbrev Mode. For instance, if you had ^R LISP ) on
the character ")" before setting Word Abbrev Mode, then after
trying to expand, ")" will show you the matching "(".
^R Expand And Self-Insert will insert its character.
Both ^R Expand And Call Old Character, and ^R Expand And
Self-Insert will inhibit expansion if given an explicit argument. If
you know ahead of time that a word will expand, and you want to avoid
this, you can give the character following the word an argument, as
opposed to typing ^X U to unexpand the unwanted expansion. Thus, if
"foo" expands to "this here", and you want to type "foo bar", you
could type either:
foo bar^XU (let it expand, then unexpand)
or foo$1 bar (inhibit expanding by giving Space an
argument of 1)
If ^R Mark Word Abbrev Prefix (Meta-') has marked a prefix for
the expanded abbrev, the prefix will be "glued" on to the expansion
by deleting the "-" that ^R Mark Word Abbrev Prefix used to separate
prefix and abbrev. Thus, if "expn" expands to "expansion" and you
want "preexpansion", type:
pre$'expn (which will look like "pre-expn" before it expands)
If the first letter of the abbrev is capitalized, then the first
letter of the expansion is capitalized. If all letters of the abbrev
are capitalized, then the first letter of each word of the expansion
is capitalized.

Node: Entry/Exit, Next: Other Modes, Previous: Expansions, Up: Top
Entering Word Abbrev Mode:
MM Word Abbrev Mode$$ (Or non-zero argument.)
The default action is to define the following character-commands:
^X ^A runs ^R Add Mode Word Abbrev,
^X + runs ^R Add Global Word Abbrev,
M-' runs ^R Mark Word Abbrev Prefix,
C-M-Space runs ^R Expand Only, and
^XU runs ^R Unexpand Last Word.
However, if the variable $Word Abbrev Hook$ exists, its contents
will be executed, allowing the user to put the above commands on
whatever characters he or she desires.
After defining the above commands, or calling $Word Abbrev Hook$,
the text break characters are defined to cause expansions. Each of
the following chars:
~@#;$%^&*()-_=+[]\|:'"{},<.>/?, Space, Return, Tab, Excl
will run ^R Expand And Self-Insert, or ^R Expand And Call Old Character.
You can inhibit redefinition of any of the above characters by putting them
into the variable $Untouched By Word Abbrev$. E.g. if you do not want the
characters "-", "_", and "=" to run expansion commands, put the string "-_="
into $Untouched By Word Abbrev$.
Exiting Word Abbrev Mode:
0 MM Word Abbrev Mode$ will take you out of Word Abbrev Mode, and restore
all break characters to non-expanding commands. Again, if $Word Abbrev Hook$
exists, it will be called. Its argument is the zero for exiting Word Abbrev
Mode, and non-zero for entering.
Exiting Word Abbrev Mode will not cause the definitions of abbrevs to be
lost; it will just render them inactive.

Node: Other Modes, Previous: Entry/Exit, Up: Top
Word Abbrev Mode tries hard to interface gracefully to other modes, such
as Auto Fill, LISP, Text, TECO, Auto Save, etc. While in Word Abbrev Mode
you can change the other modes, and things should work out ok. If the mode
changing commands redefine any of the characters that Word Abbrev Mode uses,
that will be spotted and Word Abbrev Mode will put ^R Expand And Call Old
Character on that redefined character: it will first expand, then go do
whatever the mode wanted it to do.
This observation of character-redefinition happens when the subroutine
& Set Mode Line is called. This is called whenever a buffer is switched, or
a mode is changed. If you manually redefine a character, say by doing:
m.m ^R LISP )$ u^R) $$
then Word Abbrev Mode will not notice the change, since & Set Mode Line has
not yet been called. Thus ")" will not cause expansions. However, if you
later change modes or buffers, the change will be noticed, and ")" will start
expanding abbrevs as well as showing the matching "(". To force Word Abbrev
Mode to notice your manual redefinition, just do:
mm & Set Mode Line$$
You can specify to Word Abbrev Mode that it should not redefine
certain characters, by including those characters in the variable
$Untouched By Word Abbrev$. The following characters will be
redefined to cause expansions unless they are in that variable:
~@#;$%^&*()-_=+[]\|:'"{},<.>/?, Space, Return, Tab, Excl


BIN
src/emacs1/ivory.189 Executable file

Binary file not shown.

967
src/emacs1/tmacs.430 Executable file
View File

@@ -0,0 +1,967 @@
!* -*-TECO-*- *!
!* This is the EMACS library TMACS. Note that it requires the purifier in
* EMACS;IVORY -- not the one in EMACS;PURIFY.
* Note too that when making EMACS;TMACS :EJ, you need to compress this
* source and also TMUCS >. You can use M-X Compile, since this file
* has a local Compile Command, which leaves the object in ECC;XTMACS :EJ.
* The documentation strings starting with "I" indicate internal subroutines
* not intended to be called from outside TMACS.
* In general, for easy abstracting (Abstract File), the most generally
* useful stuff should be at the top. And, documentation should be filled
* with a Fill Column of 70. You can use (local to this file) M-X Edit TMACS
* Documentation.
*!
!~FILENAME~:! !Random collection of useful functions.!
TMACS
!Type Mailing List:! !C Prints an entry in ITS mailing list file.
This works on any ITS machine. (.MAIL.;NAMES > has the ITS mailing
lists.)
For instance, M-X Type Mailing Listbug-random-program<cr> will show
you who is on the bug-random-program mailing list on your machine.
If string argument is of form <name>@<site>, <site>:.MAIL.;NAMES is
used. Only final @ indicates site, so you can do something like:
M-X Type Mailing List$BUG-@@AI$
A numeric argument limits depth of recursion on EQV-LIST members.
(Default depth is 3.)
<name>@<site> entries in EQV-LIST are not followed.
Prints "Done." when done, since it sometimes is slow. Giving a
pre-comma numeric argument inhibits done-printing, for use as a
subroutine.!
:i* [.1 !* .1: Stringarg, the mailing list.!
[f[.2[.3[.4[.5 [..o
m.m& Maybe Flush Outputuf !* F: Flusher.!
0fo..qTML Levelu.5 !* .5: Our current invocation level.!
q.5+1-(ff&1"E 3 '"#  ')"G ' !* If recursed enuf, quit.!
mF  !* If output flushed, quit.!
q.5"E !* At top level, initialize.!
m.m Kill Variable !* K: Kill Var.!
qBuffer Name !* B: Original Buffer name.!
[Previous Buffer !* Save default.!
FN 1:< mKTML So far >w !* Kill our recursion-helpers if quit.!
1:< mKTML NAMES >w !* ...!
1:< mKTML Level >w !* ...!
qBm(m.mSelect Buffer) !* Back to original buffer.!
 !* End of FN.!
f[DFile !* Save filename defaults.!
q.1u.2 !* .2: Copy of mailing list name.!
< @f.2f(:;)+1,fq.2:g.2u.2 > !* .2: Stuff after final @.!
0,fq.1-fq.2-1:g.1u.1 !* .1: Stuff before final @.!
fq.1"E q.2u.1 !* .1: No @ present, is whole name.!
fsMachine :f6u.2' !* .2: No @, is machine name.!
!* .1: Name.!
q.2:fcu.2 !* .2: Site, uppercased.!
m(m.m Select Buffer)NAMES@.2 !* E.g. NAMES@ML.!
z"E @ftReading .2:.MAIL.;NAMES  !* May take a while, tell user.!
-1,1m(m.mVisit File).2:.MAIL.;NAMES > !* Read names !
' !* file if not in.!
q..o m.vTML NAMESw !* Pass it on to recursive calls.!
fsBCons m.vTML So farw !* Buffer for entries traced so far, so!
!* dont run into ugly-looking loops.!
%.5 m.vTML Levelw !* Make recursion-level counter.!
' !* End top level init.!
"# %.5 uTML Levelw' !* Increment level count if not top level.!
q..o[.7 !* .7: Buffer to restore point in.!
.[.6 !* .6: Original point.!
qTML So faru..o !* Switch to buf with entries traced.!
bj :s
.1
 "L oEXIT' !* Quit if weve traced it before.!
i
.1
 !* If havent, add it to list now.!
qTML NAMESu..o !* Switch to buffer with NAMES.!
bj <:s
(.1"E oEXIT' !* Find the entry. ) !
0af
([;> !* Must end with Lisp atom break.!
-ful !* Back to beginning of entry.!
flu.4w !* .4: End of entry.!
.,q.4x.2 !* .2: The whole entry.!
ft.2
 !* Type whole entry.!
.,q.4:fb(EQV-LIST"E oEXIT' !* Look for an eqv-list to expand. )!
fkc flu.4w !* .4: End of EQV-LIST.!
@ fwl !* Past the EQV-LIST atom.!
< .-q.4; !* Go thru EQV-LIST.!
mf1; !* Stop if output flushed.!
@:fll !* To next S-EXP.!
0,1a-("E @:fwl !* List: take first atom.!
@fwx.3 !* .3: atom to look up.!
fm(m.m Type Mailing List).3w !* Recurse.!
ful !<!>' !* Past end of list.!
0,1a-;"E l !<!>' !* Comment: skip it.!
0,1a-)"E q.4j !<!>' !* End of EQV-LIST, done.!
@fwx.3 @fwl !* .3: EQV-LIST member atom. !
fm(m.m Type Mailing List).3w !* Recurse.!
> !* Look up all members of EQV-LIST.!
!EXIT!
q.5-1u.5 !* .5: Decremented level count.!
q.5uTML Level
q.5"E !* At top level, cleanup.!
qTML So far fsBKill !* Kill the list of entries traced.!
mkTML So far !* Kill our recursion-helpers.!
mkTML NAMES !* ...!
mkTML Level !* ...!
ff&2"e fsListen"e ftDone.
 ' !* Type done only at top level.!
"# ftFlushed.
 ''' !* Done top-level cleanup.!
"# !* Not at top level, restore buffer.*!
q.7u..o !* Switch to original (+-) buffer.!
q.6j' !* Back to original point.!
w 1  !* Return.!
!^R Select Buffer:!!Buffer Menu:! !^R Display information about all buffers.
A recursive edit level is entered on a list of all buffers.
On exit the buffer on the current line is selected.
Point is initially on line of current buffer and space will exit (like
^R Exit), so this is very much like List Buffers but
combines listing with selecting in a way that does not involve
much typing or redisplay. * means modified, - means modified and not
auto-saved, and . means current buffer.
D will mark buffer for deletion on exit,
S will mark buffer for saving on exit,
U will unmark buffer, and
~ will clear modified flags of buffer.!
[0[1[2[3[4[5[6[7[8 !* save regs!
f[DFile !* save default filename!
fsQPPtru8 !* 8: point to unwind before!
!* selecting a different buffer!
fsBCons[..o !* get us a buffer!
i # Buffer (Mode) Filename
 2u7 !* 7: line count!
0u4 fq.b/5u5 !* 4: .B index, 5: stopping point!
< q4-q5; !* Go thru buffer table; stop at end!
q:.b(q4+4!*bufbuf!)[..o !* make the buffer current so can!
!* check modified, readonly, etc.!
0u1 !* 1: flag bits!
fsModified"n q11u1' !* 1&1: nonzero if modified!
q:.b(q4+10!*bufsav!)"N !* Ignored unless auto save mode.!
fsXModified"N q12u1'' !* 1&2: nonzero if Xmodified!
fsZu3 !* 3: no. of characters in buffer!
]..o !* back to listing buffer!
.u0 4,32i !* 0: start address of this line!
q1&1"n .-2f*' !* indicate if modified!
q1&2"n .-1f-' !* indicate if not auto saved!
2,q:.b(q4+7!*bufnum!)\ !* Type the buffer's number!
i  g:.b(q4+1!*bufnam!) !* Type buffer's name,!
17-(.-q0):f"gw 1',32i !* move to column 17!
q:.b(q4+3!*bufmod!)u1 !* 1: buffer's major mode!
qBuffer Index-q4"e !* if current buffer!
qModeu1 q0u6 !* then use current mode, and save .!
.( q0+3j 2a-32"e c' f. )j ' !* and put dot next to number!
i(1) !* Type major mode!
32-(.-q0):f"gw 1',32i !* move to column 32!
q:.b(q4+2!*bufvis!)u1 !* 1: visited filename!
q1"n g1 !* type filename if there is one!
et1 q:.b(q4+9!*bufver!)u2 !* get actual version number.!
fsDVersion:"g !* ...!
fsDVersion+1"n !* ...!
i ( g2 i)''' !* Print file version if valid.!
"# q3\ i Characters' !* No filename, type the size.!
q:.b(q4+12!*bufnwr!)u2 !* Say which if any read only modes.!
q2"g i File Read-Only' !* ...!
q2"l i Buffer Read-only' !* ...!
i
 %7w !* add CRLF, increment line count!
q:.b(q4)+q4u4 !* advance past this buffer!
>
q6"n q6j' !* goto line with current buffer!
fsLinesu6 q6"e fsHeight-(fsEchoLines)-1u6' !* 6: current fsLines!
q7+1-q6"l q7+1f[Lines' !* set fsLines so that only the amount!
!* of screen needed is used, reducing!
!* redisplay of rest of buffer.!
0f[Window !* start display at top!
0fs^RInitf[^RNormal !* make normals undefined!
33.fs^Rinit[ w !* space exits ^R mode!
:i*Buffer Menu[..j !* use reasonable mode line!
0[..F !* dont let user screw himself!
!* Now bind some keys for editing the buffer menu!
@:i*| 0f[Lines m(m.mDescribe)Buffer Menu h|f[HelpMac !* HELP: describe us!
@:i*| 0l @f DS*-.l \[1 q1"e 0l fg 1' !* 1: buffer number!
q1m(m.m& Find Buffer)u1 !* 1: buffer index!
q:.b(q1+4!*bufbuf!)[..o 0fsModifiedw 0fsXModifiedw ]..o
0l .+2f  .+2,.+4 |[~ !* ~: clear modified flag!
@:i*| 0l 0,1a-32"n fg 1' !* insure not already marked!
fD 1 |[D qD[.D !* D, c-D: mark buffer for deletion!
@:i*| 0l 0,1a-32"n fg 1' !* insure not already marked!
fS 1 |[S !* S: mark buffer for saving!
@:i*| 0l 0,1a-D"n 0,1a-S"n fg 1'' !* insure already marked!
f  1 |[U !* U: unmark buffer!
!BACK!  !* let user see buffer, and move!
!* around!
0l 0,1a-D"e fg oBACK' !* dont exit on marked buffer!
@f S*-.l \u1 !* 1: buffer index of new buffer!
q1"e fg oBACK' !* dont exit on no buffer.!
q..ou2 q8fsQPUnwind !* 2: buffer menu buffer!
!* cleanup all pushed stuff so that!
!* it isnt stored in .B after buffer!
!* selection!
q2[..o jl !* menu buffer, move past header!
< :s
 ; !* find first marked buffer!
0a-D"e @f *-.l \u3 q3"n !* D: kill it!
q3-q:.b(qBuffer Index+7)"e !* if killing selected buffer,!
q1"n ]..o q1m(m.mSelect Buffer)w q2[..o''
!* select new one first!
q3m(m.mKill Buffer)' !<!>'
0a-S"e @f *-.l \u3 q3"n !* S: save it!
]..o q3m(m.mSelect Buffer)
m(m.m^R Save File)w q2[..o' !<!>'
>
]..o !* restore selected buffer!
q1"n q1-q:.b(qBuffer Index+7)"n !* if new buffer index, and if!
!* different from current buffer!
q1m(m.mSelect Buffer)'' !* select new buffer!
q2fsBKill  !* kill menu buffer!
!Graph Buffer:! !C Call ^R Buffer Graph to show schematic of buffer.!
@m(m.m^R Buffer Graph)w  !* Return no values.!
!^R Buffer Graph:! !^R Show a scale schematic of buffer in echo area.
(You can also use M-X Graph Buffer<cr>.)
Draws something like the following in the echo area:
|----B-----==[==--]---Z------------------------------------------|
1 2 3 4 5 6 7 8 9
The |--...--| indicates the whole buffer, numbers approx tenths.
=== indicates the region.
B indicates the virtual buffer beginning.
Z indicates the virtual buffer end.
[---] indicates the window.!
[.0[.1[.2[.3[.4
:f !* Ensure a valid window.!
.u.3 fnq.3j !* .3, ..N: Point, restored autoly.!
fsWindow+bj !* Go to top of window.!
fsLines f"E fsHeight-(fsEchoLines+1)' u.0 !* .0: Height of window.!
1:< q.0-1,0 :fm :l > !* Go to end of last screen line.!
.u.4 !* .4: Window bottom.!
:i*CfsEchoDisplay !* Clear the echo area!
fsZ"E !* Special case empty buffer.!
@ft|mere corroborative padding intended to give artistic verisimilitude
to an otherwise bald and unconvincing buffer|
1 @v 0f[HelpMacro !* Allow HELP to get help here.!
:fi-4110."E fiw :i*CfsEchoDisplay
@ft(Semi-quote from "The Mikado", by Wm. Gilbert)

0fsEchoActivew
:ft !''!'
w 1 '
m.m& Buffer Dashes !* D: Dash macro. Uses qregs: !
!* .0: dash.!
!* .1: hpos.!
!* .2: last buffer pointer.!
!* .3: point.!
:i.0- !* .0: Start with - as dash.!
0u.1 !* .1: Start hpos = 0.!
-1u.2 !* .2: Start last ptr at beginning.!
@ft| !* Print buffer beginning.!
fsVB mD @ftB !* Dash and print virt buffer begin.!
fsWindow+b mD @ft[ !* Dash and print window start.!
q.4 mD @ft] !* Dash and print window end.!
fsZ-(fsVZ) mD @ftZ !* Dash and print virt buffer end.!
fsZ mD @ft|
 !* Dash and print buffer end.!
0u.1 !* .1: 0, echo area hpos.!
0u.0 !* .0: 0, tenth number.!
9< fsWidth-3*%.0/10-q.1f(+q.1+1u.1)< @ft  > q.0@:= > !* Print tenths.!
0fsEchoActivew
1
!^R Draw Vertical Line:! !^R Draws from current hpos, not inserting.
Line drawn only in current window, and column printed at base of line.
This only works on ITS machines.
If any ARG given, is displacement from current hpos. E.g. -1 means
draw line through position one column left.
If C-U is specified, together with an ARG then ARG is an absolute
column. E.g. M-3 C-U as argument makes line in column 3. But
M-3 as argument makes line in column 3+current_column.!
[.2[.1 ff"G fs^Rarg'"# 0'+(fs^Rexpt"E fs^Rhpos')+8:i.1
:i*TfsMPDisplay !* Home to top.!
fsTop< :i*DfsMPDisplay >
fsLinesf"E wfsHeight-(fsEchoLines)-1'(
)< :i*H.1|HDfsMPDisplay >
.1-8:\u.2 :i*H.1.2fsMPDisplay
@ft  1
!=Abbrev:! !C Define or delete M-X abbreviations.
M-X =Abbrev$IF$Insert File$ will define M-X IF = Insert File$
to be M-X Insert File$, evaluated by name each time
M-X IF$ is used. Thus if a new Insert File is created or loaded,
that one will be used. This works nicely with command-completion.
C-U 0 M-X =Abbrev$IF$ and
C-U - M-X =Abbrev$IF$ will remove definition for M-X IF$.!
ff"G -1"L !* 0 or neg argument, kill abbrev.!
8,f Kill command abbrev: [0 !* 0: command name of abbrev.!
m.mKill Variable !* K: Vlamdring, variable-slayer.!
:fo..qMM 0"g mkMM 0w' !* If name is complete or unambiguous!
!* as given, ready to kill.!
"# :fo..qMM 0 ="g !* Perhaps just abbrev part given.!
mkMM 0 =w' !* ...!
"# :i*Ambiguous or undefined command abbrev: 0fsErr'' !* Give up.!
'' !* ...!
[1[2[3
1,f Command abbrev: ( !* STRARG1: abbrev!
8,f Full command name: u2 !* 2: MM-name.!
)u1 !* 1: MM-abbrev.!
!* Give the abbrev some active documentation, so that it will always get the!
!* latest documentation for the full command. I.e. make the documentation!
!* also "call by name".''!
@:i*|C Command abbrev for 2.
1,m.m~DOC~ 2f"n[1 g1 j2d ]1'w|(
)m.vMM ~DOC~ 1 = 2w
!* Define the command abbrev MM-variable: !
@:i*| f:m(m.m 2)  !* ...!
|m.vMM 1 = 2w !* ...!

!^R Auto Fill Comments:! !^R Refill the comment and its continuations.
To handle comment starts (or parts of them) that are repeated, e.g.
";;; " in Lisp, or perhaps "/*** " in Pl1, it will treat a duplicated
last character of the comment start or begin as part of the comment
beginning when merging comment lines.!
[1[2[3[4[5[6
qComment Startu1 !* 1: Real, minimal start string.!
qComment Endu2 !* 2: End string or 0.!
fq2"e 0u2' !* Either 0 or non-null.!
qComment Beginu3 !* 3: Desired pretty-start string.!
fq3:"g q1u3' !* 3: If no begin, then use the!
!* start string for convenience.!
fq1-1:g1u5 !* 5: Last character in start string.!
qFill Extra Space Listu6 !* 6: Characters that take 2 spaces.!
0l :fb1"e fg 1' !* Feep and exit if no comment.!
!* Merge this comment and its continuations into one comment line: !
< q2"e :l'"# :fb2' !* To end of comment.!
.u4 !* 4: Point at comment end.!
l @f l !* After next lines indentation.!
fq1f~1:@; !* Exit if not comment start.!
q4,.k !* Remove the whitespace between!
!* comment and continuation comment.!
q2"n -fq2d' !* Delete the comment end.!
fq3f~3"e fq3d'"# fq1d' !* Remove any comment begin or start.!
@f5k !* And iterated last character.!
-@f l @f k !* Kill surrounding whitespace.!
0af6:"l 32i' 32i !* Insert space to separate. Or 2!
!* spaces for some.!
> !* Keep merging.!
!* Now repeatedly auto-fill this line until it fits. Calling ^R!
!* Auto-Fill Space with an argument of 0 tells it to insert no spaces but!
!* fill once if necessary. We limit the number of iterations to a!
!* reasonable maximum (each auto-fill should rip off at least one space +!
!* one char (word). This is so some buggy auto-filler or tab wont!
!* infinitely keep causing us to fill.!
q4j 0l !* Back to comment line.!
.,( !* Get bounds of change.!
m.m^R Auto-Fill Spaceu1 !* 1: Space.!
:l 0f/2< .-(0m1f !* Auto-fill maybe, tell ^R mode.!
).@; > !* Repeat until point doesnt change.!
:l). 
!^^ TMACS Error Handler:! !S Q..P: handles TECO errors.
If first character typed is "?" then Backtrace is called.
A space makes us exit, with no action.
If option variable TMACS Error Dispatch is non-0, some other
characters may be typed, in any order, ending with a space (no
further action) or "?" (enter Backtrace):
B Display the offending buffer.
D Directory Lister is run.
W Who caused this? -- type function's name.
Typing HELP character describes the error handler.
Quits are not handled at all unless the variable Debug is nonzero.
That is so a quit will cause the buffer and modeline to be
restored and redisplayed immediately.
A QRP error (q-register PDL overflow) will cause automatic partial
unwinding of the q-register PDL if you type anything but Space.
You can thus enter Backtrace etc.!
m(m.m& Declare Load-Time Defaults)
TMACS Error Dispatch,
* Non-0 enables several characters for TMACS error handler: 0

!* It is dangerous to push anything on the q-register pdl before we have!
!* checked for a QRP error.!
:? fsErrorf"n@:fg !* Leave trace mode, print error message!
0"n !* MM Make Space doesnt exist yet.!
fsError-(@feURK)"e !* If out of address space, clean up right!
!* away.!
ft executing Make Space... !* Tell user we are fixing things.!
mMM Make Space' !* We can get there without consing any!
!* strings.!
' !* End of dont-yet-execute.!
'
"#w 0fo..q Debug"e !* ^G -- just quit right away?!
fsError fsErrThrow'' !* Yes, so redisplay immediately.!
!* Debug allows a hacker to cause an!
!* asynchronous entry into Backtrace, e.g.!
!* to see what is looping.!
!* Now, if QRP error and user types anything but Space (which exits), we!
!* partially unwind to allow room to operate.!
:fi- "e oSP' !* Must do this special case so avoid any!
!* q-register PDL pushing, which includes!
!* fs-flags.!
fsError-(@feQRP)"e !* It is a QRP error.!
:ftUnwinding partially to make room for error handler !* ...!
-9-9-6fsQPUnwindw' !* So unwind a little. The -9-9-6 avoids!
!* assuming any base.!
8f[I.Base !* 15. is base 8. I guess in case we!
!* go into Backtrace.!
f[SString !* Save search default.!
@:i*| m(m.mDescribe)^^ TMACS Error Handler |f[HelpMacro
!* HELP gives options.!
qTMACS Error Dispatch"n !* Check for special dispatch characters.!
< @:fi@:fc-B"e fiw @v !<!>' !* B -- display buffer.!
@:fi@:fc-D"e fiw 1:<mDirectory Lister>w !<!>'
!* D -- display directory.!
@:fi@:fc-W"e fiw !* W -- name who did it.!
0[1 1:< -1fsBackStringm(m.m& Macro Name)u1 >w !* 1: name!
q1fp"l :i1unknown function' !* of culprit.!
@ft(Error in 1) 0fsEchoActivew !<!>' !* Tell.!
1; >' !* Any other commands exit.!
@:fi-32"e !SP! fiw 0fsErrFlgw 0u..h fsErrThrow'
!* Space -- no action, clear error!
!* and any HELP message printed.!
@:fi-?"e fiw !* If user types ? we backtrace.!
fsVerbose"e !* if not verbose then!
1f[Verbose fsErrorfg f]Verbose' !* explain error verbosely!
f[Error !* save fsError!
2m(m.mBacktrace)+0"n f)' !* Backtrace. If it says continue, do!
f]Error' !* restore fsError!
"# fsEchoErr"e !* if errors dont complain in echo!
@:fi- "e fiw 0fsErrFlg''' !* area and user typed a space,!
!* forget the error since is still!
!* showing.!
fsErrThrow
!^R Change Case Letter:! !^R Next <argument> letters, moving past.
Numeric argument negative means move left.
Fast, does not move gap.!
[1
"g !* Positive NUMARG, move right.!
.,( :< 1af"a#40.:i1 !* 1: Changed case if letter.!
f1'w !* Change to that letter.!
c >w ).'
!* Negative NUMARG, move left.!
.,( -:< r 1af"a#40.:i1 !* 1: Changed case if letter.!
f1'w !* Change to that letter.!
>w ).
!& Set ..D:! !S Create a new ..D with chars in arg as break characters.!
-1[1 128*5,40.:i..d !* setup completely blank ..D!
128<%1*5:f..dA> !* initialize to no break chars!
i -fk<0a*5:f..d  -d> !* make chars in arg into breaks!

!^R Get Macro Name:! !^R Inserts macro name for char typed.
MARK is set before inserted name.
Handles bit and char prefixes, e.g. Meta-, ^X, unless:
Given a numeric argument, gets the name of a prefixer (e.g. metizer).
Impure-strings that are uncompressed macros are handled if their names
are present at the beginning of the macro.
Some characters run standard builtin functions whose names are found
in the BARE library. These work fine. Others which are not found
just insert their key names, e.g. Meta-O.!
[0 [.1
.:w !* Set MARK.!
ff"e !* No NUMARG, follow prefixes.!
 m(m.m& Read Q-reg Name)u0' !* 0: Name of Q-Reg.!
"# @fiu0 !* 0: 9-bit for prefix key.!
.,( g(q0 fs^RIndirect fs^Rcmacro m(m.m& Macro Name))
).' !* Get the name of the prefix.!
q0 fp"l f[:EJPage m(m.mLoad Library)BAREw' !* If builtin, we!
!* might find its name in BARE.!
q0m(m.m& Macro Name)f"nu0 !* 0: Found its name.!
.,(g0).' !* Insert and return.!
q0 fp+1"G !* Q-Reg contains bug, qv, or an impure!
!* string -- thus possible macro source.!
f[BBind !* Grab temp buffer.!
g0 !* Get the q-reg contents.!
j @ f
 r !* Move past initial CRLFs.!
0,1a-!"N !* No possible macro name here.!
:i*Not a valid macrofsErr' !* Error.!
.+1,( :s:!"e :i*Not a valid macrofsErr' !* !
2r).x0 !* 0: Macro name.!
f]BBind !* Back to original buffer.!
.,(g0). ' !* Insert macro name and exit.!
!* 0: Name of q-reg, possibly running a!
!* builtin function.!
f[BBind !* Grab a temp buffer.!
g0 j !* Insert the q-reg name.!
0,1a-"E !* ^^-type name.!
z-2"N :i*Bad ^^-type q-reg namefsErr' !* Only ^^x.!
2a#100.u.1' !* .1: 9-bit ascii code for q-reg char.!
"# !* Not ^^-type, see if ^R-type name.!
:s"E !* Not ^R-type qreg name, !
f]BBind .,(g0). ' !* ...so just return qreg name.!
bj 0u.1 !* .1: Initialize 9-bit code.!
3< 0,1a-."E !* For each period in name, !
d q.1+200.u.1' !* .1: ...update 9-bit shift bits.!
> !* End of period-iter.!
0,1a-"N !* Up to 3 dots, then ^R.!
:i*Bad q-reg namefsErr' !* !
z-2"N :i*Bad q-reg namefsErr' !* !
2a+q.1u.1' !* .1: 9-bit ascii code for q-reg char.!
!* .1: 9-bit for q-reg char.!
f]BBind !* Back to original buffer.!
q.1 m(m.m& Get 9-Bit Character Name)  !* Insert name and exit.!
!& Get 9-Bit Character Name:! !S Inserts pretty name for 9-bit ARG.
Example: 415. MM & Get 9-Bit$ inserts "Meta-CR".
An arg of "2," means say "^M" instead of "CR", etc, and ^B instead of
an alpha on TV's.!
&200."NiControl-'
&400."NiMeta-'
[0&177.U0
Q0-127"EiRubout'
Q0-27"EiAltmode'
-2"N
Q0-8"EiBackspace'
Q0-9"EiTab'
Q0-10"EiLinefeed'
Q0-13"EiReturn'
Q0-32"EiSpace''
-2"EQ0-32"Li^Q0+100.U0'''
i0
!Lock File:! !C Lock current buffer's file.
"Lock" the file in the current buffer by creating FN1 *LOCKED*.
Will complain if FN1 *LOCKED* already exists, and will tell who has it
locked (since FN1 *LOCKED* contains that person's xuname).
Fails the critical-race test.
This assumes that others will cooperate and use M-X Lock File$ and the
matching M-X Unlock File$.!
f[DFile [1[2 !* save filenames, q-regs!
qBuffer Filenamesu1
q1"e :i*No file in bufferfsErr'
q1fsDFilew
f[BBind !* explicitly popped!
1:< er*LOCKED* >"e
@y :x2 f]BBind
:i*1 is locked by 2. fsErr'
ec fsXUnamef6 ei hp ef f]BBind
:i*CfsEchoDis @ftOk, you have 1 locked. 
0fsEchoActivew
!* If creation date of file in buffer equals that on disk then just return.
Otherwise issue a warning.
!
q1fsDFilew !* get creation date of file on disk.!
e[ er fsIFCdate( e] !* ...!
)-q:.b(qBuffer Index+8)"e ' !* if same as in buffer then return!
fsModified"n !"!
ftWhile you've been editing this file, somebody has written a
new copy out! You will lose some work if you are not careful.
I suggest that you file this out under a different name and
then SRCCOM the two files.
 '
!"!
ftSince you last read or wrote this file, somebody else
wrote a new version on disk. Luckily, you haven't edited
the buffer since then. Do you want the new version
m(m.m& Yes or No)"l m(m.mRevert File)'
0u..h 
!Unlock File:! !C "Unlock" file in buffer locked by M-X Lock File.!
f[DFile [1[2 !* save filenames, q-regs!
qBuffer Filenamesu1
q1"e :i*No file in bufferfsErr'
q1fsDFilew
1:< er*LOCKED* >"n !* Oops -- file isnt locked.!
:i*1 is not locked. fsErr' !* Complain.!
f[BBind !* explicitly popped!
@y :x2 f]BBind !* Is locked, see who by.!
f~(fsXUname:f6)2"n !* not us...!
:i*2 has 1 locked -- not you. fsErr' !* So complain.!
ed !* Fine, unlock ok.!
:i*CfsEchoDis @ftOk, 1 is unlocked. 
0fsEchoActivew  !* Exit keeping message on screen.!
!& Buffer Dashes:! !I Internal routine of ^R Buffer Graph.!
!* === or --- whether in region or not.
ARG = pointer in buffer.
Uses global qregs:
.0: Dash to print, - or =.
.1: Last echo area hpos.
.2: Last buffer pointer.
.3: Point in buffer.!
-1[p !* p: Maybe point.!
-1[m !* m: Maybe mark.!
:+1"G :-(fsZ)-1"L !* Only indicate region if valid MARK.!
q.3-q.2"G q.3--1"L q.3up'' !* .p: Point is in our range now.!
:-q.2"G :--1"L :um'''' !* .m: Mark is in our range now.!
qp,qmfumup !* Ensure p less than m.!
qp+1"G fsWidth-8*qp/fsZ-q.1f(<@ft.0> !* Dash to point.!
)+q.1u.1 !* .1: Hpos of point.!
.0-="E :i.0-'"# :i.0=' !* .0: Switch -/=.!
' !* Done point.!
qm+1"G fsWidth-8*qm/fsZ-q.1f(<@ft.0> !* Dash to mark.!
)+q.1u.1 !* .1: Hpos of mark.!
.0-="E :i.0-'"# :i.0=' !* .0: Switch -/=.!
' !* Done mark.!
fsWidth-8*/fsZ-q.1f(<@ft.0> !* Dash to ARG.!
)+q.1u.1 !* .1: Hpos of ARG.!
u.2 !* .2: Update last ptr.!

!Flush Variables:! !C Kill some variables specified by search string.
Kill variables whose name contains the string argument.
String argument actually is a TECO search string, and so you can flush
variables containing "foo" OR "bar" by using the string argument
"foobar".
The list to be flushed is typed, asking Y, N, or ^R?
N means abort, ^R allows editing of the list.!
:i*[1[2 !* 1: Stringarg to match killees.!
f[BBind !* Temp buffer.!
q..o m(m.m List Variables)1 !* Insert list of matching vars.!
bj
1f<!DONE!
f<!KILL!
:ftKilling Following Variables:
 ht
ft
Ok? (Y, N, ^R) 
fi:fcu2 !* 2: Response.!
1< q2 fYN"L ftAnswer must be Y, N, or ^R.
 1;' !* Go type list etc again.!
q2-Y"E f;KILL' !* Y, go kill these vars.!
q2-N"E f;DONE' !* N, dont kill, just quit.!
q2-"E !* ^R Edit, then reask.!
0u..h  1;' !* ...!
> !* End YN^R check.!
> !* After this, can kill.!
bj !* Start killing at top.!
m.m Kill Variable !* K: Killer.!
< 1:< 0,25fm !* Go to probable end of varname.!
-:fwl !* Back to end of last word.!
!* Now have to figure enough of variable name to be unambiguous:
* I think with any algorithm, there will be ambiguous cases resulting in
* mistakes -- having to do with variables whose names are prefixes of others.
* But anyhow...:
* The buffer has a list made by List Variables which includes a description
* of the value, and we cant really tell where a long variable name ends and
* the value description begins. We will find out by trying the first 25
* letters, which is definitely part of the name, and checking if that is
* ambiguous. If so, we append the next word of the line, which must be
* another part of the variable name, and again check for ambiguity. The
* variable name will eventually be unambiguous.
!
< 0x2 !* 2: Up to first 25 lets of name.!
1:<fo..q2w>-(@feAVN)@:; !* See if 2 is unambig.!
fwl > !* If not, include next word.!
1:<mK2>"n !* Kill the variable if can.!
!* Does KV ever give an error???!
ft2 [Not Deleted]
' !* Unsuccessful ones listed.!
> !* Error in fm means blank line.!
l .-z; > !* Next line if any.!
> !* End of done catch.!
0u..h  !* Exit, refreshing screen.!
!List unused ^R characters:! !C Unused C-, M-, and C-M- characters.
If numeric argument then list unused prefix commands.!
[1[2[3[4[5
m.m& Charprint
0u1 32< q1fs^RCMacro-(0fs^RInit)"e
2,q1mP ft is not defined
' %1 >
A+400.u1
26< q1-(0fs^RInit)"e
q1mP ft is not defined
' %1 >
A+600.u1
26< q1-(0fs^RInit)"e
q1mP ft is not defined
'
q1-(Afs^RInit)"e
q1mP ft self-inserts
' %1 >
ff"e '
qPrefix Char Listu4 0u5
< q5-fq4;
q5:g4*200.+(q5+1:g4)u3
q5+2,q5+6:g4u2 q2u2
0u1 32< q:2(q1)"e
2,q3mP ft  2,q1mP ft is not defined
' %1 >
Au1 26< q:2(q1)"e
2,q3mP ft  2,q1mP ft is not defined
' %1 >
q5+6u5
>

!^R Argument:! !^R Put on digits, minus, and comma to get arguments!
fsQPPtr[9 !* 9: where to unwind to!
[0[1 !* save q-regs!
q..0&127:i0 !* 0: argument as string!
< 1,m.i !* read next character!
:fif0123456789-,:; !* if not digit, minus, or comma then exit!
fiu1 :i001 > !* add character to string!
@fiu..0 !* ..0: terminating character!
1fs^RArgpw -1u1 !* argument present, no digits yet!
fq0< %1:g0"d 3fs^RArgpw 1;' > !* if find digit then set bit!
0(q9fsQPUnwind)@:m(q..0fs^RIndirectfs^RCMacro)
!^R Break Line:! !^R Fill if too long, even out of Auto Fill mode.
Cursor may be anywhere within line.
Line will be broken (space inserted at margin) repeatedly until it
fits within the margins.
Uses ^R Auto-Fill Space.!
!* Ugly on printing terminal. Dont know how to fix that. ^R Auto-Fill Space!
!* does its own redisplay that fouls us up.!
.[0 !* 0: Original point.!
0l .[1 !* 1: Start of line.!
1[Auto Fill Mode !* Temporarily in fill mode.!
m.m^R Auto-Fill Space !* S: Filler.!
:l <.-(0msf).@;> !* Fill as much as can.!
q0:j"e :l' !* Restore point, or end of line.!
fsRGETTY"e 0t' !* Printing tty.!
1
!0:! !C Does nothing, returns nothing...
...but is good for something:
If you want to give some Teco commands from the bottom of the screen,
you can call ^R Extended Command (or any such "Meta-X") and give the
Teco commands as the "string argument".!

!UnSAILify:! !C Turn SAIL file into readable form.
M-X UnSAILify interchanges underscore and backarrow; this is good for
mail.
1 M-X UnSAILify goes further and fixes lossage caused by image FTPing
a SAIL file.!
[1
j 0s_ !* interchange underscore and left arrow!
<:s;0a#107.u1.-1f1> !* since SAIL has them backwards!
ff&1"e j ' !* if not 1 mmUnSAILify then we're done!
j 0s !* remove NULs!
<:s;-d> !* ...!
j 0s~ !* SAIL has wedged ideas about codes!
<:s;.-1f}> !* 175-176, 176 is their right brace!
j 
!& Kill Prefixed Variable Names:! !S Kill variables if names STRARG-prefixed.
STRINGARG is prefix for variable name. E.g. doing:
m(m.m& Kill Prefixed Variable Names)Cache 
will kill all variables whose names start with "Cache ".!
[1[2 !* Save some regs.!
q..q[..o !* Yank variable list into buffer.!
:i1 !* Get prefix to kill.!
:fo..q1*5,( !* get and save offset of first variable!
fq1-1:g1+1u2 !* clobber last character of string!
fq1-1:f12 !* to next character in ASCII sequence!
:fo..q1*5)k !* get offset of last variable and kill!
!* that range of buffer!

!& Insert Prefixed Variable Names:! !S Insert some variable names.
String argument is prefix for variable name. One variable name to a
line.
E.g. m(m.m& Insert Prefixed Variable Names)MM  will insert the names
of all variables whose names start with "MM ".
Also see & Kill Prefixed Variable Names, and & List Prefixed Variable
Names.!
:i*[.1 !* .1: STRINGARG, the prefix.!
:fo..q.1,0f[.2 !* .2: Index to first variable with that!
!* prefix to its name. The ,0f^@^@!
!* takes the absolute value, since may!
!* be there exactly or not.!
[.3[.4
< fq..q/5-1-q.2"L 1;' !* Stop if run off end of symtab.!
q:..q(q.2)u.3 !* .3: Maybe next matching varname.!
f~(0,fq.1:g.3).1"G 1;' !* Stop after matches.!
f~(0,fq.1:g.3).1"E !* Is a varname with matching prefix.!
g.3 !* Insert varname.!
i
 ' !* Done matching variable.!
q.2+q:..q(0)u.2 > !* .2: Next variable index.!

!^R Uppercase Last Word:! !^R Uppercase word(s) before point.!
-fwf(@fc) 
!^R Lowercase Last Word:! !^R Lowercase word(s) before point.!
-fwf(fc) 
!^R Uppercase Last Initial:! !^R Capitalize word(s) before point.!
.( -@m(m.m^R Uppercase Initial)f !* Capitalize backwards.!
)j 1 !* Restore point.!
!Uncontrolify:! !C Turn control chars into uparrowed chars.
This is good for listing a file with control characters in it on a
line printer which would not show control characters well.
String argument is a string of characters NOT to change.
TABs are turned into spaces. CRLF pairs are left alone.!
[1[2[3[T !* save regs!
:i3 !* 3: characters not to convert!
128*5fsBConsuT !* T: F^A q-vector!
@fn|qTfsBKill| !* cleanup after ourselves!
-1u1 !* 1: index into q-vector!
:i2-D94IQ..0#64I !* 2: control character converter!
32< q2u:T(%1) > !* initialize all control characters!
95< 201004020100.u:T(%1) > !* initialize all printing characters!
q2u:T(%1) !* initialize rubout!
@:i:T(9)|-D8-(FSSHPOS&7),32I| !* expanding tab!
@:i:T(13)|0,1A-10"EC'-DI^M| !* CR is ^M unless followed by LF!
@:i:T(27)|-D36I| !* ESC is $!
-1u1 !* 1: index into 3!
fq3< 201004020100.u:T(%1:g3) > !* skip characters in string argument!
ff"e h'"# f':fT !* H if no argument!

!Abort Recursive Edit:! !C Abnormal exit from recursive editing command.
The recursive edit is exited and the command that invoked it is
aborted.
For a normal exit, you should use ^R Exit, NOT this command.
The command can put a string in Abort Resumption Message
to tell the user how to resume the command after aborting it.
If the option variable Less Asking is non-0, no message will be
printed, and you will not be asked for confirmation.!
m(m.m& Declare Load-Time Defaults)
Less Asking,
* Non-0 prevents Abort and Revert from asking: 0

-fsBackStr-(m.m& Toplevel ^R)"e
:i*Already at top levelfsErr'
0fo..qLess Asking"e
qAbort Resumption Message[0
q0"e @ftAbort this recursive edit
1m(m.m& Yes or No)"e 0''
q0"n @ft
0''
1f[NoQuit
-1fsQuit
fs^RExit !* Exit the ^R. This will pop fs noquit,!
!* causing a quit afterward.!
!Revert File:! !C Undo changes to a file.
Reads back the file being edited from disk
(or the most recent save file, if that isn't the same thing).
A numeric argument means ignore the Auto Save files.
If the option variable Less Asking is non-0, you will not be asked for
confirmation.
A nonzero pre-comma argument also waives confirmation.!
m(m.m& Declare Load-Time Defaults)
Less Asking,
* Non-0 prevents Abort and Revert from asking: 0

mMM & Check Top Levelfiles
QBuffer Filenames[0
.[1
QBuffer Index[2 [3
FF&1"E !* Choose visited filenames or auto save filenames.!
Q:.B(Q2+10!*bufsav!)U3 FQ3"G !* If we recently wrote an auto-save file, read it.!
QAuto Save Count"N
Q3U0'''
q0"e :i*No file to revert from fsErr'
"E !* Query, unless that is inhibited by precomma arg.!
0fo..qLess Asking"e
@ftRestore file from disk
1m(m.m& Yes or No)"e 0'''
B[B 0,fsZfsBound
ER0
qBuffer Index[2
fsIFCDateu:.B(Q2+8!*bufdat!)
fsIFVersu:.B(Q2+9!*Bufver!)
@Y 0fsModifw 0fsXModif
fsWindow+QB:J"L 0L .fsWindow'
Q1:J
fs^RMDlyfs^RMCnt
m(m.m& Process File Options) !* Reprocess local modes!
0fo..qVisit File HookU1 !* Redo user's own processing.!
Q1"N M1' 
!~TMACS Loaded~:! !For checking if loaded or compressed in.!
TMACS !* Must have some body.!
!& SetUp TMACS Library:! !I Load-time setup.!
1,m.m& SetUp Compressed TMACS Librariesf"n[1 m1'w

!& Default Variable:! !I Just like M.C.
Kept around so old libraries generated by IVORY still work.!
!* This must be a subroutine and not something in an MM-variable put there by!
!* & setup since unfortunately the old IVORY-generated & Setups map in TMACS!
!* instead of just loading it. Thus the & setup isnt run.!
f:m.c !* Let M.C do all the work.!
!* Following should be kept as a long comment so will compress out:
* Local Modes:
* Fill Column:78
* Comment Column:40
* MM Edit TMACS Documentation: 70[Fill Column  1
* Compile Command: m(m.mGenerate Library)ECC;XTMACSEMACS1;TMACSTMUCS
* End:
*!

BIN
src/emacs1/tmucs.20 Executable file

Binary file not shown.

1680
src/emacs1/wordab.624 Executable file

File diff suppressed because it is too large Load Diff