diff --git a/build/build.tcl b/build/build.tcl index 40d92236..636c5e64 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -221,6 +221,22 @@ respond ":EJ" "\030\003" respond "*" ":kill\r" respond "*" ":delete emacs;\[prfy\] <\r" +respond "*" ":emacs\r" +respond "for help" "\033xload\033purify\r" +type "\033xgenerate\033emacs;aux\033emacs1;aux\r" +respond ":EJ" "\030\003" +respond "*" ":kill\r" + +respond "*" ":delete emacs;ts 126\r" +respond "*" ":delete \[pure\] 162\r" +respond "*" ":rename \[pure\] 163, \[pure\] 162\r" + +respond "*" "emacs\033\023" +respond "*" ":teco\r" +respond "&" "mmrun\033purify\033dump\033ts 126\033\033" +respond "&" "\003" +respond "*" ":kill\r" + respond "*" ":midas sysbin;_syseng;dump\r" respond "WHICH MACHINE?" "DB\r" expect ":KILL" diff --git a/src/emacs/emacs.teco b/src/emacs/emacs.teco new file mode 100755 index 00000000..2100a55d --- /dev/null +++ b/src/emacs/emacs.teco @@ -0,0 +1,83 @@ +!* -*-TECO-*- *! + +!* This is the TECO INIT for EMACS. It sets up the EMACS environment + necessary for dumping a new EMACS EJ file. *! + + -1fs^Idisablew !* do this first for comments! + :ejDSK:EMACS;EMACS :EJu0 !* load in the EMACS library! + er ec fs if versionu2 !* Save version number.! + fs osteco"e fs i fileu1' + "# fs i filefs d file !* Save filename.! + etdsk:emacs; !* On twenex, stick in "emacs;' rather than the! + fs d fileu1' !* actual directory on which it resides.! + + fs osteco"n !* Twenex! + :ejDSK:TWENEX.:EJw !* load in the TWENEX library! + er ec + fs i filefs d file + et dsk:emacs; + fs d fileu3 !* save filename of TWENEX library! + ' + :i*& Macro Get,q0m(q0+4)u.m !* call the loader in the EMACS library! + !* to find .M! + f[ :ej page !* save :EJ page for flushing EINIT! + :ejDSK:EMACS;EINIT :EJw !* load EINIT library! + + m(m.m& Load Essential Environment) + + q1m.vEMACS Library Filename !* save EMACS library filename! + q2m.vEMACS Versionw !* version no. too! + fs osteco"n !* Twenex! + q3m.vTWENEX Library Filenamew' !* save TWENEX library filename! + + q2:\u2 + m(m.m& Load Patches)emacs;pat2 > !* Load patches to this EMACS version.! + m(m.m& Load Patches)patch > !* Load site-specific non-version-specific patches.! + m(m.m& Load Default Environment) + + m(m.mPurify Variables) !* smash variable names to point to pure! + !* space if there is a copy there! + f] :ej page !* flush EINIT! + +!* All we should do when restarted is run ..L, which is & Toplevel ^R.! + q..lm.vMM & Startup EMACS + +!* The first entry to ^R will run the value of *Initialization*. +Here we define that to read in and process the user's init file.! + + fsosteco"e @:i*| !* ITS! + etDSK:EMACS !* set device name and FN2! + fs hsname fs dsnamew !* fill in directory! + fs xuname fs dfn1w !* and FN1! + 1:"l + 1:"l + erEMACS;*'' + fs d file[2 et@ > + !** end of system-dependent code! + fs msname fs dsname + qEMACS Version:\u1 !* sigh, still need this! + @y 1a-127"n ]2 :i*[..9 !* if init doesnt begin with rubout then! + m(hfx*( 0fsmodifiedw))' !* execute it as TECO commands! + hk 0fsmodified + 1,m(m.mLoad Library)2 !* else load it as a library,! + !* saving the filename! +  + |m.v*Initialization*' + "# @:i*| !* Twenex! + etDSK:EMACS.INIT fs hsname fs dsname + 1:"l erDSK:' + fs d file[2 et foo.. + !** end of system-dependent code! + fs msname fs dsname + qEMACS Version:\u1 !* sigh, still need this! + @y 1a-127"n ]2 :i*[..9 !* if init doesnt begin with rubout then! + m(hfx*( 0fsmodifiedw))' !* execute it as TECO commands! + hk 0fsmodified + 1,m(m.mLoad Library)2 !* else load it as a library! + !* saving the filename! +  + |m.v*Initialization*' + + 0u0 0u1 0u2 0u3 !* zero the q-regs we've used! + + hk diff --git a/src/emacs1/aux.55 b/src/emacs1/aux.55 new file mode 100755 index 00000000..f852421b --- /dev/null +++ b/src/emacs1/aux.55 @@ -0,0 +1,850 @@ +!* -*-TECO-*- Random autoloading functions, not used very often, +and not providing any fundamental capability not present in EMACS :EJ.! + +!~Filename~:! !Random functions autoloaded by standard EMACS.! +AUX + +!Edit Options:! !C Edit some or all of the permanent options. +String argument is a filter for the option names -- you will be editing all + options whose names contain the string. If you don't give a string + argument, all options will appear for editing. +A variable is an option if its comment starts with "*" or "*". (The variable + name must not contain a colon.) +When you exit the recursive edit with ^R Exit, the values are updated. +To abort, use Abort Recursive Edit. +If you are only editing a few options, only part of the screen will be used, + to reduce the amount of redisplay upon exit. +The format of the table is fairly obvious; type HELP to get details.! + + [0[1[2[3[4[9 1,f Pattern:_u9 fq9"e 0u9'!* 9: STRARG, filter, which if null! + !* means to match any option so we set! + !* it to 0 for quick testing and to! + !* avoid searches.! + + 0[..f !* No buffer hacking allowed.! + [..j !* Save mode line.! + f[Lines f[Window f[BBind !* Temporary buffer. fsWindow is saved since we! + !* dont use the whole screen if we dont have to,! + !* and we want to ensure that redisplay on return! + !* is minimized.! + + q:..q(0)u3 !* 3: no. of elements per ..Q entry! + 1-q3u0 !* 0: ..Q index.! + + !* Critical efficiency iteration coming up here -- there may be an awful lot! + !* of variables to consider. We use Excl < Excl > instead of nested conditionals! + !* since they are fast and we want to keep the size of the conditionals down! + !* since Teco has to slowly skip over them, not cacheing them for instance.! + + q9"n 0s9' !* Set the filtering search default,! + !* if one, outside the loop.! + + -(fq..q-5/(q:..q(0)*5))u2 !* 2: Iteration count. Cant give it! + !* to the iteration directly since we! + !* want to use Excl < Excl >.! + < %2; !* Iterate over ..Q symbol table.! + q0+q3u0 !* 0: up to next symbol entry.! + q:..q(q0+2)u4 fq4-2"l !' !* Comment too short -- not option.! + 0:g4-*"n 1:g4-*"n !'' !* To be an option either 1st or 2nd! + !* character of comment must be a *.! + + !* We have an option variable. See if it passes through the filter.! + + .(g:..q(q0))j !* Insert its name.! + q9"n :s"e .,zk !'' !* If name doesnt match filter, skip! + !* it.! + + !* This is a matching option.! + + zj i:  !* End name with colon, tab.! + q:..q(q0+1)u1 fq1:"l 34i .(g1)j !* String, put in quote and the string.! + < @:f"l .-z; 29i c > !'! 34i' !* Quote any ^]s or! + !* double-quotes with ^].! + "# q1\' !* Number, just get it.! + i + .u1 9i g4 !* Get comment, indented, on next line.! + q1j 1a-!"e d @:f!l .,zk' !* If varMacro, ignore the teco code.! + q1j :l .,zk !* But just the 1st line of comment.! + !* (Most will actually be only one line! + !* anyway.)! + i + !* End the comment line.! + > + + !* Option table of either all or just the matching options is now prepared.! + + :i..jEdit_Options !* Mode line for recursive edit.! + m.m&_Edit_Options_Helpf[HelpMacro !* Help for recursive edit format details.! + + 0u0 j !* 0: Total number of lines needed.! + fsLinesu1 q1"e fsHeight-(fsEchoLines)-1u1' !* 1: current fsLines! + q0+2-q1"l q0+2fsLines' !* Set fsLines so that only the amount! + !* of screen needed is used, reducing! + !* redisplay of rest of buffer.! + + j 0u..H  !* Into , allowing redisplay.! + + + !* Now change the values: ! + + 128*5,32:i*[..D !* ..D: Make a syntax table for parsing! + !* the string values.! + *5:f..D_/ !* ..D: Thinks ^] is a Lisp escape.! + "*5:f..D_| !'! !* ..D: Thinks dquote is string delimiter.! + + j + < 0,1af _:"l l !' .-z; !* Skip any indented lines.! + .,(:s:;).-1x1 !* 1: Variable name.! + q1u3 !* 3: Get this options current value.! + @f _l !* Skip over indentation to value.! + 1a-34"n :\u2 !* 2: Numeric value.! + q2-q3"n q2u1'' !* Reset the option iff its value has! + !* changed. This is just in case there! + !* is a variable macro attached -- no! + !* sense calling it if no change.! + + "# .+1,(@fll).-1x2 !* 2: String value except that it has! + !* ^]-quoted dquotes inside.! + @:i2"2" !''! !* 2: Now the exact string value.! + + !* Note that this is why we use ^] as! + !* the quoting character -- the! + !* delimited Teco insert respects! + !* superquoting, namely ^]^] and ^]dquote.! + q3fp"l q2u1' !* Was a number before -- reset to new string.! + "# f=23"n q2u1''' !* Was a different string before -- reset.! + + l > !* On to next option.! + +  !* Now all the variables are changed.! + +!& Edit Options Help:! !S fsHelpMacro for MM Edit Options.! +!* Q-reg 9 has the string used to filter the option names.! + + fsLinesf"n-5"l !* Good to have at least 5 lines for! + !* this message, especially details.! + 5fsLines''w !* Dont bind, so when exit redisplay! + !* doesnt keep part of message.! + + :ftYou_are_editing_a_table_of_all_the_permanent_EMACS_options !* Start HELP.! + q9"n f=9"n ft +whose_names_contain_"9" !''!'' !* Tailor it a bit.! + ft. +When_you_exit,_via_ !* Now find out what the exiter is.! + 2,(33.fs^RInit)m(m.mWhere_Is)"e ftM-X_^R_Exit' !* (This is like using ^R Exit\! + !* in documentation for a command.)! + ft,_the_options_left_in_the_buffer_will_be +reset.__You_can_abort_with_ + 2,(m.mAbort_Recursive_Edit)m(m.mWhere_Is)"e ftM-X_Abort_Recursive_Edit' +ft. +Do_you_wish_to_see_details_about_the_option_table_format? + + m(m.m&_Yes_or_No)"e 0u..h ' !* User doesnt want to see it. Clear! + !* ..H so typeout goes away.! + + 0fsLinesw !* For full details, always use whole! + !* screen so not MOREing a lot.! + +:ftThe_format_of_the_table_is_simple:__each_option_name_is_followed_by_a_colon, +some_indentation,_the_value,_and_then_on_the_next_line_the_comment_(which_is +indented_--_any_indented_line_(if_not_inside_a_value)_is_ignored_later_when +the_values_are_reset). + +The_value_is_either_a_number_(with_an_optional_hyphen_preceding_it)_or_a_string +(in_which_case_it_is_surrounded_by_double-quotes_("...")_and_may_be_more_than +one_line_if_desired). + +If_there_is_a_double-quote_inside_the_string,_it_must_be_quoted_by_the +_character_(Control-]).__Any_s_inside_the_string_must_also_be_quoted_with +.__(It's_ugly,_but_it_greatly_simplifies_the_implementation_and_these_should +be_rare.) + +For_instance,_consider_the_following_example_options_in_this_format: + +Option_Number_One: "this_is_a_string" +Null_String_Option: "" +Option_Number_Two: -1234 +Option_Number_Three: "Quoth_the_raven:_"Nevermore!"." +One_Bracket_Option: "" + +  + +!Edit Syntax Table:! !C Delimiter syntax table editor. +String arg is Q-register to edit. Default is ..D. +Response to "Character:" is ^G to quit, ^Q to quote, +Altmode to leave the macro, or character whose entry to edit. +When editing a character's entry, you are in overwrite mode. +After you exit the recursive edit, you are asked for another character. +First char in each table entry is space for delimiter, or A. +Second is space, (, ), /, |, ', or A for lisp syntax.! + + 1,F Q-reg:[9 FQ9"E :I9..D' !* Read location of table (default is "..D").! + FQ9-(5*200.)"N + :I* Q9_has_wrong_length_for_a_dispatch_table FS ERR' + f[D File ETGAZONK_.DEL !* Prevent clobberage by C-X C-W.! + [3 0[..F !* Prevent auto-saving.! + [..J :I..J Delimiter_Table_Editor.__ + :I*M(M.M Describe)Edit_Syntax_Table F[HELP MAC + -1F[^R Replace !* Enter overwrite mode.! + 2F[CASEN 2F[CASE !* Convert all insertions to upper case.! + F[B BIND G9 + J 0.U..0 40.< i^ q..0+100.i + fssail"N 2rdi c q..0f î"L -2d i_ q..0i'' + q..0-33."e -2d i_' + I= 5C I _ %..0&3"E-2DI +' + > + 140. + 177.*10F^? + FS SAIL"N 177.*10F ' + 0FS MODIF F[WINDOW + f+ + < J 0@V @FT +Character:_ + FIU3 Q3-@; !* Exit if user types Altmode.! + Q3-"EW' !* Quit if he types ^] or ^G (don't make the changes).! + Q3-"EW' + Q3-"EFIU3' !* ^Q quotes next character.! + Q3*10J 3C !* Go to spot in buffer for the specified char.! +  > + j 200.<3d5c2d> !* Delete the char names, leaving only edited contents.! + 0:F9 ..O !* Change contents of dispatch string to new stuff.! +  + +!Kill Some Buffers:! !C Offers to kill each buffer, one by one. +If the buffer contains a modified file and you say to kill it, +you are asked whether to write the file out first.! + + 0[1 [2 [3 [4 + < Q1*5-FQ.B; !* Stop after hacking all the buffers.! + Q:.B(Q1+1!*bufnam!)U2 !* Get next buffer's name.! + Q:.B(Q1+2!*bufvis!)U4 !* Get the name of the file it contains.! + Q:.B(Q1+4!*bufbuf!)[..O !* Select it, TECO style, so we can check its FS MODIF! + FT Buffer_2_ + Q4"N FT (File_4)_' + FS Modif"N + FT HAS_BEEN_EDITED' + "# FT is_unmodified' + FT . +_Kill_it_(Y_or_N_or_^R)? + FI:FCU3 FT3 + + Q3-"E 0[..F !* If answer is ^R, call ^R to show buffer to be killed.! + [..J :I..JWant_to_kill_buffer_2?__ + 0U..H  ]..J ]..F ]..O !' !* Zero ..F to prohibit buffer hacking.! + ]..O + Q3-Y"E !* If answer is yes, kill the buffer.! + M(M.M Kill_Buffer)2 !* Don't advance Q1 since next buffer has been moved down.! + !' + Q1+Q:.B(Q1)U1> !* Advance to next buffer.! + 0U..H  !* Cause redisplay.! + +!Edit Tab Stops:! !C Edit the tab stops used by ^R Tab to Tab Stop. +The bottom two lines just number the columns for your benefit. +The first two lines, stored in Tab Stop Definitions, are meaningful. +Periods or colons in the first line mark the tab stop columns. +A colon means tab out with whitespace; a period means tab out by +copying text from the second line (you must put the text there).! + + 0[..f + :I* m(m.m Describe)Edit_Tab_Stops  F[help mac + f[b bind + gTab_Stop_Definitions !* Push to temp. buffer holding the tab stops.! + j 2@l .,zk !* Flush anything past two lines.! + 0@f"n i +' !* Make sure ends with CRLF.! + -@l ."e zj i +' !* Make sure there are realy two lines, not one. ! + + zj fswidth/10 i +0 !* Display the column position numbers' low digits! + 0u0 fswidth/10<10,%0*10\> i + !* and their high digits.! + -1f[ ^r replace !* Make printing chars replace.! + [..j :i..j Edit_Tab_Stops__(Overwrite) + f[d file etgazonk_.del !* Prevent clobberage from accidental ^X^W.! + j  + j 2:@l 0@f"e :0@l' !* Find end of 2nd line, or end of 1st if 2nd is empty! + 0,.xTab_Stop_Definitions !* Store them as defnitions of tab stops.! +  + +!& Compare Windows:! !S Compare text in two windows. +Compares the text in the two windows, starting at the +cursor in each window, leaving point in each window +at the first discrepancy, if any, or to end of buffer. +Quitting leaves point at place comparison had reached. + +The variable Collapse in Comparison should be a string +of "insignificant" characters. Any sequence of those characters +matches any other such sequence. If the variable is not +defined, the default is CR, LF, TAB and SPACE.! + + [A -1[B [P [2 + + 0FO..QWindow_2_Buffer"E + :I*O1B Only_One_Window FS ERR' + + Q..O-QOther_Window_Buffer"E !* We cannot compare a buffer to itself.! + @ft Cannot_compare_a_buffer_to_itself. +Try_comparing_the_buffer_with_a_copy_in_another_buffer. + 0fs echo active + :i*CBI Cannot_Compare_Buffer_to_Itself FS ERR' + FS QP PTRUP + + .F[VB !* Remember this window's buffer in QD,! + Q..O[D !* as string starting from point.! + + QOther_Window_Buffer[..O + FS TOP LINE"N !* Now TECO-select the other window,! + QWindow_1_SizeF[LINES 0F[TOP LINE + :I2 1' + "# QWindow_2_SizeF[LINES QWindow_1_Size+1F[TOP LINE + :I2 2' + QWindow_2_WindowF[WINDOW !* but don't take the time for an EMACS buffer switch.! + QWindow_2_Point:J + -1F[D FORCE + + 0FO..QCollapse_in_ComparisonUA + QA"E :IA_ î' + -1F[NOQUIT + 1:< QD, QAM(M.M &_Compare_String_with_Buffer)UB !* Do comparison. QB gets flag.! + 1FS NOQUIT > + 0@V !* Redisplay the other window.! + .UWindow_2_Point !* Remember change in point or FS WINDOW of other window.! + FS WINDOW UWindow_2_Window + + QPFSQP UN !* Return to original window.! + + :I*C FS ECHO DIS + QB"E @FTMismatch +' + QB"G @FTMatch +' + 0FS ECHOACT + +!& Compare String with Buffer:! !S Compares current buffer with another. +The precomma arg should be the other buffer, +with its virtual beginning at the place to start comparison. +The postcomma arg should be a collection of "special" characters to +be collapsed in the comparison. Typically, this arg might +consist of space, tab, CR, and LF. Any nonempty string of +members of this arg matches any other nonempty +string of members of this arg. + +We move point in both buffers up to the first mismatch, +and return nonzero if the buffers match up to the end.! + + [1 !* 1 will hold! + !* the other buffer to compare! + [2 !* with the current buffer, 2 the string! + !* of characters to collapse! + + [O [Q [J + +!* If both buffers start with special characters, + skip all special characters at the front of them.! + -1,1A F2:"L + Q1[..O -1,1A(]..O) F2:"L + O Special'' + + !TOP! + !* At this point, we assume that the strings before point + in the two buffers are a match, and that in at least one + buffer the character after point is not special.! + .UO !* If .=QO afterward, we didn't match anything.! + +!* QQ keeps a copy of .-B of the buffer in Q1.! + Q1[..O .-BUQ ]..O + :< QQ:G1-(1A):@; C %Q > !* Advance in both buffers past exact match.! + Q1[..O QQ+BJ ]..O !* Skip over matched characters.! + + FQ1-QQ"E .-Z"E !* At end of both strings => return success.! + 1'' + + .-QO"E 0' !* If we found no match, return.! + + 0A F2:"L !* The last match was a special! + OSPECIAL' + + !* Because the last match was not special, + the next character in each buffer must be a special, + or we have a mismatch.! + -1,1A F2"L 0' + Q1[..O -1,1A(]..O) F2"L 0' + +!* We have found two runs of special characters. Skip each one.! + !SPECIAL! + @F2R + Q1[..O @F2R ]..O + +!* Compare the two following nonspecial characters.! + OTOP + +!List Redefinitions:! !C Describe how the current mode differs from Fundamental mode.! + + qBuffer_Index[9 + 13!*buflcl!-q:.b(q9)/2+qInitial_Local_Count-1[1 + qInitial_Local_Count*2+q9+13!*buflcl!-1[2 + [3[4[5 + + !* m9 FOO is nonzero if there is a local named foo.! + [9 :@i9| [1[2[3[4 :i3 + < %1; + q:.b(%2)u4 + fq4"g f~43"e -1'' + %2> + 0| + + qComment_Startu3 + fq3"g FT Comments_start_with_"3"!''! + FT_in_column_ qComment_Column:= + qComment_Endu3 fq3"g ft ,_and_end_with_"3"!''!' + ft. + + 0fo..qComment_Multi_Line"n ft They_can_extend_across_multiple_lines. +'' + "# FT No_comment_characteristics_are_defined. +' + m9 Fill_Column"'n+(m9 Auto_Fill_Mode"'n)+( + qAuto_Fill_Mode"n m9 Space_Indent_Flag"'n')"n + FT Text_is_filled qAuto_Fill_Mode"n ft_automatically' + ft _to_column_ qFill_Column:= ft. + qAuto_Fill_Mode"n qSpace_Indent_Flag"n + ft__New_lines_are_indented.'' + ft +' + + FT Parenthesis_matching_is + qDisplay_Matching_Paren"e ft_disabled'"# ft_enabled' ft. + + fqParagraph_Delimiter"e + FT Paragraphs_are_delimited_only_by_blank_lines. +' + ft + + + [1[2 -u5 + < %1; + q:.b(%2)u3 %2 + fq3:"l + f~3Auto_Fill_Mode"e !' + f~3Comment_Start"e !' + f~3Comment_End"e !' + f~3Comment_Column"e !' + f~3Comment_Multi_Line"e !' + f~3Fill_Column"e !' + f~3Display_Matching_Paren"e !' + f~3Paragraph_Delimiter"e + fqParagraph_Delimiter"e !'' + f~3Space_Indent_Flag"e !' + fq:..q(:fo..q3+2)"g + %5"e ft +Variables_redefined: + +' + m(m.mView_Q-register)3 + ft + + '' > + ]2]1 -u5 + +!* Now describe any locals which are ^R key definitions.! + FQ1"L M(M.M &_Load_BARE)' + < %1; + q:.b(%2)u3 %2 + fq3"l q3@fsqphomeu3 + 0:g3-Q"e fq3-2:g3-"e + %5"e ft +Keys_redefined_in_this_buffer: + +' + 1,fq3:g3u4 f4u4 + q4-(q4fs ^R Indir)"n !* If this is an indirect character,! + q4m(m.m &_Charprint) + ft is_an_alias_of_ !* then say of what.! + q4-(3/1000000.)m(m.m &_Charprint) + ft.' + "# q4,3m(m.m&_^R_Briefly_Describe)' + ft +'''> + ft(Done) + +  + +!& Process Init Vars:! !S Read the user's EVARS file of variable settings. +A filename string may be given as a numeric argument, to specify a non-standard +vars file.! + +!* The default file referred to is FOO;FOO EVARS on ITS, EMACS.VARS on Twenex. +The contents look like a local variables list but with no +special lines to begin it or end it, and no prefix or suffix. +A qvector slot may also be named, as in ":.X(A)" for the +slot for the character A in the qvector in Q.X (the C-X command) +and is treated like a ^R character name. +The major mode should NOT be specified. +Lines starting with spaces may appear between variables, as comments.! + +!* This function is copied before it is executed, and AUX is then +flushed from core. If this were not done, then if the EVARS file +loaded a library, it would keep AUX from ever going away.! + + F[D FILE + + FF&1"N  FS D FILE' !* Filename given as numeric arg.! + "# FS OSTECO"E !* No filename given, so use default.! + ET FOO_EVARS + FS XUNAME FS DFN1' + "# ET EMACS.VARS' !* Select proper filename based on op sys,! + FS HSNAME FS DSNAM' !* and the right directory.! + + [1 [3 [4 + Q..O[5 F[B BIND Q..O[6 !* Q5 has original bfr, Q6 has temp bfr.! + [..O !* Make sure, when we pop the BBIND,! + !* that the temp bfr is back in Q..O to be killed.! + + 128*5,32:i*[2 !* Q2 gets a syntax table for parsing! + !* the string values.! + *5:f2_/ !* It thinks ^] is a Lisp escape.! + "*5:f2_| !'! !* It thinks dquote is string delimiter.! + + 1:< ER @Y >"L ' !* Make temp buffer, and read in the file.! + < .-Z; + @:F"E L !' !* Ignore blank lines, in case prefix is null.! + 1AF_ :"L @L!' !* Ignore lines starting with whitespace.! + .,( C S: .-2,.+1F=::"E C' !* Scan over name of variable. Win for ...:.! + !* The C before the S makes us win on :.X(A)! + ).-1X3 !* Put name of variable or ^R character into Q3.! + + !* Get the specified value in Q4.! + .u1 @f _l !* Skip over indentation to value.! + 1a-34"e q2[..d !* Is it a quoted string value?! + .+1,(@fll).-1x4 + ]..d + @:i4"4" !''!' + "# .( :\u4 )-."e q1-1j' !* Is it a numeric value? (with at least one digit)! + @f_ l + :@f"n !* Or an old-fashioned string value?! + q1j :X4'' + + Q5U..O !* Go to the EMACS bfr to execute the definition.! + FQ3-2:G3F:"'L+( !* If the variable name is a ^R character,! + 0:G3-:"'E)"L !* or a slot in a vector such as :.X(..),! + M4U3' !* Execute value-string to get the actual value.! + !* Add some extra Altmodes in case needed.! + "# F=3 *"E M4' + "# Q4 M.V3'' !* Set the variable.! + Q6U..O @L > !* Back to temp bfr, and advance to next line.! + +!* The dumped EMACS has an actual copy of this macro as an impure string.! +!* Replace it with a bootstrap that refers to AUX. This is to save space --! +!* since it won't be used again in most cases, except when the user invokes it! +!* manually (after editing vars file, say) or when invoked by some subsystem! +!* that has its own vars file.! + + :@i*| [1 fs qp ptr[2 + !* Must kill since the M.A will otherwise get MM-variable: ! + m(m.mKill_Variable)MM_&_Process_Init_Varsw + :g(m.a AUX&_Process_Init_Vars)u1 + q2fs qp unwin + f:m(q1(]1)) + | m.v MM_&_Process_Init_Vars +  + +!Tabify:! !C Convert spaces after point to tabs. +Groups of spaces which could be transparently replaced with a tab are. +Numeric arg specifies tab stop spacing. Precomma numeric arg specifies +minimum number of spaces to change (default 3).! + + [1[2[3[4 !* save regs *! + "N F[ TABWID' FS TABWIDU1 !* Set tab width.! + F"E 3',32:I4 !* minimum number of spaces! + 0S4 !* initialize search string *! + .[0 fn q0j !* Preserve point.! + < :S; !* Find next triple of consecutive spaces.! + .-FQ4( @F_L !* Push where they start. Search for end of run.! + FSSHPOSU2 !* Q2 gets hpos of end of spaces.! + Q2-(Q2/Q1*Q1)U3 !* Q3 has where they end, past last tab stop.! + Q3R)-.U2 !* Q2 has # spaces up to that tab stop.! + Q2+1"L Q2D Q1-1-Q2/Q1,9I' !* Replace all of them except last odd few with tabs.! + Q3C> !* Move past the excess spaces at the end.! +  + +!& Correct Word Spelling:! !S Check spelling of word at point and offer numbered replacements. +0-9 => Replace misspelled word with that spelling. +% => Read a digit and query replace from beginning of buffer. +space => Exit and make no changes. +^L => Redisplay choices. + +If a Spell job does not already exist, create one and give contents +of Spell Initialization as additional JCL. + +If given a negative argument, kill the Spell job.! + + :i*Cfs Echo Disp !* Clear the echo area.! + + "L :m(m.m&_Kill_Spell_Job)' !* Kill it?! + + fs osteco"E + :iOITS !* For & ... Get Spell Job! + :iD !* Delimiter for commands.! + !* Word (F) search string ! +!"! :i*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-' + fs msname:f6[F + fs uname:F6[U + :iFDSK:F;_SPELL_U' !* Filename for temp file.! + + fs osteco"G !* On Twenex, use the Job Index (UINDEX) for temp file.! + :iOTWENEX + :iD, +!"! :i*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + fs msname + fs uindex:\[U + :iFF[SPELL-TEMP-U].TXT.0' + + [..j + [0[1 + !* Use the new syntax-table-insensitive method for getting the word ! + -@fS:[B + @FS' + qB,qEx0 !* Get the word into Q0 ! + (qB-qE)"E ' !* but punt if it's empty. ! + + .[P !* Point before correction.! + z[L !* Z before correcting.! + !* Now B is beg, E is end, P is point, Z is buffer end, 0 is word. ! + + qEj !* Go to end of word.! + + f[B Bind !* Create a buffer to lowercase it in.! + g0 0j hfc hx1 !* Get lower-cased version to 1, since! + !* Case Replace wants lower case.! + f]B Bind + + :i..j Checking_spelling_of_0. fr 0 + 1m(m.m&_O_Get_Spell_Job)BASK_0_FDQUIT + !* Q1: old word, QF: file of new ones.! + q1,qFm(m.m &_Spell_Replace_Word)"N QP :J' !* If value=1 if we! + !* should restore point simply.! + (2*QP)-(QB+QE)"G z-QL+QP :J' !* Else hairily.! + "# QP :J' !* But simply in that case.! +  + +!& Twenex Get Spell Job:! !S Get or create an Ispell fork take argument as jcl. +Gives Spell Initialization as JCL first if it exists and this creates +a new Ispell fork. A numeric argument means to assume this won't print +anything on the screen.! + + -1fo..QISpell_Fork !* -1 If no ispell fork yet.! + f[d file + :i*fo..QSpell_Initialization !* If there's anything there,! + F=I"N :iII,' !* append a comma.! + + 0fo..QIspell_Filename"E !* See if it's SYS: or EMACS:.! + 1:' + QIspell_Filename !* Ispell program name in S.! + + qJ"L + "G @fz S_I !* QI is empty string, or init and a comma.! +[1' + "# fz S_I !* Arg>0 means it won't print anything on the screen.! +[1' + Q1m.vISpell_Fork' + qJ"G + "G 0,qISpell_Fork@fz S_ +' + "# 0,qIspell_Forkfz S_ +'' +  + +!& ITS Get Spell Job:! !S Get or create a Spell job to take string arg as JCL. +Gives Spell Initialization as JCL first if it exists and this creates +a new Spell job. A numeric argument means to assume this won't print +anything on the screen.! + + fs uname:f6[U !* Uname, for spell job.! + fs jname:f6[J !* Our jname, to proceed.! + f[d file + ((F=Editor_TypeMAILT"'E)+(Fs Lispt))"N + :i*NML Does_not_work_as_inferior_to_MAIL_or_Lispfs err 0' + e?USR:U_ESPELL"N oNew Spell' !* Use old spell job if it exists.! + "G + @ :JOB_ESPELL !* If the numarg is 1, then use @ , else .! + :JCL_ + :CONTINUE + :JOB_J + :CONTINUE_ + ' + + "# + :JOB_ESPELL + :JCL_ + :CONTINUE + :JOB_J + :continue_ + ' + + !New Spell! + :i*fo..QSpell_Initialization + F=I"N :iI I' !* If there is anything, append altmode.! + "G + @ :ESPELL_I + :JOB_J + :CONTINUE_ + ' + "# + :ESPELL_I + :JOB_J + :CONTINUE_' + + +!& Spell Replace Word:! !S Replace the word at point from the choices in the argument file.! + f[D File [2 + e?2"N F+ :i*ESP Error_in_Spell_Program:_Maybe_Directory_FullFS ERR' + [1[N + [O !* O is old word.! + Q..O[B !* Pointer to old buffer.! + f[Lines f[B Bind + er 2 Y !* Read the info from Spell, and delete the file.! + ec @ed 2 + 1au1 d !* Dispatch off failure/success code and delete it.! + q1-#"E + @ft Word_not_found._ + 0 fs echoactivew 1' !* Don't restore point in these cases.! + q1-*"E + @ft Found_it._ + 0 fs echoactivew 1' + q1-+"E + :s/îwRw 0,.x1 !* Do not include the / options. ! + @ft Found_it_because_of_1._ + 0fs echoactivew 1' +!* Display and Choose words.! + zj -2d !* Remove stray crlf at end of file.! + @ft Type_a_digit_to_replace_word,_%_for_Query_Replace,_space_to_flush. + 0u0 J + + @FA !* Fill it to make choices fit on the screen.! + j 0u0 !* Count lines.! + q0+2fs Lines' !* Set fsLines so that only the amount! + !* of screen needed is used, reducing! + !* redisplay of rest of buffer.! + !Redisplay! + f[window j @v !* Display choices.! + 0u3 !* Flag: 0 means straight replace, else query.! + !Retry! !* q3 nonzero means retrying query replace that had a bad character typed at it.! + Q3"E @fiu1' !* Put character user typed in 1.! + (Q3"'N)+(q1-%"'E)"N !* If user typed a %, then query replace prompt.! + @ft !* Also if this is retry of query replace, reprompt.! + Query_replace_O_with_which_word_(0...9)?_ + @fiu1 1u3' !* Non-zero means trying to do a query replace.! + q1"D !* Replace word if it's a digit.! + q1u1 + j + :s1="E fg o Retry' + !* We don't know what characters are in the word, so let's just + search until we get either a space or a cr. ! + .[B :sî_w Rw .[E + qB,qEfc qB,qExN !* Get the lc'd word without the number.! + ]E]B + Q3"N @ftN_' + 0,q0+2@f !* Let it know we clobbered top part of screen.! + qB[..O !* Temporarily select our old buffer.! + !* We'll let the stack unwind do it for good.! + q3"E !* If this is straight replace,! + !* assume we are at the end of the word; ! + fqO FS INS LEN !* Put length of the word in FS INS LEN! + qNu1 !* and the new text in Q1.! + m(m.m &_Case_Replace)w 0' !* preserve case. Return 0 (restore point).! + "# !* It must be query replace.! + :i*CFSEchodisp + @ftO_with_N + .(j 1m(m.m Query_Replace)ONw):j + 0,1a- "E R' !* Restore point, but not inside crlf.! + 1'' !* Return 1 (don't restore point).! + q1-204"E o Redisplay' + q1-236"E o Redisplay' + q1-32"E 1' !* Just space exits. Don't restore point.! + "# fg o Retry' !* Anything else retries.! + 1 + +!& Kill Spell Job:! !S Kill Spell job or Ispell fork.! + + FS OSTECO"G !* Kill it on Twenex?! + -1fo..qISpell_Fork"L fg ' !* Not if it's not there.! + "# -qISpell_Forkfz + -1uISpell_Fork' + @ft Ispell_fork_reset._ + 0fs echoactive 0' + + FS OSTECO"E !* On ITS?! + fs jname:f6[3 !* Our jname, to proceed.! + @ :JOB_ESPELL + :KILL + :JOB_3 + :CONTINUE_ + @ft Spell_job_killed._ + 0fs echoactive' + 0 + +!& Correct Buffer Spelling:! !& Send buffer to Spell for correction. +Writes out the current file and calls Spell to correct it. Spell +outputs a file, which is then read back into the EMACS buffer. The +output file is temporary, and deleted, unless this command is given a +string argument, which specifies the filename of the corrected file. If +the Spell program errors out, type Q to return to EMACS, and +use Revert File to recover the buffer.! + + f[D File + fs msname:f6[S !* For temporary file directory.! + + :I* + !* The output filename is used if there is no output file specified! + !* as a string argument. If no string arg is given, the output file is! + !* deleted after it is read in.! + + m(m.m^R_Save_File) !* Under buffer filename, query if smaller.! + QBuffer_FilenameuF + F=A"N QAuC' !* Make the output file be strarg, if given.! + + "# !* Otherwise, use temporary name.! + fs osteco"E fs uname:f6[U !* Uname, for temp file and spell job.! + :iCDSK:S;_OSPEL_U' + "# FS UINDEX:\[U !* User index, for temp file.! + :iCS[EMACS-SPELL-U].TXT.0'' + + fs osteco"E + !* Filenames sep. by comma, commands by altmode on ITS.! + 0m(m.m&_ITS_Get_Spell_Job)CORRECT_F,CQUIT' + !* On Twenex, files are separated by space, commands by comma.! + "# 0m(m.m&_Twenex_Get_Spell_Job)CORRECT_F_C,QUIT' + + !* Check to see that the output file exists before deleting he current text.! + !* If the output file is temporary, just put it in the buffer and! + !* delete it. Leave the buffer with fs modified set. If the output! + !* file was specified by the user, then read in the file with Visit File,! + !* and don't delete it.! + + e?C"N F+ :i*ESP Error_in_Spell_Program_--_Output_file_not_found.fs err' + HK + F=A"E ER C @Y @ED C' + "# 0FsModified + m(m.mVisit_File)C' + + +!& Spell JCL:! !S Give the string argument to SPELL as JCL. +Sample use: M-X Command to SpellDUMP DICT > +If this command starts a new Spell, it is first given the +contents Qof Spell Initialization.! + + [S + fs osteco"E :iSITS :iD' + "# :iSTWENEX :iD,' + !* It probably won't mess with the screen, so give arg of 1.! + 1m(m.m&_S_Get_Spell_Job)DQUIT' +