From d68aae0339cb259fc6295fca5b9217f0998a7058 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Thu, 8 Dec 2016 14:38:38 +0100 Subject: [PATCH] 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. --- bin/emacs/ivory.:ej | Bin 0 -> 24797 bytes build/build.tcl | 10 + doc/info/ivory.6 | 321 ++++++++ doc/info/tmacs.12 | 347 +++++++++ doc/info/wordab.182 | 584 ++++++++++++++ src/emacs1/ivory.189 | Bin 0 -> 42308 bytes src/emacs1/tmacs.430 | 967 ++++++++++++++++++++++++ src/emacs1/tmucs.20 | Bin 0 -> 8048 bytes src/emacs1/wordab.624 | 1680 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 3909 insertions(+) create mode 100755 bin/emacs/ivory.:ej create mode 100755 doc/info/ivory.6 create mode 100755 doc/info/tmacs.12 create mode 100755 doc/info/wordab.182 create mode 100755 src/emacs1/ivory.189 create mode 100755 src/emacs1/tmacs.430 create mode 100755 src/emacs1/tmucs.20 create mode 100755 src/emacs1/wordab.624 diff --git a/bin/emacs/ivory.:ej b/bin/emacs/ivory.:ej new file mode 100755 index 0000000000000000000000000000000000000000..3493c895be9bcc9f48c107a95522b97f21d61176 GIT binary patch literal 24797 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 HMFRg9pS~=h literal 0 HcmV?d00001 diff --git a/build/build.tcl b/build/build.tcl index c077b5f4..05773afa 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -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" diff --git a/doc/info/ivory.6 b/doc/info/ivory.6 new file mode 100755 index 00000000..2ccef04e --- /dev/null +++ b/doc/info/ivory.6 @@ -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: + + "," ":" + is any horizontal or vertical whitespace. + is a string. Quote any ":"s with the + 2-character sequence Control-] Control-Q. + Quote any Altmodes or Control-]s with just a + Control-]. + 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 , John Pershing , and +Eugene Ciccarelli . + +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.: + . + +^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: diff --git a/doc/info/tmacs.12 b/doc/info/tmacs.12 new file mode 100755 index 00000000..7f233bb6 --- /dev/null +++ b/doc/info/tmacs.12 @@ -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 + 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 + + +^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 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 + This allows you to create abbreviations for function names that + you call via M-X. E.g. to make M-X LLL be an abbreviation for + M-X List Loaded Libraries, just do: + M-X =AbbrevLLLList Loaded Libraries + 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 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 will show + you who is on the bug-random-program mailing list on your machine. + If string argument is of form @, :.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.) + @ 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.) + 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 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 _ 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 _ No Break + S Set so _ and BS are not breaks. + Pushes a ..N so definitions for _ and 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. diff --git a/doc/info/wordab.182 b/doc/info/wordab.182 new file mode 100755 index 00000000..d23d7f72 --- /dev/null +++ b/doc/info/wordab.182 @@ -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$$. (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$$. + +********** + + 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$ for a mode abbrev, and + $X * 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$$ 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$$ 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: + + ::= null | <1def> CRLF + <1def> ::= : " " + ::= + ::= null | ( ) + ::= null | + + refers to spaces and tabs. There can be no colons in an +abbrev, though there can be quotes in the expansion. If 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 + diff --git a/src/emacs1/ivory.189 b/src/emacs1/ivory.189 new file mode 100755 index 0000000000000000000000000000000000000000..18f9cec4c0ede05d58ce0e01043ccabacb000f69 GIT binary patch literal 42308 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 F{V!`42p#|c literal 0 HcmV?d00001 diff --git a/src/emacs1/tmacs.430 b/src/emacs1/tmacs.430 new file mode 100755 index 00000000..0d8c05df --- /dev/null +++ b/src/emacs1/tmacs.430 @@ -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 will show + you who is on the bug-random-program mailing list on your machine. +If string argument is of form @, :.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.) +@ 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.) +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: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 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 !* 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:-(@feAVN)@:; !* See if 2 is unambig.! + fwl > !* If not, include next word.! + + 1:"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: + *! diff --git a/src/emacs1/tmucs.20 b/src/emacs1/tmucs.20 new file mode 100755 index 0000000000000000000000000000000000000000..b4a7b9c133fd5fe14ff7d25e679f241e7885ad5a GIT binary patch literal 8048 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 literal 0 HcmV?d00001 diff --git a/src/emacs1/wordab.624 b/src/emacs1/wordab.624 new file mode 100755 index 00000000..cfbf39ae --- /dev/null +++ b/src/emacs1/wordab.624 @@ -0,0 +1,1680 @@ +!* -*-TECO-*- *! +!* This source is compiled with IVORY, not PURIFY! +!* Recent modifications: + 11/4/83 622 ECC Improve ^R Unexpand Last Word so that when it tells + Teco of the changed area, it tries to trim away any + prefix part that is the same. Typical case since the + whole line is kept for unexpanding. + 8/14/82 621 KRONJ Fix tab-expander to not get NIB (0, before q1-.a) + 4/24/82 619 ECC 1. Fix tab-expander installation to check the function + being replaced in the same way the others do, by + looking at the first n characters. This allows + loading WORDAB twice without tab exploding, or test + loading. 2. STL (if word too long) bug fixed. 3. Fix + Define.. to not rely on user ..d to define lispy (). + 3/21/82 618 ECC 1. Merge in the active-documentation code written long + ago and kept in WABDOC. Remove Old... user command. + 2. Change & WRDAB Process Options Hook to not bind any + keys to expanders if in a recursive edit level. + This allows unbinding when exit levels to work -- + otherwise WRDAB Old nnn variables are smashed and + cannot be restored. + 3. Change ^R Abbrev Expand for Tab to allow any kind + of insert at point, not just whitespace. Checks + old tab's return values more carefully to decide. + 9/04/81 615 ECC Removed spurious ; in tab expander. Made WORDAB All + Caps be a option variable, so Edit Options will see + it, as will Help-V etc. + *! +!~FILENAME~:! !Word Abbrev Mode package. Documentation in INFO under EMACS.! +WORDAB + +!& Setup WORDAB Library:! !S Run when WORDAB is loaded. +If you do non-trivial hacking of Word Abbrev mode, you should be on + the WORDAB@MIT-AI mailing list. +Calls variable WORDAB Setup Hook, if it exists. That can do things + like auto-loading a file of abbreviations. It must also connect + keys. +If the hook does not exist (or is 0), we will connect the standard + Word Abbrev mode keys: + C-X C-A runs ^R Add Mode Word Abbrev, + C-X C-H runs ^R Inverse Add Mode Word Abbrev, + C-X + runs ^R Add Global Word Abbrev, + C-X - runs ^R Inverse Add Global Word Abbrev, + M-' runs ^R Word Abbrev Prefix Mark, + C-M-Space runs ^R Abbrev Expand Only, and + C-X U runs ^R Unexpand Last Word. +Appends to variables Set Mode Line Hook and Exit Hook.! + + m(m.m& Declare Load-Time Defaults) + Word Abbrevs Modified, Non0 means definitions have changed: 0 + Save Word Abbrevs, + * 1 => save all abbrevs on exit, -1 => just save incrementals: 0 + Additional Abbrev Expanders,: 0 + Only Global Abbrevs,: 0 + Word Abbrev Mode,: 0 + WORDAB Setup Hook, + If non0 is Teco code to run when WORDAB loaded (it must set keys): 0 + + + [1[2 !* save regs! + 6*5fsQVectoru.e !* .E: QVector of random WORDAB! + !* variables.! + qOnly Global Abbrevs"e !* Both globals and modals.! + m.m& WRDAB Mode or Global Expandu:.e(0)' !* .E(0): abbrev lookup! + !* subroutine! + "# !* Only globals.! + m.m& Global Expandu:.e(0)' !* .E(0): abbrev lookup subroutine.! + + m.m& Expandu:.e(1) !* .E(1): & Expand subroutine.! + 0u:.e(2) !* .E(2): old string.! + 0u:.e(3) !* .E(3): new string.! + 0u:.e(4) !* .E(4): new string end.! + + + @:i1|( !* 1: Our SML hook.! + !* The parenthesis passes along! + !* any value since we are appending.! + + !* Inserts " Abbrev", and passes along any given string (old style! + !* hooks accumulated a string of mode line things instead of! + !* inserting). Call & WRDAB Process Options Hook to do the expander! + !* character reconnecting.! + + m(m.m& WRDAB Process Options Hook) !* Set characters if necessary.! + 0fo..qWord Abbrev Mode"n !* In Word Abbrev Mode.! + i Abbrev' !* so put that into mode line.! + )| !* End of our SML hook.! + + 0fo..qSet Mode Line Hooku2 !* 2: Old SML hook.! + q2"e q1'"# :i*21'm.vSet Mode Line Hookw + !* Install our SML hook if none! + !* previous, otherwise append to! + !* SML hook.! + + + 0fo..qExit Hookf"ew :i*'u1 !* 1: Old exit hook.! + @:i*|1 !* Old stuff.! + qWord Abbrevs Modified"n !* New hook.! + qSave Word Abbrevsf"gw !* ...! + m(m.mWrite Word Abbrev File)' !* ...! + "#"l m(m.mWrite Incremental Word Abbrev File)''' !* ...! + |m.vExit Hookw !* ...! + + + !* Set up Word Abbrev Mode fsVarMacros so setting variables causes action! + !* Note that the value passed to a fsVarMacro is the new value, and the! + !* current value of the variable is still available in the variable itself --! + !* i.e. the variable value isnt changed until after the macro.! + + :fo..qWord Abbrev Modeu1 !* 1: ..Q index of mode variable.! + @:i:..q(q1+2)|!* 1 => turn on Word Abbrev Mode, 0 => turn it off! + !* This variable is an option too.! + !* Now the fsVarMacro part. NUMARG is the new value of the! + !* variable: positive if the mode shoud be turned on, 0 or! + !* negative if should be turned off. Old value is still in the! + !* variable. Make sure we run & Set Mode Line to (1) put "Abbrev"! + !* in the mode line, and (2) set all the expander keys.! + + 1fsModeChangew  | !* The fsVarMacro. A shortie.! + + + :fo..qOnly Global Abbrevsu1 !* 1: ..q index.! + @:i:..q(q1+2)|!* 1=> use only global word abbrevs, 0 => both kinds! + !* This variable is an option too.! + + !* Now the fsVarMacro part. NUMARG is new value, old is still in! + !* variable. Sets C-X C-A and C-X C-H unless user has a WORDAB! + !* Setup Hook. Changes the abbrev-checker.! + + qWORDAB Setup Hook[1 !* 1: 0 or hook.! + "n m.m& Global Expandu:.e(0) !* 1, just global abbrevs.! + q1"e m.m^R Add Global Word Abbrevu:.x() !* C-X C-A.! + m.m^R Inverse Add Global Word Abbrevu:.x()'' !* C-X C-H.! + "# m.m& WRDAB Mode or Global Expandu:.e(0) !* 0, both kinds.! + q1"e m.m^R Add Mode Word Abbrevu:.x() !* C-X C-A.! + m.m^R Inverse Add Mode Word Abbrevu:.x()'' !* C-X C-H.! +  | !* End of the fsVarMacro.! + + + :fo..qAdditional Abbrev Expandersu1 !* 1: ..Q index of expander list.! + q:..q(q1+1)f"n,m(m.mMake These Characters Expand)'w !* Check if any.! + @:i:..q(q1+2)|!Non-standard characters that should cause expansion.! + ,:m(m.mMake These Characters Expand) !* Give the! + | !* list a varMacro comment.! + + !* Note that it isnt an option. If we decide to make it one,! + !* then the fsVarMacro will have to worry about repeatedly! + !* appending the same characters, e.g. because Edit Options! + !* will reset the variable upon exit even if unchanged.! + + !* Finally, we do key-setting unless the user has a setup hook. In that! + !* case the hook must set any keys, along with whatever else it wants to! + !* do.! + + 0fo..qWORDAB Setup Hooku1 !* 1: Setup Hook or 0.! + q1"n m1' !* Call the hook if there is one.! + "# !* No hook, so we connect the standard keys. Note that regardless of! + !* Only Global Abbrevs, C-X + and C-X - will always be global hacking! + !* definers. The variable only affects C-X C-A and C-X C-H.! + + m.m^R Unexpand Last Wordu:.x(U) !* C-X U.! + m.m^R Abbrev Expand Onlyu... w !* C-M-Space.! + m.m^R Word Abbrev Prefix Mark!"!u..' !* M-Apos.! + m.m^R Add Global Word Abbrevu:.x(+) !* C-X +.! + m.m^R Inverse Add Global Word Abbrevu:.x(-) !* C-X -.! + qOnly Global Abbrevs"n !* Globals only.! + m.m^R Add Global Word Abbrevu:.x() !* C-X C-A.! + m.m^R Inverse Add Global Word Abbrevu:.x()' !* C-X C-H.! + "# !* Modals and globals.! + m.m^R Add Mode Word Abbrevu:.x() !* C-X C-A.! + m.m^R Inverse Add Mode Word Abbrevu:.x()'' !* C-X C-H.! + + 1fsModeChangew  !* Go into Word Abbrev mode if its! + !* variable says to.! + +!Expand Word Abbrevs in Region:! !C Finds abbrevs in region; offers to expand each. +Searches region for word abbrevs. When one is found, the buffer is + displayed with the cursor just after the abbrev. The character + you then type determines what action is taken: +Space expands the abbrev and goes on to the next one. +Rubout goes on to the next one without expanding. +Altmode exits this command without expanding. +Period expands and then exit. +Comma expands and stays so you can look it over. Then type one + of these characters again. +Exclamation mark expands this and each remaining abbrev without + asking. +Hyphen expands and glues to a prefix and stays. The prefix and + abbrev should be separated by a "-". +F causes this paragraph to be filled. +C-R enters a recursive edit level, so you can move point or do + minor editing. +C-L clears and redisplays the screen and stays.! + + !* Note the s used below to bound the WORDAB Ins Chars string value.! + m(m.m& Declare Load-Time Defaults) + WORDAB Ins Chars, Self-inserting expanders: !~@#;$%^&*-_=+[]()\|:`"'{},<.>/? + + WORDAB Old Chars, Hairy expanders: || + Word Abbrev Prefix Mark, Point of prefix mark: 0 + + + [0[1[2[3[4[5 0[6 !* 6: 0 iff should ask.! + 0[..f !* ..F: Disallow file hacking.! + :,.f-zu0j !* Jump to top of region.! + !* 0: End of region as .-Z.! + [.1[.2 !* Dot-qregs for passing to! + !* .E(1), the expander. .1! + !* will be the abbrev, and .2! + !* will be index into ..Q! + 0[Auto Fill Mode !* Bind auto-filling off.! + 0u..h !* First redisplay will.! + qModeu2 !* 2: Mode for expand checking.! + qWORDAB Ins Charsu1 !* 1: Get list of all characters that are expanders.! + qWORDAB Old Charsu4 :i114 !* ...! + :i*Expanding abbrevs[..j fr !* Display modeline.! + + f"e !* 3,4: bound last word.! + q3,q4x.1 !* .1: last word.! + :fo..qX .1 2 Abbrevf"gu.2 oEXP'w !* .2: ..q index if abbrev.! + :fo..qX .1 * Abbrevf"lw :c !'u.2 !* ...! + + !EXP! + 1u5 !* 5: Non-0 means can expand.! + < q6"e 2,m.i !* Redisplay and prepare for input! + !* without prompting or echoing. This! + !* will handle HELP, for instance.! + fi:fcu4' !* 4: Ask if expand.! + "# 32u4' !* 4: Force expand without asking.! + + !* Each of the following conditionals should either exit (1;) or! + !* repeat (Excl) this iteration. Falling through to the end of! + !* the iteration means an illegal character was typed. First the! + !* expanders. They expand if Q5 not = 0.! + + q4-!"e 1u6 32u4' !* 4: Excl turns into Space, and! + !* 6: sets no-asking flag.! + q4-32"e q5"n m:.e(1)' 1;' !* Space means expand and go.! + q4-,"e q5"n m:.e(1) 0u5'"# fg' !' !* Comma means expand, stay.! + q4-."e q5"n m:.e(1)' f;DONE' !* Period means expand, quit.! + q4--"e !* Dash means mark, expand, and stay.! + q5"n -:@f-*0,0-1uWord Abbrev Prefix Mark + !* The *0,0 just gets the! + !* 1st value.! + m:.e(1) !* Do the expansion and gluing.! + 0u5' !* 5: 0 means have expanded here.! + "# fg' !' !* Cannot expand any more.! + q4-"e  0u5 !' !* 5: Let user edit and then disallow! + !* further expanding here since point! + !* may not be after the abbrev which! + !* may not even be there either.! + q4-F"e fsVZ-q0f[VZ !* Protect end of region Q0.! + m(m.m^R Fill Paragraph)w !* Fill.! + f]VZ !* Get back end of vbuf.! + @v 0u5 !' !* 5: Stay but disallow further! + !* expanding since we dont really know! + !* that we are at an abbrev.! + q4-"e f;DONE' !* Altmode means quit.! + q4-14."e f+ !' !* Clears, redisplays, stays.! + q4-¢e 1;' !* Rubout means not expand, go.! + q4-?"e 4110.fsRereadw !' !* ? is like typing Help-character.! + + !* Getting here means none of the character-conditionals were taken,! + !* so the character is illegal. Complain.! + + fg q4m(m.m& Charprint) ft is meaningless here. + !* Tell what character is wrong.! + 4110.fsRereadw !* Go act like Help-character so tell! + !* what is ok.! + > !* Ignore any other commands.! + ' !* End of conditional on finding a! + !* word to check for expansion.! + @f1l > !* Move past expanders.! + + !* Used to be :FWL but since expanders do not have to be word! + !* delimiters, might loop infinitely on an abbrev which expands! + !* essentially to itself (e.g. emacs), followed by a non-delim! + !* expander, e.g. apostrophe in Text mode.! + +  + +!^R Abbrev Expand Only:! !^R Expand abbrev before point, but insert nothing. +If given an argument, will feep if last word isn't an abbrev.! +!^R Abbrev Expand ! !* For & Set Word Abbrev Chars.! + .( !* Save . for checking if expanded.! + 1f !* ...! + )-."e ff"g fg'' 1 !* Feep if ARG and no expansion.! + +!^R Abbrev Expand And Call Old Char:! !^R Expand abbrev before point, then old action. +Explicit numeric argument inhibits expanding. + f*0+1m(m.m& WRDAB Old Char Describe)! + +!^R Abbrev Expand ! + 1f 1 !* Exit here if thrown to.! + +!^R Abbrev Expand And Self-Insert:! !S Expand last word if an abbrev, then self-insert. +Giving an explicit numeric argument inhibits expansion, just inserting + that many copies of character that ran this. + f*0m(m.m& WRDAB Old Char Describe)! +!^R Abbrev Expand ! + 1f 1 !* Exit here if thrown to.! + +!^R Abbrev Expand for Tab:! !^R Expand abbrev at point if old Tab action inserts. +If Tab will not insert at point, no expansion is attempted. + (E.g. the Tab is reindenting the line, but point is mid-line.) +Explicit numeric argument inhibits expanding. + f*0+2m(m.m& WRDAB Old Char Describe)! + +!^R Abbrev Expand ! + [1[2[3[4 qWRDAB Old 11[5 [6 !* 5: Old tab function.! + 1f 1 !* Maybe thrown out of.! + +!^R Word Abbrev Prefix Mark:! !^R Remember point as end of an abbrev prefix. +Expansion of the prefix may occur unless an numeric argument is given. +Remembers this point as a prefix-end, and inserts a hyphen (which will + disappear if an abbrev expands just after that hyphen). E.g. you + might type "inter", mark that as a prefix (you see "inter-"), and + then type an abbrev ("inter-comm " which becomes + "intercommittee").! + m(m.m& Declare Load-Time Defaults) + Word Abbrev Prefix Mark, Point of prefix mark: 0 + + +!^R Abbrev Expand ! + ff"E !* No expanding if an ARG.! + 0,0a"c m:.e(0)'' !* Expand! + . m.vWord Abbrev Prefix Markw + .,(i-).  !* Hyphen is deleted when! + !* expansion occurs.! + +!& WRDAB Mode or Global Expand:! !S Maybe expand previous word. +Expand previous word if mode or global abbrev. +This goes on Q:.E(0) if user wants both modals and globals.! + -fwx*[.1 fq.1-86"g' !* .1: Last word, 86 max length to! + !* avoid STL error.! + qMode[.2 !* .2: Mode name.! + :fo..qX .1 .2 Abbrevf"lw :fo..qX .1 * Abbrevf"lw''u.2 + !* .2: Abbrev ..Q offset! + :m:.e(1) !* expand! + +!& Global Expand:! !S Expand previous word if global abbrev. +This goes on Q:.E(0) if user wants only globals.! + -fwx*[.1 fq.1-86"g ' !* .1: Last word, 86 max length to! + !* avoid STL error.! + :fo..qX .1 * Abbrevf"lw'[.2 !* .2: Abbrev ..Q offset! + :m:.e(1) !* expand! + +!& Expand:! !S .1 is abbrev, .2 is ..Q offset +This is the abbrev-expander, goes on Q:.E(1). +A pre-comma numeric argument inhibits auto-filling. (Since ^^M, e.g., + is called by some to insert CRLF but not auto-fill.)! + + m(m.m& Declare Load-Time Defaults) + WORDAB All Caps, + * Controls whether all-caps abbrev expands to all-caps. + 1 - all-caps expands to all-caps; if 0 - only 1st letters are caps: 0 + Word Abbrev Prefix Mark, Point of prefix mark: 0 + +!* +Say last word is "foo" and current mode is "ala": +If X foo ala Abbrev (for current mode ala) exists, it has exp. +Else if X foo * Abbrev exists (global abbrev), it contains expansion. + (Thus any mode abbrev "foo" overrides a global abbrev "foo".) +If expansion occurs: + If a hyphen to left of last word, and Word Abbrev Prefix Mark points + before it, then the hyphen is removed, gluing prefix to expansion. +If first letter of abbrev is capitalized, first letter of expansion will + be capitalized too. +If first and last letter of abbrev is capitalized (e.g. all letters), + we do more upper-casing, controlled by WORDAB All Caps: + If 0 then the first letter of each word in expansion is capitalized. + If non-0 then the entire expansion is upper-cased. + For one-word expansions, the former choice is meaninless so we do the + latter, fully upper-casing the single word. +In fill mode, line may be broken. +The comment for the abbrev variable is a string-number that tells the + number of times the abbrev has been used.! + +!* Information saved to allow unexpanding: + .E(2) is the "old string" -- from the beginning of the line up to and + including the abbrev. + .E(3) is the "new string" -- from the beginning of the line up to and + including the expansion. + .E(4) is the end point of the new string. + + Note that this allows auto-filling to change things a little before the + abbrev (e.g. whitespace) that will be ok since it doesnt go back before + the beginning of the line. We assume that the stuff after the abbrev + remains the same after expansion. Possibly some day auto-filling might + change it but...! + !* .1: abbrev.! + !* .2: ..Q-offset for abbrev var.! + [..0 !* ???! + q:..q(q.2+2)[.3 !* .3: usage-count string for ab var.! + q.3fp-101"N :i:..q(q.2+2)1' !* If count wasnt string, e.g. set by! + !* local mode of file, make string of 1.! + "# .(g.3)j .(1a-#"n \+1:\u:..q(q.2+2)')j fq.3d' !* Increment! + !* usage-count (string).! + + 0ff(x:.e(2)):[.6w !* .E(2): save old string for! + !* unexpanding later.! + !* .6: Point at start of line.! + + -fq.1d !* Delete the abbrev.! + 0,0a--"E !* Hyphen to left, ! + qWord Abbrev Prefix Mark+1-."E !* ...and a prefix just before it.! + :i.1-.1 !* Update last word to include hyphen.! + -d'' !* ...So remove hyphen, gluing prefix on.! + + .[.4 !* .4: Point before expansion.! + g:..q(q.2+1) !* Insert the expansion.! + .[.5 !* .5: Point after expansion.! + -1[.7 !* .7: start at char 0 (we increment 1st)! + fq.1[.8 !* .8: get length of Q.1! + <%.7-q.8; !* dont search beyond the end of string! + q.7 :g.1"a0;'> !* but find the first alphabetic char ! + q.7-q.8"l q.7:g.1"u !* 1st letter of abbrev was capitalized.! + q.4j :fwl !* find where to start capitaliztion.! + 1 @fc !* So capitalize expansion.! + q.8-1 :g.1"u !* Last letter of abbrev was capitalized.! + qWordab All Caps"e !* Supposed to uppercase first letters.! + 0u.3 !* ... .3: 0 word count.! + :< 2:fwl .-q.5; %.3w !* ... .3: Iter over expansion, count! + !* ... words.! + 1 @fc >w !* ... Cap each word in expansion.! + q.3"e q.4,q.5 @fc'' !* ... One-word expansion means all caps.! + "# !* Supposed to cap whole expansion.! + q.4,q.5 @fc'' !* ...So uppercase everything.! + '' !* End of first let capped.! + + + q.5j !* Move to end of expansion.! + q.4,q.5 f !* Tell ^R of changes to buffer.! + + + !* Now repeatedly auto-fill this line until it fits. We may need to fill! + !* multiple times since expansion may be several words long. 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.! + + ff-1"G oUPDATE ' !* No auto-fill if pre-comma ARG.! + + qAuto Fill Mode"e oUPDATE' !* If not filling, can skip this.! + + m.m^R Auto-Fill Space !* S: space.! + 0f/2< .-(0mSf !* Auto-fill maybe, tell ^R mode.! + ).@; > !* Repeat until point doesnt change,! + !* which means no fill happened.! + + !UPDATE! + + q.6,.x:.e(3) !* .E(3): Save new string for! + !* unexpanding later.! + .u:.e(4) !* .E(4): Save end of new string too.! + + !* Now we maybe call a word abbrev macro.! + 0:g:..q(q.2+2)-#"e !* Aha -- a word abbrev macro.! + q:..q(q.2)u.4 !* .4: abbrev variable name.! + fq.1+3,fq.4-7:g.4u.4 !* .4: just the mode part of it.! + mX .1 .4-WABMAC Abbrev' !* So call its macro part.! + +  + +!^R Unexpand Last Word:! !^R Undo last expansion, leaving the abbrev. +Another ^R Unexpand Last Word will redo the expansion. +An effort is made to keep point unchanged, but if unexpanding causes a change + in the text around point, point may move.! + +!* Information saved to allow unexpanding: + .E(2) is the "old string" -- from the beginning of the line up to and + including the abbrev. + .E(3) is the "new string" -- from the beginning of the line up to and + including the expansion. + .E(4) is the end point of the new string.! + + + [0[1[2[3[4[5 + + !* First figure what point to restore when done. Note that string is not! + !* just expansion or abbrev, but entire line up to and including expansion or! + !* abbrev. We restore point if after the string (using .-Z), or if it is! + !* before the string (using .), or if it is in the first part of the string! + !* -- the part of length min(l(old),l(new)). This part is likely to be text! + !* before the abbrev on the same line, so is a good guess for restoration.! + !* P is .E(4), L1 is .E(3), L2 is .E(2).! + + .-(q:.e(4)-(fq:.e(3)-fq:.e(2)f"lw 0'))"l !* . lt P-(max(0,l1-l2)).! + .u4 fnq4j' !* 4: Point before or in overlap.! + "# q:.e(4)-.f"g+.'"#w .'-zu4 fnq4+zj' !* 4: Point after string restored, but! + !* in string moves to end of string.! + + q:.e(4):j"e oNONE' !* Back to end of new string.! + q:.e(3)u0 !* 0: New string.! + fq0u1 q1:"g oNONE' !* 1: Length of new string.! + .-q1f"l oNONE'u2 !* 2: Start of new string.! + q:.e(2)u3 q3fp"l oNONE' !* 3: Old string.! + q2,.f~0"n !* Make sure new string is where it is! + !* supposed to be.! + !NONE! fg @ft +No last expansion 0fsEchoActivew 1 ' !* ...! + + q2,.k !* Remove the new string.! + g3 !* Insert the old string.! + + !* Now try to specify the changed region as small as possible. The problem! + !* is that the old/new strings are entire lines. We will compare them to try! + !* to trim down to (near) the difference. In particular, for common case of! + !* one word expanding to larger word or phrase, dont want the beginning part! + !* of line included: (note that ,0f takes the absolute value) ! + + q2+(f=03,0f)-1,.f !* Tell Teco of the changed area.! + + !* Now reorder .E information to allow another unexpand to actually do a! + !* re-expansion.! + + q0u:.e(2) !* New string becomes old string.! + q3u:.e(3) !* Old string becomes new string.! + .u:.e(4) !* Current point is end of the now new! + !* string which is to say the old! + !* string if you catch my meaning.! + 0 + +!WORDAB:! +!Word Abbrev Mode:! !C Turn Word Abbrev mode on or off. +Given no argument, the mode is toggled (turned on if it was off, and + turned off if it was on). +Given positive argument, the mode is always turned on. +Given 0 or negative argument, the mode is turned off. +Giving this command 1 as a pre-comma argument means that you only use + global abbrevs, and things are set up to be faster (e.g. faster + expansion checking since it doesn't have to check both global and + local abbrevs). +Each of the following chars: ~@#;$%^&*()-_=+[]\|:'`"{},<.>/?, Space, + Return, and Tab, will cause expansion of abbrevs followed by their + normal action. +If you wish to supply additional characters that should expand, see + the description of Make These Characters Expand. +If you wish to completely replace this list of expanding characters, + set the variable WORDAB Ins Chars in your init or EVARS file to + the string of characters that should expand.! + +!* M-X Word Abbrev should be M-X Word Abbrev Mode, by the policy that says! +!* that just giving the name of the mode should call the mode function. Just! +!* as M-X Text should turn on Text mode.! + + [0 + ff&2"n !* First, if we were given a pre-comma NUMARG, that means we! + !* should reset the kind of expander-checker (modal/global or just! + !* global). We let the fsVarMacro for Only Global Abbrevs! + !* do all the work.! + uOnly Global Abbrevs' !* ...! + + ff&1"n "'gu0' !* 0: if NUMARG, then -1 if NUMARG was! + !* positive, 0 else.! + "# qWord Abbrev Mode"'eu0' !* 0: 0 if was on, -1 if was off.! + q0,0fuWord Abbrev Mode !* Set the variable, running its! + 0 !* fsVarMacro to turn the mode! + !* on/off.! + +!Define Word Abbrevs:! !C Define abbrevs from a definition list in the buffer. +Buffer should contain the word abbrev definition list. +If given a pre-comma numeric argument, all abbrevs will be killed + before defining the new ones from the buffer. (The old abbrevs + are not killed until we are sure that the syntax of the buffer's + definition list is correct.)! + +!* We put the whole definition list (teco version) onto the variable for the! +!* incremental definitions, just to be complete. For huge lists this could be! +!* pretty bad, but then that doesnt seem likely.! + +!* Format of buffer: + ::= null | + ::= : " " + may be more than one line, and may have '"'s in it as long as + they are quoted with another '"'. + ::= + ::= null | ( ) + ::= null | +For now nothing else, no :s in . + is the name of a major mode (e.g. LISP), if abbrev is to be + effective only in that mode. It is ommitted if the abbrev is to be + effective in all modes. + is a usage-count for the abbrev -- i.e. how many times the + abbrev has been used before. Could be #0 too for word abbrev macros. + is any number (including 0) of spaces and tabs.! + + m(m.m& Declare Load-Time Defaults) + Word Abbrevs Modified, Non0 means definitions have changed: 0 + + + !* For nice errors to the user, since the standard EMACS ..P will redisplay! + !* the buffer, syntax errors jump to a common point to switch back to the! + !* human buffer.! + + [.1[.2[.4[E !* E for error messages.! + q..o[B !* B: Users definition buffer.! + g(q..o(f[BBindw)) !* Temp buf, init with defns.! + bj 0s <:s;ric> !* Teco-quote alts, ^]s.! + zj i + !* Ensure something after final quote! + + bj + < @f +l .-z; !* Past any blank lines.! + fwfx.1 !* .1: Next .! + 0,1a-:"n :iENo : ending abbrev .1 oERR' + d !* Remove colon.! + @f  k !* Remove .! + 0,1a-("E d .u.2 :fb)"e :iENo ) after mode name for abbrev .1 oERR' + !* .2: Point starting name.! + -d q.2,.fx.2 d' !* .2: name.! + "# :i.2*' !* .2: * for global.! + @f  k !* Remove .! + @f#0123456789 fx.4 !* .4: usage-count.! + !* Note that # can be used to flag! + !* this ab as having a WABMAC.! + fq.4"E :i.40' !* .4: 0-string by default.! + @f  k !* Remove .! + 0,1a-34"N :iENo quote to start expansion for .1 oERR' + d i:i* !* Delete quote, make command.! + 0s" !'! <:s"e :iENo quote to end expansion for .1 oERR' + 0,1a-":@; c> !'! !* Find unquoted doublequote.! + 15.,1a-15."n + :iEPossible unquoted " in expansion for .1 -- final " not at end of line + oERR !''!' + -d !* Remove endquote.! + iM.VX .1 .2 Abbrevw !* Make expansion command.! + i M.CX .1 .2 Abbrev.4 !* Make set-comment command.! + > !* Next abbrev defn.! + j 0s"" <:s; -d> !''! !* Take quote-quoters off.! + + !* If we got here ok, the syntax in the buffer is good. Now we can kill! + !* previously defined abbrevs if we were given a pre-comma.! + + ff&2"n m(m.mKill All Word Abbrevs)' !* Kill, kill, kill.! + + m(hx*) !* Define by running buffer.! + !* This used to be m..o but sometimes Teco seems to have trouble --! + !* rare but strange when it happens, e.g. seeming to get the wrong! + !* start PC or something.! + + 1uWord Abbrevs Modified + + j g( 0fo..qLately Changed Abbrevsf"ew :i*' ) i + !* Append to incremental definitions.! + hx*m.vLately Changed Abbrevsw !* ...! + +  + + !* Syntax error reporting. Switch to users definition buffer, and! + !* put point at the beginning of the erring line. We cannot really! + !* do better with certainty since Teco-quoting altmodes and ^]s fouls! + !* up point (otherwise Z-. would be about the same as in the human! + !* buffer except for final CRLF.) So we count lines back from end of! + !* buffer.! + + !ERR! + + 0l .fsVBw 0u.2 zj <-l b-.; %.2w> !* 2: # of lines from end.! + qb[..o !* Switch to user buffer.! + zj !* Put point at erring line.! + qe fsERR  !* Report the error, and catch any! + !* unexpected continuing.! + +!Make Word Abbrev:! !C Define one word abbrev, global or for any mode. +After doing M-X Make Word Abbrevfoofind outer otter, typing "foo" + will automatically expand to "find outer otter". +3rd string argument, if any, is the mode for the abbrev. +No 3rd string argument means use the current mode. +3rd string argument = "*" means this make a global abbrev. +This command defines just one abbrev, as compared to Define Word + Abbrevs which defines several abbrevs from a list in the buffer.! + + :i*( :i*( :i*[.3)[.2)[.1 !* .1: Abbrev.! + !* .2: Expansion.! + !* .3: Mode or * or null.! + fq.3"E qMODEu.3' !* .3: Mode or *.! + + q.1,q.2 m(m.m& Check And Make Word Abbrev).3 !* Define.! + w 1  + +!Make These Characters Expand:! !C Add characters to the list of abbrev expanders. +E.g. M-X Make These Characters Expand1234567890 will cause the + digits to expand any abbrev before them, just like #$%.,/? etc. + Note, though, that this will not necessarily make digits be + word-delimiters. +If your keyboard has Top-characters (e.g. Top-Z is alpha), you can + have them be expanders too, though some of them can't be typed to + ^R Extended Command (namely Top-Q and Top-M). Also: if you + put this command into an init file, be careful to double any use + of Top-S (namely C-]). +You can have an EVARS file (as opposed to an init file) declare + additional expanders too in a simple way -- just put the + characters into the variable Additional Abbrev Expanders. E.g. to + make the digits expand, put the following line into your EVARS + file (you need the "*" to force it to be a string): +Additional Abbrev Expanders:*1234567890 (Top-character users: in an + EVARS file you would not need to double Top-S.)! +!* The string of expanders may also be passed as a pre-comma numeric argument.! + + !* Note the s used below to bound the WORDAB Ins Chars string value.! + m(m.m& Declare Load-Time Defaults) + WORDAB Ins Chars, Self-inserting expanders: !~@#;$%^&*-_=+[]()\|:`"'{},<.>/? + + WORDAB Old Chars, Hairy expanders: || + + + !* We add the new expanders to the self-inserter list, since they will be! + !* moved to the old-character list automatically and correctly in most cases.! + !* There are some weird situations, possibly wrong: having lambda (Top-V and! + !* also Backspace) in the list will make Backspace self-insert a lambda! + !* instead of moving back. This is because the check is not for! + !* self-insertion but just builtin-ness. That could be corrected. See the &! + !* WRDAB Turn On Ins Char routine.! + + [0[1 + ff&2"n u0' !* 0: Pre-comma NUMARG, new expanders.! + "# :i0' !* 0: STRARG, new expanders.! + qWORDAB Ins Charsu1 !* 1: self-inserter list.! + :iWORDAB Ins Chars10 !* Append new expanders to! + !* self-inserter list.! + :m(m.m& WRDAB Process Options Hook) !* Process the expander lists now to! + !* install the expanders and migrate! + !* any hairy old definitions to the! + !* WORDAB Old Characters list.! + +!^R Add Mode Word Abbrev:! !^R Define an abbrev for word(s) before point. +Negative numeric argument means to delete the word abbrev. (If there + is no such mode abbrev, but there is a global, it asks if it + should kill the global.) +Positive numeric argument (>0) means expansion is that many last + words. +Zero numeric argument means expansion is between point and MARK. +(Extension writers: If Teco's fs^RMark set, that means expansion is + between . and fs^RMark.) +The abbrev is only effective when in the current mode (e.g. LISP).! + "L f @:m(m.m^R Kill Mode Word Abbrev) ' !* Neg ARG, delete.! + qMode[.1 !* .1: Current major mode.! + f @m(m.m& Add Word Abbrev).1.1 Abbrev !* Call with SP ! + !* for varname, MODE Abbrev as prompt.! + w 1  + +!^R Add Global Word Abbrev:! !^R Define an abbrev for word(s) before point. +Negative numeric argument means to delete the word abbrev. +Positive numeric argument (>0) means expansion is that many last + words. +Zero numeric argument means expansion is between point and MARK. +(Extension writers: if fs^RMark set, that means expansion is between + . and fs^RMark.) +The abbrev is effective in all major modes.! + "L f @:m(m.m^R Kill Global Word Abbrev) ' !* Neg ARG, delete.! + f @m(m.m& Add Word Abbrev)*Global Abbrev !* Call with * ! + !* stringarg for varname, Global... as! + !* prompt string.! + w 1  + +!^R Inverse Add Mode Word Abbrev:! !^R Define the expansion for abbrev before point. +Numeric argument n means nth word before point is to be an abbrev + (e.g. you thought it already was, and you are now n words + beyond). No numeric argument means the word just before point, + same as argument of 1. +Reads a one-line expansion for the abbrev, defines it, and expands + it.! + + qMode[.4 + .-z[.0 !* .0: Orig .-z.! + -:fwl !* Move back to end of abbrev.! + -fwx*[.1 !* .1: Abbrev.! + 1,m(m.m& Read Line)Expansion for .4 abbrev ".1": [.2 !''! + !* .2: 0 or expansion string.! + q.2"e 1' !* 0, abort.! + fq.2"e 1' !* Null, abort.! + m(m.mMake Word Abbrev).1.2 !* Current mode abbrev.! + @m(m.m^R Abbrev Expand Only)f !* Expand abbrev before point.! + q.0+zj !* Back to orig point.! + 1 !* Return, display done already.! + +!^R Inverse Add Global Word Abbrev:! !^R Define the expansion for abbrev before point. +Numeric argument n means nth word before point is to be an abbrev + (e.g. you thought it already was, and you are now n words + beyond). No numeric argument means the word just before point, + same as argument of 1. +Reads the expansion in the echo area. (This command cannot define + multi-line expansions.) +Defines that abbrev, and then expands the abbrev before point. +Aborts if you abort the line-reading with Rubout, or if the expansion + is null.! + + .-z[.0 !* .0: Orig .-z.! + -:fwl !* Move back to end of abbrev.! + -fwx*[.1 !* .1: Abbrev.! + 1,m(m.m& Read Line)Expansion for global abbrev ".1": [.2 !''! + !* .2: 0 or expansion string.! + q.2"e 1' !* 0, abort.! + fq.2"e 1' !* Null, abort.! + m(m.mMake Word Abbrev).1.2* !* Current mode abbrev.! + @m(m.m^R Abbrev Expand Only)f !* Expand abbrev before point.! + q.0+zj !* Back to orig point.! + 1 !* Return, display done already.! + +!^R Kill Mode Word Abbrev:! !^R Remove the definition for one abbrev. +Same as ^R Add Mode Word Abbrev with a negative numeric argument.! + :i*Fundamental fo..qMODE[.2 !* .2: Mode name.! + 1, m(m.m& Read Line)Kill .2 Abbrev: [.1 !* .1: Abbrev.! + q.1"E ' !* Abort.! + 0fo..qX .1 .2 Abbrev"E !* No such mode abbrev.! + 0fo..qX .1 * Abbrev"E !* And no global either.! + FG @ft".1" is neither .2 mode nor global abbrev. !''! + 0fsEchoActivew 1 ' !* Do nothing, and dont erase message! + "# FG @ft".1" is not a .2 mode abbrev, but is a global abbrev. +Kill it? !''! + 1m(m.m& Yes Or No)"E !* ask him! + @ft Not killed. 0fsEchoActivew 1 ' !* he said no! + :i.2*'' !* .2: Reset to kill global.! + m(m.mKill Variable)X .1 .2 Abbrev !* Expunge abbrev.! + m(m.mKill Variable)X .1 .2-WABMAC Abbrev !* And any hook on it.! + 1uWord Abbrevs Modified + + 0fo..qLately Changed Abbrevsf"ew :i*'u.4 !* .4: Incremental abbrevs.! + @:i*|.4 +mkX .1 .2-WABMAC Abbrev +mkX .1 .2 Abbrev| m.vLately Changed Abbrevsw + !* Add an incremental. K will be! + !* bound to Kill Variable in the! + !* file.! + w 1  + +!^R Kill Global Word Abbrev:! !^R Remove the definition for one abbrev. +Same as ^R Add Global Word Abbrev with a negative numeric + argument.! + 1, m(m.m& Read Line)Kill Global Abbrev: [.1 !* .1: Abbrev.! + q.1"E ' !* Abort.! + 0fo..qX .1 * Abbrev"E !* No such.! + FG @ft".1" is not a global abbrev. !* so tell him! + 0fsEchoActivew 1  !''! ' !* and let it stay on the screen! + m(m.mKill Variable)X .1 * Abbrev !* Expunge abbrev.! + m(m.mKill Variable)X .1 *-WABMAC Abbrev !* And any hook on it.! + 1uWord Abbrevs Modified + + 0fo..qLately Changed Abbrevsf"ew :i*'u.4 !* .4: Incremental abbrevs.! + @:i*|.4 +mkX .1 *-WABMAC Abbrev +mkX .1 * Abbrev| m.vLately Changed Abbrevsw + !* Add an incremental. K will be bound to! + !* Kill Variable in the file.! + w 1  + +!& Add Word Abbrev:! !S Reads an abbrev for words before point. +Stringarg1 is "*" for global abbrev, and space-modename for a mode + abbrev, e.g. " TECO". +Stringarg2 is & Read Line prompt. +Calls & Read Line to read the abbrev. +ARG non-0 means expansion is last ARG words. (Includes breaks in + between words, but not those before first or after last word.) +ARG 0 means expansion is between point and MARK. +If fs^RMark set, then for any ARG expansion between . and fs^RMark. +If the abbrev is already defined, user is asked if redefinition + wanted. +The abbrev must not contain any break characters. +Abbrev variable is constructed: X abbreviation Abbrev. Its + value is a string which is the expansion.! + :i* [.2 !* .2: Modename part of varname.! + [.3[.4[.5.[.6 fnq.6j !* .6: Auto-restoring point.! + + 1:"N FG F*w 1 ' !* No expansion found.! + !* .3: expansion start.! + Q.3,. fx.3 !* .3: expansion.! + m.m& Shorten String !* S: & Shorten String.! + m.m& Read Line !* R: & Read Line.! + q.3mSu.4 !* .4: Short expansion string.! + 1,mR for ".4": [.1 !''! !* .1: Abbrev.! + q.1"E 1 ' !* Abort.! + + q.1,q.3 m(m.m& Check And Make Word Abbrev).2 !* Define.! + 1  + +!& Check And Make Word Abbrev:! !S Basic definer subroutine. +Pre-comma numeric argument is abbrev. +Post-comma numeric argument is expansion. +String argument is "*" or modename. +Checks for break characters in abbrev (not allowed).! + + m(m.m& Declare Load-Time Defaults) + Word Abbrevs Modified, Non0 means definitions have changed: 0 + Last Word Abbrev Defined, Variable name: 0 + + + :i*[2 [1 [3 !* 1,2,3: abbrev, mode, expansion.! + :iLast Word Abbrev DefinedX 1 2 Abbrev + q1[4 [5 !* 4: Abbrev copy, for letter checking.! + fq1< 0,1:g4u5 !* 5: 1st char in rest of abbrev copy.! + 5"b fg @ft +Break chars not allowed in abbrev 0fsEchoActivew 1 ' + 1,fq4:g4u4> !* 4: Each iter, chop off one letter.! + + m.m& Shorten String !* S: & Shorten String.! + + 0fo..qX 1 2 Abbrevu4 !* 4: 0 or old expansion.! + q4"N f=34"N FG !* Already defined, ask confirm.! + q4mSu4 !* 4: short form of old expansion.! + @ftRedefine "1" from "4"?  !''''! !* ...! + 1m(m.m& Yes or No)"E @ftNot redefined. !* tell him! + 0fsEchoActivew 1 '' !* dont flush the message! + "# @ftAlready so defined. !* tell him, and! + 0fsEchoActivew 1 '' !* Dont reset usage-count.! + + q3m.vX 1 2 Abbrevw !* Define expansion.! + m.cX 1 2 Abbrev0 !* Set usage-count comment string.! + 1uWord Abbrevs Modified + + f[BBind !* Temporary buffer.! + 0fo..qLately Changed Abbrevsf"ew :i*'u4 !* 4: incrementals.! + g4 !* Get previous incrementals.! + @i| +mvX 1 2 Abbrev| !* Up to where expansion goes.! + !* V will be bound to & Make Non-Usage! + !* Abbrev Variable in the file.! + .(g3)j !* Get expansion, point before.! + 0s <:s; r i c> !* Teco-quote altmodes and C-]s.! + zj @i|0| !* Finish off the incremental.! + !* Note that the usage count is a fake! + !* -- seems not possible to do right! + !* for incrementals.! + hx*m.vLately Changed Abbrevsw !* Save the incrementals.! +  + +!Edit Word Abbrevs:! !C Allow user to edit the list of defined word abbrevs. +Note that any '"'s are doubled so that the syntax is unambiguous. + E.g. if the abbrev 'xsay' is to expand to 'He said "Hello".', + then it will be: + xsay: 1 "He said ""Hello""." +A recursive edit level is entered. When exited by ^R Exit the + buffer will be considered as new definitions of all word + abbrevs. Any abbrevs missing from the list will be killed. +Abort Recursive Edit will abort M-X Edit Word Abbrevs, leaving + word abbrevs untouched.! + + fq(:i*)"g !* We do not edit just some.! + :i*C fsEchoDisplayw !* So clear the echo area,! + @ftWarning: M-X Edit Word Abbrevs ignores its string argument -- +it does not filter. All abbrevs are being edited. !* ...! + 0fsEchoActivew' !* ...! + + 0[..f !* Disallow file hacking.! + f[BBind !* Get a temp buffer, ! + m(m.mInsert Word Abbrevs) bj !* ...and set up list to edit.! + :i*Edit Word Abbrevs[..J !* Set mode line.! + + !* The iteration/error-catch is so that if the user gets an error in! + !* Define Word Abbrevs, the user will stay editing the abbrevs, so can! + !* correct incrementally -- rather than having one error force the! + !* entire edit again.! + + fw !* But if successful, exit.! + > !* ...! + + fsEchoDisplayw CfsEchoDisplayw !* Clear echo area.! + @ftWord abbrevs redefined. !* Tell user.! + 0fsEchoActivew !* Dont clear echo area after.! + 1 + +!List Word Abbrevs:! !C Print some or all word abbrev definitions. +Lists a table of word abbrev definitions for currently defined + abbrevs. +If string argument is null, all abbrevs are listed. +If there is a string argument, it filters which abbrevs' definitions + are listed. (Actually, it is a TECO search string.) If the + abbrev, its mode, or its expansion contains the filter that + definition is listed. +Giving a numeric argument will control what the filter applies to: + 0 or 7 (same as no argument): abbrev, mode, or expansion + 1: abbrev only + 2: expansion only + 4: mode only +Combinations by summing the above -- e.g. 3 means abbrev or expansion, + but not mode.! + + f[BBind !* Temporary buffer to insert into.! + :ftabbrev: (mode) count "expansion" + + !* Print header.! + 1,(f)m(m.mInsert Word Abbrevs) + !* Insert them, listing as go. Pass! + !* along any argument and filter.! + fsListen"e ftDone. +'"# ftFlushed. +' !* Tell user we are done, how.! + 1 + +!Insert Word Abbrevs:! !C Insert a list of some or all word abbrev definitions. +Inserts a table of word abbrev definitions for some or all of the + currently defined abbrevs. Format is that used by M-X List Word + Abbrevs and M-X Edit Word Abbrevs. +If string argument is null, all abbrevs are inserted. +If there is a string argument, it filters which abbrevs' definitions + are inserted. (Actually, it is a TECO search string.) If the + abbrev, its mode, or its expansion contains the filter, that + definition is inserted. +Giving a numeric argument will control what the filter applies to: + 0 or 7 (same as no argument): abbrev, mode, or expansion + 1: abbrev only + 2: expansion only + 4: mode only + Combinations by summing the above -- e.g. 3 means abbrev or + expansion, but not mode. +Extension writers: giving a 1 pre-comma argument causes the + definitions to be listed as they are inserted.! + + [1[2[3[4[5[6[7 [9 1,f Insert abbrevs matching: f"e'[0 + + !* 0: Match string.! + fq0"g 0s0'"# 0u0' !* 0: 0 if no filter. Else! + !* set search default here.! + f"n&7'"#w 7'u1 !* 1: Bits, non-0.! + .f[VB fsZ-.f[VZ !* Narrow bounds.! + + "n m.m& Maybe Flush Output' !* A: Flusher needed if typing as we! + !* go.! + + :fo..qX u9 q9"l -q9u9' !* 9: ..Q index to first! + !* abbrev.! + + + fq..q/5-q9/(q:..q(0))( !* Number of slots to examine.! + q9-1u9 !* 9: Start back one word.! + )< !* Iterate over variables.! + + q:..q(%9)u2 !* 2: Next variables name.! + q:..q(%9)u3 !* 3: Its value.! + q:..q(%9)u4 !* 4: Its comment.! + + .u5 !* 5: Start of abbrev insert.! + + q3fp"l oNEXT' !* Skip variable if numeric value.! + !* E.g. may be a local abbrev in! + !* another buffer. Or just broken.! + + g2 !* Insert variable name.! + -7f~ Abbrev"n oNEXT' -7d !* Skip if not abbrev.! + q5j 2f~X "n oNEXT' 2d !* ...! + + @:f l d .u6 !* 6: Point between abbrev, mode.! + + zj .u7 g3 !* 7: Point between mode, expansion.! + !* Insert value string.! + + q0"n !* Must filter this abbrev.! + q1&1"n q5,q6:fb"l oINS'' !* Bit 1 -- filter abbrev.! + q1&2"n q7,z:fb"l oINS'' !* Bit 2 -- filter expansion.! + q1&4"n q6,q7:fb"l oINS'' !* Bit 3 -- filter mode.! + oNEXT' !* Filter failed -- skip abbrev.! + + !INS! !* Now we are sure we insert this! + !* abbrevs definition. Must prettify! + !* the junk inserted so far.! + + q6j !* To end of abbrev.! + .,q7f=*"e !* Global abbrev.! + d i: ' !* ..! + "# q7-zu7 !* 7: Z-relative point now, between! + !* mode and expansion.! + i: ( !* Separate abbrev, mode.! + q7+zj i) ' !* Separate mode, count.! + g4 !* Get comment -- usage count or sharp! + !* if WABMAC.! + i " !* Separate count, expansion.! + <@:f"l .-z; i" c> !* Double all double quotes in the! + !* expansion.! + i" + !''''! !* Terminate the expansion, finishing! + !* the definition for this abbrev.! + + "n !* Pre-comma NUMARG means type out as! + !* go and flush if typeahead.! + q5,.t' !* Type now, flush later.! + + .u5 !* 5: Set so the q5,zk is no-op.! + + + !NEXT! !* Some jump here to skip an abbrev.! + + q5,zk !* Kill garbage if skipping.! + "n ma1;' !* Abort if typeahead. Done here so! + !* will flush as soon as user types --! + !* if did it when type, would be long! + !* wait until a filtered abbrev,! + !* perhaps.! + + > !* On to next variable.! + + h !* Return bounds of inserted! + !* definitions.! + +!Kill All Word Abbrevs:! !C Kill all abbrev definitions, leaving a blank slate. +It is as if you had not read or defined any word abbrevs.! +!* For use in conjunction with editing what M-X Insert Word Abbrevs inserts, + and then after M-X Kill All..., doing M-X Define Word Abbrevs. + Or just something user might want (I do at times).! + + [.1[.2[.3 + q..q[..o zj !* Buffer: symbol table.! + !* Will go thru symtab backwards looking! + !* for word abbrev variables.! + + :f !* End of COND.! + > !* End of iter over all entries.! + + 0uWord Abbrevs Modified !* Since as if never defined any! + !* abbrevs, they are therefore not! + !* modified yet.! + :i*m.vLately Changed Abbrevsw !* And no incrementals.! +  + +!Read Word Abbrev File:! !C Define word abbrevs from an abbrev definition file. +Stringarg is word abbrev definition file. +Default is ;WORDAB DEFNS. +File may be in default fast-loading foramt or human-readable format. +This will not complain if the file does not exist.! + + + f[DFile 1f[FnamSyntax !* Save default filename *! + 0fo..qLast Word Abbrev Filef"n fsDFilew' !* Either last-used or *! + "#w etDSK:WORDAB DEFNS fsHSnamefsDSnamew' !* else a default. *! + 4,4f Word Abbrev Filef"ew'fsDFilew !* Read string argument *! + fsDFilem.vLast Word Abbrev Filew !* save for defaulting *! + e?"n ' !* Exit if file not found, quietly.! + f[BBind er @y !* Read in QWABL file. *! + + !* See if human-readable format definition file: ! + + 10f~m.m& Make "n !* All QWABL files start that way, and! + !* no Define Word Abbrevs type can.! + :m(m.mDefine Word Abbrevs)' !* Is user-readable kind, define from! + !* it, the slow way.! + + !* The file is in the QWABL style: ! + + m(hx*) !* Define by running buffer since! + !* QWABL files are just big Teco! + !* macros that define the abbrevs.! + !* This used to be m..o but sometimes Teco seems to have trouble --! + !* rare but strange when it happens, e.g. seeming to get the wrong! + !* start PC or something.! + +  !* Make sure we pop things.! + +!Write Word Abbrev File:! !C Write all the current abbrev definitions to a file. +Stringarg filename. Default is WORDAB DEFNS. +Argument present means do not write out usage counts. +Normally writes a fast-loading format file, but if you have the + Readable Word Abbrev Files option variable set to 1, it will write + a human-readable format file (like that used by + List Word Abbrevs). +Default filenames come from last definition filename used.! + + m(m.m& Declare Load-Time Defaults) + Readable Word Abbrev Files, * Non-0 means write human-readable kind: 0 + + [.0[.1[.2[.3[.4[.5 f[DFile !* save regs! + 1f[FnamSyntax !* Lone fn is first fn. *! + 0fo..qLast Word Abbrev Filef"n fsDFilew' + "#w etDSK:WORDAB DEFNS fsHSnamefsDSnamew' + 4,1f Word Abbrev Filef"ew'u.0 !* Read string argument *! + et.0 fsDFileu.0 !* .0: Set default fn. *! + q.0m.vLast Word Abbrev Filew !* Save for next time. *! + + f[BBind !* Temp buffer. *! + + qReadable Word Abbrev Files"n !* User wants readable kind.! + m(m.mInsert Word Abbrevs) !* Make a list of that kind.! + oWRITE' !* Go write them out.! + + :fo..qX u.2 !* .2: $X ^@$ offset, before any abbrevs.! + q.2"L -q.2u.2' !* .2: $X ^@$ offset, positive.! + !* .2: Running ..Q index for abbrevs.! + ff&1"E !* QWABL file has usage counts. *! + @i|m.m& Make Usage Abbrev Variable !* V: Will be variable-maker. *! +|'"# !* QWABL file has no usage counts. *! + @i|m.m& Make Non-Usage Abbrev Variable !* V: Will be variable-maker. *! +|' + iq..q[..o !* Will select symtab buffer. *! + + 0s !* Search default, used for! + !* quoting Alts and C-]s.! + fq..q/5-q.2/3( !* Number of var slots to examine in ..Q.! + q.2-1u.2 !* .2: Start ..Q - 1.! + )< q:..Q(%.2)u.3 !* .3: Next variable name.! + q:..Q(%.2)u.4 !* .4: Next variable value.! + q:..Q(%.2)u.5 !* .5: Next variable comment.! + q.4fp"L oNEXT' !* Skip variable if value is number.! + !* (Local vars become 0 when not in their! + !* buffer.)! + f~(0,2:g.3)X "N oNEXT' !* Skip this variable if not $X ...$, ! + f~(fq.3-7,fq.3:g.3) Abbrev"N oNEXT' !* ...or if not $... Abbrev$.! + iMV.3 !* Insert var-maker call, varname. *! + + .(g.4)j <:s; r i c> zj i !* Insert expansion and Teco-quote any! + !* Altmodes or C-]s in it.! + + ff&1"E g.5 i' !* Insert usage if no argument or only! + !* pre-comma argument.! + i + !* Finish this definition.! + + !NEXT! > !* Repeat for next variable.! + + !WRITE! + + eihpef.0 !* Write it out.! + er fsIFileu.0 ec @ft +Written: .0 + !* Tell user the full filename.! + 0uWord Abbrevs Modified !* Abbrevs no longer modified with! + !* respect to save files.! + 0fsEchoActivew 1  + +!Write Incremental Word Abbrev File:! !C Write abbrevs defined/changed since dumping this environment. +Writes to file named by string argument. Defaults to home directory, + INCABS > (INCABS..0 on Twenex.). +This command is used by people with a large number of abbrevs, and who + dump their environments. The init file should generally use M-X + Write Word Abbrev File, and the & Startup... should use + M-X Read Incremental Word Abbrev File.! + +!* (This does not reset the default filename for M-X Write Word Abbrev + File and Read Word Abbrev File. I'm not sure of the correctness + of this, though.)! + + m(m.m& Declare Load-Time Defaults) + Word Abbrevs Modified, Non0 means definitions have changed: 0 + + + [1 + e[e\ fne^e] f[DFile 1f[FNamSyntax !* Save I/O channels, filename.! + etDSK: fsHSNamefsDSNamew etINCABS > !* Default to home directory.! + 4,1f Incremental Filef"e w'u1 !* Read string argument *! + + f[BBind !* Temporary buffer.! + g(0fo..qLately Changed Abbrevsf"ew :i*') !* Get incrementals, which are! + !* teco commands.! + z"e :i*No incremental abbrevs to write fsErr' !* Better to err than! + !* print a message, since more useable! + !* by other commands.! + !* Put the file-header on, which will bind QV and QK, as well as select the! + !* symbol table buffer. Keep this header as two lines, for possible back! + !* compatibility to Lisp Machine usage. (Ugh... Still necessary/)! + + j @i|m.m& Make Non-Usage Abbrev Variable q..q[..o +m.mKill Variable +| !* Were no incrementals.! + + eihpef1 !* Write to filename STRARG.! + er fsIFileu1 ec @ft +Written: 1 + + 0uWord Abbrevs Modified !* No longer modified with respect! + !* to save files.! + 0fsEchoActivew 1 + +!Read Incremental Word Abbrev File:! !C Define abbrevs changed since dumping. +String argument is filename that contains incremental abbrev + definitions, written by M-X Write Incremental Word Abbrev + File. Default is home directory, INCABS >. +This command is used by people with a large number of abbrevs, and who + dump their environments. The init file should generally use M-X Write + Word Abbrev File, and the & Startup... should use this function. +This will not complain if the file does not exist.! + +!* (This does not reset the default filename for M-X Write Word Abbrev + File and M-X Read Word Abbrev File. I'm not sure of this, but it + seems correct.)! + + [1 f[DFile !* Save default fielname *! + e[ fne] f[DFile 1f[FNamSyntax !* Save input channel, filename.! + etDSK: fsHSNamefsDSNamew etINCABS > !* Default to home directory.! + 4,4f Incremental word abbrev filef"e w'u1 !* Read string argument *! + et1 !* Set default from argument *! + e?"e !* File exists.! + f[BBindw er @y !* Read in QWABL file. *! + j @:i1|m.m& Make Non-Usage Abbrev Variable q..q[..o +m.mKill Variable +| !* 1: Header lines (new type).! + fq1f=1"e fq1c'"# g1' !* Past header lines if there.! + !* Doesnt really matter though, and! + !* old-style ones are ok to keep on.! + !* Just is less junk to keep in! + !* variable, and Write Incremental! + !* Word Abbrev File will add it on! + !* anyway.! + .,zx*m.vLately Changed Abbrevsw !* Save the incls.! + m(hx*)' !* Define and kill abbrevs by running! + !* buffer.! + !* This used to be m..o but sometimes Teco seems to have trouble --! + !* rare but strange when it happens, e.g. seeming to get the wrong! + !* start PC or something.! + +  + +!& Make Usage Abbrev Variable:! !S Like .V and .C combined, for speed. +STRARG1 is abbrev variable name. +STRARG2 is abbrev expansion with altmodes, ^]s quoted with ^]s. +STRARG3 is usage-count string. +Assumes ..Q is selected as buffer (..O).! + :i*[.1 !* .1: Abbrev varname. *! + :i*[.2 !* .2: Abbrev expansion. *! + :i*[.0 !* .0: Usage count string. *! + :FO..Q.1[.3 !* .3: Variable index. *! + Q.3"L -Q.3*5J 15,0I 15R q.1,.FSWORDW 0,.+10FSWORDW !* .3 neg *! + -Q.3U.3' !* .3: Pos index. *! + q.3+1*5j q.2,.fswordw !* Stick in expansion string. *! + 5c q.0,.fswordw  !* Stick in usage count string. *! + +!& Make Non-Usage Abbrev Variable:! !S Like .V and .C combined, +but faster. +STRARG1 is abbrev variable name string. +STRARG2 is abbrev expansion string. +Assumes ..Q is selected as buffer (..O).! + :i*[.1 !* .1: Abbrev varname. *! + :i*[.2 !* .2: Abbrev expansion. *! + :FO..Q.1[.3 !* .3: Variable index. *! + Q.3"L -Q.3*5J 15,0I 15R q.1,.FSWORDW 0,.+10FSWORDW !* .3 neg *! + -Q.3U.3' !* .3: Pos index. *! + q.3+1*5j q.2,.fswordw !* Stick in expansion string. *! +  + +!Attach Word Abbrev Keyboard Macro:! !C Abbrev will run a macro after expanding. +The last keyboard macro defined is attached to a word abbrev as its + word abbrev hook. Just after that abbrev expands, this hook is + executed. +BE CAREFUL -- keyboard macro attachment is not always + well-defined, due to some strange Teco effects. Not everything + works that "ought to". +First string argument is abbrev to attach it to. If null, the last + one defined is used. +Second string argument is mode (null means use current mode). Use "*" + if you mean to attach it to a global abbrev. If you are attaching + to the last defined abbrev, you can use anything for this string + argument. +Note that word abbrev hooks will be saved by M-X Write Word Abbrev + File and M-X Write Incremental Word Abbrev File, just like normal + abbrevs. Also, they appear in definition listings (e.g. by M-X + List Word Abbrevs or M-X Edit Word Abbrevs) in pairs, such as the + following: +textmode: #0 "-*-Text-*-" +textmode: (*-WABMAC) 0 "m(m.mText Mode)"! + + [1[2[3[4 + qModeu2 !* 2: Current mode.! + 1,f Abbrev: u1 !* 1: Abbrev.! + 1,f Mode (2): u3 !* 3: Mode specified.! + fq3"n q3u2' !* 2: Mode to use.! + :fo..qLast Kbd Macro"e :i*No last keyboard macrofsErr' + qLast Kbd Macrou4 !* 4: Last keyboard macro string.! + m(m.m& Attach Word Abbrev Hook)124 +  + +!& Attach Word Abbrev Hook:! !S Put some Teco code on a word abbrev. +The first string argument is the abbrev, second is mode name (or "*" + for global abbrev). Given null abbrev, we use the last defined. +The third string argument is a hook to call after expanding that + abbrev. +Note that word abbrev hooks get saved in incremental and full files, + just like normal abbrevs.! + + m(m.m& Declare Load-Time Defaults) + Word Abbrevs Modified, Non0 means definitions have changed: 0 + Last Word Abbrev Defined, Variable name: 0 + + + [1[2[3[4[5 + :i*( :i*( :i3 )u2 )u1 !* 1,2,3: abbrev, mode, hook.! + f[BBind !* Temporary buffer, accumulates! + !* incremental definitions.! + + fq1"e qLast Word Abbrev Definedf"ew :i*No last word abbrevfsErr'u1 + 2,32f1u2 !* 2: Position of abbrev end.! + 2,q2:g1( !* Just the abbrev.! + q2+1,fq1-7:g1u2 !* 2: Mode name.! + )u1' !* 1: Just the abbrev.! + + :fo..qX 1 2 Abbrevu4 !* 4: ..Q index for abbrev.! + q4"l !* No such existing abbrev.! + :i*CfsEchoDisplayw !* Clear echo are.! + q2u5 f=5*"e :i5global' !* 5: Better for error message.! + "# !* Was modal -- see if user! + !* meant the global version.! + :fo..qX 1 * Abbrev"g !* Aha, the global one exists.! + @ft1 is not a 2 abbrev. Did you mean global?  !* ...! + 1m(m.m& Yes or No)"n :i2* oOK''' !* Yes.! + + @ft1 is not a 5 abbrev. Want to define it?  !* Prompt.! + 1m(m.m& Yes or No)"e ' !* No.! + 1,m(m.m& Read Line)Expansion for 5 abbrev 1: f"e'u5 + !* 5: New expansion.! + q5m.cX 1 2 Abbrev0w !* Define the abbrev.! + i +mvX 1 2 Abbrev !* Up to expansion.! + .(g5)j <:s;ric> !* Teco-quote , C-]s.! + zj i0' !* Finish the incremental.! + + !OK! + + !* This next must be M.V not M.C since M.C would not redefine it, and! + !* we want to allow redifining these.! + + q3m.vX 1 2-WABMAC Abbrevw !* Make the corresponding abbrev that! + !* carries the hook as its expansion.! + m.cX 1 2-WABMAC Abbrev0w !* Make sure it has a usage count.! + m.cX 1 2 Abbrev#0w !* Set the usage count to indicate a! + !* word abbrev hook.! + i +mvX 1 2-WABMAC Abbrev !* Incremental up to expansion.! + .(g3)j <:s;ric> !* Teco-quote s, C-]s.! + zj i0 +m.cX 1 2 Abbrev#0w !* Finish the incrementals.! + + j g(0fo..qLately Changed Abbrevsf"ew :i*') !* Append our incrementals to! + !* the old ones.! + hx*m.vLately Changed Abbrevsw !* Put the bunch back.! + 1uWord Abbrevs Modified !* They need saving now.! + +  + +!& WRDAB Old Char Describe:! !S Tell what a character does after expanding.! +!* Called by WORDAB "active documentation", with the arguments passed by + Described modified slightly by F*0+n, where n becomes our + post-comma, and any pre-comma is passed to us from Describe. +Post-comma numeric argument tells which caller: + 0: ^R Abbrev Expand And Self-Insert + 1: ^R Abbrev Expand And Call Old Char + 2: ^R Abbrev Expand for Tab +Pre-comma numeric argument: + none: no character being described, we just return. + string: q-register name. If not a 9-bit q-register we return. + 9-bit: we describe the old function.! + + [0[1[P + ff&2"e ' !* Just return if no character! + !* given to us.! + u0 !* 0: 9-bit or q-register name.! + fp:"l 1:"n '' !* 0: Q-register to 9-bit, or if! + !* cannot, just return.! + + "e Afs^RInitu1' !* 1: Old function is self-inserter.! + -1"e 8[..e q0:\u1 ]..e !* 1: Code as octal string.! + qWRDAB Old 1u1' !* 1: Old function.! + -2"e qWRDAB Old 11u1' !* 1: Function run after Tab.! + + ftAfter possibly expanding, it  !* Note that they wont print the! + !* character name again.! + + !* Temporarily bind key to the old thing so M-? will describe it! + !* correctly -- e.g. even if it is a previx dispatcher, in which case! + !* it looks at the keys binding.! + + q1,q0f[^RCMacro !* Will be bound back when done.! + q0,q1:m(m.m^R Describe) + +!& WRDAB Process Options Hook:! !S Check for characters to change. +Calls a subroutine to see-if/do any expand characters need updating.! +!* Is a little slow for someone who makes Word Abbrev Mode local. Could fix.! +!* Note the s used below to bound the WORDAB Ins Chars string value.! + m(m.m& Declare Load-Time Defaults) + WORDAB Ins Chars, Self-inserting expanders: !~@#;$%^&*-_=+[]()\|:`"'{},<.>/? + + WORDAB Old Chars, Hairy expanders: || + + + [.0[.1[.6[.7[.8 Afs^RInit[.2 !* .2: Self-inserter, used by checkers! + !* and turn-offers.! + m.m^R Abbrev Expand for Tabu.0 !* .0: Tab expander.! + 0fo..qWord Abbrev Mode"n !* word abbrev mode?! + !* Recursive edit levels are tricky: we cannot bind new expanders there,! + !* without having old-vars which are separate by level, e.g. using the! + !* variable WRDAB Old [1] 40 for a level-1 binding. Otherwise, rebinding! + !* in a recursive level will destroy the lower levels old-var, if any.! + !* This scheme is complicated to implement, so I will not bother, but! + !* instead just disallow binding in a recursive level. However, unbinding! + !* should be handled, in case the user turns word abbrev mode off.! + 0:g..j-["e !* We are in a recursive level.! + :i.0' !* .0: A null macro -- no check/bind.! + "# qI-q.0"n !* Not rec-level. Turn on Tab?! + f~I!^R Abbrev Expand -19"n !* Be sure -- e.g. WORDAB might be! + !* loaded twice, or test-loaded.! + qIm(m(m.m& Global or Local)I)WRDAB Old 11 !* Yes, save old tab! + !* in either global (using .V) or local (using .L) var.! + q.0uI'' !* and set it to tab expander.! + m.m& WRDAB On PO Checku.0' !* .0: Checker loop.! + m.m& WRDAB Turn On Ins Charu.7 !* .7: Turn on ins.! + m.m& WRDAB Turn On Old Charu.8' !* .8: Turn on old.! + "# qI-q.0"E !* WAM off. Must turn off Tab?! + qWRDAB Old 11uI' !* Yes.! + m.m& WRDAB Off PO Checku.0 !* .0: Checker loop.! + m.m& WRDAB Turn Off Ins Charu.7 !* .7: Turn off ins.! + m.m& WRDAB Turn Off Old Charu.8 !* .8: Turn off old.! + ' !* End WAM off conditional.! + qWORDAB Ins Charsu.1 !* .1: inserting breaks.! + + m.m^R Abbrev Expand And Self-Insertu.6 !* .6: ^R Ins! + m.0 !* Check them, fix.! + + qWORDAB Old Charsu.1 !* .1: Call-old breaks.! + m.m^R Abbrev Expand And Call Old Charu.6 !* .6: Old Char! + q.8u.7 !* .7: Old version for m.0.! + m.0 !* Check them, fix.! + +  + +!& WRDAB Off PO Check:! !S Check list of chars for expanders, fix. +q.1: List of characters. +q.6: ^R Macro to check against. +q.7: Subroutine to call if char runs .6.! + -1[.4[.5 !* .4: Index into .1.! + < %.4-fq.1; !* Stop when done with .1.! + q.4:g.1u.5 !* .5: Charcode for next INS char.! + q.5-q.6"E q.5m.7' > !* If same, fix it.! +  + +!& WRDAB On PO Check:! !S Check list of expand characters for changes +q.1: List of characters. +q.6: ^R Macro to check against. +q.7: Subroutine to call if change.! + -1[.4[.5 !* .4: Index into .1.! + < %.4-fq.1; !* Stop when done with .1.! + q.4:g.1u.5 !* .5: Charcode for next INS char.! + q.5-q.6"N q.5m.7' > !* If changed, fix it.! +  + +!& WRDAB Turn On Ins Char:! !S Make a self-inserter expander. +Caller has .2 bound to self-inserter builtin. +Numeric argument: 9-bit of key to use.! +!* If character does not run the self-inserting builtin routine, +it becomes a call-old expander, and character is moved from the + variable WORDAB Ins Chars to WORDAB Old Chars.! + !* Note the s used below to bound the WORDAB Ins Chars string value.! + m(m.m& Declare Load-Time Defaults) + WORDAB Ins Chars, Self-inserting expanders: !~@#;$%^&*-_=+[]()\|:`"'{},<.>/? + + WORDAB Old Chars, Hairy expanders: || + + + [.0 !* .0: Ascii for key.! + q.0[.4 !* .4: Keys macro.! + q.4-q.2"e !* It runs the self-inserter.! + m.m^R Abbrev Expand And Self-Insertu.0 !* Set ins.! + ' !* And return.! + + !* Character does NOT run a self-inserter. It might already be running an! + !* expander. Or if not, it will migrate to the call-old list.! + + q.4fp"g !* Cannot F~ a builtin, not a string.! + f~.4!^R Abbrev Expand -19"e '' !* If already an expander, quit.! + !* (Works for uncompresseds too.)! + qWORDAB Ins Chars[.1 !* .1: $ins$! + f.1[.2 !* .2: Position in $ins$! + 0,q.2:g.1[.3 !* .3: Ins chars before this one.! + q.2+1,fq.1:g.1u.1 !* .1: Ins chars after.! + :iWORDAB Ins Chars.3.1 !* $ins$: Take out this char.! + qWORDAB Old Charsu.1 !* .1: $old$! + :i.2 !* .2: This char, string.! + :iWORDAB Old Chars.1.2 !* $old$: Add this char.! + + m.m^R Abbrev Expand And Call Old Charu.0 !* Set key.! + [.6 8[..e :\u.6 ]..e !* .6: Octal string for char.! + q.4m(m(m.m& Global or Local).0)WRDAB Old .6 + !* Yes, save old char in either global! + !* (using .V) or local (using .L) var.! +  + +!& WRDAB Turn On Old Char:! !S Make a call-old expander. +Numeric argument: 9-bit of key to use.! + + [.0 !* .0: Old char 9-bit.! + q.0[.1 !* .1: Old char macro.! + q.1fp"G !* If not a builtin now, ! + f~.1!^R Abbrev Expand -19"E !* If already an expander, ! + '' !* ...then quit while ahead.! + m.m^R Abbrev Expand And Call Old Charu.0 !* Set key.! + [.6 8[..e :\u.6 ]..e !* .6: Octal string for char.! + q.1m(m(m.m& Global or Local).0)WRDAB Old .6 + !* Yes, save old char in either global! + !* (using .V) or local (using .L) var.! +  + +!& WRDAB Turn Off Ins Char:! !S Reset char ARG to @fs^RInit.! + [.0 !* .0: 9-bit.! + @fs^RInitu.0  !* Reset.! + +!& WRDAB Turn Off Old Char:! !S Reset char ARG to what was before.! + [.6 8[..e :\u.6 ]..e !* .6 Octal string for char.! + 0fo..qWRDAB Old .6[.1 !* .1: Maybe old char function.! + [.2 !* .2: 9-bit.! + q.1u.2  !* Reset key.! + +!& Global or Local:! !S Return Q.L or Q.V... +Returns Q.L if argument is a local q-register, Q.V otherwise.! + [1[2[3[9 !* save regs! + [ -1:fsQPHome(]*w)u3 !* get home of our q-register argument! + qBuffer Indexu9 q9+8u2 !* ! + q:.b(q9)-9/2u1 !* ! + q1< q:.b(%2)-q3"e q.L ' %2w > !* if q-register is local then return! + !* .L! + q.V  !* else return .V! + +!& Shorten String:! !S Produce a short string, showing beginning/end. +Numeric argument is a string pointer.! + [.3[.4[.5 !* .3: Long ARG string.! + fq.3-40"G !* If expan is long, only show part.! + 0,16:g.3u.4 !* .4: first 16 letters of exp.! + fq.3-16,fq.3:g.3u.5 !* .5: last 16 letters.! + :i.4.4.....5' !* .4: first and last 16 letters.! + "# q.3u.4' !* .4: expan is short, whole expan.! + q.4  !* Return short string.! + +!* Following should be kept as (only) long comments so will be compressed out: + * Local Modes: + * Fill Column:78 + * End: + *! + \ No newline at end of file