!Write File:! !C Store buffer in specified file. This file becomes the one being visited. Specify filename as string argument. Precomma arguments have hairy meanings; see the code.! !* "1," says called by ^R Save File; inhibits calling & Set Mode Line and auto-save reinitialization. Also inhibits setting visited filenames. Also means if we lose trying to write a specific version number we should write an incremented version number. "-1," as argument inhibits updating the buffer's file cdate as well. If not at top level (can't switch files now), doesn't update anything about the current buffer except FS MODIFED, but does return the written file's creation date so the caller can store it.! QBuffer_Index[2 [4 0F[VBW 0F[VZW !* Write whole bfr regardless of virtual bounds! :F "L Q.F-Q..F"E !* If at top level, default to buffer filenames.! Q:.B(Q2+2!*bufvis!)F"N FS D FILE''' 5,1F Write_File[1 ET1 !* Set default names and open file.! F[D FILE ET[TECO]_OUTPUT 0FS D VERSW < 1:< EI >F"E 0;'U4 !* Try with different versions! F~(0,7:G4)OPN0130"N !* If we get error because two people trying at once,! F~(0,7:G4)OPN0750"N Q4FS ERR'' !* Try other version numbers! &77777.FS D VERS> !* till we find one which is not in use.! F]D FILE FS OF CDATE [3 !* Remember file date.! HP !* Write the data.! -1"E :'1< EF >+0U4 !* Close the file. If ^X=1, save any error code.! Q4"L F~(0,7:G4)OPN0750"E !* If can't write specific version,! 0FS D VERS EF' !* Write a new version.! "# Q4FS ERR'' 0FS MODIF !* Have written out => can flush without writing it again.! 0FS X MODIF +1"E FSRGETTY"E O NoPrint'' !* Don't announce auto saves on printing tty.! FSOFILE[1 FSRGETTY"E :FT' :I*C FS ECHO DIS @FTWritten:_1 FS ECHO LINES-1"N @FT ' 0FSECHO ACT !No Print! Q..F-Q.F"N Q3 ' !* File written. If not from EMACS's current buffer, that's all.! FSZ U:.B(Q2+11!*bufsiz!) !* Update last saved size even if auto save.! FS ^R MDLY FS ^R MCNT :"L !* If precomma arg not -1,! Q3 U:.B(Q2+8!*bufdat!) !* update last saved file date and version.! FS OF VERSF"L FS OFILEF[D FILE FS DFN2:F6( F]D FILE)' U:.B(Q2+9!*bufver!) 1FS MODE CH' "N 0' !* If doing ^R Save File, return -- filename not changed.! FS D FILEU1 M(M.M Set_Visited_Filename) 1 0 !& Read Command Name:! !S Read in an command name, with completion. Rubout, ^D, ^U and ^L perform editing. Space and Altmode do completion. ? lists choices. Takes a prompt-string as a following string argument. A numeric argument is the initial contents of the string to be accumulated. A pre-comma arg containing the "4" bit means don't wait for a confirming CR; the "2" bit means complete over the symbol table in CRL List using the prefix string in CRL Prefix. The "8" bit is deliberately ignored. The "16" bit permits names that don't match. The "32" bit means CR is allowed with an empty name. The F^K command with the "8" bit set in its precomma arg calls & Read Command Name, passing along its arguments. Two values are returned, the second being the completed string (or 0 if exit was due to over-rubout). The first is bit-decoded; 1 means we displayed the string, 2 means the terminating character was Return. See Source code for more info.! !* If the 16 bit is set in the pre-comma arg, then names which don't match are permitted. How to specify one is controlled by the value of CRL Non-Match Method: 2 bit: CR will terminate without performing completion 4 bit: LF will terminate without performing completion The default value is 2. CRL Name Lister can (if not zero) contain a function for use in assembling the list of matching items, for "?". This function is used as follows: (1) For each name to display, the function is called with no pre-comma arg, and a post-comma arg which is an index into CRL List (which can be found in Q.1). The function should insert information about that name into the buffer beginning at point, and include a CRLF at the end. (2) The function is called with a pre-comma arg of 1, with the buffer containing all the names. The entire buffer will be displayed after the function returns. (Some things it can do: sort the names, insert a heading, etc.) If the variable CRL Name Type is nonzero, it should contain a string such as "buffer" which fits in the slot: "You are entering a name..." It is used in help messages. If the variable CRL Help is nonzero, it is printed after the regular help message is given. *! [0[1[2[3[4[5[6[7 !* save regs! 1F[^P CASE !* Ignore case when sorting! :I6 !* Read prompt string argument! 0[8 !* Q8 is nonzero if we are echoing.! 0[9 !* Q9 is nonzero => type altmode after completed name.! q..q[.1 :i*MM_[.2 !* Q.1 and Q.2 for normal case of MM-command completion --! !* use standard symbol table and "MM " prefix to select! !* only the MM-variables.! 0[.0 !* Q.0 contains whether and how to allow non-matches.! &20."n 2fo..Q CRL_Non-match_Methodu.0' &2"n qCRL_Listu.1 !* Q.1 has the symbol table to complete over.! 0fo..qCRL_Prefixu.2 !* Q.2 has the prefix string -- only variables starting! q.2"e :i.2'' !* with that are considered, and the returned name does! !* not include the prefix string.! 0[.3 !* Q.3 = number of chars not to erase & reprint! !* when completion occurs (already complete & verified)! 0[.4 !* Number of chars of name printed.! 0f[HelpMacro !* Help character should be seen be FI! f[BBind fq()"g g()' !* Make temp buffer to accumulate command name in.! q..ou5 o Read !Redisp! 1u8 :i*CfsEchoDis !* Clear echo area! fs rgetty"e @ft ' @ft6 @ht !* Retype prompt string and input! zu.4 o Read !Barf! !* Here if tried to complete and no match! fg !* and that is not allowed. Type bell.! fs rgetty"n @ft_' !* Force cursor back to echo area on ITS.! o Read !Changed! !* Come here when completion augments the string.! q8"n !* If we have started printing,! fs rgetty"n q.4-q.3< :i*X fs echo dis > !* Reprint any chars that weren'r verified! q.3,z@t' !* and print new ones.! "# q.4,z@t' !* On printing tty, just print new ones.! zu.4' zu.3 !* All chars we have are verified, even if not printed.! !* If name is fully complete, think about exiting.! q9"n &4"n !* If pre-comma arg has the 4 bit, return completed name.! q8,q3' q8"n @ft 0u9 !* If waiting for CR with completed string, type an! :fi-13"n o Redisp''' !* altmode, but if next char isn't cr, flush the Alt.! !Read! q8"e 0:"e o Redisp'' @:fiu0 q0-4110."e oHELP' fiu0 !* Handle HELP! q0-32"e ."e o Read'' !* Ignore initial spaces.! q0f Š_?"l !* Not a special character! q0- "e Q.0&4 "n !* LF typed so return immediately! q8"n @FT  ' !* echo return! q8+4,(HX*) '' q0-"e fiu0' !*  quotes the next character! q0i !* Add char to buffer.! q8"n fs^RMode"n -1@t %.4 '' !* Echo if in ^R mode! oRead' !* back for more! q0-"e !* Turn ^R into ^ and R.! i^ R q8"n fs ^RMode"n -2@t %.4 %.4'' oRead' q0-177."e !* Rubout?! q8"e q0fsReRead oRedisp' z"e q8,0 ' !* Rubout when string empty returns 0.! zj 0au0 -d !* Put char being rubbed in Q0, and remove from buffer.! fsrgetty"e @ft0 ' !* Type character if cannot erase! "# q0-40."l oRedisp' !* Erase if possible! :i*X fs echodis Q.4-1u.4 q.4-q.3"l q.4u.3' oRead'' q0- "e oRedisp' !* ^L redisplays the current string! q0f:"l hk 0u.3 oRedisp' !* ^D and ^U flush input and reprompt.! q0-?"e !* Help requested?! &2"e !* Completing over MM-commands, so load BARE.! f=(0,2:g5)^R"e !* Must do it befor the F[BBIND.! m(m.m &_Load_Bare)'' f[BBind :ft !* Get buffer to mess with! &2"e !* Completing over MM-commands, so look thru libraries.! fs :ej page*5120+400000000000.u7 !* ptr to 1st file! < fq7:; g(q7m.m~DIRECTORY~) !* get directory for file! q7+4+fq7u7 !* ptr to next file! > j .u3 i  < 2r :s 5; 0l q3,.k l !* save command name! .-z; .u3 0:l > q3,zk' !* Done mapping down library space.! !* Now pick out possibles from the symbol table.! :fo.1.25,0fu3 !* Q3: index to first match in symbol table.! :fo.1.25›,0fu4 !* Q4: index to last match in symbol table.! q4-q3/q:.1(0) < !* iterate over all matches in symbol table.! 0fo..q CRL_Name_Listeru7 q7"n q3m7' !* Either call user's routine! "# !* or do the standard thing.! q:.1(q3)u7 !* Q7: Matching symbol name! fq.2,fq7g7 i  ' !* insert variable name! q3+q:.1(0)u3 !* next match in symbol table! > j &2"e < :s~; 0lk>' !* Don't mention functions with ~ in their names.! 0fo..q CRL_Name_Listeru7 q7"n 1,m7' !* Either call user's routine! "#   l   !* or sort list,! j < .-z; x1 l < .-z; 1f=1"N 1;' k > > !* remove duplicates! ' ft Here_are_the_possible_completions_of_what_you_have_typed:  ht 0fsflushedw f]BBind !* Type the matching commands! 0u..h f oRedisp' !*** Character typed is space or altmode or CR.! !Retry! q0-î"e !* if CR, see if we should return without! !* doing completion. return if...! (Q.0&2"'n)( !* 2-bit of CRL Non-Match Method is set or...! )  ((z"'e)&(&40."'n)) "n !* empty name and 32-bit of arg is set! q8"n @FT  ' Q8+6,(HX*) '' &2"e z-1"e 0a:fcfLVKEIW:"l !* Hack one-letter abbreviations if want MM-name.! h@fc f~5L"e i ist_' f~5V"e i iew_' f~5K"e i ill_' f~5E"e i dit_' f~5I"e i nsert_' f~5W"e i hat_' o Changed''' !* Done hacking one-letter abbreviations.! :i3 :i4› !* Q3 has the largest thing we abbreviate! !* Q4 has the smallest! :fo.1.25,0fu1 !* get offset of the smallest symbol! fq.1/5-q1"g q:.1(q1)u2 !* whose name we abbreviate! f~2.2,0f-fq.2"g fq.2,fq2:g2u4'' !* and use it as smallest! :fo.1.25›,0fu1 !* get offset of the largest symbol! q1-1"g q:.1(q1-q:.1(0))u2 !* whose name we abbreviate! f~2.2,0f-fq.2"g fq.2,fq2:g2u3'' !* and use as largest! &2"e !* Now map down library space if we want an MM-command.! f=(0,2:g5)^R"e !* If name starts with ^R, make built-in functions avail.! m(m.m &_Load_Bare)' fs :ej page*5120+400000000000.u7 !* ptr to 1st file! f[BBind !* get temp. buffer to do G's into! < fq7:; !* exit if no more files! q7+8+fq(q7+4)u2 !* ptr to FO table of file! :fo25,0f*5u1 fq2-q1"g q1,q1+5g2 !* If smallest thing we abbreviate in this file! .-5fsword+q2u1 !* is smaller than smallest so far, it is new smallest! f~14"l q1u4'' :fo25›,0f*5u1 q1-14"g q1-10,q1-5g2 !* Same for largest thing we abbreviate in this file! .-5fsword+q2u1 f~13"g q1u3'' hk q7+4+fq7u7 !* ptr to next file! > f]BBind' f~34u1 !* get no. of chars of A and B that match! q1"l !* if smallest > largest then no match.! (&20."'e)(q0-32"'n) "n o Barf ' :i7 q7u2' !* but that is ok if non-match ok! !* and user typed a space! "# q3u7 q1"n 0,q1-1:g3u7' !* q7 gets common initial segment of q3 and q4.! z,fq7:g7u2' !* Q2 gets that, minus the chars we already have.! q0-î"e fq4-fq7"e q4u3 0u1'' !* CR: if smallest is initial seg of biggest,! !* regard it as a full completion.! q0-32"e !* Space: complete only the first word.! fq2"e q1"n !* if not exact match, but no completion possible,! 0,0a-32"e oBarf' !* barf if second space in a row.! 32i q8"n @ft_ %.4' oRead'' !* but allow one space to be forced in.! 32f2+1u2 q2"g !* Space and completion is possible: stop! 0,z+q2:g7u7'' !* at first space.! "# fq2"e q1"n fq4-z"n oBarf' !* Not space and ambiguous => barf unless exact match.! q4u3''' !* Exact match => regard as fully completed.! f~34"e fq3-fq7"e !* Entire name has been completed.! q0-î"e q8"n @ft ' 2+q8,(:i*3)' !* If char typed is CR, return completed name.! !* Copy the name, in case it comes from BARE.! 1u9'' !* Otherwise, say name is complete.! hkg7 o Changed !* Stick in completed text, maybe redisplay, continue.! !HELP! fiw :ftYou_are_typing_in_ &2"e ftthe_name_of_an_EMACS_extended_command !* Normal MM-name completion.! :i7_command' "# 0fo..q CRL_Name_Typeu7 !* Completion over some arbitrary list.! fq7"g :I7_7 ' "# :I7 ' ft a7_name ' ft. Use_Rubout_to_delete_previous_characters;_use__to_delete_the_whole_thing. Typing_Space_or_Altmode_causes_as_much_of_the_name_as_possible_to_be filled_in_for_you_(this_is_called_completion). Type_?_to_list_all_the7_names_which_match_what_you_have_typed. &6-4"e ft !* no CR required and completing! !* over command names; assume that! !* this was called from M-X! If_completion_fills_in_the_entire7_name_an_Altmode_()_appears. __You_can_then_start_typing_the_arguments_to_the_command. __Terminate_them_with_a_Return.__If_there_are_no_arguments, __you_can_use_just_Return_after_a_sufficient_abbreviation.' "# ft If_completion_fills_in_the_entire7_name,_ &4"e !* CR required! ft an_Altmode_()_appears. ' "# !* no CR required! ft it_will_be_chosen. ' Q.0&2"e ft !* CR completes! Typing_Return_will_complete_the7_name_and_terminate. &40."n ft !* also null entry allowed! __You_may_also_type_Return_if_there_are_no_other_characters, __to_enter_a_null7_name '' "# ft !* CR doesn't complete! Typing_Return_will_terminate_the7_name,_without_completion. ' Q.0&4 "n ft !* LF doesn't complete! Typing_Linefeed_will_terminate_the7_name,_without_completion. ' 0fo..q CRL_HelpU7 !* more help info! q7"n FT 7 '' FT  0u..h f oRedisp !* -*-TECO-*-! !^R Incremental Search:! !^R Search for character string as you type it. C-Q quotes special characters. Rubout cancels last character. C-S repeats the search, forward, and C-R repeats it backward. C-R or C-S with search string empty changes the direction of search or brings back search string from previous search. QSearch Exit Charm(m.m& Charprint) exits the search; with search string empty it switches to non-incremental ^R String Search. Other Control and Meta chars exit the search and then are executed. If not all the input string can be found, the rest is not discarded. You can rub it out, discard it all with C-G, exit, or use C-R or C-S to search the other way. Quitting a successful search aborts the search and moves point back; quitting a failing search just discards whatever input wasn't found. On printing terminals, C-L types line found but doesn't exit the search.! [D !* QD is direction and # times to search.! 0[L !* QL > 0 iff failed to find current search string,! 10.[R !* QR is state register: ! !* 40. => ^R or ^S repeating search or gobbling default.! !* 10. => just starting.! !* 4 => printing char just read.! !* 2 => rubout just done wants full redisplay.! !* 1 => rubout just done.! [Q @:iQ` !* MQ pushes current info: ., qL, q2, q0, qD.! q4+1*5-fq3"e !* We are going to push in q3, so make sure space exists.! q3[..o zj 200,0i ]..o' .u:3(%4) !* Push point, search string,! qLu:3(%4) q2u:3(%4) q0u:3(%4) !* this character, and current direction of search.! qDu:3(%4) ` [T fs tyi sourc"e @:iT` !* MT updates the echo area.! Q9-Q.9"N 2[R' Q9U.9 !* Q9 holds prompt for echo area. Redisplay if changed.! fs rgetty"n 2&qR"n !* If we need to redisplay the whole thing,! qc fs echo dis !* home up and clear line first,! @ft 9:_ q2u8'' !* then type the prompt and decide to retype whole string.! @ft 8 :i8  !* Update displayed search string.! ` ' "# :iT' !* Don't display if inside a macro.! [C :IC TL !* QC has string to home up in echo area and clear line.! [0 !* Q0 holds type-in character being processed.! [2 :i2 !* Q2 holds accumulated search string.! [8 :i8 !* Q8 has accumulated stuff to type in echo area.! [9 !* Q9 has [Failing ][Reverse ]Search for echo area.! 0[.9 !* Q.9 has last value of Q9 actually displayed.! 1fo..qSearch_Exit_Option !* QE nonzero => random control chars exit.! 200fs q vector [3 !* Q3 holds stack for partial search strings.! -1[4 !* Q4 is stack pointer.! [5 !* Q5 is random temp.! .[P !* QP has old point (to maybe push at end).! [S :IS M.M&_Isearch_RuboutUS :MS !* QS has & Isearch Rubout (autoloading)! :I* M(M.M&_Isearch_Help) F[Help Mac 1f[noquit [6 [7 !* Q6 and Q7 are the success and failure echo strings.! qD"g :i6I-Search :i7Failing_I-Search' qD"l :i6Reverse_I-Search :i7Failing_Reverse_I-Search' q6u9 !* Search starts out successful.! 0[I !* QI is nonzero when we are reading input.! fs rgetty"e fs tyi sourc"e @ft _S:_' !* On printing tty, start typing out.! 1fstypeo'' !Restart! 1:< 1uI -2f[noquit !* Set up an errset to catch quits.! < qL"e q6' "# q7'u9 q9-q.9"n mt' !* Display direction and status in echo area.! 0@V 1uI :fiu0 0uI @fiu5 q5fs^r indir-qSearch_Exit_Char"e fq2:@; ! 0fsnoquitw qD:m(m.m ^R_String_Search)' q5-8"e o Funny' q5-176."g o Funny' q5-"e o Control' !* If Altmode isn't the exit char, it's like a ctl char! q5-î"e  FS REREAD' !Normal! 4uR !* Handle printing char.! mQ !* Push ., qL, q2, q0 and qD into q3, for rubbing out.! :i2 2 0 !* stick this char at end of search string,! fs tyi source"e !* If not inside a keyboard macro,! fq8"n mt' !* Update the display.! @ft 0 "# !Try! !* Note if fall through we are inside a failing conditional.! mt !* Update the displayed search string.! '' qL"n !' !* No point in searching if know it would fail.! .u5 40.&qR"e !* For ^S, ^R suppress the moving back so don't no-op.! qD"g fq2-1r' !* Move back, so that from FO/\O we find the FOO.! "# fsz-qP f[ vz fq2-1"g fq2:c"e zj'' f]vz'' !* After finding FO backwd, move fwd 3 so can find FOO.! qD:s2"l !' q5j 1uL fg ! !* But if search fails, undo that motion back.! !Funny! q5-177."e o Rubout' !* Only control characters and backspace get past here.! q5&537.-S"e o Forward' !* Check for C-S and C-s (ignore case bit).! q5&537.-R"e o Backward' !* Note: mustn't change q5 since Control rereads it.! q5&537.-Q"e o Quote' q5&537.-L"e fs rgetty"e o Reprint' o Control' qE"e o normal' o Control !Reprint! !* ^L on printing tty prints current line.! 0t ft..a t ft _S:_2 !* Then re-prompt.! ! !Quote! !* ^Q quotes the next character.! 1f[noquit fs osteco"n -1f[helpch' fiu0 fs osteco"n f]helpch' 0fs quitw f]noquit o normal !Forward! !* ^S means search again forward.! qD"l :i6I-Search :i7Failing_I-Search' q4"L qD"g o Default' !* ^S as 1st char going fwd => gobble default string.! "# 1uD !'' !* ^S as 1st char, going backward, changed to fwd.! mQ !* Push ., qL, q2, q0 and qD into q3.! qD"L 0uL' !* If reversing direction, don't assume search will fail.! 1uD !* String not null: make sure going fwd,! 40.uR !* Mark us as a ^S so don't change search string,! o try !* just search for it a second time.! !Backward! !* ^R means search again backward.! qD"g :i6Reverse_I-Search :i7Failing_Reverse_I-Search' q4"L qD"l o Default' !* ^R as 1st char going backwd => gobble default string.! "# -1uD !'' !* ^R as 1st char, going forward, changed to backwd.! mQ !* Push ., qL, q2, q0 and qD into q3.! qD"g 0uL' !* If reversing direction, don't assume search will fail.! -1uD !* String not null: make sure going backwd,! 40.uR !* Mark us as a ^R so don't change search string,! o try !Default! !* Come here to use default search string.! mQ !* Push current state so can rub the default out.! qSearch_Default_Ring[..o !* Find the default! .fs word u2 ]..o !* and gobble it.! fq2"l :i2' q2u8 40.uR !* Inhibit moving back before starting to search.! o try !Rubout! q4"l fg !' !* Rubout when string is empty does nothing.! ms !* Call & Isearch Rubout.! qL"e q6' "# q7'u9 !* Fix displayed direction and status for echo area.! mt ! !* Redisplay and loop back.! !Control! q5 fs reread 0; > f]noquit >u0 @feqit-q0"e @fg !* If we quit, record in journal file.! !* Record Rubout if quit while searching,! !* record :^G if failing or waiting for input.! qL"'gqI"N :i*:' "# :i*_›' fsjrn wr QL"g mt !* If failing, rub out the unfound chars and restart.! o Restart' qI"e ms mt o Restart' !* If quit while actually searching, restart.! QPJ 0fsnoquit -1fsquit' !* If succeeding, restore starting point and quit.! q0f"n fs err' !* Error not a quit => pass it on.! fq2"g qSearch_Default_Ring [..o !* New search char, save prev default.! fq(.fsword)-1"G 5c .-z"e j'' !* If previous default is worth saving, push it! q2,.fsword !* Store current (new) default! ]..o' fs tyi source"e @ft  ' !* Echo an altmode to show we have exited.! qP mMM_&_Maybe_Push_Point !* Maybe leave mark at place search started.! 0