!* COMPLT.EMACS.6, 17-Aug-82 14:35:36, Edit by LSR Added completion on variable names to Make Local Variable and Kill Local Variable. Also fixed buffer name lister to allow for string file versions on ITS.! !~FILENAME~:! !Provide completion for buffer and variable names.! COMPLT !& Setup COMPLT Library:! !S Install changes. Installs the new Select Buffer on C-X B and the new Kill Buffer on C-X K. The old functions connected to these keys are saved away in QOld C-X B and QOld C-X K. (If variable COMPLT Setup Hook is non-zero, this is macroed instead.) ! !* Assumes that the user does not have MM-variables for any of the functions defined in the library. (Correct assumption for the standard EMACS.) ! QEMACS_Version-162"L :I*COMPLT_requires_EMACS_version_162_or_above.:FG ' 0FO..Q COMPLT_Setup_Hook [0 FQ0 "G :M0 ' 0 FO..Q Old_C-X_K "E Q:.x(K) m.v Old_C-X_K ' m.m Kill_Buffer U:.x(K) !* Install new Kill Buffer! 0 FO..Q Old_C-X_B "E Q:.x(B) m.v Old_C-X_B ' m.m Select_Buffer U:.x(B) !* Install new Select Buffer!  !& Kill COMPLT Library:! !S Un-install changes. Runs variable COMPLT Kill Hook if it exists. Otherwise restores functions bound to C-X B and C-X K.! 0 FO..Q COMPLT_Kill_Hook [0 FQ0 "G :M0 ' 0 FO..Q Old_C-X_K F"N U:.x(K) MM Kill_Variable Old_C-X_K' 0 FO..Q Old_C-X_B F"N U:.x(B) MM Kill_Variable Old_C-X_B'  !& Read Buffer Name Prep:! !S Set up for reading buffer name with completion. Initializes the CRL variables (leaving them pushed on the stack).! [CRL_List [CRL_Prefix !* push the variables! [CRL_Name_Type [CRL_Name_Lister FS QP PTR [P !* save QP PTR for popping! !* of other temporaries! !* build FO-style list of! !* buffer names and buffer indices! 5 FS Q VECTOR [L 2 U :L(0) !* 2 entries per list elt! FQ.B/5 [0 0[1 !* # entries in Q.B => Q0! !* Start current buffer entry => Q1! [2[3 < Q1-Q0; Q:.B(Q1+1!*bufnam!) U2 !* buffer name => Q2! -(@:FO L 2) U3 !* where in QL bufferbelongs! Q3 "G QL[..O 5*Q3J 10,0I ]..O !* make 2 slots! Q2 U:L(Q3) Q1 U:L(Q3+1) ' !* initialize them! Q:.B(Q1) + Q1 U1 > !* advance to next buffer! QL UCRL_List :I* UCRL_Prefix :I*buffer UCRL_Name_Type m.m&_Buffer_CRL_Lister UCRL_Name_Lister QP FS QP UNWIND !* return without popping ! !& Buffer CRL Lister:! !S CRL Name Lister for & Read Buffer Name. Adds visited filename and modified bit to list of buffer names.! f[ d file FF&2"n BJ !* insert a heading! I__Buffer_Name_________Visited_File_Name   ' "# [1 Q:.1(Q1)[0 !* Q0 gets buffer name! Q:.1(Q1+1)U1 !* Q1 BUFFER index! Q:.B(Q1+4!*bufbuf!)[X !* buffer looking at! QX[..O FS MODIFIED (]..O)"E I__ ' "# I*_ ' !* modified bit! G0 20-FQ0 :F"G w2 ',32I !* buffer name & some spaces! Q:.B(Q1+2!*bufvis!)u0 q0 "E QX[..O FS Z(]..O) \ I _characters' "# G0 ET0 q:.B(Q1+9!*bufver!)[3 fs d version :"G fs d version+1 "n I _( !)! fq3 "L q3\ ' "# g3 ' !(! I) ''' I  !* CRLF! '  !Select Buffer:! !C Select or create buffer with specified name. Can accept the buffer name as a string arg, or the buffer number as a numeric arg, or a string pointer as arg (when used as a subroutine). If there is a buffer with that name, it is selected. Otherwise, a buffer with that name is created and selected. When a new buffer is selected the first time, if Buffer Creation Hook is nonzero, it is run after the buffer is selected. A precomma arg is the prompt string to use. Uses & Read Command Name to read buffer name with completion. Null buffer name selects the default; method for entering a new buffer name depends on setting of QCRL Non-match Method. ! MMM_&_Check_Top_Levelbuffers [4 0[3 FF&1"N U3' !* Numeric arg => use it as buffer or buffer # to select.! "# "E :F "G :i3'' !* Precomma arg, or no postcomma arg, => read string arg.! Q3"E !* Else must read from tty.! "N u4' !* Precomma arg is prompt string to use.! "# :i4 Select_Buffer' QPrevious_Bufferu3 !* Get name of default new buffer to put in prompt.! 1,Q3M(M.M &_Find_Buffer)"L Q:.B(1)U3' !* read buffer name! !* with completion! m(m.m&_Read_Buffer_Name_Prep) 62.,m(m.m&_Read_Command_Name)4_(3):_U3 Q..H"N F' 0U..H !* Don't wait for space: redisplay text immediately.! FQ3"L 0' !* Give up if get a rubout instead.! '' Q3[5 !* Save name (or buffer #) in Q5.! FQ3"E QPrevious_BufferU3' !* Null string means previous buffer.! 1,Q3 M(M.M&_Find_Buffer)[1 !* Get index in buffer table of this name or number.! Q1u4 !* Q4 remains negative, for a new buffer.! Q1"L !* No such buffer => make one now.! FQ3"L :I*No_such_buffer FS ERR' !* Refuse to create buffer if bfr number spec'd.! FQ5"E 0U1 0U4' !* If ^XB and prev bfr non ex, use 1st buffer instead.! "# Q3 M(M.M &_Create_Buffer)U1'' !* Else create the specified buffer.! QBuffer_IndexU3 Q1-Q3"E 0' 1F[Noquit !* Prevent quitting half-switched.! 0FO..Q Buffer_Deselection_Hook[5 Q5"N M5' Q.B[..O ZJ 0K ]..O !* Get gap in buffer table out of the way.! Q3,13!*buflcl!F.B !* Swap old buffer's locals back into its entry.! QBuffer_FilenamesU:.B(Q3+2!*bufvis!) !* Stick its filenames back into entry.! QMode U:.B(Q3+3!*bufmod!) !* Stick selected mode into entry.! !* Simultaneously swap out old buffer's TECO default filenames and window address, and swap in the new buffer's.! Q:.B(Q1+6!*bufwin!) FS WINDOW U:.B(Q3+6!*bufwin!) Q:.B(Q1+5!*buftdf!)F"E W' FS D FILE U:.B(Q3+5!*buftdf!) !* We now are "between buffers".! Q:.B(Q1+2!*bufvis!)UBuffer_Filenames !* Get filenames of new buffer.! Q:.B(Q1+1!*bufnam!)UBuffer_Name !* For our records, save its name! Q:.B(Q1+3!*bufmod!)UMode 0F[VARMAC !* Set QAuto Save Mode to match the truth.! Q:.B(Q1+10!*bufsav!)UAuto_Save_Mode !* But don't try calling the function! F]VARMAC !* Auto Save Mode -- nothing is really changing.! Q1 UBuffer_Index !* and its index, for when we deselect it.! Q:.B(Q3+1!*bufnam!)UPrevious_Buffer !* remember previously selected buffer's name.! Q:.B(Q1+3!*bufmod!) U3 Q1,13!*buflcl!F.B !* Get new buffer's local variable values.! 1FSMODE CHANGE !* Recompute mode line eventually.! Q:.B(Q1+4!*bufbuf!) U..O !* Now really switch to this buffer.! 0FO..Q Buffer_Selection_HookF"N [..N' Q:.B(Q1+5!*buftdf!)"N ' !* If buffer has been selected before, that's all.! Q:.B(Q1+1!*bufnam!)U4 FS OS TECO "E F64'"#Q4' FS DFN1 !* If buffer selected for 1st time, set default fn1 from name.! QDefault_Major_ModeU4 !* Select the desired major mode.! FQ4"G M(M.M4_Mode)' 0UAuto_Save_Count 0FO..QBuffer_Creation_HookU4 !* If buffer selected for 1st time, maybe run user's hook.! Q4"N M4'  !Kill Buffer:! !C Kill the buffer with specified name. Takes name as a string (suffix) argument, or reads it from terminal. (Uses & Read Command Name for completion: null name means the current buffer.) Alternatively, the name (as string pointer) or the buffer number may be given as a prefix argument. If the buffer has changes in it, we offer to write it out.! FF&1"N [1 ' !* Numeric arg => use it as buffer # to select.! "# !* Read name of buffer! !* with completion! m(m.m&_Read_Buffer_Name_Prep) 52.,f Kill_Buffer:_ [1' FQ1"E MMM_&_Check_Top_Levelbuffers QBuffer_NameU1' !* Null string means current buffer.! [2 [3 Q1 M(M.M&_Find_Buffer)U1 !* Get index in buffer table of this name.! Q:.B(Q1+2!*bufvis!)"N !* If the buffer is visiting a file,! Q:.B(Q1+4!*bufbuf!) [..O !* Select it! FS MODIF"N !* to see if it needs to be written back! Q:.B(Q1+12!*bufnwr!)"E !* (and is not read-only).! Q:.B(Q1+1!*bufnam!)U2 FS TYPEOUT"L @' FT Buffer_2_contains_changes.__Write_them_out FS TYPEOUT"L 1' M(M.M &_Yes_or_No)"N Q:.B(Q1+2!*bufvis!)F[D FILE FS OSTECO"N 0FS D VERS' 0[..F M(M.M Write_File) ]..F F]D FILE''' ]..O' Q:.B(Q1)U2 !* Get length in words of entry.! Q1-QBuffer_Index"E !* If trying to kill the current buffer,! 0U:.B(Q1+10!*bufsav!) !* Turn off auto save - might save as visited file.! :I* Killing_current_buffer;__Select_which_other_buffer !* ! ,M(M.M Select_Buffer)' !* select a different one first.! 1F[NOQUIT Q:.B(Q1+4!*bufbuf!) FS BKILL !* Kill the actual buffer (why wait for GC?).! 10.F? !* Also errs out if try to kill selected buffer.! Q.B[..OQ1*5J Q2*5D !* Delete the entry from the table.! QBuffer_Index-Q1F"G +Q1-Q2 UBuffer_Index' 0U..H  !* If killed buffer preceded current one, current one's! !* index has been changed.! !Insert Buffer:! !C Insert contents of another buffer into existing text. Specify buffer name as string argument.! !* Read buffer name! !* with completion! m(m.m&_Read_Buffer_Name_Prep) 72.,f Insert_Buffer:_ [1 fq1"e qPrevious_Bufferu1' Q1M(M.M &_Find_Buffer)[2 !* Else get index of specified buffer.! G:.B(Q2+4!*bufbuf!) !* Select the specified buffer, and! .: FK(FKC) !* Put mark at end, point before.! !View Buffer:! !C View a buffer moving by screenfulls. Buffer name is string argument; null arg means selected buffer. Space moves to next screen, Backspace moves back a screen. Return exits leaving point in current screen. Anything else exits and restores point to where it was before; and if it isn't Rubout, it is executed as a command. Also useful on fast storage scopes like the Tektronix. However, Backspace is only available on real displays.! m(m.m&_Read_Buffer_Name_Prep) 72.,f View_Buffer:_ [1 0[2 fq1"e qBuffer_Nameu1' !* If arg is null, use current buffer.! "# Q1M(M.M &_Find_Buffer)[2 !* Else get index of specified buffer! Q:.B(Q2+4!*bufbuf!)[..O' !* and select it, for TECO.! [..J :I..J Viewing_Buffer_1__ .[P FN QPJ :I* [..A !* SAVE ., ..A! q2"e :F FS WINDOW+BJ' "# q:.b(q2+6!*bufwin!)+bj f[ window' 1,M(M.MView_File) !* Actually display and process Space and Backspace.! FS REREAD"L ' !* flushed by rubout or space past end.! :FI-î"E FIW !* ^M => leave the cursor in the center of the screen.! FS RGETTY"E .UP .' FSWINDOW+BJ Q2"N .-BU:.B(Q2+6!*bufwin!)' FSLINESF"EW FS HEIGHT-(FS ECHO LINES+1)-(FS TOP LINE)'/2L .UP .'  !& Read Variable Name Prep:! !S Set up for reading variable name with completion. Sets up all the CRL variables (they are left pushed on stack).! :I*variable [CRL_Name_Type Q..q [CRL_List :I* [CRL_Prefix !* return without popping! !Kill Variable:! !C Eliminates definition of specified variable.! m(m.m&_Read_Variable_Name_Prep) !* read variable name with! !* completion! 12.,f Kill_Variable:_ [0 :fo..q0 [0 !* Find the variables idx in symbol table (..Q)! q0"l ' !* Not defined =) do nothing.! q..q[..o q0*5j 15d 0 !* Else delete the 3 words describing it! !View Variable:! !C Type out contents of variable. Simply reads a variable name, and then calls View Q-Register. Uses completion if the name is read from the terminal.! m(m.m&_Read_Variable_Name_Prep) !* read variable name with! !* completion! 12.,f View_Variable:_ [0 m(m.mView_Q-Register)0  !Set Variable:! !C Set the value of a named variable. The name of the variable is a string argument. If you supply a numeric argument, that is the new value. Otherwise, a second string is the new value. Completion is available for the variable name, with Space and Altmode. Abbreviations are not allowed unless you complete them; any nonexistent name creates a new variable.! m(m.m&_Read_Variable_Name_Prep) !* read variable name with! !* completion--do not! !* allow null name! .32.,F Set_Variable:_( FF"E 1,F Value:_' "# '[1 )[0 !* with completion, no need! !* to permit abbreviation! !* by the user! :F "L @ ' :FO..Q 0:"G 0M.V0' !* Create variable if it doesn't exist.! Q1U0 0 !* Set value in any case.! !Make Local Variable:! !C Make a variable local to the current buffer. Example: M.LFoo Variable (since this function lives in .L). The variable name must be given in full, not abbreviated. Its local value starts off the same as its global value. However, a numeric argument to this function sets the local value. "1," as arg means assume that the local doesn't exist yet. "2," means make a permanent local that won't go away when major mode changes.! m(m.m &_Get_Library_Pointer)EMACS m(m.m &_Read_Variable_Name_Prep) !* read variable name with! !* completion--do not! !* allow null name! 32.,f Make_Local_Variable:_[0 fm(qLm.m Make_Local_Variable)0  !Kill Local Variable:! !C Kill one of the current buffer's local variables. The global value is restored.! m(m.m &_Get_Library_Pointer)EMACS m(m.m &_Read_Variable_Name_Prep) !* read variable name with! !* completion! 12.,f Kill_Local_Variable:_[0 fm(qLm.m Kill_Local_Variable)0