diff --git a/bin/emacs/ivory.:ej b/bin/emacs/ivory.:ej new file mode 100755 index 00000000..3493c895 Binary files /dev/null and b/bin/emacs/ivory.:ej differ 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 00000000..18f9cec4 Binary files /dev/null and b/src/emacs1/ivory.189 differ 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 00000000..b4a7b9c1 Binary files /dev/null and b/src/emacs1/tmucs.20 differ 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