diff --git a/README.md b/README.md index f292962..9faf73a 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,10 @@ not included. "This is for/from Lambda, I do not know the version sadly :( The copy comes from Joe Marshall who used to work at Gigamos." +- Multics Emacs 12.9 from web.mit.edu. + + Last changed in 1989-11-14. + - Emacs 13.8 from http://decuslib.com/decus/vax85b/gnuemax/emacs/ Possibly with VMS modifications. diff --git a/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs-history-comment.info b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs-history-comment.info new file mode 100644 index 0000000..020111d --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs-history-comment.info @@ -0,0 +1,47 @@ +02/13/86 add-history-comment, add-hcom + +Syntax: esc-X add-history-comment + or: esc-X add-hcom + + +Function: allows entry of a history comment while within EMACS. If +this is the first history comment entered, the EMACS extension sets up +the "HISTORY COMMENTS" header and "END HISTORY COMMENTS" footer. The +approve value and summary are prompted for. + + +Notes: You will be prompted for the approve value and the summary. A +null response (carriage return) is valid for the approve value but not +for the summary as it is a required field. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.changes.info b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.changes.info new file mode 100644 index 0000000..ca341c8 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.changes.info @@ -0,0 +1,50 @@ +02/17/89 Significant changes in Emacs 12.9 for MR12.3 + +1. f (rmail-forward) to forward the current message to an address + (list) that will be prompted for. A numeric argument will allow + the user to enter redistribution comments via a comments buffer. + +2. x (rmail-toggle-seen) to toggle the seen switch on the current + message. This switch is displayed to the user as the minor mode + "Seen" and will be turned on immediately a message is brought into + the RMAIL buffer to be displayed. + +3. ? (rmail-help) to display brief information about each of the + RMAIL mode (additionally the reply and comment buffers) requests + that are available. + +4. q (rmail-quit) is being modified to only question a user quitting + when no rmail commands have been entered between the arrival of + new mail and requesting of rmail-quit. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.errors.info b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.errors.info new file mode 100644 index 0000000..e45d952 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.errors.info @@ -0,0 +1,551 @@ + +09/21/87 emacs +Known errors in the current release of emacs. +# Associated TR's +Description + +386 phx20768 +Emacs gets an error if the height of the user_i/o window is reduced +during a video system Emacs session (e.g. doing ^Z^Z and shrinking the +window for a status line). + +385 phx20663 +If the user lacks w access to an output file, and answers "no" to the +"Do you want to write to the protected file ?" query, a confusing +error message, containing only [wd]>nil, is displayed. + +384 phx20641 +If the current line fills the entire window, ^V (next-screen) appears +to do nothing. This is because it tries to maintain a line of overlap +between the old and new screen, and that overlapping line happens to be +the entire old screen. + +383 forum.2730 +Redisplay does not do the right thing if multiple buffers are on +display in multiple windows, and the values of tab-equivalent differ +among the buffers. + +382 phx20344 +If accept-messages-path was used to accept messages on a mailbox other +than the user's default, the Emacs message handler is not removed from +that mailbox when quitting from Emacs. If a message is then received +in the mailbox a null pointer fault will result. + +381 phx20346 +reverse-regexp-search for "^string" goes to the beginning of the +previous line containing "string" anywhere, rather than a line +beginning with "string". + +380 phx20282 +"esc-X help" refers to >documentation>subsystem>emacs_dir instead of +>documentation>subsystem>emacs. + +377 phx19966 +editor-main-init setq's default-fill-column and default-comment-column, +thus overriding the defaults that are specified in e_option_defaults_. + +375 phx19737 +The sequence: + emacs -ns + ^X-3 esc-? ^E esc-R + results in an Emacs internal error followed by a fault referencing a +lisp temp segment, which recurs if you try to pi back in. + +374 phx19730 +The previous-command variable is not maintained properly. This can +cause problems for commands that change their action when invoked +consecutively (e.g. rubout-word and complete-command). Commands which +throw to top-level rather than returning normally (such as the +minibuffer termination key), and commands which are on +*transparent-commands* leave previous-command unchanged, so the +affected commands think that they have been invoked consecutively when +they have not. + +373 +complete-command (esc-SPACE) will get into a loop returning a sequence +of the same completions if the completion-list contains a duplicated +element. + +372 +Fundamental/.ext-commands contains "alm-mode" twice, which causes error +373 to occur. + +369 +"destroy-buffer-contents" should release the buffer's temp segments. +This is an easily-solved, special case of the general problem described +in entry 368. + +368 +Emacs never reclaims the space in its buffer temp segments that becomes +unreferenced after a line gets copied into a lisp string, until the +buffer is destroyed. Perhaps a GC daemon could be created that would +zero the unreferenced lines in the temp segs (in the hopes that an +entire page might be zeroed). Or perhaps the routines that replace a +filecons with a string or delete lines could keep track of the amount +of wasted space, and trigger a compaction of the temp seg when this +passes a specified threshhold (the GC daemon cannot compact because it +might be invoked after a pseudo-pointer has been extracted from a +filecons). + +367 phx19619 +The internal documentation for the "replace" command says that it will +not prompt for the second string if the first isn't found. This is not +true. + +366 phx19617 +multi-word-search (^XW) should start its search at the end of the +current word if it is in the middle of a word. Otherwise it might +treat the remainder of the word as a whole word. For instance, if +point is between the e and w in "foreword", "^XW word" will stop at the +end of "foreword". + +361 phx19374 +accept-messages-path references an undefined function +console-messages-interrupt-handler (it should be +console-message-interrupt-handler). + +360 phx19218 +Switching windows (i.e. ^XO) before the first redisplay can cause a +buffer named "nil" to be created. It is difficult to kill this buffer. + +359 phx19170 +e_cline_'s any_other handler doesn't ignore stringsize like +default_error_handler_ does. + +358 phx19119 +Recursive command-quit's cause problems. At top-level it will cause a +"throw can't find catch. pgazonga" infinite loop. In a minibuffer it +will cause the minibuffer to be aborted and quits to be ignored. To +reproduce: + esc-esc unwind-protect (command-quit) (command-quit) + +355 forum.2414 +e_mail_pl1_$emacs_read_message returns an error code if it can't send +the cknowledgement. It should ignore this, as read_mail does. + +354 forum.2414 +If RMAIL gets an error reading or formatting a message "nil" is +displayed instead of the line count and message. + +353 phx18981 +The electric-pl1-mode function overrides bindins of : and ; that are +set in the pl1-mode-hook. + +348 phx18717 +^X^E should make sure that the file_output buffer is modifiable. + +345 forum.2233 +The list *transparent-commands* should include control-prefix when +vt1xx_keys_ is loaded. + +339 phx18154 +LDEBUG esc-R (ldebug-reset-break) does not check that the break +s-expression is still in the source buffer before deleting it. If the +user manually deletes that s-expression then it will delete the +following sexp. + +333 +If you specify a pathname as the terminal type (with -query or -ttp) +you must explicitly give the .ctl suffix. + +330 phx17744 +^X_ (underline-region) underlines newlines. + +329 phx17727 +Lisp mode incorrectly indents the third line of this construct: + (a + '(,b + c)) + +This seems to be due to the asymmetry of forward-sexp and backward-sexp +when there are prefix read-macros around. Some fixes are in [aref +1087] in Emacs meeting. + +328 +The short name for -shared_static (undocumented) should probably be +-ss, which is what the run_command_task command uses. + +325 phx17524 +Buffer editor doesn't recognize buffer names (when implementing G +request, for instance) that have a ">" past the 20th character. + +324 phx17333 +If Emacs gets an RQO while writing out a file it doesn't always reset +the terminal properly, because it doesn't run the DCTL-epilogue. In +the case of a VT100, for instance, the scroll region is not reset. +tty_ modes, however, do get reset properly. + +322 phx17317 +When RMAIL re-uses a reply buffer it doesn't make sure that the "Ack" +minor mode is reinitialized to match the acknowledgement flag. + +320 +There are paths through e_tasking_ which will cause a +return_conversion_error. See the "signal program_interrupt" statement; +if it returns then it falls through to an incompatible entrypoint. + +319 phx17174 +Type ^X` test.test CR CR + ^X` noproj CR CR + pretty soon you will get "lisp: car or cdr of a number" loop. + +313 phx16932 +Emacs doesn't recognize sentences if the full stop is followed by ) or +". + +311 phx16888 +The "A new message has arrived" message has a 50% chance of being +overwritten by the "Do you wish to quit?" query. Perhaps making the +message a local display would work better. + +310 phx16888 +If a minibufffer-print is followed by a minibuffer-response then the +question will overwrite the previous output. + +309 phx16877 +Emacs self-doc for delete_char says that it moves the rest of the line +"one to the right", which should be "one to the left." + +308 phx16872 +If the response to the terminal type query is all numbers then Emacs +just says "Do not understand. Try again" instead of going to the "list +of types" query. + +305 phx16606 +Macro edit parser does not understand negative numeric arguments. The +function macedit-digitp should recognize initial hyphens. + +302 +It doesn't work to capitalize (esc-C) an underlined word. + +294 mail.2.11 +edit-dir doesn't understand directories that have no files. + +287 phx16787 +If you ^G out of the "Do you wish to quit rmail?" question after +deleting the last message the message is marked for deletion but stays +on display. + +286 phx16785 +Repeat-last-message (^X~) uses the last recipient if I have sent a +message since receiving one. + +284 mail.4.83 +The Emacs lisp error handler doesn't interact with errset properly. +"esc-esc errset (error 'foo 'bar 'fail-act) nil" should just return +nil, but it prints the error message. + +273 mail.4.46 +esc-^B (backward-sexp) goes into an infinite loop if there is a +semicolon ahead of point on the line. + +270 mail.4.30 +runoff-fill-region only works if the point is at the end of the region, +not at the beginning. + +263 +If you mark a buffer for deletion in buffer-edit, and kill it with ^XK +before exiting buffer-edit then you get serious errors. + +258 phx16454 +It is difficult to kill buffers whose names end in whitespace, as ^XK +and ^XB rtrim the buffer name. + +240 phx15723 +The dg132b CTL doesn't provide enough padding for insert/delete lines. +At higher speeds it may be better to just redraw the screen. + +239 +When Emacs signals quit the resetwrite can cause the initial string or +epilogue string. It should do its own resetwrite when the user hits +BREAK, and then it should signal quit with an info structure that +indicates that no automatic resetwrite should occur. + +233 phx15433 +global-print (^XS) leaves out some lines if the search string contains +a newline. This is because its main loop goes to the beginning of the +next line before each search; it should only do this in the one-line +case. + +228 phx15349 phx09740 phx13412 +The initial redisplay takes a fault if the buffer is looking at a large +segment. + +227 phx15350 +If Emacs takes a fault, it leaves the user in rawi mode. + +226 phx15228 phx20036 +You can't send mail from xmail if you have a tasking Emacs, and thenyou +cannot get back into the Emacs. + +224 phx15059 phx16507 +Scroll-current-window (^Z^V) allows the cursor to be on the bottom line +of the window when the line should wrap. This gets redisplay confused. +Scenario: + Go into two-window mode, with the top window having seven lines. + Read in a file with several (>8) wrapping lines in a row. + esc 6 esc G esc - ^Z^V <= gets into the above state + esc - ^Z^V <= shows how confused it is + ^X O <= further confusion f redisplay + +217 phx14593 +In overwrite-mode, backslash still inserts. So does ^Q, but this is by +design. + +216 phx14519 phx16784 +Commands implemented using word-operator (esc-C, esc-L, and esc-U) do +not work properly if point on the whitespace preceding the first word +of the buffer. + +215 phx14519 phx17565 +Commands implemented using the word-operator macro (esc-C, esc-L, and +esc-U) do not work properly if there is no word in the buffer (or +perhaps if the buffer is empty). A fix is given in the TR. + +213 phx16399 +Tasking Emacs should die more gracefully if you turn the video system +on or off under it. This also applies if you turn on/off the video +system under a suspended normal Emacs. + +211 phx14400 +Real underlining display loses a letter if a capital letter is +underlined twice. + +206 phx13052 phx15086 phx15464 +Sometimes gets error_table_$io_no_permission on reconnection. This is +probably due to getting the same devx. + +205 phx12602 +The window editor sometimes overwrites another buffer with the +window-editor information. This happens if you delete the window in +which the window editor is running. + +202 +In Multics-mode gets rid of the error_output switch. This is due to +the loss of syn_$syn_attach_. + +198 phx13758 +^V and esc-V are confusing when redisplay turned off. They can also +get confused if they are typed ahead. + +194 phx13572 +Emacs guesses that some terminal types are printing-terminals without +checking for a CTL first. + +191 phx13136 phx13722 +Minibuffer output isn't always folded when it runs over the +screenlinelen. + +188 phx13062 phx14762 +Some searching routines do not set gratuitous marks properly, causing +^W to wipe the wrong text. + +185 phx12887 +Dired buffers that are modified should stop ^X^C from exiting w/o query. + +182 phx12653 +^XO doesn't do anything with redisplay off. + +180 phx12556 +check-entry-name in e_multics_file_ should call check_entryname_, not +check_star_name_$path. + +167 phx12166 +A minibuffer message occurring during a local display sometimes aborts +the local display. + +162 phx11972 +indent-rigidly should redo tabification in line. + +158 phx02711 +Speedtype does not accept >4 character abbreviations, and setab command +does not diagnose either. + +157 phx03081 +pop-up windows/message mode problems. + +156 phx11749 +Local displays generated while in minibuffer don't get flushed. + +154 phx11779 +ESC-U/ESC-C/ESC-L should know how to correct _ canonicalization within +word when case-changing. + +153 phx11755 phx11964 +Multiple windows/set-screen-size blows away windows on ambassador +because of deficiency in DCTL code. + +144 phx11398 +LDEBUG breakpoints leave you in buffer where they occur, without LDEBUG +bindings, and prints message into current buffer. + +132 phx10148 +Multics Mode with Process buffer showing in two windows (with differnt +current points) confuses window manager about current window. + +130 phx09878 +Word definition seems a little screwed up in ^Z_ and ESC_ and ESC-T. + +128 phx09256 phx19080 +Single-character procedure names at begin of new pl1 file in electric +PL/I mode cause ":" electric to beep and not do its job. + +117 phx10073 +Emacs should diagnose illegal keystring ^Z-- (two minuses). + +109 phx09931 +esc-/ ^$ CR on blank line doesn't find next blank line. + +104 phx09863 +Misspellings and bad grammar in extensions.info. + +92 phx09539 +In fortran mode, with free-format fortran, positioning to source +lines should use fortran's line numbers, not Emacs'. + +89 phx09343 +Defcom for untabify is binding tab-equivalent to a string. + +87 phx09365 +Lines longer than fill column make CR in message buffer fail. + +86 phx03655 phx10392 +Emacs ^X^M qedx , BREAK, pi, q, pi sometimes fails in lisp_oprs_. +(Gets segfault or mme2 error). Might be lisp bug. + +84 phx09201 +ESC-Q leaves a blank line with fill prefix after a paragraph just filled. + +83 phx09092 phx09256 phx12741 phx15394 +Emacs doesn't handle colons well for label arrays in electric +PL/1 mode (specifically try "action (4):"). Semicolons also not +handled well after declarations. + +There is a fix for the label array bug in Emacs forum [1604]. + +81 phx08766 +Emacs does not observe MAP mode. + +78 phx08592 +Emacs needs to know which conditions should be ignored, and which passed +through, and needs to pass conditions like "endpage" through. + +77 phx08295 phx08925 phx12693 +^C doesn't do right thing after ^XE. + +75 phx06948 +Multiple ESC-^Q cause strange interaction with redisplay; sometimes +paragraph creeps up and off screen, sometimes causes unnecessary +redisplay. + +74 phx08227 +e_pl1_$get_mcs_tty_info appears to not know that diablo1620's does +have tabs (and doesn't direct Emacs to use tabs in printing-tty output). + +69 phx08002 +When in electric-pl1-mode, ";" inside string should cause "Unbalanced +PL/1 quotes" but not newline/special action, just insert ";". + +68 phx07939 +Local keybindings need to be "pushed"; when do electric-pl1-mode, +fill mode, fill off, SEMI/TAB get rebound to self-insert instead +of pl1-mode-special-whatever. + +63 phx07303 +LRU minibuffer-print line-selection algorithm needs to be better. + +61 phx07287 +Emacs should do resetread on quit. + +59 phx06969 +On printing terminal (TI745) "Writing" got overwritten by +pathname -- possible padding bug in TI745 ctl. + +52 phx06832 +Marks not always moved correctly on ^W; see TR. + +47 phx06696 +Setting minibuffer size resets screensize. + +45 phx06634 +When a major-mode change happens, the OLD major mode should be +cleaned up before the new one is instated. In particular, trying to +use an old fortran-mode buffer in most other major modes +will still find CR bound to fortran's return-and-indent. + +44 phx06599 +ESC-W (copy-region) doesn't respect ESC-^W (doesn't append to +last deletion.) + +43 phx06588 +pl1-comment-current-line should obey comment-column, NOT maintain its own +comment column (pl1-comment-column). + +36 phx06301 +Rmail bugs: (1) Should do a go-to-or-create-buffer "Incoming Mail", not +go-to-buffer. (2) rmail.info needs to be installed. (3) The feature +whereby ^XR in an emacs with a non-quitted rmail returns to reading +the mail you were reading MUST BE Documented. + +29 phx05495 phx05675 phx06167 +Speedtype mode and speedtype/fill interaction have several bugs. +Bill York's new speedtype should be installed. + +18 phx03094 phx13763 +On tek4025, Emacs should first ask user to set command character. +Would be nice to have a real cursor, also. + +16 phx05086 phx06698 phx08108 phx11313 phx11397 phx13319 +Emacs gives useless error message on RQO - should try to clean + up pdir automatically if that's where the error is. + +15 phx05073 +accept-messages doesn't work in recursive Emacs'. This is caused by +the console-message package not re-instating old accept_messages state; +this will be fixed when the new message routines roll around. + +13 phx04933 +Bugs in ^XR after reading another mailbox, then trying to read own. +See TR. + +8 phx06674 +^X:'ing to a person when that recipient's message buffer has been +deleted blows out badly. (Two error messages, including one from +go-to-line-point). + +6 phx04679 phx09752 phx14625 +Windows displaying the same buffer sometimes don't keep their own +curpoint; moving in one, then ^XO or ^X4 to the other sometimes +causes the second to redisplay to the point of the first. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.info b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.info new file mode 100644 index 0000000..b3a3b65 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/info_segments/emacs.info @@ -0,0 +1,128 @@ +02/12/85 emacs + +Syntax as a command: emacs {-control_args} {paths} + + +Function: enters the Emacs text editor, which has a large repertoire +of requests for editing and formatting text and programs. + + +Arguments: +paths + are pathnames of segments to be read in. Each is put into its own + appropriately named buffer. Star and archive component pathnames + are accepted. + + +Control arguments: +-apply function_name arg1 arg2...argi, +-ap function_name arg1 arg2...argi + evaluates (function_name 'arg1 'arg2...'argi), where the args are + arguments to the named Lisp function (e.g., an Emacs request). This + is valuable for constructing abbreviations. This control argument + must be the last argument. +-line_length N, -ll N + sets the line length to be different from the terminal's default + line length. +-force, -fc + permits the use of terminal type control arguments (-ttp, -query, + -reset) when in the video system. + + +-line_length N, -ll N + sets the line length to be different from the terminal's default + line length. +-line_speed N, -ls N + indicates line speed to obtain proper padding (for ARPANet users), + where N is the output line baud rate in bits/second. It is ignored + in the video system. +-macros path, -macro path, -mc path + loads the segment, specified by path, as Lisp, so that features + therein are available. +-no_force, -nfc + prevents the use of terminal type control arguments when in the + video system. (Default) +-no_start_up, -no_startup, -ns + prevents use of your startup (start_up.emacs). + + +-page_length N, -pl N + sets the page length to be different from the terminal's default + page length. +-query + queries you for a terminal type without checking the Multics + terminal type first. The query response can be any recognized + editor terminal type. (See "Notes.") + + +-reset + specifies that Emacs disregard the terminal type set by + -terminal_type and set it in accord with the Multics terminal type + instead (see "Notes"). +-terminal_type STR, -ttp STR + specifies your terminal type to Emacs, where STR is any recognized + editor terminal type or the pathname of a control segment to be + loaded. If STR is not a recognized type, Emacs queries you after + entry, providing a list of recognized types. (See "Notes.") + + +Notes: None of the terminal type control arguments (-ttp, -reset, +-query, -line_speed) are generally necessary; they are only used for +solving various communications problems. + +The control arguments -query, -reset, and -terminal_type are +incompatible. You can't use them in the video system unless you +provide -force. + +Emacs is a display-oriented editor designed for use on CRT terminals. +Several modes of operation for special applications (e.g., RMAIL, PL/I, +FORTRAN) are provided; the default mode entered is Fundamental major +mode. + + +For a basic introduction to the Emacs Text Editor and descriptions of +the most generally used editing requests of emacs fundamental mode, see +the Introduction to Emacs Text Editor (CP31). You can find a tutorial +introduction to the Emacs Text Editor, fully describing the editing +requests available and containing instructions for using special +features of emacs, in the Emacs Text Editor User's Guide (CH27). A +guide for programmers writing extensions and terminal control modules +(CTLs) in Lisp is provided in the Emacs Extension Writer's Guide +(CJ52). + +You can get a complete list of available requests in emacs via the +make-wall-chart request while in emacs. Type the following: + emacs + ESC-X make-wall-chart + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/info_segments/list_emacs_ctls.info b/web.mit.edu/multics-history/source/Multics/doc/info_segments/list_emacs_ctls.info new file mode 100644 index 0000000..1de5590 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/info_segments/list_emacs_ctls.info @@ -0,0 +1,45 @@ +09/28/82 list_emacs_ctls + +Syntax: list_emacs_ctls {terminal_type} + + +Function: produces a list of all known Emacs terminal types, or +verifies the existence in your search rules of specified Emacs terminal +controllers. + + +Arguments: +terminal_type + is a terminal type name. It can be a single starname. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/ctl-writing.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/ctl-writing.info new file mode 100644 index 0000000..93c7c1b --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/ctl-writing.info @@ -0,0 +1,373 @@ +06/25/79 - Writing Emacs Terminal Control Modules ("CTL"s) + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command** + + + + + + Support of video (and printing) terminals in Emacs is accomplished +via terminal-dependent modules known as "CTL"s (from the typical name, +e.g., "super58.ctl" for a "super58" terminal). There are about two +dozen supplied CTLs. They are kept in the directory >unb +Emacs will attempt to locate an appropriate CTL in this directory at the +time Emacs is entered; the decision as to which CTL will be made based +upon the terminal type maintained by Multics, and optional Emacs control +arguments. + + To support a type of terminal not supported by a supplied CTL, it is +necessary to write a new CTL. A CTL is written as a Lisp source program, +name TTYTYPE.ctl.lisp, TTYTYPE being the name of the terminal type which +will be supported. If this terminal type is in your site's TTF (Terminal +Type File), the name chosen should appear the same as appears in the TTF, +except that the name of the CTL should be all lower case (Emacs will lower-case +terminal types when looking for CTLs). + + CTLs are usually written by example from supplied CTLs. Personnel +with no knowledge of Lisp at all have achieved this successfully. A +relevant introduction to Lisp may be found in extensions.info in the Emacs +documentation directory. Once the CTL is written, it must be compiled +before it can be used. Compilation is performed via the Lisp compiler, lcp, +which is kept in >unb. A typical command line to compile +a CTL might be + + lcp super58.ctl + +This will produce an object segment, super58ctl, which, when debugged, can be +installed in the system library. To use a CTL being debugged, invoke +emacs with the "-ttp" control argument and the full pathname of the +_c_o_m_p_i_l_e_d CTL: + + emacs -ttp >udd>Support>Jones>emacs_development>super58.ctl + +See emacs.info in the Emacs Documentation directory for the valid +control arguments for managing terminal types. + + ************************************************** + + + The most effective method of writing a new CTL is to take one that +was written for a similar terminal and modify it. Almost all of the extant +CTLs were written in this way. The source for all supplied CTLs is kept +in >>ldd>unb>s>bound_emacs_ctls_.s.archive. The sources are Lisp source +segments, generally one or two printed pages long. Good starting points are + + o vip7200.ctl.lisp, typical of terminals that do not have the ability + to insert or delete lines or characters. + + o vip7800.ctl.lisp, typical of terminals that do have these abilities. + The two facilities are independent, either one, both, or neither + may be present, although use of terminals without insert/delete + lines at less than 300 baud may be found to be unacceptable. + + The interfaces (function definitions) in a CTL are standardized. They +have the same names in all CTLs. The Emacs screen manager will call these +interfaces anonymously after the appropriate CTL has been loaded. The +interface DCTL-init is called at Emacs start up time; it has the responsibility +of setting various flags, and initializing the terminal. It should +contain the statements + + (setq idel-lines-availablep t) if the terminal can insert/delete lines + (setq idel-lines-availablep nil) if it cannot + (setq idel-chars-availablep t) if the terminal can insert/delete characters + (setq idel-chars-availablep nil) if it cannot + (setq screenheight N.) Where N is the number of LINES on the screen + (note the dot after the N). + (setq screenlinelen M.) Where M is _o_n_e _l_e_s_s than_ the number + of characters in a line on this terminal. + Again, note the dot. + (setq tty-type 'TYPENAME) Where TYPENAME is a word like "super58" + that identifies the terminal type. + + At the time DCTL-init is invoked, the variable "ospeed" is set to the +speed of the communications line in _c_h_a_r_a_c_t_e_r_s _p_e_r _s_e_c_o_n_d. +This may be used to perform padding calculations. + + Also before DCTL-init is invoked, the variable "given-tty-type" is set to +the name by which the CTL was loaded with the ".ctl" suffix stripped. This +variable can be used in DCTL-init (and elsewhere) to enable and use different +features of a terminal dependent on the name used to reference that terminal. + + The following functions are available to the CTL writer: + + o Rtyo takes one argument, a number (fixnum), and outputs + that number as ASCII data. For instance, (Rtyo 141) will + output an "a", and (Rtyo 33) will output an ESC. + + o Rprinc takes one argument, a character string, and outputs + it. For instance, (Rprinc "]I") outputs a right bracket and + an I. + +Both of these functions buffer their output until the Emacs screen manager +deems it appropriate to dump this buffer. This will always be done at +the end of any redisplay at all, and after DCTL-init is called. + + The CTL writer must maintain the values of the special (global) variables +X and Y as the zero-originned screen position where the cursor was left. +In return, he or she gets to inspect these variables to do positioning +optimization. + + The CTL writer must provide the following interfaces to be called by +the Emacs screen manager: + + o DCTL-init - (of no arguments) - Must set the flags listed above, + initialize the terminal (if necessary), clear the terminal screen, + and leave the cursor at position (0, 0) (home). + + o DCTL-position-cursor - (of two arguments, a new X position and + a new Y position) - Move the terminal's cursor to the given + position, if not there already. Position 0, 0 is defined as the + upper left hand corner of the screen. This function must check + the variables X and Y, and output no characters if the cursor is + known to already be at the desired position. Otherwise, it must + use the values of X and Y to determine what type of motion is necessary, + output characters to move the cursor, and update X and Y to the input + parameters (the delay of the buffered output is not an issue). + + Typically, DCTL-position-cursor will determine which is the optimal + movement based upon the relative positions of the cursor and the desired + position. For terminals that have many forms of cursor movement, + some combination of backspaces, linefeeds, and carriage returns + may be adequate to effect some forms of cursor movement. Sometimes + the sequences generated by the "arrow buttons" on the terminal + may be used for relative positioning. Just about all terminals + include some form of absolute positioning. The choice of optimal + cursor positioning should be based upon which will output the fewest + characters to effect the desired move. See hp2645.ctl.lisp for an + example of a very well optimized cursor positioner. + + One useful trick in the writing of DCTL-position-cursor is the use of + recursion. See adds980.ctl.lisp for an example. If you choose to use + terminal tabs, then your DCTL-init must set them, and you must take + care not to clear them. No supplied CTLs (other than the extremely + special-case printing terminal controller) use tabs. + + o DCTL-display-char-string (of one argument, a character string to + be displayed). Must output this character string to the terminal + at the current assumed cursor position. The string is guaranteed + to contain no control or other non-printing characters, and each + character in it is guaranteed to take up one and only one print + position. Be careful to update cursor position after printing + the string; the lisp function "stringlength" may be used to ascertain + the length/printing length of the string. + + o DCTL-kill-line - (of no arguments) - Clear the line from the current + assumed cursor position to the end of the line, and, importantly, + _l_e_a_v_e the cursor at that original assumed position. Most + video terminals have a clear-to-end-of-line feature; it should be + used here if available. Some terminals do not, yet this function + must be provided anyway. The machinations for "simulating" clear + to end of line are moderately arcane; see adm3a.ctl.lisp for an + example of clearing to end of line by overwriting with blanks. + Performance of this technique at 300 baud is generally completely + unacceptable, rendering such terminals unfit for use with Emacs + (or any other display editor) at that speed. + + o DCTL-clear-rest-of-screen - (of no arguments) - Clear the screen + from the current assumed cursor position to the end. Leave the cursor + where it was supplied. Some terminals have a "clear whole screen" + function, but not clear to end of screen. For the time being, this + will do, although we may use the added functionality in the future. + If your terminal does not even have a clear-whole-screen function, + it is probably not worth using with Emacs. If you choose to use tabs + in cursor positioning, be wary of clearing them via this function. + + We have just listed all the required functions. Some terminals require +control sequences to change "modes" between normal Multics operation and +operation within Emacs. (For example, a terminal might be switched between +line-at-a-time transmission and character-at-a-time transmission.) Yet other +terminals might use features during the operation of Emacs which should be +disbaled/reset when using Multics. (For example, the VT100 uses "scroll" +regions to simulate insert/delete lines. However, if a scroll region exists, +it will make parts of the screen unusable when using Multics.) It is possible +and quite common to switch between Multics and Emacs by using the ATTN key and +the "pi" command. In this case, the terminal will be in the wrong mode at +various times. If the terminal for which you are writing a CTL exhibits this +behavior, you should add the following statements to DCTL-init: + + (setq DCTL-prologue-availablep t) to specify that certain functions must be + performed each time Emacs "mode" is entered + from Multics "mode". + (setq DCTL-epilogue-availablep t) to specify that certain functions must be + performed each time Multics "mode" is + entered from Emacs "mode". + +In addition, you must then supply the following two functions: + + o DCTL-prologue - (of no arguments) - Perform any operations which are + required when Emacs "mode" is entered from Multics "mode". This + function will be invoked immediately after DCTL-init is called and + after Emacs is reentered after a QUIT via either the "pi" or "start" + commands. + + o DCTL-epilogue - (of no arguments) - Perform any operations which are + required when Multics "mode" is to be entered from Emacs "mode". This + function will be invoked immediately before Emacs is exited when the + ^X^C (quit-the-editor) command is invoked and immediately before Emacs + is suspended when the ^Z^Z (quit) command is invoked or the ATTN key is + hit on the terminal. + + If you have stated that insert/delete lines is available, via setting the +flag idel-lines-availablep to t, you must supply the following two functions. +If you set this flag to nil, you need not write these functions: + + o DCTL-insert-lines - (of one argument, a number of lines to be + inserted) - Open up the given number of lines on the screen. + There will be guaranteed to be that many blank lines (created by + DCTL-delete-lines) at the bottom of the screen at the time this + function is invoked. The cursor will be at position 0 of some + line at the time DCTL-insert-lines is invoked. It must push + the contents of that line "down" the supplied number of lines, + leaving the cursor in the same place, the line the cursor is on + and the n-1 succeeding lines blank. + + o DCTL-delete-lines - (of one argument, a number of lines to be + deleted) - Delete from the screen the supplied number of lines, + starting with the line the cursor is on on down. The cursor is to + be left in the same place it was given. That many blank lines + will be assumed to be pulled up on the bottom of the screen. + + If the flag idel-chars-availablep is set t, indicating that insertion +and deletion of characters is available, the following two functions must +be supplied: + + o DCTL-insert-char-string - (of one argument, a character string + to be inserted at the current assumed cursor position). The + character string supplied is to be inserted at the current + cursor position. All characters at, and to the right of the + current cursor position are to be pushed over to the right. There + will be guaranteed to be only blanks on the screen in the region + which will be "pushed off". The cursor is to be left (and updated + as being at) the end (after the last character) of the string inserted. + + o DCTL-delete-chars - (of one argument, the number of characters + to be deleted). The supplied number of characters, starting with the + character at the cursor and on to the right, are to be physically + deleted from the screen. All characters to the right of these + characters are to be moved that many positions to the left. That many + blanks will be assumed to be moved in from the right edge. The cursor + is to be left where it was supplied. + + Writing a CTL usually involves editing an existant one, trying it, +modifying it, and iterating until it is solid. One will use the "-ttp" +control argument many times to switch back and forth between "printing +terminal mode" and the new CTL when logged in from the terminal on which the +CTL is being developed. For terminals with insert/delete features, +it may be convenient to debug the CTL first without these features (claim +they are not there in the DCTL-init), and add them later. Similarly, +one is encouraged to write "more optimal" DCTL-position-cursor's once +one has one that works at all, for the convenience of editing the CTL with +Emacs substantially reduces the effort of improving it. + + For some terminals, padding may be necessary for some operations at some +or all line speeds. If terminal behavior appears random, or garbage is left +on the screen after a ^L or ^K, this may be the problem. Check the manual +for your terminal about padding requirements. It may be convenient to define +a function called DCTL-pad, which takes a number of microseconds or +milliseconds as an argument, and issues enough pad characters ((Rtyo 0) +or (Rtyo 177) are common, check your terminal manual for what your terminal +expects) to perform this padding. The variable "ospeed" gives the line +speed in characters per second, for use in such calculations. Getting +the padding right may involve quite a bit of tinkering on some terminals; +one proven method in cases where padding is felt to be a problem is to specify +a very large amount of padding (e.g., a second) and cut it down until it works. +See dd4000.ctl.lisp for an example of terminal padding. + + ************************************************** + + The Lisp special forms _c_o_n_d and _d_o are used heavily in CTLs and +not documented in extensions.info. Emacs environment macros (do-forever, +if, etc) should not be used in CTLs, thus the native Lisp forms are necessary. +Here are the descriptions of cond and do: + + (cond ((= this that) (thing1)(thing2)) + ((> a b)(second)(third) 27) + ((< c 15)(other)) + (t (last 5)(chance))) + +means: + + "If this equals that, call thing1 of no arguments, then call thing2 of + no arguments, and return as the value of the cond the value returned + by thing2. OTHERWISE, if a is greater than b, call "second" with + no arguments, then call "third", and return 27 as a value. YET + OTHERWISE, if c is less than 15 (all numbers octal), return the value + obtained by applying "other" to no arguments. If none of the above + are true, call "last" with an argument of 5, and then return the value + obtained by calling "chance" with no arguments." + +"cond" is very much like PL/I's + + if ( .... ) then do; + ..... + end; + else if ( .... ) then do; + ..... + end; + else if ( .... ) then do; + ..... + end; + else do; + ..... + end; + +The format of Lisp "do" used in CTL's to iterate is of this form: + + (do VARIABLE INITIAL-VALUE REPEAT-VALUE TEST form1 form2 form3.. ) + +It is identically equivalent to PL/I's + + do VARIABLE = INITIAL-VALUE + repeat REPEAT-VALUE + while (^ TEST); + + form1;form2; ... + end; + +which, itself, is equivalent to + + VARIABLE = INITIAL-VALUE; +l: if TEST then go to e; + form1;form2;... + VARIABLE = REPEAT-VALUE; + go to l; +e: ; + +The variable VARIABLE is locally defined inside the "do". It may be used +in the forms inside the "do", in the "end test" TEST, and in the repeat +value REPEAT-VALUE. + +(END) + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs-tutorial.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs-tutorial.info new file mode 100644 index 0000000..97dad2c --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs-tutorial.info @@ -0,0 +1,2001 @@ + An Introduction to Using Multics Emacs 10/27/79 + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + +Multics Emacs is an integrated editing, text-preparation, and screen +management system designed to take advantage of the features of modern display +terminals to aid in interactive text entry and editing. In some sense, it is +an editor: yet a more appropriate description would be a "text processing +subsystem": continuous interaction with text is its mode of operation, not +"editing" via carefully structured "editing requests". + + Although it is possible, and valuable, to use Multics Emacs from a +"printing terminal", i.e., one that uses paper and ink, it is oriented +towards video terminals, and its usage is best learned on a video terminal, +preferably at 1200 baud or better. + + Sit down at a video terminal logged into Multics. Invoke Emacs +by typing its name at the command processor: + + emacs + +Depending upon the facilities available at your site, Emacs may or may not +ask you: + + What type terminal do you have? + + +If Emacs poses this question, which it will only ask you once per login +session, as opposed to clearing the screen, type in the name of the type of +terminal that you have. If you do not know this, ask your Site Support +personnel. If you type a bad name, Emacs will type out the names of all +terminals it knows how to support, so that you can type the right name. Or +type "quit" to give up. Terminate the name of the terminal with a +carriage-return, as you would any Multics input. + + Now Emacs will take several seconds to get started up; it has a lot to +do at start-up time. When it has started up, it will clear the screen, and +display the line + + Emacs (Fundamental) - main + +at the lower left of the screen. This line is called the _m_o_d_e _l_i_n_e. +It tells you several things, most important of which is that you are talking to +Emacs, as opposed to the command processor, or some other editor. +"Fundamental" is called the _m_o_d_e. There are various _m_o_d_e_s +best suited to preparing text, programs in different languages, and other +tasks. Fundamental mode is the first and simplest mode. It has no +specialized features at all. "main" is the _b_u_f_f_e_r _n_a_m_e. You can be editing +many things at once with Emacs, like qedx. Each separate thing being edited +is edited in a separate "sub-editor" called a _b_u_f_f_e_r. The buffers have names; +"main" is the name of the buffer you start out in. + + The region between the top of the screen and the mode line is where text +appears, and where we deal with text. This area of the screen is called the +_w_i_n_d_o_w. It will always display 20 or so consecutive lines of the document or +program you are editing. The region below the mode line has two areas, +the _p_a_t_h _l_i_n_e and the _m_i_n_i_b_u_f_f_e_r, which we will deal with +later. + + You will note the blinking _c_u_r_s_o_r in the upper-left-hand corner +of the screen. The cursor may be a blinking underline on some terminals, or +a blinking or solid box on others. The cursor is always on some position on +the screen. The cursor is the single most important object in Emacs: +we must familiarize ourselves with it, and must always concern ourselves with +its whereabouts on the screen. All "action" happens at the cursor: all text +we enter is entered "at" the cursor (and the cursor moves), and text we delete +is deleted at the cursor, as well. + + Now we are going to enter some text. We do not have to tell Emacs that +we are going to type. There is no "input mode" or "edit mode": we just type. +Type these words on the terminal, do _n_o_t end it with a carriage return, line +feed or other special character, the period should be the last character you +type: + + This is sample text. + +You will note that you do not see what you have typed immediately, but +soon after you start typing, the text on the screen will "catch up" with you. +This is because you have waited a few minutes since the last time you typed, +and Multics has "forgotten" about you temporarily. In general, you may see +what you type as soon as you type it, or sometimes a little later, depending +on the load on Multics. This is very different than other Multics programs; +other programs rely on the terminal to type out what you type in, but Emacs +must type it out for you. + + You will also note a little star come on under the word "Emacs": this +is called the "modified" star. When it is there, it means that the +text in your buffer is different than the text you read in, if any, or +is new text (as is the case here), and hasn't been written out to a file. +When the "modified" star is on, you know that you wil have to write your text +out before exiting Emacs. + + You will see the text you typed at the top of the screen. It just +appeared there as you typed it. You did not have to issue a "print request": +The line you are looking at at the top of the screen is the beginning of your +document: you are looking at your document, not an "input line", or an +"output line" or a "printout". At all times, you are looking at your +document. + + Look at the screen. You will see the cursor to the right of the period +in the sentence "This is sample text". You should begin to think "We are +to the right of the period on that line." At all times, the person using +Emacs must think of himself or herself "at" some point in his or her document, +that "point" being indicated on the screen by the cursor. + + Now let us add another line. Type the "carriage return" key on your +terminal to end this line and start another one. "Carriage return" is a +character, just like "T", "h", "i", or "s", or a space. Typing it will +put a "carriage return" character into your text, and move the cursor to +_b_e_y_o_n_d the carriage-return character, which is to say, the beginning of the +next line. Having entered the carriage return, type: + + Here is more text yet. + +Again, the text appears on the screen as we type it. The line we had typed +earlier stays where it is, we now have a two-line document. Using what we +know already, we can type in a whole document! It is just like using a +typewriter. + + This is fine, until we make an error. We have to fix errors as we note +them. Let us type a line with an error in it on purpose. Go to the next +line, by typing a carriage return, and type: + +Multix + + +We have made an error. The "x" in "Multics" should have been a "cs". What +do we normally do in Multics if we type a wrong letter? We use #, the _e_r_a_s_e +_c_h_a_r_a_c_t_e_r. The same is true in Emacs, but watch what happens. Type the "#" +(pound sign, or number sign) character. Observe that the "x" in "Multix" +physically disappears off the screen, leaving no trace of itself or the pound +sign! The character has been erased; our document is on the screen. The "x" +is no longer in our document. What is more, there is no trace or record of +the mistake we made, or what we did to correct it. The document is correct +on the screen, as always. Now, to put in the c and the s, just type the c +and type the s, and the word "Multics" will appear correct. + + We can continue in this fashion, entering text just by typing it, ending +lines with carriage returns when we want to go on to the next line, until our +whole document is entered, correcting mistakes with #, but soon we may find +a need to change, or modify, some text we had already entered. For example, +let us change the line we entered that said: + + This is sample text. + +to say: + + This is some sample text. + +adding the word "some" after the word "is". The way we do this in Emacs is to +"go" to the place in the text after the word "is", to _m_o_v_e or _p_o_s_i_t_i_o_n +ourselves there, by moving the cursor there. We want to go up two lines and +over a few characters. First, let us "get to" the right line. We will go there +one line at a time. We will tell Emacs "Go to the previous line". + + Look on your keyboard for a key labelled "CTL", "CTRL", "CONTROL", +"CNTRL", or the like. This is a very important key for Emacs; it is called the +_c_o_n_t_r_o_l key. It is like a shift key: you hold it down, and while holding it +down, you type one or more normal characters. Like a shift key, pressing it +and releasing it has no effect. When you press the "p" key (DON'T do it now), +you get a lower-case "P". If you press the "p" key while holding the "SHIFT" +key, you get an upper-case "P". If you press the "p" key while holding the +"CONTROL" key, you get something called a "Control P". It is a different +_v_a_r_i_e_t_y of P, just like p and P, except instead of being an upper case +letter or a lower case letter, it is a called a "control character". All +control characters are commands to Emacs. You have seen what happens +when you type normal upper and lower case characters; they go into the +document. Control characters are used to control Emacs, to manipulate the +cursor and manipulate text. + + To make Emacs move the cursor to the P_revious line, we use the control +character "Control P", the P_ being for P__r_e_v_i_o_u_s. Do so: hold down the +"CONTROL" key, like a shift key, and press the "P" key, while still holding +the "CONTROL" key, then release both. Now watch the screen: you will observe +that the cursor will indeed move up to the previous line, to a place right +above where it had been. This happens as soon as we type the Control P, +we do not have to type (and must not type!) a carriage-return or other +character to make it happen. Note also that when we type Control P, +we do not "see" our command anyplace on the screen, all we see is what it did. +This is a very important principle in Emacs: what you see on the screen is +what you have in your document, and it does not matter what you used to +achieve that state. + + Now let us go up one more line, to the first line. Hold down the control +key again, and press "P" while holding it. Again, the cursor will jump up +a line. + + Now that we are on the correct line for the change we wish to make, we can +move around on that line to get to the correct place. We can move +_b_a_c_k_w_a_r_d_s on that line by telling Emacs to "go backwards": as you guessed, +this is done with a "Control B", B_ for B_ackwards. Hold down the control key. +Now, slowly, press the "B" key, while still holding the control key, eight or +nine times. You will see the cursor move backwards, that is, to the left, +one position for each time you press the "B" key. Soon you will reach the +beginning of the line, at which time, you cannot go any further back, because +that is the beginning of your text. Emacs will cause your terminal to beep +at you, to indicate that you have made an error. Wait for all the beeping to +finish, and release the control key. + + We now want to move forward to the place after the word "is", in order +to insert the word "some". Hold down the control key, and type the letter +"F" several times. "Control F" is the Emacs command for "forward", i.e., +move the cursor forward one character. While still holding down the control +key, type F's until the cursor is under (or covering, on some terminals), the +letter "s" of the word "sample". If you type the Control F too many times, +simply type Control B's until you get to the right place. What you are +doing now is the most important form of interaction with Emacs- issue commands +until you are "at the right place", or "the right thing has happened", doing +one command at a time and observing its effect, and repeating that process +until you have achieved what you want. This is _i_n_t_e_r_a_c_t_i_v_e editing, as +opposed to counting the number of lines or characters, etc., and issuing +commands to move 15 lines and 4 characters, etc. (although you can do this +too in Emacs if you really need to). Visual feedback is the most important +single feature of Emacs. + + Now we are at the "s" of sample, and we wish to put the word "some" +right there (i.e., at the cursor). That is trivial: simply type the four +letters s, o, m, and e. You will watch Emacs move the rest of the line over +and you now have on that line: + + This is somesample text. + +with the cursor still under the "s" of "sample". Immediately, we perceive a +problem: there is no space between "some" and "sample". We did not enter a +space, this is exactly what we told Emacs to do. Let us enter a space: +simply hit the space bar. Now we have: + + This is some sample text. + +with the cursor still under the "s" of "sample". We have now fixed the +text we wished to. Note that in order to type in the new word, "some", we did +not have to say anything special, we just moved the cursor to the right +place, and started typing. Whenever we type a non-control character (other +than #, @, and \), it goes into the text at the cursor, and moves the cursor +over one to the right. If you think for a little while, you will notice that +that is what it did when we were simply typing in the lines on the screen! + + Now we must get back to the end of the document, where we had left off +when we decided to add the word "some" to the first line. We can do this by +going to the N_ext line, and the N_ext line, until we are where we want to be. +As you doubtless surmise, we do this with the "Control N" command, N_ for +N_ext. Hold down the control key (as you have seen, if you do _n_o_t, the +characters you type will go into your text!), and press "N" twice. Each time, +the cursor will move one line down. We are now on the right line. You will +find that you are at the end of that line; Emacs tries to keep you in the same +"column" when going between lines, but the line with "Multics" on it is much +shorter than the line you started from (the first line, which now says, +"This is some sample text."), so you are as far as you can be on this line. + + Now let us finish the sentence "Multics is a computer system." We see +that the cursor is right after the "s" in Multics": if we just type "is", we +will get + + Multicsis + +which is surely not what we want. So type a space, and the cursor moves to +the right as a space goes into your text. Now continue entering the words + + is a computer system. + +and sure enough, your entire text appears correct before you: + + This is some sample text. + Here is more text yet. + Multics is a computer system. + + You may want to continue experimenting with the things you have just +learned: when you are done, you will have to leave the editor: this is done +as follows: type a "Control X" followed by a "Control C" (C_ for C_ommand +level). This is not an easy command to type or remember, but that is +reasonable, because you may be editing for hours, and you will only type it +once. One way to type it is to hold down the control key, and type an "X" and +a "C" while holding it. Emacs will respond, + + Modified buffers exist. Quit? + +because you have done work that you have not written out (we will learn +about writing out work later). Answer "yes" (type the letters y, e, and s, +and a carriage return). Emacs will clear the screen, and leave you at +Multics Command level. + + We have now learned the six most important Emacs commands: + + # Erase the last character + Control F Go F_orward one character. + Control B Go B_ackward one character. + Control N Go to the N_ext line. + Control P Go to the P_revious line. + Control X Control C + Quit the editor. + + + Practice using them until you are thoroughly familiar with them. They +are the most important and useful commands. With these commands, and one or +two others, you can do just about anything you will ever be called upon to +do. All the other commands just make it easier to do more complex things, +but you can always move around and type in text with these commands. + + + Deleting and Killing. + + Next we will learn how to delete text. We already know something about +this subject; we know how to use "#" to delete characters that we type in +as we type them in. Here we will learn to remove other portions of the text. +Enter Emacs as before. Type in the following text, as we did before. So that +you can follow the lesson properly, be careful to break the lines +(type carriage return) exactly as you see here: + + Once upon a time there were four bears. They lived in a house on the + edge of the forest. There was a father bear, a mother bear, and a + baby bear. One day the bears went out in the woods. + +The last thing you should have typed should have been "woods.", and the +cursor is to the right of the period in "woods.". Let us now fix the +obvious designated excess of bears: we want to change the word "four" to +"three" in the first line. As all else in Emacs, the way we do this is to +"go" to the place in question, with the cursor, and then perform local +surgery on the text at the cursor. Let us use what we have learned before, +and use the "previous line" command (invoked by striking "Control P") +twice, to get up to the first line. We now find we are in the middle of +the word "They", and we wish to go backward on this line until we are at the +word "four". So we use the "backward characters" command, invoked by +striking "Control B", for "backwards". We probably have to strike it about a +dozen times, so we should hold down the "control key" (like a shift key) with +one finger and hit "B" about a dozen or so times until the cursor is right +at the letter "f" of the word "four". If we go too far, go "forward by +characters" with "Control F" until we are at the "f" of "four". + + This may have seemed long and difficult to get to that word; there are +easier ways, and we will learn them in time, but for now, we will continue to +present the fundamental concepts and commands in the order which will allow +you to do the most as soon as possible. + + We now wish to change the word at the cursor to the word "three". In +Emacs, we do not "change" or substitute. We get rid of what we don't want, +and type in what we do want. So what we will do is _d_e_l_e_t_e the word +"four", and type in the word "three" (which we already know how to do!). +The way we will delete the word "four", for now, is by destroying it one +character at a time. We will use the "delete character" command, which +is invoked by hitting "control D", "D" for D_elete. Do this once, by +holding down "control" and pressing "D" _o_n_c_e while "control" is down. +Watch the screen. You will see that the first line is now changed: + + Once upon a time there were our bears. They lived in a house on the + +The "f" has disappeared! It has been _r_e_m_o_v_e_d from the line; the cursor +is now under the "o". Note that if we type a (D_O_N_'T_ do it) "t" now, +it will say + + Once upon a time there were tour bears. They lived in a house on the + +So let us get rid of the rest of the word "four" by hitting "Control D" +three more times, slowly, watching the screen. We now have, when this is +done: + + Once upon a time there were bears. They lived in a house on the + +The cursor is under the _s_e_c_o_n_d of the two spaces now between the words +"were" and "bears". The rest is easy; we type the letters t, h, r, e, and e, +and the word "three" appears letter by letter, between "were" and "bears", +pushing over the rest of the line as we type it. So we have now learned the +"delete character" command, which is used by typing "Control D", which +physically removes the character at the cursor from the screen and our text. + + Often we need to delete a lot more than a few characters; we want to +remove large pieces of lines, or many lines. We will now learn the +"kill lines" command, which is invoked by striking "Control K", K_ for K_ill +Lines. We wish to change the last sentence, + + One day the bears went out in the woods. + +to + + The bears often ate porridge. + +Again, the way we do this is to position the cursor to the point we want to +change, and then operate upon the text. We want to get to the letter "O" in +the word "One" on the last line. Use the Backward Character, Forward +Character, Next Line, and Previous Line commands (Control B, Control F, +Control N, Control P) any way you know how until the cursor is under the +"O" of the word "One". Now type a Control K, and watch the screen. All the +text between the cursor and the end of the line wil vanish from the screen +and from the text. Although we could just type in the new sentence right here +and now, there is a very important feature to be learned at this point. +Type a Control Y. This invokes the "Yank" command: watch the screen. The text +we had just killed is brought back. The "Yank" command brings back anything +we just killed, if we decide that killing it was a mistake. In this way, +we can fix damage that we do by accident by mistaken or inadvertent killing of +text. Almost every command in Emacs that deletes text puts the text it deletes +into a special safe place called the _k_i_l_l _r_i_n_g, where the Yank command +can find it. What is more, killed text _s_t_a_y_s in the kill ring +so that you can yank it back many commands later, or even somewhere else in +your text after you accidentally or purposefully killed it; this way, you need +not notice your mistake as soon as you make it. + + The "Delete Character" command does not put the characters it kills +in the kill ring; if you accidentally delete a character, it is easy enough +to retype it; if you delete many characters by hand, it is probably not a +mistake. + + The Yank command has left the cursor after the sentence it has +retrieved; let us re-position the cursor, with the cursor-moving commands we +know, back to the "O" in "One", and use "Control K" again to remove the +sentence. Now type in the new sentence, + + The bears often ate porridge. + +and the correction is made. + + "Kill Lines" (Control K) is a very versatile command, that does different +things depending upon whether it is used in the end of a line or not. +Let us enter some new text. Type "Control N" (Next Line) about four times +to get to a fresh place on the screen. Note that the cursor is at the +left margin; these lines are empty. Type the following well-known verse: + + I wandered lonely as a cloud + That floats on high over vales and hills. + And all at once, I saw a crowd + A host of lovely daffodils. + Beside the lake, beneath the trees, + Fluttering and dancing in the breeze. + +Position the cursor to under the "I" which starts the verse, using +all the cursor positioning commands that you know about. Now delete +all the text on that line, that is "Kill to the end of the line", by typing +a Control K. Observe the screen: the line becomes blank. Now type +Control K again, and watch the screen. All the rest of the poem moves up. +We now state what Control K does, and this explains why: + + When not at the end of a line (i.e., at the beginning, or in the + middle, Control K deletes all text between the cursor and the + end of the line, leaving the cursor at what is now the end of the + line. + + When at the end of a line, Control K "removes the carriage-return", + or "sticks the next line on to the end of this one", making one + line. If the line that the cursor is on has nothing in it + (except the carriage return), this means make this line go away. + +Now type Control K again. The line + + That floats on high over vales and hills + +will empty out. Type it once more, and that (now empty) line will disappear, +and the cursor will be at the beginning of the next line of the poem. You can +now see that typing Control K many times will delete lines one by one, off the +screen, as you type it. + + Now we will show some magic. Invoke the "Yank" command again, by +striking a Control Y, and watch the screen. Both lines we deleted came back, +intact! There has been something going on behind the scenes on the kill ring +as we have been typing Control K's: If we type an unbroken succession of +Control K's, the "killed text" is _m_e_r_g_e_d on the kill ring, so that one yank +gets it all back. Because of this feature, we do not have to painstakingly +reconstruct text that we killed line-by-line as we have done. If we did not +want to bring all of it back, it is no problem to go back and kill some of the +text that we yanked back and didn't want, but this is a lot easier than having +to retype text that we killed and couldn't yank back. Almost all Emacs +commands that delete text participate in this _k_i_l_l _m_e_r_g_i_n_g with themselves and +each other to help you recover accidentally deleted text easily, no matter how +you deleted it. + + + We have now learned three new commands, for deleting text: + + Control D Delete Character at cursor. + Control K Kill to end of line, if not already at end of line. + If at end of line, merge line with next line. + Control Y Yank back text that we accidentally killed. + + All these commands, of course, delete what is at the cursor, or bring +back text at the position of the cursor. + + Type some text, and experiment with these commands until you feel +comfortable using them, and then exit the editor as we did earlier. + + Reading and writing files. + + One of the most important things to know how to do is to read in Multics +Files, and write them out. There are three commands for doing this, and we +will now learn about them. When we read in a file, it is read into a +_b_u_f_f_e_r. Each file will be read into its own buffer. When we read a file in, +the first twenty or so lines will appear on the screen, just as though +you had typed them in. You only see as many lines at one time as fit on +the screen, however, the whole file is there, and if you try to position +the cursor to some line that is not on the screen, either by doing +Control N's so that the cursor tries to go off the bottom, or Control P's +so that the cursor tries to go off the top, or any other way, Emacs will +choose such lines to display on the screen such that the line you want the +cursor to be on is indeed shown. + + Let us read in a file. For this we use the "Find File" command. Enter +Emacs in the usual fashion. Because we do not read in files that often while +editing, the Find File command requires two keystrokes. It is invoked by the +two-key sequence "Control X Control F" (the F is for F_ind F_ile). Type this +by holding down the control key, and typing an X and an F while it is down. + + You will see the cursor go to the bottom of the screen, below the +mode line, and Emacs will say + + Find File: + +with the cursor at the end of the word "File: ". This is called a _p_r_o_m_p_t: +Emacs is waiting for you to type an "answer" to its question, in this case, +the pathname of the file to be read in. You are now in the _m_i_n_i_b_u_f_f_e_r, a +little one-line window below the mode line, used for answering prompts. +We were prompted in the minibuffer previously when we tried to exit Emacs with +modified buffers. Type the pathname of a file: a good pathname is + + >doc>subsystem>emacs>emacs.info + +which is the command writeup for Emacs. Type this pathname: you need not put +any spaces before or after it. If you make a mistake while typing, you can use +#, Control B, Control D, Control F, or any other command to edit the +pathname itself while you are typing it! End the pathname with a +carriage-return. Assuming you have typed the pathname correctly, +Emacs will now print the word "Reading.." in the minibuffer, letting you know +that it is reading in this file, and strike it out when it has finished +reading it. A little later, you will see the screen start to fill up with the +first windowful of the file. The cursor will be at the first character of the +first line. Now look at the mode line. You will see that the buffer +name is no longer "main", but "editor". The buffer name is taken from +the first component of the entry name of the file read in (in this case, +the file was "editor.info", so it is "editor"). Below the mode line is +something new, the full pathname of the file in this buffer. This is called +the _p_a_t_h _l_i_n_e, and tells us exactly what file we are editing. Of course, we +are not really editing that file, but a copy of it, and the changes we may +make will not be reflected to that file unless we try to write out the +buffer to the file. + + Now type a Control X, and an Equal Sign (=). Be sure to release the +control key before striking the equals sign. Be careful to remember to hold +the shift key if equal-sign requires a shift on your terminal. Emacs will +print in the minibuffer, + + 513 lines, current = 1 + +or something similar. Control X = is the Line Counter command. It tells you +how many lines there are in your document, and what line number the cursor +is currently on. Control X = is a handy command to know. + + Now type Next Line commands (Control N) slowly until the cursor is +on the line right above the minibuffer. Be very careful, just this time, +to do this slowly enough, so that the cursor stays in the main window. +Now note carefully the contents of the line it is on. I cannot tell you +what line that is, because I don't know how many lines your terminal has +on its screen, and that governs what line your cursor will be on now. +Now strike control N once more. You will see Emacs rewrite many lines +on your screen, and, if your terminal has the capability to do so, move +many lines around. When it is finished, the cursor will be at the +beginning of a line in the middle of the screen. Look at the line +above that. You will note that it is the same line that was at the bottom +of the screen a second ago. Control N indeed went to the next line of the +text after the line the cursor was on, as it is supposed to. Now do another +Control X =. Emacs will say something like + + 513 lines, current = 22 + +If you look at the screen, you will see that the cursor is on the twelfth +or so line of the screen, not the 22nd! However, you are editing the +file (or the buffer) and not the screen! The line you are on is indeed the +twenty-second line of the file. If you were near the end, you might be on +the 500th line or so, even though there are only 21 lines or so in the main +window. Since you can only display about 21 lines at once, Emacs chooses +_w_h_i_c_h 21 lines automatically to make sure the line that you want the +cursor to be on is on the screen. + + You can now edit this file as though you had typed it in, using all the +commands that you know. You can move the cursor about, delete characters, +kill lines, or enter new text at will. Try putting in a new word or +killing a line. At once, the word + + Modified + +will appear in the minibuffer, letting you know that you have changed the +file since you read or wrote it, and will have to write it +out if you want your work to be saved. It is not easy to do five hundred +Control N's to get through the file; we will learn more ways later of +moving around buffers faster. + + Having made some editing changes to the file, we want to write it out. +The command that writes back a file that you read it is called "Save same +file": it is invoked by the two-character sequence Control X Control S +(S for S_ave). Try it. You will get the error message + + Incorrect access on entry. + +You cannot write out this file, because it is my file, and I did not give you +the access required to write on my file. So let us write it out to a copy in +our own directory: For this, we use the Write File command, which is invoked +by the two-character sequence Control X Control W (W for W_rite File). Enter +this sequence. Emacs will prompt in the minibuffer: + + Write File: + +Now type the pathname of a place you want to write it to: + + myinfo.info + +End with a carriage return. You will see the path line change to indicate +the new pathname. As Emacs is writing it, you will see the word "Writing.." +appear in the minibuffer. When the word "Written." replaces the word +"Writing..", you know that the file has been successfully written out to +the Multics Storage System. + + Now you can edit some more, and move around within the buffer, and +when you wish to write the file out again, to the same place it was last +written to, Save Same File (Control X Control S) will do the trick. Again, +the Writing../Written in the minibuffer lets you know when Emacs is done +writing. + + We have now learned four new commands: + + Control X Control F Find file, read in a file. Asks for pathname + in the minibuffer. + + Control X Control S Save Same File, writing out the buffer to the + last place it was read from or written to. + + Control X Control W Write File: Write a file to a new place. + Asks for pathname in the minibuffer. + + Control X = Line Counter: tell how many lines in the buffer, + and what line we are on. + + + Searching + + + A fundamental ability that is needed in editing is that of looking +for a particular sequence of characters, or _s_e_a_r_c_h_i_n_g. In the context of +E__m_a_c_s, this means finding a given sequence of characters in the buffer, +and moving the cursor to that point. There are two simple commands +for searching in Emacs: we will learn them next. + + Enter Emacs as usual. Enter the following text: + + Now is the time and the only time for those who have + their time to give their time. + + Using Control P (Previous Line) and Control B (Backward Character) +move the cursor to the upper left hand corner (under the "N" of "Now") +of the screen. We will now search for the word "time". We use the +String Search command, which is gotten by typing a Control S. Do it. +Emacs responds in the minibuffer: + + String Search: + +We now enter the four letters t, i, m, and e. End the string with a carriage +return. You will see the cursor return +to the main window, but now it will be immediately after the first occurence +of the word "time". Let us replace the word "time" here by "day". We will +learn a little trick. By all rights, we should go backwards (Control B) +four times, and then delete characters (Control D) four times to delete +the word "time". That would work; however, there is an easier way. Type +a pound sign (#). Note that the "e" of "time" goes away. If we type +the "#" another three times, the t, i, and m will go away too! This is what +pound sign always does: it deletes the character to the left of the cursor, +whether you just typed it in or not. Think about it. When you type in a +character, the cursor moves to the right of it, and it is now to the left of +the cursor. Typing pound sign makes it go away because pound sign deletes +the character to the left of the cursor. This is distinct from Control D, +which deletes the character _a_t the cursor. + + Finish deleting the first occurence of the word "time", and type in +"day". Now let us look for "grime". Type a Control S, and in response to the +prompt "String Search: ", type the letters g, r, i, m, and e, and a +carriage return. Emacs will respond + + Search fails. + +in the minibuffer, because it could not find the string "grime", and +the cursor remains in the place where it was when the Control S was +typed. Now let us again look for "time". Type a Control S, the letters +t, i, m, and e, and carriage-return. The cursor advances to the next "time" +in the buffer. Do it again, and the same thing happens. Note carefully +that Control S only searches forward in the buffer, from where the cursor +is at the time it is used to the end of the buffer. It will not look +backwards. That is why it puts you _a_f_t_e_r the string it finds, so that +it will not find the same one all the time. Note how easily we can find +the same string many times in a line. + + Now go back to the beginning of the buffer, with Control P's and +Control B's. We are going to look for the string "time" again, but this +time, a little bit differently. Type a Control S. Emacs again prompts, + + String Search: + +Type a carriage return.. You will see Emacs put the word "time" right in the +minibuffer, as though you had typed it, and find the first "time". When you +answer a search command's prompt with an "empty search string", that is to +say, typing carriage return, Emacs will re-use the last "search string" +(sequence of characters) you were searching for. This applies to all the +various search commands. Using this, we can search many times for the same +thing, without having to retype it into the minibuffer. Search two or three +times for "time" again (please do this, so that this lesson will continue to +work). + + Now we will learn a very important Emacs command, "Get out of what you +are doing", which is gotten by issuing a Control G. Try it. Your terminal +will beep at you. Control G always causes your terminal to beep at you. +Now type a Control S again. Emacs will prompt in the minibuffer, as always, + + String Search: + +Suppose we decide that we didn't want to search for anything, and that typing +the Control S was a mistake. Now type a Control G: the cursor will exit +the minibuffer, and the terminal will beep. The search command has been +aborted. Control G can always be used to exit the minibuffer to abort +any command that you change your mind about in midstream, such as +Find File, or Write File, etc. It can also be used after typing a +large number of cursor movement commands to cause your terminal to "beep" +when they are all done. Sometimes, this is useful when the system is slow, +as a way of letting you know that Emacs has "caught up" to what you told it +to do. Control G is very important, it is an "out" whenever you start +doing something that you change your mind about, or aren't sure what you +typed. If you ever find yourself in the minibuffer with a prompt that +you think you didn't ask for, or don't understand, like + + Eval: + +you can be sure that typing a Control G will get you out of it without +doing any harm. + + The next command we will learn about is Reverse String Search: it is +invoked by striking a Control R. Try it. Strike a Control R. Emacs will +prompt in the minibuffer: + + Reverse String Search: + +Type carriage return, like for Control S (String Search). The string "time" +will appear in the minibuffer, as we had promised. The cursor will be left +_b_e_f_o_r_e (i.e., under the first character of) the first occurence +of "time" going backwards from where the cursor was when you typed the +Control R. If the cursor was right after a "time", it will now be at the +front of the same one. Do it again. The cursor will go one "time" back +each time, until there are no more between the cursor and the beginning of the +buffer, at which time Emacs will respond + + Search Fails. + +in the minibuffer. If we want to change one of these "time"s to an +"hour", we need only type four Control D's (Delete Character) and the +word "hour" after finding one. + + Reverse String Search is just like String Search, except + + 1. It goes backward to the beginning of the buffer, while forward + search goes forwrd to the end. + 2. It leaves the cursor _b_e_f_o_r_e (at the front of) the found + string, while String Search leaves it _a_f_t_e_r. + +Otherwise, String Search and Reverse String Search both prompt in the +minibuffer, take a string terminated by a carriage return to use for a search +target, and use an empty string (a carriage return as answer) to indicate that +the last search string used should be used again. + + When you are searching for something in Emacs, you have to know if you +want to search forward or backward for it, from where you are now; usually, +you know this. If you don't, you should search forward. If the search fails, +just hit a Control R and a carriage return, and Emacs will search backward for +the same string. If _t_h_a_t search fails, the string is really not in the +buffer. + + We now have learned three new commands: + + Control S String Search. Prompts for a string in the minibuffer, + which must end with a carriage return. An empty string + uses the last string over again. Searches forward for + that string to the end of the buffer, and leaves you + after it. + + Control R Reverse String Search. Same as above, but goes backward. + Leaves you at start of found string. + + Control G (Command Quit) Get out of anything, and beep the + terminal. Often used to get out of minibuffer + prompts that you change your mind about. + + + Two Very Useful Commands + + We will now learn two useful commands that you will use all the time. +We will not give any examples here, because what they do is so simple. Try +them yourself any way you want, but learn them. + + Control A Go to beginning of line. Moves the cursor to the beginning + of whatever line it is on. The way to rememeber it + is that "A is the first letter at the beginning of the + alphabet". We could not use "B" for "Beginning", + because, as we know, Control B is for "Backward + Character". + + Control E Go to end of line (E for E_nd). Moves the cursor + to the end (after the last character, before the + carriage return) of whatever line it is now on. + On a line with nothing on it (nothing _i_n it but a + carriage return), this does nothing. + + + + Wiping, the Mark, and the Region + + We will now learn three new concepts, and three new commands. +We will learn them in order to be able to delete arbitrary extents of text +(i.e., "from here to there", or "all that stuff") as opposed to killing +lines and characters carefully to get rid of exactly what we want. Enter +Emacs. Type in a paragraph or so of text, of your choice. Choose a +few words next to each other somewhere. It is all right if they are not +on the same lines. Let us delete this "extent", that "much" of the text. +The command we will be using is Wipe Region, which is invoked from +Control W (for W_ipe Region). We tell it what to "wipe", that is, wipe off +the screen and out of the text, or delete, by giving it the "here" and +"there", that is, the "limits" or "boundaries" of the region to delete. +It will delete all the text between the two points we tell it to. + + How do we specify the "region" of our buffer that control W is to delete? +By its limits. How do we specify the limits? One limit will be the cursor +at the time we strike the Control W. The other is specified by an "invisible +cursor" called "the mark". There is at most one "mark" in each buffer. Until +we "set the mark", there is no mark in the buffer. Type a Control W. +You will find that Emacs will complain that there is no mark, and nothing +will happen. We "set the mark" by moving the cursor to the place we +want "the mark" to be, and issuing the command "Set the Mark", which is +invoked by Control @. This is a very tricky command to type. It is typed, +like any control character, by holding the control key, and typing, in +this case, the character @. On some terminals, you may even have to +hold Control and Shift at once to make this happen, if you normally have +to hold the Shift key to get an @. If you have trouble with this, ask someone +familiar with the terminals in use at your site; tell him you are trying to +"Generate an ASCII NULL, or a Control At Sign", and hopefully he or she can +show you how to type one. + + Move the cursor to be under the _f_i_r_s_t character of the first word that +you have singled out for deletion. We will set "the mark" here. Type the +Control @. Absolutely nothing will happen: this command doesn't "do" +anything visible. Now move the cursor to right _a_f_t_e_r the _l_a_s_t letter of the +_l_a_s_t word in the group we singled out for deletion. We are now ready, in +principle, to issue the Control W (Wipe Region) command, but let's not. +There is usually something we want to do right before issuing a Control W: We +want to check that "the mark" is where we think it is, because it might have +been some time ago that we set it. For this we use the command "Exchange +Point and Mark" ("point" is the name for the place in the buffer that the +cursor is located at. If you don't understand the difference between that +and the cursor itself, ignore it for now.) This command switches the cursor +and "the mark" around, putting the cursor where the mark was and the mark +where the cursor was. The visible effect of this is to move the cursor to +where the mark was, so we can see where it was. The "Exchange Point and Mark" +command is issued by typing Control X Control X (i.e., two Control X's in a +row). Remember "X" for E_xchange. Do it. The cursor will move to under the +first character of the region we are trying to delete, the place where we +had set the mark. Now before doing any other commands, do another +Exchange Point and Mark (Control X Control X) to get back. +It is very important that you do not move the cursor at all before typing +the second pair of Control X's, or you will exchange the mark with the +wrong point! It is very common to type Control X Control X, Control X +Control X in this way, to "verify" the "region" between the "point" and +"the mark". + + Now issue the Control W (Wipe Region) command. You will see that all +the text you singled out for deletion disappears from the screen (and thus +from your text). If there was a carriage return in the middle of them, you +will see that that too has gone, and one big line now replaces the two lines +between which the carriage return had been. + + Like The Kill Lines command (Control K), the Wipe Region command +(Control W) puts what it removes in the kill ring. Type a Control Y now +(the Y_ank command). All the text you had deleted reappears. If you +ever hit Control W by accident (for instance, instead of Control E), and +see loads of text mysteriously vanish, just type Control Y and it will +all come back. As a matter of fact, if you ever see text vanish off your +screen or out of your buffer for a reason that you don't think you understand, +the chances are better than even that simply typing a Control Y will +fix it all up. + + A useful feature of the Yank command is that it puts "the mark" at the +_b_e_g_i_n_n_i_n_g of the text it retrieves, and (as can be seen), leaves +the cursor after it. This has two implications that should be noted: + + 1. After you have yanked some text, no matter for what reason, you + can make it go away again simply by typing Control W (Wipe Region), + since the cursor and the mark exactly specify the boundaries of + what was yanked. + + 2. After you have yanked something, no matter for what reason, you + can get to (move the cursor) to the beginning of the yanked text + by exchanging the cursor and the mark, simply by typing + two Control X's, the "Exchange Pont and Mark" command. + + If we had known the second of these facts when we were learning about +Control K (Kill Lines), we could have gotten to the beginning of the +sentence + + One day they went out in the woods. + +after we had yanked it back simply by typing Control X Control X. + + The text in the buffer between the cursor and the mark is called +"the region". There are many Emacs commands besides Wipe Region (Control W) +which use the region, and the commands we learned for setting the limits +of the region and testing what they are are useful for all of them. + + We have learned three new commands: + + Control @ Set the mark to be where the cursor is now. + + Control X Control X + Switch the cursor and the mark around, to show us + where the mark was. The mark is now where the cursor + was, and the cursor is now where the mark was. + + Control W Wipe Region. Remove the text between the mark and the + cursor from the text and the screen. Save it on the + kill ring for possible subsequent yanking. + + Numeric Arguments + + + Next we learn about how to say "go FIVE characters forward", or +"go FOUR next lines down" and so forth. Commands for which it is meaningful +and useful to specify "how many times" to do them usually will accept what +is called a "numeric argument", which is essentially a repetition count. +For instance, if we give the "Next Line" command (Control N) a numeric +argument of 25, it will go 25 lines down instead of one line down as it usually +does. If we give the "Delete Character" command (Control D) a numeric +argument of 6, it will delete 6 characters, instead of the one it usually +does. + + Search around on your keyboard for a key labelled "ESC", "ESCAPE", +"ALT", or "ALTMODE", or something like that. This is called the "ESCAPE" +key, which generates a character called the "ESCAPE character". We +will refer to it by the letters ESC; this means strike and release the +ESCAPE key, do _n_o_t type the letters E, S, and C! + + We specify a numeric argument to a command by typing an ESC character +(hitting and releasing the ESCAPE key once), the number we want, and +the command we want to receive the argument. For instance, to delete +six characters, we would type the _t_h_r_e_e keys + + ESC 6 Control-D + +That is, strike the escape key, the 6 key, and a Control D in that order. +All the characters will disappear at once: you will not see them go one by +one. Similarly, if you said + + ESC 249 Control-N + +while on the first line of a large file, the screen would fill immediately +with lines 240 to 261 (roughly) of the file, with line 250 and the cursor +in the middle. You will be spared watching the cursor and the screen +step through 250 lines one by one; it is done all at once. + + The following commands that we have already learned about accept +a numeric argument to mean "Do it that many times". The complete list +is given in the Emacs reference document: + + Control B Backward Character + Control D Delete Character + Control F Forward Character + Control N Next Line + Control P Previous Line + +If you give a numeric argument to Control K (Kill lines), it does _n_o_t +do that many Control K's, it does something more useful. Starting +with the current point on the current line, it kills entirely (removes) +that many _e_n_t_i_r_e lines. Thus, if you are at the beginning of a line +(doing a Control A, Go to Beginning of Line can ensure this), + + ESC 4 Control-K + +will delete this and the next three lines entirely. Of course, these +lines will be put as one on the kill ring, and will "_k_i_l_l _m_e_r_g_e" +with preceding or following "kill type" commands as described above. + + The "Yank" command also does something useful and different with +a numeric argument. The kill ring is so called because it is like a ring +of text excerpts that were deleted. Whenever you kill some text, +the "ring" is rotated one of its ten positions, and the newly killed text +goes in the front position, replacing what had been in the tenth position. +It is like a merry-go-round with ten horses, and one on/off point. +The ten positions on the kill ring thus contain the last ten text excerpts +that you killed. (When kill merging occurs, this does not happen, as the +new text gets "stuck on to" the text in the ring at the on/off point). +When you use a "Yank" command (Control Y), it is always the latest thing +that you killed (i.e., the excerpt at the on/off point) that is retrieved. +If you want the _s_e_c_o_n_d latest thing instead, simply give the +Yank command a numeric argument of 2 by typing + + ESC 2 Control-Y + +instead of just + + Control-Y + +and that will happen. + + There is a wonderful command that expresses the following situation. +"I deleted some text. Then I went somewhere else, and I deleted some +more text. Then I decided that the first text I deleted was really O.K.; +deleting it was a mistake. So I went back to the point where I deleted it +from, and used the Yank command (Control Y). However, that was a mistake, +because it brought back the text from the second thing I had deleted, +which was, indeed, the last thing I had deleted. I wish I could say +"Get rid of that stuff, and bring back the previous saved text in the +kill ring." " + + There is such a command. It does precisely that. It gets rid of +the text between the cursor and the mark (which was, presumably just yanked +by mistake), without saving it on the kill ring, "rotates" the kill ring +one position _b_a_c_k_w_a_r_d_s, and retrieves the text at the on/off station. + +It is typed by the two-character sequence + + ESC y + +That is to say, press the two keys, ESCAPE and Y (lower case or capital, it +does not matter) one after the other. (Be careful to type the two-key +sequence deliberately and firmly; do NOT hold down the ESC key while typing +Y: it is NOT like the CONTROL key.) It is called the "Wipe this and Yank +Previous" command: + + ESC Y Wipe this and Yank Previous. I don't like what + I just yanked. Get rid of it, and bring out the + previous thing I killed. + +By doing many ESC Y's in a row, until you "find the kill that you want", +you can "go shopping" in the kill ring for saved text. + + Whether you realize it or not, normal letters and numbers are actually +Emacs commands, too! For instance, we know that Control D means "Delete the +character at the cursor". But what does an ordinary "D" mean? What happens +when you type an ordinary "D"? What happens when you type any number or letter +or punctuation mark? It goes into the buffer, and appears on the screen. +The first thing we ever did was to type ordinary text into Emacs. +Printing characters (other than #, @, and \), are said to be +_s_e_l_f-_i_n_s_e_r_t_i_n_g, because if you type one, it inserts itself into +the text. + + We mention this now because giving a numeric argument to a self-inserting +character causes it to insert itself that many times. For instance, +if we type + + ESC 2 4 Q + +we will see twenty four Q's appear on the screen all at once. This is a +good way to get lines of dashes, underscores, stars, etc. + + If ever you type a numeric argument, or are in the middle of typing +a numeric argument, or have just typed ESC, and you decide that you +didn't mean it, or you are not sure as to whether you typed the numeric +argument or not, type a Control G, which G_ets you out of anything. The +reassuring beep of Control G will verify that any possible numeric argument +has been discarded. + + The First Help Command, and Local Displays + + There is a command that will tell you what command a given key performs. +This is a good command to use if you are not sure what a given key does, and +you do not have the documentation on hand. It displays the documentation for +a given command on the screen. It is called Describe Key, and is invoked by +striking the two-key sequence + + ESC ? + +Try it. Let's find out about what Control E is and does. +Type an ESC, and then a question mark. Emacs will prompt in the +minibuffer with + + Explain Key: + +Now actually type a Control E, in the usual manner. Emacs will probably wait +a little while before responding, especially if this is the first time you +have used ESC ? since entering Emacs and system load is heavy. Be patient. +The documentation for Control E, Go to End of Line, will appear at the top of +the screen, replacing whatever text you were editing on the screen. Bu do not +worry, it did not destroy your text; it is just being "displayed" to you on +the screen "in front of" your text. The line of dashes and stars: + + -- * * * * * * * * * * * * -- + +is there to let you know that your buffer has not been destroyed, but simply +that there is information being displayed for you to see "in front of" it. +Such a display is called a L__o_c_a_l D__i_s_p_l_a_y. We will shortly learn how to get +rid of the local display, when we are finished viewing it, and restore the +window on our buffer to the screen. + + The documentation for Control E begins with the line + + ^E go-to-end-of-line + +"^E" is the shorthand for "Control E" which is used in the reference document, +and in displays and error messages produced by Emacs. It is a good shorthand, +because "Control X Control Q ESC B Control D" etc., can get long-winded. +We will use this convention from hereon in. When we say "^A", we will mean +"Control A", i.e., hold down the control key and strike an A", _n_o_t the +character "^" followed by an "A". + + "go-to-end-of-line" is the _c_o_m_m_a_n_d _n_a_m_e associated with +^E. At this stage, it serves only to remind us of what ^E does. When a great +deal of proficiency in using Emacs has been acquired, these command names +can be used in computer programs to build commands of your own. +As a matter of fact, once you know the command name, you can "connect" any key +of your choice to any command of your choice if you don't like the default +layout of what key does what (see the writeup of the "set-key" and +"set-permanent-key" extended commands if you want to learn about this). + + The documentation describing go-to-end-of-line follows the line giving +the key name and command name. The documentation is the same that you would +find in the Emacs reference document; it describes everything there is to know +about the command in question. + + When we have finished viewing the local display of the command +documentation, we wish to remove it from the screen. If you just start +editing again, typing editor commands, the display will vanish as soon as you +start typing, putting back on the screen what had been there. However, you +might not know where the cursor was "supposed to be", because the local +display is standing there in front of it. For this reason, a command is +provided that does _n_o_t_h_i_n_g _a_t _a_l_l. Since typing _a_n_y editor command makes the +local display go away, this command may be used for making local displays go +away without doing anything else. It is invoked by striking the Linefeed key +on your terminal. The "noop" (No Operation) command is invoked by Linefeed +(which is the same as Control J on all terminals). For reasons too complex to +describe here, it is recommended, and cannot hurt, to hit Linefeed two or +three times to get rid of a local display. + + Sometimes, local displays will take more than one screen. In this case, +the last line of the screen will say + + --More?-- (Space = yes, CR = no) + +If you see this on the last line of the window, hit the space bar once to see +each successive screen of the local display. When you are at the last screen +of the local display, the line of dashes and stars + + -- * * * * * * * * * * * -- + +will appear, and Linefeeds may be used to restore the buffer to the screen. +If, during a multi-screen local display, you decide that you do not want to +see the rest of the display, typing a carriage return instead of the space bar +will terminate the display and restore the buffer to the screen. + + Occasionally, you may forget what command a given key invokes, or need to +find out "what you just did by accident". You can ask for the name of the +command invoked by a given key without the documentation. This can be +preferable at low terminal speeds, or on a slow system, where the local +display can take some time, or if you just need a reminder of what is +"connected" to some given key. This can be done with the Describe Key command +by giving it a numeric argument, i.e., + + ESC 1 ESC ? + +(a four-key sequence). Type that. Emacs will prompt: + + Show Key Function: + +Type, for instance, a Control W. Emacs will respond in the minibuffer, + + ^W = wipe-region + +which is precisely what we wanted to know. + + We now know two new commands: + + ESC ? Describe Key. Prompts for you to type a key, + and supplies the documentation for that key as + a local display. If given a numeric argument, + tells what command is invoked by that key. + + Linefeed No Operation. Type it two or three times to remove + a local display from the screen. + + + T__h_e B__u_f_f_e_r _a_n_d _t_h_e S__c_r_e_e_n + + + Very often we wish to "page" through a document, reading through it like +a book, either to actually read it, or to "flip through" until we arrive at +the place we want to see or edit. Using Emacs, this is accomplished by +"paging" through the text in the buffer screen by screen. That is to say, +after we finish reading or looking at the text on the screen, we want to see +the next screenful (actually, the next windowful). The next windowful of text +is that text in the buffer which immediately follows the text now in the +window. That is the text we wish to progress to, and fill the window with. +The command for doing this is "Next Screen", which is gotten by striking +Control V (for V_iew Next Screen). This is a very easy key to type with your +left hand alone; use your thumb, while holding down the control key, to page +through successive windowfuls of a document. + + Read in some file and "^V through it". You will note that each time you +strike a Control V, the cursor will be left at the upper left-hand corner of +the screen: not only has the window been filled with new text, but the cursor +is now in a different place in the buffer, at the beginning of the text which +fills the window. The text now in the window, of course, is not the only part +of the buffer you may edit. If, for instance, after using ^V, you use a ^P to +go to the previous line, you will observe Emacs choosing a different portion +of the buffer to display in the window. Emacs usually chooses its window, +(i.e., what part of the buffer to show in the window) automatically, governed +by where in the _b_u_f_f_e_r you moved the cursor. ^V is one of several ways, and +the first we have learned thus far, to explictly select what will be displayed +in the window. + + Note that when you use ^V, the first line of the new screen will be the +same as the last line of the old screen. This is to give you some context, +and a sense of continuity, so you will know you haven't missed anything, or +forgotten what you were reading while the screen was being refilled. + + As we can page "forward" through a buffer, so we can page "backward" as +well. As this is less common, it takes two keystrokes. The two-key sequence +ESC V invokes the "Previous Screen" command. Remember, C__o_n_t_r_o_l V for the next +screen, E__s_c_a_p_e V for the previous one. ESC V will make the last line of the +new screen be the same as the first line of the old one. + + Now we can go forward and backward through the buffer line by line (^N +and ^P), character by character (^F and ^B), windowful by windowful (^V and +ESC V), or by searching (^S and ^R), and we will learn many more ways yet. +However, among the most common of needs are to go to the _b_e_g_i_n_n_i_n_g of the +buffer, the _e_n_d of the buffer, and to a given line number. +The command "Go to Beginning of Buffer" is invoked by the two-key sequence +ESC <. Think of the "less than sign" as an arrow pointing backward to the +beginning of the buffer. Using ESC < will place the first windowful of the +buffer on the screen, and place the cursor at the very first character of the +buffer. This is often useful when going through the entire buffer looking +for something or changing things one by one as you see them. + + As you might have guessed, ESC > is "Go to End of Buffer". The "greater +than sign" may be thought of as a little arrow pointing to the end of the +buffer. It places the last windowful of the buffer on the screen, and +places the cursor on the newline character (the "carriage return") which ends +the last line of the text in the buffer. That is the furthest place in the +buffer that the cursor can go; it is the end of the last line in the buffer. +There is no way to move the cursor to beyond that character. If, after using +ESC >, you see the cursor on a line by itself, that simply means that there is +an "empty line", i.e., one with nothing but a newline in it, at the end of the +buffer. + + When editing Multics programs, it is often very useful to go to a given +line number (e.g., the 240'th line of the buffer), because many Multics tools +give diagnostics in terms of line numbers in their input files. If you happen +to be positioned on the first line of the buffer, going to the 241's line is +easy; just do 240 ^N's by typing + + ESC 2 4 0 ^N + +If you are not on the first line, you could use ^X= (Line Counter) to figure +out where you are, subtract, and use ^P or ^N with the right numeric +argument, but this is hardly reasonable. Therefore, Emacs provides the +"Go to Line Number" command, which is invoked by the two-key sequence +ESC G (G for G_o). The numeric argument to ESC G tells it what line number to +go to. For instance, + + ESC 2 5 9 ESC G + +will move the cursor to (the beginning of) line 259 of your text, no matter +what line you are on now. As is the case with searching, ^N and ^P, and any +Emacs cursor movement commands, if the target of the motion (the place in the +_t_e_x_t being gone to) is not on the screen, a new window will be selected and +displayed automatically such that the target of the motion _i_s on the screen. + + When editing multiple files, each use of ^X^F (Find File) will result in +a new buffer. You may switch between buffers with the "Go Buffer" command, +which is invoked by ^XB (B for B_uffer). Be careful when typing this command: +be sure to release the control key before typing the "B" (the B need not be +capitalized; Emacs does not distinguish between upper and lower case letters +in editor commands (other than self-inserting characters)). When you type a +Control X and a B, Emacs will prompt for a buffer name to go to. Type the +name of the target buffer, ended by a carriage return. If you give the name +of a buffer that does not exist, Emacs will create such a buffer, and display +it on the screen (you will see an empty window). If you give the name of a +buffer that does exist, Emacs will refresh the screen with the last windowful +of that buffer that you were editing, that is to say, such a window of that +buffer that the last point you were at with the cursor when editing in it is +now on the screen, and the cursor will be placed at that point. + + Note that when you switch buffers with "Go Buffer", the mode line +changes, to indicate the new buffer name (and the new buffer modes, if they +have changed as well, because modes may be different in different buffers, and +are "remembered" in that buffer. We will learn later about some useful +modes.) The path line (the line under the mode line) will change as well, to +let you know the pathname of the file which was read into this buffer (or last +written out from it). + + You may list all of the buffers in a given invocation of Emacs with the +"List Buffers" command, ^X^B (Control X, Control B). The listing of buffers +will be displayed as a local display; hit linefeed two or three times to get +rid of it, as all local displays. The name of each buffer, and the pathname +of the file in it, if any, will be displayed. To the left of the buffer names +will be two symbols, for some buffers, ">" and "*". The "greater than" sign +will be placed to the left of the name of the buffer in which you are now +editing. The star will be next to the name of any buffer which is "modified", +i.e., has never been written out (but isn't empty), or has been modified since +last read in or written out. Only when there are "no stars" will ^X^C allow +you to exit Emacs without querying you. + + Go Buffer (^XB) provides a convenient service for going back to the last +buffer you came from. If you answer its prompt + + Buffer: + +with _j_u_s_t a carriage return, i.e., no buffer name, Go Buffer will go back to +the last buffer you had been in before entering the current buffer. This may +be used to "visit" another buffer and come back easily. + + Occasionally, you may not believe what you see on the screen. Sometimes +bad telephone lines, or unexpected messages from Multics, or things you just +don't understand ("I _k_n_o_w that's not there!) may cause the screen contents to +become invalid. This may be due to hardware problems, bugs in new versions of +Emacs, or bugs in your terminal. At any rate, there is a need to clear the +entire screen and put it back the way it should be, without any regard for +what was there. This is like clearing one's throat, or clearing the top +of the table. This is accomplished with the Redisplay Command, which is +gotten by striking ^L. ^L is used for this purpose because many terminals, +and some parts of the Multics Communications System, associate the Control L +character with the clearing of screens. Try striking ^L; you will see the +screen clear, and be refilled, with the cursor in the middle of the screen +(unless you are at the top of your text buffer, in which case it will be at +the top). On fast terminals, ^L can be used just to "reposition the window" +such that the line with the cursor on it is at the middle of the window. +(this will work on all terminals, but may be too slow to be useful on slow +lines). ^L will also make local displays go away, and on fast terminals, is +often used for this purpose as well. ^L with a numeric argument is used to +reposition the window, i.e., keep the cursor at the same point in the buffer, +but "move the window around" so that the line with the cursor on it +is at a place of your choosing in the window; a numeric arguemtn of zero is +the top of the window, and so forth. See fundamental-mode.info for more +information on this. + + We have now learned seven new commands for manipulating screens and +buffers: + + Control V Next Screen. View the next screen of the buffer + in the window, and leave the cursor at its top. + + ESC V Previous screen. View the previous screen of the + buffer in the window, leave the cursor at its top. + + ESC < Go to the beginning of the buffer. + + ESC > Go to the end of the buffer. + + Control X B Go Buffer. Prompt for the name of another buffer, + and switch to it, displaying it on the screen at the + last point you left off editing it. If you give + ^XB no buffer name, it will go to the previous buffer + you had been in. + + Control X Control B + List Buffers. Show as local display the names, + file pathnames, and modified/not modified status of + all existent buffers. + + Control L Redisplay Command. Clear the screen and refresh it, + eliminating possible non-understood garbage. With a + numeric argument, reposition the window. + + ESC G Go to Line Number. Go to the beginning of the line + whose line number is supplied as a numeric argument. + + + A__p_r_o_p_o_s _a_n_d E__x_t_e_n_d_e_d C__o_m_m_a_n_d_s + + Some commands are issued by a single keystroke, such as ^D, which invokes +the Delete Character comand, delete-char. Other, less common ones, are +invoked by two-key sequences beginning with ESC, such as ESC G, which invokes +the command go-to-line-number. Others, less common yet, are invoked by +two-character sequences beginning with ^X (X for E_xtended key). Commands that +are the least common have to be invoked by actually typing in the name of the +command. + + By "less common", we do not mean that a command is obscure, little-used, +less important, or not widely known or understood. What we do mean is that +during the course of normal editing, you will use it fewer times than more +common commands. For instance, you only use ^X^C (quit-the-editor) once per +editing session, but it is one of the first and most important commands you +must learn! The commands that you must type most often are made the easiest +to type. The simplest commands to type (the single key "control"'s) are those +that you would want to type _r_a_p_i_d_l_y. A fine example of this is ^T, +twiddle-chars, which exchanges the last two characters typed. It is not a +necessary command, as two pound signs and two more characters can do whatever +it does. But given that ^T can be typed in one character, it is useful. + + The commands known as "Extended Commands" are those invoked by typing +their command names at Emacs. An example of an extended command is "fillon", +which enters "fill mode" in a buffer. Fill mode is a setup of a buffer such +that you do not have to worry about the ends of lines when typing text, and +never type carraige return (except, of course, when ending prompts, or where +you want explicit control over the format and line-breaks of your document). +Fill mode is ideal for typing in text from a written page, or composing a +document spontaneously. One types and types and lines get broken +automatically. + + To invoke the "fillon" command, we clearly cannot just type the characters +"fillon" at Emacs, or they will go into the buffer like any other characters. +We must somehow tell Emacs that we wish to type the name of an extended +command. The "Extended Command" command, which is invoked by ESC X, does this. +The "X" is for E_xtended. Type the two-key sequence Escape X. +Emacs will prompt in the minibuffer, + + Command: + +Now type the word "fillon" (no quotes, just the six characters), followed by a +carriage return. You will see the name of the "fill" _m_i_n_o_r _m_o_d_e appear in the +mode line after the name of the current _m_a_j_o_r _m_o_d_e (Fundamental). + + In general, we invoke an extended command by typing ESC X, the name of +the command (and then any arguments, if the extended command takes command +arguments), and a carriage return. + + Now try fill mode. Type in a long, very long sentence, consisting of +very many real, separate words. Watch what happens when you get to the end of +the screen, as you type successive words. Do not worry about typing carriage +return; your lines will be automatically "filled" as they become too long. + + The most important extended command is the "apropos" extended command. +"Apropos is a word (from the French) meaning "about, or having to do with". +It is used to find the names, and keys, of all commands that have to do with a +given topic. It is used if you remember something about a particular command, +but you cannot remember the key that invokes this particular command, or what +its name is. The "apropos" extended command will find all commands that have +a given character string in their name, and tell you what keys invoke them. + + For instance, suppose you forgot the name of the key that went to the end +of a line. Type + + ESC X apropos end CR + +(The "CR" means "carriage return"). Apropos will display, as a local display, +the names of all commands available in this buffer whose names contain the +character string "end". It will tell you of ^E (go-to-end-of-line), +ESC > (go-to-end-of-buffer), and a few surprises (such as ^XM, s_e_n_d-mail), and +others. Once we learn from apropos what commands are available, we may be +jolted into recognition ("Oh, yes, ^E was go-to-end-of-line!"), or need more +information ("Hmm, ^E looks right. I'd like to know more about it."), and use +ESC ? (Describe Key), by typing, say ESC ? ^E, to get the full documentation +on a particular command. + + Apropos will also list all relevant extended commands, when listing +commands whose names speak of a particular topic. We cannot use ESC ? +(Describe Key) to find out about extended commands, for it prompts for a +single key, and tells about it. If we typed "fillon" to ESC ?, it would read +the "f", and tell us about "f" ("f" puts an f into the buffer, etc.), and put +"illon" into our buffer. So, there exists an extended command to retrieve +documentation for extended commands: it is called "describe". To find out +about the "fillon" extended command, we type + + ESC X describe fillon CR + +The command documentation will be shown as a local display. We can find out +about describe itself, + + ESC x describe describe CR + +or about apropos + + ESC X describe apropos CR + +if that is what we want to do. + + + We now know the three commands that constitute the core of the Emacs +self-documentation and help system: + + ESC ? Describe Key. Prompts for a one or two key sequence, + and gives as local display the documentation for the + command invoked by that key. + + ESC X describe CR + Gives as local display the documentation for the extended + command whose name is given. + + ESC X apropos CR + Gives as local display a list of commands whose names + contain the character string given as , and + tells what keys invoke them, in the current buffer. + Relevant extended commands are also listed. + + The "<" and ">"'s in the above descriptions do not mean that you should +type <'s and >'s. They are being used as "pointy brackets". That is to say, +"" means any character string, being some topic you want help on. +We use the "pointy brackets" so that you will not be misled into typing the +character string "topic". + + We have also learned of the "fillon" extended command: + + ESC X fillon CR + Enters "fill" minor mode in the current buffer. This + causes overlength lines to be wrapped around and broken + as they cross the "fill column". Ask the "describe" + extended command to tell you more about fill mode. + + + W__o_r_d C__o_m_m_a_n_d_s + + Some of the most useful commands in Emacs are those which relate to +words. Even if we are typing computer programs or other non-English text +material, the facility to move around word by word, delete words, etc., is a +very useful one. + + The word movement and deletion commands have a deliberate parallelism +with the character movement and deletion commands: ^F, ^B are Forward +Character, Backward Character, and ESC F, ESC B are Forward Word, Backward +Word. Similarly, ^D and # are Delete Character and Rubout Character, while +ESC D and ESC # are Delete Word and Rubout Word. + + A "word" in Emacs consists of an unbroken string of upper and lower case +alphabetics (a-z and A-Z), underscores and backspaces. For instance, +"new_payroll" is a word, "_b_e_g_i_n" is a word, "delete-char" is two words, and +"segname$entry" is two words. "March, I said." is three words. + + The "Forward Word" command (ESC F) moves the cursor forward over one +word. If the cursor is currently on a character that is part of some word, +the cursor will be moved to the first character after that word. For +instance, if the cursor is on the "e" of the word "Yes" in the fragment + + "Yes, it is true," he said. + +and the Forward Word (ESC F) command is issued, the cursor will be left +positioned on the comma after the word "Yes". If the cursor is now on a +character between two words (even if they are separated by many blank lines, +or many lines full of punctuation, breaker bars, etc.), Forward Word will +position the cursor to the first character after the _n_e_x_t word in the buffer. +Thus, if the cursor is on the comma after the word "Yes" in the above example, +and the Forward Word command is issued, the cursor will be moved to the space +after the word "it". + + Moving around by words is often the fastest way, or the most convenient +way to move the cursor to where you want to go from where you are. It is +quite common to type ESC F ESC F ESC F etc. to move a word at a time, watching +the cursor. You might also judge "I want to go six words forward, roughly", +and issue the key sequence + + ESC 6 ESC F + +which is allowed, because Forward Word accepts a numeric argument as +a repetition count. However, doing ESC F's one at a time to move forward +word-by-word is still an often-needed technique. There are some problems in +that technique, however, because any slip-up in typing + + ESC F ESC F ESC F ESC F + +and you may have + + ESC F ESC F ESC ESC F F ESC F + +or similar, which is not what you want. (If, by the way, you fall into this +trap, and ESC ESC gives you "Eval:", do a ^G to get out of it.) Therefore, +the command Re-execute Command (^C) is provided to make this and similar +operations easier and less error-prone. Typing a Control C re-executes the +last editor keystroke command entered. Thus, after typing ESC F to go forward +a word, each typing of the single keystroke ^C will go forward another word. +With good system response, this can be very effective. + + To go backward by words, Backward Word (ESC B) is provided. It is +similar to Forward Word, and most other Emacs forward/backward motion +commands. If the cursor is on some character of a word, other than the first +character, it will be moved to the first character of the word. If on the +first character of a word, or between words, Backward Word will move to the +first character of the previous word (i.e., further back in the buffer). +If we have the fragment + + He said, "Come, let us reason together." + +and the cursor is on the "e" of "let", Backward Word would move it to the "l" +of "let". Successive Backward Word's would move it to the "C" of "Come", +the "s" of "said", and the "H" of "He". ^C (Re-execute Command) may be used to +repeat Backward Word (or any other Emacs command) in the same way as we +described for Forward Word. + + Here is a good example of the interaction between Forward Word and +Backward Word. To put parentheses around the sobriquet "Tony" in + + Anthony Tony Burns. + +assuming that the cursor is at the "." after "Burns", we type + + ESC B ESC B + +to put the cursor at the "T" of "Tony. Then we type an open-parenthesis, which +inserts itself at the cursor, leaving us with + + Anthony (Tony Burns. + +and the cursor still on the "T" of "Tony", which has now moved over. +Now ESC F puts the cursor on the space after "Tony", and typing the close +parenthesis finally gives us + + Anthony (Tony) Burns. + +with the cursor on the space after "(Tony)". The total keystroke sequence +was + + ESC B ESC B ( ESC F ) + +How easy. + + Deleting words is perhaps the second most common editing operation (after +deleting characters) when entering text. Most often, we type a word, and +decide that we did not want that word, or mistyped it sufficiently thoroughly +that we wish to retype it entirely. We wish to delete the last word we typed, +which is to say (note the similarity to the use of #), the word to the left of +the cursor. Parallel to #, ESC #, Rubout Word, is used for this purpose. It +deletes the word, or what is left of a word, if the cursor is in the middle of +a word, to the left of the cursor. Its action can best be described as though +it were doing + + ^@ Set the Mark + ESC B Backward Word + ^W Wipe Region + +That is to say, Rubout Word does a Backward Word, and removes all text between +where the cursor winds up and where it started. Successive Rubout Word's +remove words farther and farther back. Like all deleting commands (other +than character deleting), Rubout Word participates in kill-merging, which is +to say, that after one or any number of successive words have been removed by +Rubout Word, a yank (^Y) will get them all back. If successive words, and the +punctuation and whitespace between them, are deleted by Rubout Word, a single +Yank command will get back the whole deleted area, intact, punctuation, +whitespace, and all, as it initially stood. Rubout Word accepts a +numeric argument as a repetition count, and, like all commands, can be +repeated with ^C. + + Note that when issued in the middle of a word, Rubout Word will delete +that part of the word to the left of the cursor. If immediately after a word, +it will delete only the characters of the word. At any other point, it will +delete all characters between the cursor and the previous word, and that word. +All these facts follow from the definition given above. + + Forward word deletion may be performed by Delete Word, invoked by ESC D. +It deletes the word, or part of a word, to the right of (including the +character at) the cursor. It deletes forward, from the point where the cursor +is, to the point where Forward Word, ESC F, would go. Successive ESC D's +will participate in kill-merging, and delete text word-by-word, all capable of +being retrieved in one Yank (^Y). If issued with the cursor on the first +character of a word, Delete Word will remove the entire word. If issued in +the middle of a word, Delete Word will remove all the characters from the one +at the cursor up to and including the end of the word. If issued between +words, it deletes all whitespace and punctuation up until the next word, and +the next word along with it. Consider the sentence + + We have not any melons today, Mrs. Johnson. + +with the cursor under the "r" of "Mrs.". To replace "melons" by "pears", +we type + + ESC B ESC B ESC B + + +to put us on the "m" of "melons", and the ESC D, to delete the m, e, l, o, n, +and s, leaving us with + + We have not any today, Mrs. Johnson. + +with the cursor on the second of two spaces between "any" and "today". We +then type the word "pears". + + A unique set of capabilities is provided by three commands which control +the "case" of words, i.e., lower case ("jack"), upper case ("JACK"), or +"Capitalized Initial", ("Jack"). These three commands are: + + ESC L Lower Case Word + ESC U Upper Case Word + ESC C Capitalize Initial Word + + Each of these commands may be issued with the cursor _o_n a word, that is, +on any character of it, or _i_m_m_e_d_i_a_t_e_l_y _a_f_t_e_r a word to alter the case of that +word. For instance, suppose we had just typed + + thomas + +with the cursor immediately after the "s" of "thomas". To capitalize +"thomas", we need only issue the two-key sequence ESC C, and we have + + Thomas + +The cursor is always left immediately after the word whose case was +transformed. If we wish to capitalize several words, say + + thomas alva edison + +we can move the cursor to any letter of the word "thomas", type ESC C, leaving +us on the space after "Thomas", ^F to put us on "alva", ESC C, leaving us +between "Alva" and "edison", and ^F and ESC C one last time, leaving us after +"Edison". + + The three word-case-altering commands all leave the cursor immediately +after the word whose case is altered. Since the character immediately after a +word is a good place from which to issue a word-case-altering command, +we can position the cursor immediately after the word "thomas", and +type ESC C ESC L ESC U ESC C ESC L etc., and watch Thomas, thomas, THOMAS, +Thomas, thomas, etc., replace each other on the screen until we find the one +we like. A word-case-altering command may be issued from anywhere within a +word or immediately after it, but it will leave the cursor immediately after +the word. + + The word-case-altering commands deal with all the characters in a word, +not just the first. Thus, a word like "MaGicAl" can be converted to +"Magical", "magical", or "MAGICAL" by use of these commands. Thus, the +word-case-altering commands can be used to fix typos caused by holding down a +shift key too long. For instance, in trying to type "Joralemon", we might +type "JOralemon". An easy job for ESC C, Capitalize Initial Word. Issuing +this command after we type the "n" gives us at once "Joralemon". + + If a word-case-altering command is issued between two words, but _n_o_t +_i_m_m_e_d_i_a_t_e_l_y after the first word, it will alter the case of, and move to the +end of, the next word. Thus, sequences of ESC C ^F ESC C ^F, etc., will +capitalize successive words, regardless of how much punctuation or whitespace +separates them. + + Related to the word-case-altering commands are the underlining and +underline-removing commands, ESC _ and ESC -. These commands are used to +cause a word to be underlined, or to remove the underlining from an underlined +word. It is important to note that most current video terminals either do not +have the ability to underline text at all, or can only do it in ways that are +either very limited or not useful. Therefore, underlined text in Emacs +appears as + + H\010__\010e_\010l_\010l_\010o + +where + + H__e_l_l_o + +is wanted. The "\010"'s are backspaces; they are shown in this way because +almost no video terminals can overprint characters, even among those that have +limited underlining capability. The text in the buffer, which will be written +out to your file, actually contains the proper number and placement of +backspaces: the "\010" representation is only the way they _a_p_p_e_a_r on the +screen. + + Typing in backspaces in order to underline words when talking to Multics +is confusing, difficult, and error-prone enough when using a printing +terminal: the familiar sequence of "H e l l o backspace backspace backspace +backspace backspace _ _ _ _ _" or worse is even less convenient on a video +terminal that cannot overstrike. + + A word can be automatically underlined correctly by use of the Emacs +Underline Word command, ESC _ (the two-key sequence, Escape Underscore. Be +careful to remember to use the shift key to get the underscore if, on your +terminal, you would use the shift key any other time to get an underscore!) To +use this command, position the cursor to any place within a word to be +underlined, or immediately after, just as for the word-case-altering commands. +ESC _ will then cause this word to be underlined correctly, and leave the +cursor positioned immediately after it. Just as with the word-case-altering +commands, to type in a word and underline it, say "_b_e_g_i_n", we type the seven +keys + + b e g i n ESC _ + +The fact that we issued the Underline Word command immediately to the right of +a word (which we had just entered) causes that word to be underlined. + + The command ESC - (Escape Minus-sign), Remove Underlining From Word, +is used to take out underscores and backspaces (i.e., de-underline) a word +that is underlined. Like the word-case-altering commands and Underline Word, +it may be issued with the cursor at any point within the word of interest, or +immediately after it. Just as with the word-case-altering commands, +successive ESC _'s and ESC -'s will add and remove underlining from the same +word, in alternation. + + As with the word-case commands, to underline successive words, + + ESC _ ^F ESC _ ^F ESC _ ^F + +will do the job. + + A thoroughly unique ability of Multics Emacs is the ability to search for +_w_o_r_d_s as opposed to _s_t_r_i_n_g_s, when required. Suppose we had the sentence + + Yes, I know, Miss Smith's theater + is the One for _m_e! + +Let us assume that the cursor was on a previous line, or in the word "Yes", +and we wanted to find the word "is". We could use String Search, ^S, and +reply + + i s ESC + +to the prompt + + String Search: + +but this would get us to the "is" in "Miss", which is not what we want. +We could search again, but there is a better way. Use of the Word Search +command, ^XW, will find a _w_o_r_d, not a part of a word. If we had typed ^XW +when trying to find the word "is", Emacs would have prompted: + + Word Search: + +We then type the word, "is", as we would have for String Search, and a +carraige return. + + Word Search can find words regardless of capitalization or underlining. +For instance, using Word Search to find the words "one" or "me" in the above +sentence would find "One" and "_m_e". + + Word Search can also find _s_e_q_u_e_n_c_e_s of words, which is to say, several +sequential words, separated by any amount of punctuation or whitespace. If +the cursor were far above the above fragment, in the document in which it +appeared, we could find our fragment by answering ^XW's prompt, + + Word Search: i know miss smith CR + +and the cursor will be left immediately after the "h" of "Smith", for the +words: + + I know, Miss Smith + +appear in sequence. The comma between "know" and "Miss", as well as all +spaces, and the capitalization of I, Miss, and Smith, are ignored by Word +Search. In fact, we could have searched: + + Word Search: theater is the CR + +and the cursor would be left after the word "the", in the second line of the +fragment. The newline (carriage return) separating "theater" from "is" is +simply whitespace, which is ignored by Word Search. When we say that +whitespace and punctuation is ignored by Word Search, we do not mean that +having whitespace or punctuation is the same as not having _a_n_y: what _i_s meant +is that any amount of whitespace or punctuation will be treated the same, as +separating one word from the next. Thus, + + ^XW jack knife CR + +will find + + jack knife + Jack, knife + J__a_c_k... "KNIFE!!" + +but not + + jackknife + +which is one word, not two. + + Word Search can also help searching by searching for words that start +with a given string. This is useful for searching for long word. To indicate +that a word-prefix is being searched for, we type the first letters of the +word followed by an asterisk, for example, + + anted* + +to search for "antediluvian" We can use an abbreviated word in this way as +part of a word-sequence being searched for, for example, + + ^XW the anted* era CR + +to search for + + T__h_e "A__n_t_e_d_i_l_u_v_i_a_n" E__r_a + + Word Search is clearly an extremely powerful and useful command. Like +most other Emacs search commands, typing simply carriage return to its prompt, +i.e., a null, or empty search string, re-uses the last search string. Word +Search searches from the current point in the buffer (where the cursor is) to +the end of the buffer, indicating the usual + + Search Fails. + +with its characteristic beep if the word or words being searched for could not +be found. There is no reverse word search; however, Word Search with an +argument, for example + + ESC 1 ^XW + +will search from the beginning of the buffer to the end. A word of caution, +however. Because Word Search is such a powerful command that checks for so +many different occurences, it can be slow, especially on a large file, and on +a slow system. Searching from the beginning of a file will almost always +make it slower, taking a long time. In general, the ordinary String Search +(^S) should be used for best response if you can tell (as with other editors) +what exact characters you are looking for; use word search when you do not +know what characters you are looking for, but you do know what words. + + Perhaps the best example of a use for Word Search is the editing of an +input segment to a text justifier, like compose or runoff, when you have a +hard-copy of the output (.compout or .runoff) segment before you. You can +use Word Search to search for a group of words that you see in the output +segment: they will be found in the input segment, even if compose or runoff +inserted or deleted many spaces or moved them around on different lines when +filling or justifying text. + + We now summarize the various commands for manipulating words: + + Word Motion of cursor: + + ESC F Move forward a word, to the end of the current word, or + (if now at the end of a word or between words) to the end + of the next word. + + ESC B Move backward a word, to the beginning of the current + word, or (if now at the beginning of a word or between + words) to the beginning of the previous word. + +Deleting words and parts of words: + + ESC D Delete forward from the cursor to the end of a word. If + between words, this will delete the word to the right of + the cursor. + + ESC # Delete backward from the cursor to the beginning of a + word. If between words, this will delete the word to the + left of the cursor. + +Changing qualities of words: + These commands apply to the word in which the cursor appears, + or the word which IMMEDIATELY preceds the cursor: + + ESC U Convert the word to all UPPERCASE. + + ESC L CONVERT THE WORD TO ALL lowercase. + + ESC C lowercase the word, and then give it + An Initial Capital Letter. + + ESC _ U__n_d_e_r_l_i_n_e the word. + + ESC - De-underline _t_h_e _w_o_r_d. + +Searching for words or groups of words: + + ^XW Word Search. Search forward for the word or sequence of + words in the search string. The search string is ended by + the ESC character. + +------------------------------------------------------------ +============================================================ +Further Sections that should be written: + + Indentation and whitespace commands: + ESC M, ESC I, ^O, ESC ^O, ^X^O, ^M action, ESC \, ESC ^. + Fill prefix, fill mode. ESC Q, ESC ^I + + Text movers: ESC W, ESC ^W, ^XX, ^XG. + Buffersmen: ^XH, ^XI, ^XK. + + 2-window mode, ^X1 ^X2 ^X3 ^XO, ESC ^V. + + Sentences and Paragraphs: + ESC A, ESC E, ESC K, ^X#. ESC [, ESC ], ESC H. + + Keyboard Macros, ^X(, ^X), ^X*, ^XE, ^XQ, save-macro. + + Miscellany: ^U, ^U^U, @, Comout (^X^E), \, ESC ^Y, Regexp + and global searches. Dired, Rmail. accept-msgs. + + Utter random miscellany: ^X^M, ^X^R, ^X^L, ^X^U, ^X ESC. + ESC ^F, ESC ^B. + make-wall-chart. set-screen-size. opt. "Hairy" searches. + + Printing terminal usage. ^XV. +------------------------------------------------------------ +============================================================ + + This document is not finished. It may never be finished, because as fast +as I can describe Emacs, it keeps growing. Please look through emacs.info for +whatever looks like it might interest you. Look through fundamental-mode.info +for any commands that look interesting. Try them and see what they do. +Make use of the builtin help facility, apropos, describe, and ESC ?. +Dprint and look at any of the info segments you think may interest you; there +is a complete list of available info segments +in emacs.info in >doc>subsystem>emacs. + + -Bernard S. Greenberg + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.gi.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.gi.info new file mode 100644 index 0000000..88103aa --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.gi.info @@ -0,0 +1,358 @@ +Multics Emacs -- 04/23/81 + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + Multics Emacs is a display-oriented text-preparation and editing +facility modelled after the EMACS editor of R. Stallman and others on the +MIT AI Lab's PDP-10. + + The pathname of Multics Emacs is >unb>emacs. The normal +arguments to the emacs command are the pathnames of files to be read in and +edited. The command has the added names multics_emacs and e. + + This info segment contains basic information about accessing Multics +Emacs, and the most fundamental information about its use. For a list of +editor commands available in the default environment (Fundamental Mode), see +fundamental-mode.info in this directory. The reader should be aware of the +following documents in >doc>ss>emacs; you should obtain a copy +of fundamental-mode.info if you have not already. Most of these documents are +intended to be printed and read; they are not intended for perusal with the +"help" command: + + emacs.info This info segment. + + fundamental-mode.info The editor commands available in the + default environment. + emacs-tutorial.info A tutorial introduction to using Multics + Emacs (incomplete, but valuable) + pl1-mode.info Documentation of the features for editing + and creating PL/I programs. + lisp-mode.info Documentation of the features for editing + and creating Lisp programs. + fortran-mode.info Documentation of the features for editing + and creating FORTRAN programs. + rmail.info Information on the Emacs mail reading and + sending subsystem. + windows.info A description of the window management + system, and the window and buffer + editor subsystems. + emacs.changes.info A reverse chronological transcript of + missives announcing changes to + Multics Emacs. + emacs.status.info A list of known bugs, deficiencies, and + planned features, and their status. + extensions.info Information for those wishing to write + their own code in the Emacs + environment, including an introduction + to Lisp. + extensions.changes.info Changes to extensions.info. + + ldebug-mode.info Information on the interactive debugging + facility for Lisp code in Emacs. + ctl-writing.info Information on how to write new terminal + support packages to support additional + types of video terminals. + + Mail complaining about bugs, or missing features, should be sent to +emacs.bugs at MIT-Multics or via the standard trouble report mechanism at any +other site. There exist mailing lists for changes, both for all ARPANET sites +and Phoenix System M. If you wish to be put on these mailing lists, or taken +off, please send mail to either of the above addresses. + + Invoking the emacs command places you in an editor buffer named +"main". Text may be typed immediately: it goes directly into the buffer. +The carriage-return key is used to terminate lines. The cursor of a video +terminal, or the print head of a printing terminal, shows the place where +text will next go. The cursor (or print head) corresponds to a point in the +buffer known as "point". "Point" moves around as characters are typed. +Point may be moved explicitly by "editor commands", which are issued by +typing either single "control" characters, or two-character sequences. +Commands exist to move point over words, paragraphs, characters, sentences, +etc., forward and backward one or many times. Commands exist to delete +characters, words, sentences, etc., and to retrieve or rearrange text so +deleted. Various sets of commands are available to deal with various types +of editing tasks: the file fundamental-mode.info tells what commands are +invoked by what keys, and what they do. + + "Control" characters are entered by holding down the key marked +"CTL", "CTRL", "CNTRL", "CONTROL", or the like, and pressing some other key +(say, "N", to get a "Control N") while the "CONTROL" key is being held down; +it is like a "shift" key. In some cases, although not for letters, it may be +necessary to hold the CONTROL and SHIFT keys to get some characters. Control +characters are represented by the circumflex character in all Emacs +documentation: "^N" means a "Control N", i.e., the character generated by +depressing the "N" key while the "CONTROL" key is being held down. Many +Emacs commands are invoked by 2-key sequences whose first key is the "ESCAPE" +key; this key is often marked "ESC", "ALT", or "ALTMODE". It is denoted by +"ESC" or "esc" in the documentation. The "ESC" key generates a character; +it should be depressed and released like any other key. + + In this document, and all the Emacs documentation, "CR" means the +"carriage return" key. "\177" means the "DEL" or "RUBOUT" key. "TAB" means +the "TAB" key; if your terminal does not have a "TAB" key, "Control I" will +do as well. + + There is an automatic documentation feature in Emacs; to find out +what any key does, depress and release the ESC key, and type a question mark +(i.e., type the TWO KEYS in order, ESC and ?). Emacs will then prompt: + + Explain Key: + +Then type the key or key sequence (for instance, a Control N) about which you +wish to find out. Emacs will display (or print) the appropriate +documentation automatically (it may take a little time to find it, however). +When you resume editing, the documentation will be removed from the screen. + + "Point" is considered to be between two characters; it is to the +left of the blinking cursor. Newline characters at the ends of lines count +as one character each, as do tabs, backspaces, and other control characters +in the text (all control characters other than tab and linefeed are displayed +in the usual Multics octal escape format, e.g., \032). + + Emacs will often prompt for information such as search strings, file +names, buffer names, etc., in an area at the bottom of the screen (or on an +indented line on a printing terminal) called the "minibuffer". This is a +little buffer: one can edit it, for example, use the familiar "#" to delete +unwanted characters as a regular buffer. Responses in the minibuffer are +almost always terminated with the Carriage Return key. To get out of a +minibuffer at any time without executing the command, type two Control G's. +The terminal will beep, and the minibuffer command will be aborted. + + Only the most common commands are invocable from one-or-two key +sequences; other commands, known as "Extended commands" must be invoked by +their full name. In order to invoke an extended command, type the two +characters ESC and X: Emacs will propmpt in the minibuffer for the name and +arguments of the extended command. Type them, and a carriage return. To +obtain the documentation for any extended command, use the "describe" +extended command. Type, ESC, X, describe, a space, the name of the extended +command you wish to find out about, and a carriage return. For instance, +type + + ESC X describe speedtype CR + +to learn about the "speedtype" command. + + The "apropos" extended command can be used to find all commands +(and what keys invoke them) that "mention" a particular subject in their +command-names. This can be used to find what command you want when you don't +know what key invokes it. Type ESC X describe apropos CR to find out about +it. + + Many commands can be repeated many times automatically by giving +them a "numeric argument". This is done by typing ESC, the number desired, +and then the basic command. For instance, ^D (Control D) deletes a +character. ESC 3 ^D deletes three characters. Other commands use the +presence or value of a numeric argument to perform alternative actions, or +modify their actions: this is documented in the documentation of the +individual commands. A brief list of commands that accept numeric arguments +appears below. Negative arguments can be supplied by typing a minus sign (-) +after ESC; negative arguments generally cause "backwards action", for instance +going backward by screens instead of forward. + + Single-character commands usually deal with spacing over, or +otherwise manipulating characters or lines. Two-keystroke commands starting +with the ESC key usually deal with words or sentences, often parallelling the +single-character commands (example, Control D is delete a character, ESC D is +delete a word). More uncommon commands start with "prefix" control +characters: for instance, Control X Control F reads in a file. Characters +need not be shifted (upper case) when entered after ESC or a prefix +character. + + Here is a list of very few simple commands. To find out more about +any of them, use ESC ? as described above: + + ^X^F Find, i.e., read in a file. + + ^N Go to the next line. + ^P Go up to the previous line. + + ^A Go to the beginning of the line. + ^E Go to the end of the line. + ^F Go forward a character. + ^B Go backward a character. + + ESC-< (Escape Less-than) Go to the beginning of the buffer. + ESC-> (Escape Greater than) Go to the end of the buffer. + + ^S Search forward. CR ends the search string. + ^D Delete a character. + # Delete last character. + ESC ? Help- find info on a command. + + ^X^C Quit Emacs. + ^X^W Write out buffer to a file. + + There are many, many commands. See fundamental-mode.info. To find +out about all the "search" commands, type ^_ A search CR and so forth. +Typing Control Underscore (^_) gets you into a help facility: ^_? gets it to +describe what it can do. + + ---------------------------------------- + + The following commands repeat with numeric arguments: + + ^B ^C ^D ^F ^N ^O ^P ^Q # ESC-A ESC-B ESC-D ESC-E + ESC-F ESC-# ESC-[ ESC-] + + Also tells ^Y how many back to yank. + Also tells ^K how many lines to kill. + Also tells ESC-Q whether to adjust or not. + Also tells ^XS whether to use string or QEDX-like matching. + Tells ^X2 how big to make top window. + Tells ^XV how many lines to print. + Tells ESC-R how to position the cursor, and ^L the screen. + Tells ^X* whether to display long form, and macros how to + iterate. + Tells ^XD whether to edit the working directory or some other. + Tells ESC-I whether to indent to words on last line, or look up. + + ------------------------------------------------------- + +Here is a brief table of some common cursor motion and deleting commands: +(\177 means the "RUBOUT" or "DEL" key) + + Forward Backward End-of Beginning-of Delete Delete + Forward Backward + +Character ^F ^B ^D \177 or # + +Line ^N ^P ^E ^A ^K + +Word ESC F ESC B ESC F ESC B ESC D ESC \177, ESC # + +Sentence ESC E ESC A ESC E ESC A ESC K ^X \177, ^X# + +Paragraph ESC ] ESC [ ESC ] ESC [ + +Screen ^V ESC V ESC99ESC R + ESC0ESC R + +Buffer ESC > ESC < + ---------------------------------------- + + If you have set your Multics erase, kill, and character-escape +characters to other printing characters than the usual #, @, and \, Emacs +will use them for these purposes. If you use the standard Multics editing +characters, or have non-printing characters as editing characters, Emacs will +use #, @, and \ in their usual sense. + + Emacs attempts to determine the characteristics of your terminal +from the Multics terminal type. If you are logged in via the ARPA network, +Emacs will attempt to negotiate the "Supdup Output" TELNET option to +determine your terminal type. If the Multics type is ASCII, or your User +Host does not support the Supdup Output option, or your Multics terminal is +not of a recognized type, Emacs will ask you the type of terminal you have +with a question of the form: + + What type terminal do you have? + +You may answer "quit" to this response to exit Emacs immediately. + + In addition, three control arguments for setting the terminal type +are recognized by Emacs when given as the FIRST command line argument. These +are: + + emacs -ttp STRING or emacs -terminal_type STRING + tells Emacs that your terminal type is STRING. The value of STRING + may be any recognized editor terminal type or the pathname of a + control file to load. The terminal type given by STRING will be + set permanently. IE: changing your Multics terminal type will not + affect Emacs' memory of this STRING. + + emacs -reset + causes Emacs to forget any characteristics of the terminal set by + the -ttp option. Emacs will once again check the Multics terminal + type as is the normal case. The line speed (if set by -line_speed) + is forgotten as well. + + emacs -query + causes Emacs to immediately ask the user for the terminal type + without checking the Multics terminal type first. The answer you + give may be any STRING accepted by the -ttp option. + + The following control argument may be supplied to indicate to Emacs +your line speed. Although Multics normally supplies this information to Emacs +automatically, network users may find it necessary to use this control +argument to obtain proper padding: + + emacs -line_speed BAUD-RATE + where BAUD-RATE is the output line baud rate in bits per second. + +The -line_speed control argument need only be supplied once per process. If +used, it must be the first control argument given, or may follow -ttp, -query +or -reset immediately. + + Emacs looks for a file called start_up.emacs in the home directory. +It may be full of Lisp forms, or be a compiled Lisp object segment. It will be +loaded (executed) if it exists. Execution of the start_up segment will be +suppressed if emacs is given the -no_startup (-ns) control argument, which must +follow all the terminal type control arguments but precede any pathnames on the +command line (or, of course, be the only control argument). + + After the start_up segment (if any) is executed, the following +control arguments are processed by the "default start up": + + emacs -mc path or emacs -macros path + path is a pathname. Loads path as Lisp, like teco$macro. + + emacs -ap fun arg1 arg2 or emacs -apply fun arg1 arg2 + evaluates (fun 'arg1 'arg2 ... ) + Valuable for constructing abbrevs. + + emacs paths + where paths are not any of the above. Does a find-file (^X^F) on + each path. + + The actions of the default start up may be suppressed by the start_up +segment if the latter sets the list variable +"suppress-default-start-up-execution" to t. + + Emacs accepts META characters from AI TV's, and does TELNET +break/interrupt processing. + + ******************** + + Multics Emacs was designed, implemented, and documented by Bernard +Greenberg. William York has been co-implementor. Gary Palter designed and +implemented the current Multics file interface and "hairy search commands", the +current internal command definition facility (defcom), and has otherwise +contributed very heavily. Richard Lamson designed and implemented the current +message and interrupt facility. Many other people have contributed ideas and +suggestions. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.install.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.install.info new file mode 100644 index 0000000..3475245 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.install.info @@ -0,0 +1,401 @@ +5/12/80 - Site instructions for installing Emacs at your site. + 10.0 Release. + +** This document is not intended for use with the help command. ** +** It is intended for perusal by print, dprint, or an editor. ** + + + +______________________________________________________________________ + + + Multics Emacs is a state-of-the-art text processing and editing system. +A new version is being distributed as part of Release 10.0, as an unbundled +offering. It offers facilities comparable to stand-alone word-processing +systems, combined with the power of the entire Multics environment. + + Multics Emacs is a very large and complex subsystem which requires +special actions and customizations to be effected by site personnel: +this document specifies these actions. + + Multics Emacs is basically a "real-time video editor." This means that +as opposed to interacting with a user on a line-by-line basis, modifying text +in response to "command lines", and printing text on demand, a selected +portion of the text being edited is continuously displayed upon a screen. +The terminal identifies a given location in the text via its cursor. +By typing selected characters, the text at the cursor is modified, deleted, +moved, etc., and the image of the text on the screen is dynamically updated +to reflect these changes as they are made. New text is entered simply +by typing it. There is no need for a "print" request; text is always visible. +There is no need for a "substitute" request; once undesired text is deleted, +new text is simply entered. + + Responding to characters typed at a keyboard in a real-time video +environment requires careful screen maintenance in response to each character +typed _a_s _i_t _i_s _t_y_p_e_d: to simply print a character upon the screen +as it is typed requires intelligent screen maintenance. It is impermissible +to allow the terminal or the front-end processor to echo characters. Thus, +Multics Emacs must respond to _e_v_e_r_y character as it is typed. +The ability to respond to every single character as it is typed is a new one +for Multics; until now, there was no need for it. This feature is provided +by _b_r_e_a_k_a_l_l _m_o_d_e, a feature of the Multics Communications +System (MCS). + + Although every effort has been made to streamline the per-character +loop of Emacs and Multics, including extensive modification to the +mainframe and communications processor software, response to every +character "in real time" is innately much more expensive in CPU and paging +than response to "whole lines". Implementors of real-time video editors +on many systems have all found that these editors are much more expensive +than non-video editors because of this. Yet, various scenarios of +mainframe time availability, video terminal availability, working hours, +and system resource pricing have made the technology of real-time editing +extremely popular in spite of the innate expense. + + It is the responsibility of the site personnel to make the +commitment to allow this software to be used at all at his or her site, +and if that commitment is made, to ascertain at precisely what point, at +what times of day, and on what configurations does, if at all, Emacs usage +become problematic. In two and a half years of experience at the Honeywell +exposure sites, UNRESTRICTED Emacs usage has not ONCE created +a performance problem; nevertheless, a very large number of Emacs +users may have a deleterious effect on system performnace. + + ************************************************** + + Multics Emacs is a developing, experimental offering. It is still +undergoing development. There are known bugs and deficiencies. All known +problems and deficiencies are listed in the file emacs.status.info in the +documentation directory >doc>ss>emacs. In spite of these bugs and problems, +Multics Emacs is eminently usable, quite robust. Multics Emacs has been in +heavy use at the two Multics development sites for three years, and has +acquired a user community of hundreds. + + +Emacs' trouble-reporting mechanism is the same as for all other Multics +Software; the TR system should be used. Please check the known bug list +before generating a trouble report. We intend to maintain reasonable +compatibility in user interface in future releases; the internal interfaces +available to the extension writer, however, are more subject to change. +However, the intent is to fully document all changes. + + + ************************************************** + + + The use of Multics Emacs, and its entire repertoire of command and +function, for the installed version, is documented in Honeywell Manual +CH27, "Emacs Text Editor User's Guide". The writing of user extensions +and terminal support modules (not of interest to anyone except very +advanced users and site maintenance personnel) is documented in Honeywell +Manual CJ52, "Emacs Editor Extension Writer's Guide". + + The unofficial documentation which was the only documentation before +the release of the above-mentioned manuals is distributed in +>doc>ss>emacs, where this info segment lives. Starting there, the segment +emacs.gi.info contains all other online documentation pointers. This +documentation is inteded to be dprinted, and is not suitable for perusal +with the "help" command. This documentation, however, is completely +up to date, and often contains information in more detail, and +differently organized than the published manuals. + + ****************************** + + Multics Emacs was modelled after the EMACS editor at the MIT Artificial +Intelligence Lab. EMACS (on the AI Lab PDP-10's) was written, in TECO, by +staff members of the MIT AI Lab and the (MIT) Laboratory for Computer Science +(LCS), without whose encouragement and support this project would not have +been possible. + + Multics Emacs makes no claims to current or future compatibility with +other implementations of EMACS or any other editor. Although largely +compatible in general philosophy and repertoire with the AI Lab editor, there +are significant differences, both in some specific commands with which we +chose to differ, facilities implemented in one and not the other, and things +that are of necessity different due to the difference in operating systems. +Nevertheless, users familiar with any video editor generally find no problem +whatsoever adapting to another. + + Compatibility with AI Lab EMACS is not a large consideration for the +future. + + Multics Emacs was implemented from scratch at Honeywell with +contributions from some programmers at the MIT Information Processing Center. +No part of any other program on any other system was used, studied, copied, +translated, or otherwise incorporated during the development of Multics Emacs. + + ************************************************** + + Emacs resides in the unbundled library, >system_library_unbundled. +There are four object segments there: + + o bound_multics_emacs_. The basic editor, online + documentation system, command dispatcher, and display + manager. + + o bound_emacs_packages_. Various optional features, including + the modes for editing PL/I and Lisp programs, the directory + and buffer editors, and so on. + + o bound_emacs_rmail_. The Emacs mail system. + + o bound_emacs_preinit_. Code needed at the time Emacs modules + or extensions are compiled or loaded, including the + command definition facility and the default binding tables. + + The source for these segments is kept in the conventionally-named +source archives in the unbundled source library. + + *****IMPORTANT***** + + The terminal-specific knowledge of Emacs is embedded in small Lisp +programs known as "ctls", whose exectuable objects reside in +>unbundled>emacs_ctls. The site is expected to add terminal control +modules to this directory as needed at each site. The names on the +"ctl"s, as well as the names on links in the ctl directory, must reflect +the names (in the TTF) for terminals used at your site. Any terminal +type to be supported by Emacs at your site must have the name +ctl on the appropriate ctl in the ctl directory: As shipped from +Phoenix, the ctl directory and TTF are consistent; you must adjust +the ctl names for local terminal names in use at your site, as well +as supply new ctls for terminals not supportedd in the distributed release. +The primary names of the segments and links will be the only names +reported (stripped of the "ctl" suffix) in response to user query +about what types of terminals are supported at your site. +Instructions on these matters, as well as writing new ctls, +are given in CJ52, as well as online in ctl-writing.info. Source for +the ctls is in emacs_ctls.s.archive in the unbundled source library. +There is a link in >unb>emacs_ctls to >unb>e_pl1_. + + People writing emacs "extensions" (see below) are encouraged to use +the source of Emacs as a model; thus, it ought be retained on line, but +need not be. This is even more true for the terminal control modules. + + + Also in the unbundled directory is: + + o emacs.sv.lisp, the "Saved Lisp Environment" from which Emacs + initializes its Lisp Environment each it is invoked. This + environment is produced by executing the exec_com + make_emacs.ec, which is supplied in + bound_multics_emacs_.s.archive. This exec_com _m_u_s_t be + executed every time the creates and installs + a new version of bound_multics_emacs_ (this is NOT needed + for the released version). The resulting object, + emacs.sv.lisp must then be installed in >unbundled. + The old saved enviroment need not + be renamed, as Emacs only reads it once at startup time, + and does not retain pointers to it. + + The environment must also be "resaved" (i.e., make_emacs.ec + executed) if a new version of the program e_binding_table_ is + installed in >unbundled (other than the released). + This program defines the default key bindings. + It is in bound_emacs_preinit_. + + Failure to re-save the environment when either bound_multics_emacs_ + or e_binding_table_ is changed will result in users getting + the message "Error lisp_linkage_error by .... The version of + is not the same one as was loaded into this + environment." Users will receive this error whenever Emacs + is re-invoked in a process after a new version has been installed. + Users should be advised to new_proc if they receive this message + if dynamic installation of Emacs at your site is a possibility. + The environment _m_u_s_t be resaved if any of these programs are + changed; new_proc will not alleviate the problem. A copy of + the exec_com also exists in bound_multics_emacs_.s.archive. + + o e-macros.incl, an object program. This program is the + compiled version of the include file, e-macros.incl.lisp. + Having this object program, which can be generated by + directly compiling the include file, makes use of the + include file (which uses this compiled version if + locatable) much more efficient. + + ***************************** + **********IMPORTANT********** + ***************************** + + There are several site-specific objects that Emacs expects to find. +These segments used to reside in a directory >sc1>emacs_dir; this +is no longer necessary. The following are the segments. + + o emacs_info_vfile_, an indexed sequential vfile used by the online + documentation system to store command descriptions in encoded form. + This MSF vfile resides in >unbundled. Make sure that + users have s on the MSF dir and r on the components. Experts + familiar with the online documentation system can change + or augment online command documentation without installations + if they have rw to this MSF, thus, it is site modifiable. + + o A segment, metering.acs, access to which controls logging of + Emacs usage (see the section below). (Site optional). + + +There should exist a link in >unb>include, or wherever your site chooses to +put the include file e-define-command.lisp, to e_define_command_ in the +executable directory. This is needed in order for the two include files, +e-macros.incl.lisp and e-define-command.incl.lisp, to find the program +e_define_command_ at the time these include files are used at extension +compile time. There must also be a link from wherever the include file +e-macros.incl.lisp is kept to the segment e-macros.incl in the executable +directory. + + ************************************************** + + The table rmail-full-name-table, which used to reside in >sc1>emacs_dir, +is no longer necessary, as its functionallity has been subsumed by the +my-personal-name Emacs variable. + + ************************************************** + + A well-debugged version of the Multics MacLisp subsystem is being +shipped in >unbundled in Release 10.0, specifically for the support of +Multics Emacs. Honeywell is neither supporting nor documenting Multics +MacLisp in Release 10.0 as other than part of the support of Multics Emacs. + + + Multics MacLisp was developed at the Massachusetts Institute of +Technology, under government funding. Documentation is available from +the MIT Information Processing Center. Honeywell currently supports Multics +MacLisp only to the degree required to keep Honeywell-supplied subsystems +implemented in it operative. + + There is an introduction to the language Lisp, in which Multics Emacs +is coded (and "extended") in the file "extensions.info" in the Emacs +documentation directory, as well as in CJ52. This introduction is felt to +be adequate for those wishing to write their own Emacs "extensions" (see +below), and was written with that in mind. It is not, however, a general +introduction to the subject, or adequate to fully understand the source +code of the deep levels of the Emacs editor. + + The Multics MacLisp subsystem in the unbundled library is complete and +fully operative. It is the most advanced version of Multics MacLisp. The +principal user interfaces are: + + o lisp, the interpreter + + o lcp, lisp_compiler, which can compile source segments named + .lisp into object segments loadable by the interpreter + + o lap, the Lisp-oriented Multics assembler. + + o display_lisp_object_segment, a tool. + + Honeywell will fix bugs in Lisp that affect Emacs, as shipped in Release +10.0. We make no statement about any level of future support or documentation, +or continued support even at this level of Multics MacLisp. + + ************************************************** + + Although Multics Emacs is easily used by personnel with no technical +training or programming experience, those with some programming experience +can utilize it even more effectively via "extensions". Extensions are +fragments of Lisp code, not part of the deep level of the editor, which +imbed knowledge of given problem domains, without knowledge of the internal +data structure of the editor, or even more to the point, of display management, +at all. Examples of supplied extensions are the various language modes +and the Emacs mail subsystem. + + Via extension writing, a given shop can create Emacs environments for +selected (or all) users with locally defined functionality, such as document +formats, special languages, and other text processing considerations, +available on keystrokes to the Emacs user. Similarly, a user who is not +completely satisfied with the way some Emacs command behaves is encouraged to +look at the source and add his or her own version to his environment. + + It is a major design feature of Multics Emacs that extension, the +development of prepared functionality, is performed in a very powerful, +concise, and clean language, namely Lisp extended by appropriate "Lisp +Macros". This design differs from that of conventional editors, which use the +same language that they present as a user interface for writing "macros". By +necessity, those languages are always compromised in both directions, +conciseness for interactive editing, and the diversity of a programming +language for "macro writers". Emacs does not suffer this deficiency. + + CJ52, "Emacs Extension Writer's Guide," includes a complete explanation +from the ground up of all knowledge about Lisp necessary to write extensions, +including how to debug them interactively within Emacs, and take full +advantage of Lisp mode. extensions.info, in >doc>ss>emacs, is much of the +same material, but is less complete, less up to date, and less accurate. + + We strongly recommend that some programmer at your site look into +these documents, just to see the type of thing that can be done. Tailored +Emacs environments provide a way to use all the text processing and display +management power of Emacs to best suit your data processing needs. It is +our experience that programmers with no background in Lisp at all have +been able to write extensions proficiently in one day; even non-technical +personnel have successfully written extensions. You will find that +writing "Emacs extensions in Lisp" means very little more than saying +what you want done in English with a pair of parentheses around each line. + + + ************************************************** + + An audit trail mechanism exists with Emacs to monitor the usage and +resources consumed by Emacs users. By default, it is not enabled. To enable +it, the site should create the segment >unbundled>metering.acs, zero max +length, giving rw access to *.* or all persons/prjects to be audited. The +site must then modify the segment emacs_data_.cds, which can be found in +bound_multics_emacs_.s.archive, changing the value of "text_data.log_dir" to +the pathname of a directory. The site must create this directory, put a +terminal quota on it, and give all users (or *.*) being audited sma to this +directory. An IACL of rw *.* should be put on this directory. Watching rate +of growth of logs in this directory, and cleaning it out, is the site's +responsibility. If not cleaned, record quota overflows will prevent people +from using Emacs. This facility is not "secure", and is intended for +performance monitoring purposes. + + Users will create log segments automatically in this directory, +which can be displayed with the print_log tools. Entries are of the +three forms: + + 98 1426.0 0 Jones.SYSTEMS.a: Entering emacs on VIP7801 none a.l111 + 101 1427.1 0 Jones.SYSTEMS.a: (VIP7801) in 11, r0/r4 echo 0/3, out 927. + 101 1427.1 0 Jones.SYSTEMS.a: 1.0 min, v/cpu 1/5 mem 67 paging 1029/1218 + +The first message, at entry time, gives the user ID, the user's terminal type +as specified to MCS, the user's answer-back, and the line over which the user +is logged in. The second two messages occur at the time that the user leaves +Emacs. The first message gives the user name, the terminal type as finally +negotiated with Emacs, the number of input characters, the number of +characters echoed by the supervisor via echo negotiation, the number of +characters echoed by Emacs that would have been echoed by the supervisor were +the system faster than the user's typing, and the number of output characters. +The second message gives, in addition to the user ID, the elapsed real time in +Emacs, virtual and real CPU consumption, memory units (in thousands), and +paging device and all page faults. + +(END) + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.status.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.status.info new file mode 100644 index 0000000..299935b --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.status.info @@ -0,0 +1,252 @@ +04/23/81 - List of known bugs and deficiencies in Multics Emacs. +See the end of the file for explanations of categories and markings. + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + +Bugs: + # Date Sev Difficulty Description + | | +05/79: +049*79.05.29 7 3 F: ESC-E, ESC-] can hang at end of buffer. + +04/79: +048*79.04.03 6 2 F: ESC-Y not after ^Y irretrievably wipes text. + + +03/79: +047*79.03.23 9 8 T: Bad echo negotiation bugs exist. +046 79.03.18 3 6 M: No forwarding facility. +045 79.03.17 3 3 D: Fortran mode doc still not in vfile. +044*79.03.03 3 5 F: Lisp errors not caught/minibuffered. + + +02/79: +043*79.02.08 6 3 R: ^V and ESC-V ought beep at buffer limits. +042*79.02.08 7 4 M: Too many d's make RMAIL fault. (can't duplicate) +041*79.02.07 8 7 R: set-screen-size can leave bad lines on screen. +040 79.02.06 6 9 R: ESC-< ^V redisp opt. causes obscure results. +039*79.02.06 7 7 M: Messages swallowed by emacs if QUIT hit (accept-msgs). +038*79.02.06 7 4 M: Mail not deallocated if rmail not quit cleanly. +037 79.02.06 6 3 F: runoff-fill-region is mark-position-sensitive. +036*79.02.06 4 2 F: "Modified" is issued for empty buffers. + + +01/79: +035 79.01.29 4 4 PL1: Subscripted labels sometimes indent badly. +034 79.01.22 4 7 D: I/O attachment of info vfile left attached. +033*79.01.22 5 5 M: Reply-to is not supported. +032*79.01.22 2 7 F: Knight-TV meta numbers don't work. +031*79.01.21 9 1 M: text of messages gets pushed on kill-ring. +030*79.01.21 9 1 D: documentation pushed on kill-ring before display. +029*79.01.17 9 9 F: fundamental-mode ex. comm. doesn't revert bindings well. +028 79.01.12 5 3 T: Inverse video fields not cleared on VIP7800. + + +12/78: +027*78.12.27 6 1 M: ^X^S moves cursor. +026*78.12.27 9 1 D: ^X2, ^X3, ^XF documentation is obsolete. +025*78.12.15 8 7 R: If last line in top window is overlength, it is + mis-displayed when two-window mode exited. + + +11/78: +024*78.11.21 2 1 F: ESC-^Y doesn't set the mark. +023*78.11.09 4 2 F: "Search fails." message overwrites search string. +022 78.11.08 4 6 L: Unbalanced constructs leave cursor in random places. + + +10/78: +021 78.10.27 5 6 CI: "emacs -mc a b" reads file b, etc. +020*78.10.20 3 5 F: Negative arguments are not supported. +019 78.10.06 4 8 R: Initial redisplay done even if input pending. +018*78.10.04 7 9 R: idel-chars not used in overlength lines. + + +09/78: +017*78.09.25 9 9 F: ^Q does not work in macros. +016 78.09.22 5 8 F: ^X^O deletes formfeeds. +015*78.09.22 3 10 R: ESC-99 ESC-R moves screen if last line too long. +014*78.09.15 8 8 R: minibuffer prompts are editable, should not be. +013 78.09.13 6 5 F: speedtype abbrevs > 4 chars fail. +012*78.09.12 6 5 PL1: private auto-dcl files exist, should be merged. +011 78.09.12 6 10 PL1: auto-dcl does not use the search facility. +010*78.09.05 9 5 F: comout does not trap Multics errors properly. +009 78.09.05 7 4 F: ^G beeps before all redisplays are done. +008*78.09.05 8 4 L: Local displays sometimes damage two-window mode. +007 78.09.01 5 4 R: Deleting end of buffer leaves screen blank. + + +08/78: +006*78.08.29 3 1 CI: Unread input is saved across emacs invocations.NOT SO. +005 78.08.28 9 5 PL1: Tab and semicolon in quoted strings leaves the + cursor in a random place. +004 78.08.28 1 3 R: Trailing whitespace (ac tb) gets printed. +003 78.08.28 4 3 F: De-underlining consecutive underlined words loses. +002*78.08.25 2 4 R: Random whitespace is sometimes printed in mid-line. +001*78.08.23 5 1 CI: emacs does not recognize some TTT tty names. + + +Suggestions: + +030 79.05.29 3 4 F: Deconfuse loadlib/loadfile, use search rules, etc. +029*79.03.31 3 2 F: "new-line" should not eat last blank line. +028*79.03.03 3 5 F: End all prompts with CR, no more ESC. + + +02/79: +027*79.02.06 8 8 R: ^V/ESC-V with arguments to repeat redisplay-free. +026 79.02.06 8 10 F: Fill paragraph by paragraph (etc.) text. +025 79.02.06 4 8 F: Recursive editors in ^XQ/hairy searches, etc. + + +01/79: +024*79.01.26 4 5 F: Query-replace command, builtin (not macro). +023 79.01.18 5 3 F: Explicit kill-ring-pop, or yank-and-pop command. +022 79.01.18 8 4 F: An insert-other-buffer-here command. +021*79.01.18 9 1 D: ESC-X help ought do something useful. +020 79.01.17 3 1 PL1: electric colon should not electrify in mid-program. + (should check for next line end/empty) +019*79.01.05 9 1 D: apropos should diagnose or accept multiple args. +018 79.01.03 9 1 R: set-screen-size ought default full for no arg. + + +12/78: +017*78.12.27 6 9 F: ^C of a ^S or ^R (etc.) should re-search same string. +016 78.12.27 7 9 F: Comout should deal with commands that ro/co internally. +015*78.12.26 8 10 M: Rmail save/log requests. +014*78.12.26 8 9 M: Rmail to read other-than-your-own mailboxes. +013*78.12.26 7 9 M: Rmail should reply to recipients. + + +11/78: +012 78.11.28 3 10 M: Handle memos and progress as emacs interrupts. +011 78.11.28 2 10 F: Expand active functions in file-name prompts. +010 78.11.28 3 9 F: Expand abbrevs in file-name prompts. +009*78.11.09 4 2 F: Leave search string visible when search fails. + + +10/78: +008*78.10.06 3 3 F: ^@ should respond visibly. + + +08/78: +007 78.08.30 3 4 F: Substitute globally times, n given. +006 78.08.25 2 1 F: Comout that uses different strategies for different + amounts of output (LEJ has such). +005 78.08.23 2 2 R: ^XV should "integrate" output with following redisp. +004 78.08.22 1 5 R: Visible "End of Buffer" marker on screen. +003 78.08.22 4 5 R: ^XV that prints .-n,.+n (before and after cursor). +002 78.08.22 1 2 F: Global substitute command showing changed lines. +001 78.08.22 2 2 R: ^XV should delimit its printed output with "---". + + +Major Projects: + +012 79.02.06 5 20 F: COBOL mode. Problem is nobody knows what it + should do. +011 79.02.05 5 30 F: Have a "tags" (multi-language label-cataloguing) + package. No particular problem, just work. +010 79.01.02 6 30 F: Have a completing reader. Problem is large amount + of engineering and implementation work, and prerequisite + of MP 009. +009 79.01.02 8 20 F: Organized cataloguing and argument checking on + extended commands. Problem is design. +008 78.12.19 7 35 R: Support underlining on "field-type" video TTY's. + Same problems as Major Project 007. + +007 78.12.19 8 28 R: Support overstriking on printing, TV, and other + ^H-recognizing terminals. Problem is overhaul of + redisplay data and control structure, specif. detabbify. +006 78.11.28 9 50 F: Keep buffers in non-PDIR place, optionally, for + safety". Problem is Lisp representation of buffers. +005 78.09.21 9 25 F: Start_up files in some non-Lisp ASCII format. Problem + is designing and implementing a robust reader/evaluator + that gives credible diagnostics. +004 78.09.21 8 20 F: Redesign/reimplement option mechanism. Problems are + lack of info on options in autoload files not yet loaded, + and concomitant lack of error checking. + +003 78.09.13 6 15 F: Speedtype improvements. Problem is lack of save/edit + ability, bugs in hashing algorithm, integration with native + Multics Speedtype. +002 78.08.30 8 25 R: Synchronize with or abort output. Problem is too much + typeout, waiting for unwanted redisplays. Difficulties + are needed MCS features, and inconsistent partial screens. +001 78.08.23 8 30 R: Substantially improve printing terminal redisplay. + Largest problems are middle-of-line edits, asynchrony + in deciding what to print, too much typeout. + + +Other tasks: +001*79.02.06 8 9 CI: Install new Lisp; update macros to use unwind-protect. + Problems are paperwork, exposure. +002 79.02.06 10 30 D: Finish user documentation (emacs_tutorial.info). +003*79.02.06 4 2 Update Emacs on CISL, incl. vfile. +004*79.02.06 2 5 Support ADDS980 terminal in Arizona. +005*79.02.06 9 2 Upgrade to MCS echo negotiation. (Yet to debug new + interrupt synchronization under mcs_echo_neg as well). + + +Explanations of categories and markings: + +* indicates that the bug has been fixed. +Bug categories are: F - fundamental emacs; CI - command interface; +R - redisplay; PL1 - PL/1 mode; L - Lisp mode; M - Mail/message subsystems; +D - Documentation/auto-doc; T - terminal/network support. + + +Definitions: + +A "bug" is a user-visible deficiency causing unexpected results, loss of +display or data, or useless output or display, or action at variance with the +documentation. Severity and estimated difficulty are rated on a scale of 1 to +10. 10 is the most urgent and hardest. + +A suggestion is a suggested design augmentation or modification that is open +to debate about relative merit; it is not a bug fix. Suggestions do not +include missing isolatable sub-subsystems. Suggestions requiring major +redesign or new implementation are listed under "Major projects", and do not +qualify as suggestions. + +A major project is a design/implementation enhancement involving substantial +redesign and reimplementation, or the implementation of an entirely new +subsystem within Emacs. + +(END) + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.wall-chart.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.wall-chart.info new file mode 100644 index 0000000..994792a --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/emacs.wall-chart.info @@ -0,0 +1,87 @@ + Multics Emacs Wall Chart (Fundamental mode) 12/8/81 + + + +# rubout-char ^XO select-other-window esc-ESC eval-lisp-line +@ kill-to-beginning-of-line ^XQ macro-query esc-F forward-word +CR new-line ^XR rmail esc-G go-to-line-number +ESC escape ^XS global-print esc-H mark-paragraph +\ escape-char ^XV view-lines esc-I tab-to-previous-columns +\177 rubout-char ^XW multi-word-search esc-K kill-to-end-of-sentence +^@ set-or-pop-the-mark ^XX put-variable esc-L lower-case-word +^A go-to-beginning-of-line ^X\177 kill-backward-sentence esc-M skip-over-indentation +^B backward-char ^X^B list-buffers esc-N down-comment-line +^C re-execute-command ^X^C quit-the-editor esc-P prev-comment-line +^D delete-char ^X^E comout-command esc-Q runoff-fill-paragraph +^E go-to-end-of-line ^X^F find-file esc-R move-to-screen-edge +^F forward-char ^X^G ignore-prefix esc-S center-line +^G command-prompt-abort ^X^I indent-rigidly esc-SPACE complete-command +^J noop ^X^L lower-case-region esc-T twiddle-words +^K kill-lines ^X^O delete-blank-lines esc-U upper-case-word +^L redisplay-command ^X^R read-file esc-V prev-screen +^N next-line-command ^X^S save-same-file esc-W copy-region +^O open-space ^X^T toggle-redisplay esc-X extended-command +^P prev-line-command ^X^U upper-case-region esc-Y wipe-this-and-yank-previous +^Q quote-char ^X^W write-file esc-[ beginning-of-paragraph +^R reverse-string-search ^X^X exchange-point-and-mark esc-\ delete-white-sides +^S string-search ^X_ underline-region esc-\177 rubout-word +^T twiddle-chars ^Y yank esc-] end-of-paragraph +^U multiplier ^Z; kill-comment esc-^ delete-line-indentation +^V next-screen ^ZF object-mode-find-file esc-^B balance-parens-backward +^W wipe-region ^ZG go-to-named-mark esc-^F balance-parens-forward +^X# kill-backward-sentence ^Z^@ set-named-mark esc-^G ignore-prefix +^X( begin-macro-collection ^Z^B edit-buffers esc-^I indent-to-fill-prefix +^X) end-macro-collection ^Z^F get-filename esc-^O split-line +^X* show-last-or-current-macro ^Z^G ignore-prefix esc-^V page-other-window +^X. set-fill-prefix ^Z^L redisplay-this-line esc-^W merge-last-kills-with-next +^X0 remove-window ^Z^V scroll-current-window esc-^Y yank-minibuf +^X1 expand-window-to-whole-screen ^Z^W edit-windows esc-_ underline-word +^X2 create-new-window-and-go-there ^Z^Z signalquit esc-~ unmodify-buffer +^X3 create-new-window-and-stay-here ^Z_ remove-underlining-from-word +^X4 select-another-window ^_ help-on-tap +^X; set-comment-column esc-# rubout-word +^X= linecounter esc-% query-replace +^XB select-buffer esc-/ regexp-search-command +^XCR eval-multics-command-line esc-; indent-for-comment +^XD edit-dir esc-< go-to-beginning-of-buffer +^XE execute-last-editor-macro esc-> go-to-end-of-buffer +^XESC escape-dont-exit-minibuf esc-? describe-key +^XF set-fill-column esc-A backward-sentence +^XG get-variable esc-B backward-word +^XH mark-whole-buffer esc-C capitalize-initial-word +^XI insert-file esc-CR cret-and-indent-relative +^XK kill-buffer esc-D delete-word +^XM send-mail esc-E forward-sentence + + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/extensions.changes.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/extensions.changes.info new file mode 100644 index 0000000..214410e --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/extensions.changes.info @@ -0,0 +1,49 @@ +Information for Emacs extension writers- changes to extensions.info. + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + +10/08/78 +New function for extension writers: + + map-over-emacs-buffers FUNCTION ENV + Executes FUNCTION once for each buffer defined in this editor + invocation. FUNCTION is supplied two arguments. The first + is the symbol which is the name of the buffer, and the second + is ENV. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/extensions.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/extensions.info new file mode 100644 index 0000000..d4df362 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/extensions.info @@ -0,0 +1,3077 @@ +11/10/79 - Emacs extensions + +(Updates to this document are kept in + >exl>emacs_dir>info>extensions.changes.info) + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + An editor _e_x_t_e_n_s_i_o_n is a user-provided capability, added to the +editor which augments its power and repertoire. It is different from a +macro, which is simply a collection of editor commands gathered up and +(perhaps) given a name. Extensions are _p_r_o_g_r_a_m_s; in Multics Emacs, +they are written in the language of the Multics Emacs environment. One good +definition of an extension is a body of code which augments the editor's +capability, but does not need to know how data in the editor is stored or +manipulated. In this sense, all of the word, sentence, paragraph, +Lisp-list commands, and the various "modes" (e.g., PL/I mode) are extensions. + + The person who wishes to add to his Multics Emacs environment any +powerful or sophisticated capability must learn to write extensions. The +keyboard macro facility (^X(, ^X)), is not intended for such usage. In this +document we explain how to write extensions. + + One of the guiding design principles in the Multics Emacs editor was +that the creations of editor extensions, either by the editor implementors or +end users, should be in a programming language of established elegance and +power. This primer will give you a starting point for writing Lisp code to +run as editor extensions in the Multics Emacs environment. If you have some +knowledge of Lisp already, it will be of value. However, I shall assume that +the reader has no familiarity with Lisp, but perhaps with PL/I or BASIC. + + I will assume that the reader _i_s quite familiar with Multics Emacs as +far as having used it, and acquired some proficiency and familiarity with its +general usage and visible organization. + + + + An Introduction to Lisp for People Who Don't Want + To Have to Know Lisp to Write Emacs extensions. + ----------------------------------------------- + + Lisp programs are built of _f_u_n_c_t_i_o_n_s, which are vaguely like procedures +or subroutines in other languages, although more akin to PL/I and ALGOL +functions. We write a Lisp program by creating a file full of function +_d_e_f_i_n_i_t_i_o_n_s. A function definition specifies the name of a function, and +what it does. Here is a sample function definition: + +(defun addandmult (a b c) ;Here is a comment + (* (- a b) + (+ a b c))) + +This says, "Here is a function named addandmult. It takes three arguments, +which, as parameters, we will call a, b, and c. Compute the result of +multiplying the difference of a and b by the sum of a, b, and c. Return that +number as a _r_e_s_u_l_t, or _v_a_l_u_e. + + Here is another function definition: + +(defun squareprint (arg) + (print "The square of") + (print arg) + (print "is") + (print (* arg arg)) + 5) + + This function, when invoked, will print the message "The square of", +print the value of its argument, print the word "is", and print the value of +the square of its argument. It _r_e_t_u_r_n_s the value 5. The function +"squareprint" has side effects: it causes output on the console. It also +returns a value, the number 5. Note that all Lisp functions produce a value; +only some produce side effects. The first function we defined returns the +product of those numbers as a value; the second returns 5. + + If we look at squareprint, we see that it almost consists of +"statements", the "print statements" that print things. These statements +are called _f_o_r_m_s, and what they are in fact are calls to _o_t_h_e_r functions, in +this case the built-in _p_r_i_n_t function. In the form + + (print "The square of") + +the print function is being passed as an argument the string "The square of". +Like all functions, _p_r_i_n_t will return a value, in +this case, something which we will not use. The side-effect of +printing something will occur. In the form + + (+ a b c) + +we are asking to invoke the "+" function, which is also built-in, passing it +as arguments the values of the parameter-variables a, b, and c. It will +return a value, which is the requested sum, and produce no side effects. + + There are five forms in the function-definition for _s_q_u_a_r_e_p_r_i_n_t: + + (print "The square of") + (print arg) + (print "is") + (print (* arg arg)) + 5 + + Forms immediately inside a function definition are executed +sequentially, like statements in other programming languages. The value +produced by the last form is the one the function itself returns. What does +it mean to "execute" a 5? "Execute" is not exactly the right term, that is +where the problem lies. What really happens is that these forms are +_e_v_a_l_u_a_t_e_d. This means that a value is produced from them. Evaluating a 5 +produces the number 5; evaluating the form + + (+ a b c) + +calls the "+" function with the appropriate arguments, and produces whatever +value the "+" function returns. The value produced by the "print" function +is something which is not interesting, but a value is produced. + + Numbers, like 5, and strings, like "The square of" are said to evaluate +to themselves. Things between parentheses, like + + (+ a b c) + (print "The square of") + +are calls to functions, which are evaluated by calling the function +indicated, and producing the value it returns. Function calls have the syntax + + (FUNCTIONNAME ARGFORM1 ARGFORM2 ARGFORM3 ... ARGFORMn) + +FUNCTIONNAME is the name of the function to call; the ARGFORMs are themselves +forms, which will be evaluated to produce the arguments to give to the +function. Thus, we see that to evaluate (i.e., "execute" and find the value +returned by so executing) a form like + + (+ (* a b) + 15 + c) + + We evaluate the _i_n_n_e_r _f_o_r_m (* a b) to produce a value, + We evaluate the 15 to produce 15 (remember, numbers and strings evaluate + to themselves) + We evaluate the _v_a_r_i_a_b_l_e c to produce its value, + + And pass these three values on to the "+" function, and return what + it returns. + + Thus, forms are seen to be either numbers like 5, strings like "is", +variables like b, or function calls like (* a b). + + Variables are much like variables in other languages. A variable has a +value, which is called its _b_i_n_d_i_n_g. At this stage of the exposition, this +value must be a string or a number. When a function is invoked, the +parameter variables (like a, b, and c above) of the function acquire the +arguments of the function call as bindings. Evaluating a variable produces +its binding as a value. For instance, if someplace in a function we cause +the form + + (addandmult 2 (+ 3 2) 6) + +to be evaluated, a, b, and c will have the bindings 2, 5, and 6 while +the forms in the definition of _a_d_d_a_n_d_m_u_l_t are being evaluated. This is not +unlike the subroutine parameter mechanism in other languages. It is very +different insofar that it specifies what _v_a_l_u_e a variable has during +"subroutine" execution. In PL/I or FORTRAN, a parameter is associated with +a variable in the calling program, not a value, during subroutine execution. + + There are parameter variables, as we have used above, temporary +variables, which we will meet below, and global variables. Regardless of +what "kind" of variable we are dealing with, they all have bindings (values), +and evaluation of the variable produces that value. + + Summarizing our naive introduction to dataless Lisp: + + 1. Lisp programs are built of functions. + + 2. Function definitions consist of the word "defun", the + function's name, a "parameter list", and a number of forms, which + are to be sequentially evaluated at function call time, with + a pair or parentheses around the whole thing. + + 3. The value of the last form in a function will be the value returned + by that function. + + 4. Forms can be either strings, numbers, variables or calls on functions. + Forms are _e_v_a_l_u_a_t_e_d to produce values, + which are passed around between functions as arguments and results. + + 5. Strings and numbers evaluate to themselves. + + 6. Variables evaluate to the datum to which they are bound, which, + for a parameter, is the corresponding argument to the containing + function. + + 7. Function calls contain the name of a function to call and + forms which are evaluated to produce the arguments to the + function. Function calls may produce side-effects. Like any form, + when a function call is evaluated, it produces a value. + + + + + P__r_e_d_i_c_a_t_e_s + + Programming languages need conditional execution. In order to control +conditional execution, we need things upon which to base a decision. There +are two data objects in the Lisp world corresponding to truth and falsity, +for the purposes of parts of the Lisp system that deal with conditions. +There are a set of functions called _p_r_e_d_i_c_a_t_e_s which return these objects as +values. For instance, there is a function called ">" which, invoked as + + (> 4 6) + +will return the indicator of falsity, and when invoked as + + (> 4 1) + +will return the indicator of truth. Predicates work just like other +built-in and non built-in functions, like print, addandmult, squareprint, +and +. They take arguments, and produce a result. In the case of +predicates, however, the result is not a string or a number, but +an indication of truth or falsity. The result of a predicate can be used +by the "_i_f special form" to control the execution of a function, and we +will consider _i_f shortly. + + Here are some of the most useful Lisp predicates. In all of these +examples, A1, A2, S1, O1, etc., stand for _f_o_r_m_s, which means they +can be 12, (+ 6 q), (myfun 33 (- a b)), etc. When we say below that +"A1 is a number" below, what re really are trying to say is that A1 +is some form which _e_v_a_l_u_a_t_e_s to a number, such as 3, (+ 6 2), +or x49, if x49's value is indeed a number. + + Predicates for numbers: A1 and A2 are numbers: + + Predicate Example Returns TRUTH if ..., otherwise falsity. + _________ _______ ________________________________________ + + = (= A1 A2) A1 and A2 are the same number. + > (> A1 A2) A1 is a bigger number than A2. + < (< A1 A2) A1 is a smaller number than A2. + + Predicates for strings: S1 and S2 are strings: + + samepnamep + (samepnamep S1 S2) S1 and S2 are strings of identical + content, i.e., the "same string". This is + the standard way to see if two strings are + the same, as in (samepnamep test "-hold") + alphalessp + (alphalessp S1 S2) S1 collates before S2 alphabetically, e.g., + (alphalessp "Able" "Baker") returns truth, but + (alphalessp "Zeke" "Joe") does not. + + Predicate for symbols (including character objects), which we will + learn more about later: SY1 and SY2 are symbols. + + eq (eq SY1 SY2) SY1 and SY2 are the same symbol. + + Predicates for any objects: O1 is some object, of perhaps unknown type: + + fixp (fixp O1) O1 is a number, as opposed to some other kind + of object. + stringp (stringp O1) O1 is a string, as opposed to anything else. + symbolp (symbolp O1) O1 is a symbol, as opposed to anything else. + null (null O1) O1 is not only a symbol, but the very important + and critical symbol named "nil". + + Lisp Special Forms + ------------------------- + + Now there are a number of _s_p_e_c_i_a_l _f_o_r_m_s in Lisp, which do not go by the +simple rules given above. We have already seen one. The function-defining +form, which begins with the word "defun", is not simply a function call with +forms to produce the function's arguments. By all rights, a form like + + (defun square (x) + (* x x)) + +should, when evaluated, evaluate, in order, to produce arguments for "defun", + + 1. A variable named "square". + 2. The form "(x)", calling a function named "x" with no arguments. + 3. The form "(* x x)", multiplying the value of a variable named "x" + by itself, + +and then pass these three values onto the "defun" function. This, however +is not actually what happens. Evaluating the "defun" form causes a function +named "square" to be defined, whose parameter list and "body" are as given. +Defun is a _s_p_e_c_i_a_l _f_o_r_m, and when Lisp sees "defun" as the function-name in a +form it has been asked to evaluate, it says "Stop everything, I'm going to +do something special with this, in this case, define a _f_u_n_c_t_i_o_n built out of +this _f_o_r_m _i_t_s_e_l_f." It is _n_o_t a call to "defun" with arguments. Although +this may seem kludgey at first, it can be shown that one must have at least +one such special form in order to have an operative Lisp system of any kind. + + There is a special form in the Multics Emacs Lisp environment called _i_f, +which is used to control conditional execution (conditional evaluation). +Here is an example of its use: + +(defun which-is-greater (first second) + (if (> first second) + (print "The first one is the greater.") + else + (if (> second first) + (print "The second one is greater") + else + (print "They are equal"))) + +The syntax of _i_f is as follows: + + (if + + + ... + + else + + + ... + ) + + Any number, including none, "THEN-FORM"s may be supplied. Similarly, +any number, including none, of the "ELSE-FORM"s may be given. If there are +no "ELSE-FORM"s, then the keyword "else" may be omitted, too. + + Note that all the forms in the _i_f are _n_o_t sequentially evaluated; the +word _e_l_s_e is not even intended to be a form. If all of the forms inside the +_i_f were evaluated, it would be useless, for execution (evaluation) would not +be conditional. That is why _i_f is a special form; there are special rules +about how forms inside it are to be evaluated. The rule for all non-special +forms is the same: you evaluate all the sub-forms sequentially to produce the +arguments to the function. + + The _i_f special form evaluates the : if it results in truth, +the s are sequentially evaluated, and the value of the last one is +returned as the value of the _i_f. Otherwise, the s are evaluated +sequentially, and the value of the last returned. If there are none, +something useless is returned (nil, to those knowledgeable in Lisp). + + There are two global variables in Lisp, called "t" and "nil", whose +bindings are always the truth and falsity indicators respectively. Thus, + + (if t + (print "Truth") + else + (print "Not so truth")) + +when evaluated, will always print "Truth". + + There is a way to change the value of a variable. The only way we have +seen so far that variables acquire values is by being parameters, and +acquiring values at function call time. Values can be changed by the special +form _s_e_t_q: + +(defun adder-of-one () + (print "The value of x is") + (print x) + ("And the value of x plus one is") + (setq x (+ x 1)) + (print x)) + +A _s_e_t_q form has the word _s_e_t_q, the name of a variable, and an inside form. +The inside form is evaluated, and that value assigned to the variable. It is +like an assignment statement in other languages. + + There is a construct for looping in the Multics Emacs Lisp environment. +It, too, is a special form. It is called "do-forever": + +(do-forever + (print "Yay Multics") + (print "scitluM yaY")) + +will, when evaluated, print these two sayings forever. The way you stop +doing in a do-forever is to evaluate the form "(stop-doing)": + +(defun print-n-times (n) + (do-forever + (if (= n 0)(stop-doing)) + (print "foo") + (setq n (- n 1)))) + +This function, given a number as an argument, will print "foo" that many +times. The "=" builtin function/predicate compares its two arguments, which +must be numbers, and returns truth or falsity depending on whether or not they +are numerically equal. Note that the arguments to "=" are _n_o_t n and 0, but +rather, the number which is the binding of n and 0. The number which is the +binding of n is different each time around the loop; that is the point of the +program. It is _s_e_t_q which changes the value of n each time around, as +do-forever executes the loop. A "do-forever" form generally returns something +useless (nil), unless you exit by saying (return 5) or (return nil), or +(return a), in which latter case the value of the variable a is returned. + + One can acquire temporary variables via the special form "let": + +(defun sumtimesdif (x y) + (let ((sum (+ x y)) + (dif (- x y))) + (print "Sum times difference is ") + (print (* sum dif)) + (print "Sum squared is") + (print (* sum sum)))) + +This function has two temporary variables, sum and dif, which are +initialized to the values of (+ x y) and (- x y). The general syntax of +"let" is: + + (let ((VAR1 VAL1) + (VAR2 VAL2) + ........... + (VARn VALn)) + + + ....... + ) + + The temporary variables VAR1...VARn exist only within the _l_e_t. They get +the initial values of VAL1-VALn, which are forms that will be evaluated. +Then, with all these temporary variables set up and initialized, the FORMi's +are evaluated sequentially, and the value of the last FORMi is returned by _l_e_t. + + Another, less useful way of acquiring temporary variables is via the +special form _p_r_o_g. Forms inside a _p_r_o_g are evaluated sequentially, like +forms in a function definition. However, the first "form" in a _p_r_o_g is not +really a form at all, but rather a list of temporary variables used in the +_p_r_o_g, such as "(a b c)". That is why _p_r_o_g is a special form. The value +returned by _p_r_o_g is usually useless, unless (return...) is used to return +something meaningful. + + Inside a _p_r_o_g, one can also put "labels", to use for +go-to's: + +(defun bar2 (x y) + (prog () ;note the empty variable list + (if (< x y)(go lab1)) + (print "X is not less than Y") + (return nil) ;return "false" indication + lab1 + (print "so be it!") + (return t))) ;return "true" indication. + +Note the special form _g_o, whose _o_p_e_r_a_n_d (_n_o_t argument) +is a _l_a_b_e_l to which to "go", i.e., continue sequential evaluation of forms in +the prog. You wil find that labels are rarely needed, due to the powerful +_i_f and _d_o-___f_o_r_e_v_e_r constructs. + + There are special forms for or-ing and and-ing predicate results: they +are special because they stop evaluating their operands (from which arguments +are produced) when they "know" their answer for certain: + + (if (and (not (= x 0)) + (> (// 10 x) 5)) + (print "Quotient too large.")) + +The _n_o_t function inverts truth and falsity. +The double-slash indicates division, because slash is the escape character in +Lisp. + + Note that the _a_n_d will not attempt to evaluate the second form within it +if the first produces falsity. This prevents an error which would result if +an attempt were made to divide by zero. Sequential execution and stopping +at an intermediate result are a defined and useful feature here, as opposed +to the logical operators of, say, PL/I. + + There are two more special forms worth mentioning while we are on the +topic, progn and prog2. _p_r_o_g_n is used to force sequential execution of forms +and returning the value of the last. For instance, + +(if (and (> x 3) + (progn (print "Oh dear this is getting serious") + (> y 5)) + (print "Fatal difficulty"))) + +_p_r_o_g_n returns the value of its last form. Thus, the _a_n_d tests x being +greater than 3, and y being greater than 5, before the "print" of "Fatal +difficulty" is evaluated. The printing of "Oh dear..." occurs as part of the +evaluation of the _p_r_o_g_n, it is only the second value in the progn which _a_n_d +gets to see. The _p_r_o_g_n is used to force evaluation of the _p_r_i_n_t form. + + _p_r_o_g2_ is even a bit stranger, but often just the thing one needs. _p_r_o_g2_ +is just like _p_r_o_g_n, except that it returns its _s_e_c_o_n_d argument, evaluated, +rather than its last. It must have at least two arguments. It is used for +clever tricks that involve saving some value which is subsequently going to +be destroyed. The following form, when evaluated, interchanges the values of +x and y: + +(setq x (prog2 0 ; this zero is evaluated to 0, and + ; its value thrown away. + y ; the value of y is obtained here, and + ; remembered as it is here. + (setq y x))) ; x is evaluated, and that value + ; assigned to y. The value of setq + ; is that value. + ; But the value of the _p_r_o_g2_ is that value of y as it was before we + ; assigned into y, and now the outer setq assigns that to x. + + + S__y_m_b_o_l_s + + There is one more type of data object in Lisp that will concern us at +present. It is called the _s_y_m_b_o_l. Symbols are named data objects kept in a +registry of symbols, by Lisp. For current purposes, there is only one symbol +of any name. Symbols are used in Multics Emacs to represent buffer names, +and various quantities associated with buffers. Lisp uses symbols to keep +track of functions, and internally to keep track of global variables. + + To use a symbol in a program, we give the name of the symbol preceded by +the ASCII quote character, '. For instance, the form + +(setq x 'Brunhilde) + +assigns the symbol named Brunhilde to x. Note that this is different +from + +(setq x "Brunhilde") + +which assigns the _s_t_r_i_n_g Brunhilde to x, and from + +(setq x Brunhilde) + +which assigns the value of the variable Brunhilde to x. + + L__i_s_p L__i_s_t_s + + The final data-type of Lisp with which we will have reason to deal is the +_c_o_n_s (for construct), and the larger data-type built out of it, the _l_i_s_t. +Conses are blocks which relate to two (usually other) objects in the +environment, which are known as its _c_a_r and its _c_d_r, for historical reasons. +The function "cons", given two objects, produces a new cons, whose car and +cdr, respectively, are the two objects given. For instance, let's say +that the variable "x" has a value of the string "Brunhilde", as above, +then + + (cons 7 x) + +produces a cons whose car is the number 7 and whose cdr is the string +"Brunhilde", returning it as a value. The functions "car" and "cdr" +may be used to obtain the car and cdr of a cons. Let us say that we had +set the variable "c" to the result of the form (cons 7 x) above, then + + (car c) + +produces the number 7 as a value. + + The usual thing to do with conses is to make larger and larger structures +out of conses, by setting up conses whose car and cdr are more conses, +and so forth, until we have a large enough structure to represent all the +values we need. The resulting construction serves the same purpose +as a PL/I structure: its various parts have meaning assigned by the +programmer. + + The most common construction of conses is the "list". A list +is defined as a chain of conses, each of which has the next one +in the chain as its cdr, except the last one, which has the symbol "nil" +as its cdr. A list built in this way of n conses is called a list of n +_e_l_e_m_e_n_t_s, the elements being the n objects which are the cars of the conses. +The cons at the head of the list is identified as being "the list": its +car is the first element in the list, its cdr is the cons whose +car is the second element of the list, and so forth. Let us +construct a list of the numbers 2, 4, 5, and 7, in that order, and +set the variable "b" to it: + + (setq b (cons 2 (cons 4 (cons 5 (cons 7 nil))))) + +(Note that the variable "nil" is peculiar insofar as its value is always +the symbol "nil", thus we need not say 'nil.) + +There is a function that simplifies the writing of such forms, for +constructing lists: it builds lists directly, and accepts any number +of arguments. It produces the same result as the type of construction +shown above. It is called "list": + + (setq b (list 2 4 5 7)) + +To get the third element of the list, once this form were evaluated, we +could evaluate the form + + (car (cdr (cdr b))) + +(ie.e, the car of the cons which is the cdr of the cons which is the +cdr of the cons which is the value of b). Again, there are +Lisp functions to simplify such constructions. The above form +is equivalent to + + (caddr b) + +In general, for up to 4 car's and cdr's deep, total, functions +like cadr, cdar, caddr, cadar and so forth, are provided (up through caaaar +and cddddr). The first four elements of a list are gotten by +car, cadr, caddr, and cadddr (it is good exercise to work that +through and verify why this is the case). + + When lists are printed out by Lisp, they are represented +as a pair of parentheses around the printed representations of all +of the elements, in sequence, separated by spaces. Thus, if +Lisp printed out the list which was b's value above, it would +appear + + (2 4 5 7) + +Conses whose cdr is the symbol nil may always be viewed as lists +of one item, and are so printed out by Lisp, unless it is in the +process of printing a larger list of which the cons at issue is +a chain-link. Conses whose cdr is neither nil nor another cons +are printed with a dot preceding the cdr. Thus: + + (cons 'a 'b) => (a . b) + (cons 'a nil) => (a) ;a list of one element + (cons 'a (cons 'b 'c)) => (a b . c) + (cons 'a (cons 'b nil)) => (a b) ;list of two elements + (cons 'a (cons (cons 'b 'c)(cons 'd nil))) ;list of three + => (a (b . c) d) + +Lists can be put into programs, by quoting them, as we quote symbols: + + (setq b1 '(this is (a list)(of lists))) + +Two functions are provided to redefine the car or cdr of an existing cons. +They can be very dangerous if misused, especially if they alter a list as in +the form above, which is written into a program as a constant. rplaca +(replace car) and rplacd (replace cdr) each take two arguments, the first is +the cons which is to be altered, and the second is the new car or new cdr +respectively. the returned value is the cons itself. + + A_C_T_U_A_L_L_Y_ W_R_I_T_I_N_G_ E_M_A_C_S_ E_X_T_E_N_S_I_O_N_S_ + + The starting point for writing extensions is building functions out of +provided functions in the Emacs Lisp environment, and hooking them +up to keys. The documented set-key and set-permanent-key commands can be +used to connect keys to Lisp functions that you provide, as well as to +provided commands and keyboard macros. + + Many simple and useful extensions are just groups of provided commands +strung together. For instance, suppose that we want to write a function that +goes to the beginning of a line, deletes all whitespace there, goes to the end +of the line, does the same, and then goes back to the beginning of the line. + + Interactively, we would type; + + ^A ESC-\ ^E ESC-\ ^A + +to do this. To write such a function, called "shave-line", let us say, we +would write this: + +(defun shave-line () ;keystroke functions take no args. + (go-to-beginning-of-line) + (delete-white-sides) + (go-to-end-of-line) + (delete-white-sides) + (go-to-beginning-of-line)) + +Write this function in a file, with the editor of your choice. When in +Emacs, say ESC-X loadfile PATHNAME CR, to load it in as code. Then hook it +up, perhaps by saying + + ESC-X set-key ^XA shave-line CR + +Then, hitting ^XA will cause the chosen sequence of actions to happen. In +order to find out the names of the functions that we had to use to code shave- +line, all we had to do is ask ESC-? what the names of the functions on ^A, +^E, and ESC-\ were. + + Now we want to be able to do more complex things, like use conditionals +and variables. Let us say that we wanted a function that went to the +beginning of a line and deleted all words that started with "foo" from the +beginning of the line. + +(%include e-macros) + +(defun foodeleter () + (go-to-beginning-of-line) + (do-forever + (if (looking-at "foo") + (delete-word) + (delete-white-sides) + else (stop-doing)))) + +The (%include e-macros) must be at the beginning of any file that uses the +Emacs environment Lisp macros. The file e-macros.incl.lisp is found in the +same directory as the editor. It should be in your "translator" search path +in order to do any Emacs extension development work. + + What this function does in essence is type ^A, and as long as the first +three characters on the line are "foo", does ESC-D's followed by ESC-\ to +remove the whitespace after the word. When the first three characters are no +longer "foo", it will return. "looking-at" is an Emacs predicate (to be +described in detail below) which tests whether a given string is to the right +of the current "cursor". We will no longer discuss the issue of how to hook +this or any other function up to a given key; we have already covered that +adequately. From this point on, we will only discuss coding functions. + + If you write the function foodeleter, hook it up to a key and use it, +you will watch all foo-starting words magically disappear at once from the +begninning of a line with foo-starting words at its front, when you strike +this key. Note that the code for foodeleter has no mention of printing, +output, or displays. It cares and or knows exactly as much about them as you +do when typing Emacs keystroke commands. It just manipulates the text in the +buffer, and the screen or printing terminal is managed automatically by the +magic of the Multics Emacs redisplay. The display need never be thought +about in coding Emacs extensions. + + It is a major intentional feature that many of the commands that are +connected to keys can be, and should be used in coding extensions. +go-to-end-of-line, go-to-beginning-of-buffer, skip-over-indentation, +forward-char, and delete-word are typical of them. There are some commands, +however, that should not be used from extension code. For example, if you +wanted to search for some string, you do not want to invoke +string-search, which is what ^S is connected to, for that will prompt +the user in the minibuffer for what to search for. Here is a table of +some keystroke commands that you should not use in extensions, what you +should use instead, and why: + +KEY DONT USE USE INSTEAD WHY + +^N next-line-command next-line next-line command worries + about screen position, + which is expensive and + usually not needed. + Also worries about + numeric arguments. + +^P prev-line-command prev-line Same reasons as above. + +^K kill-lines kill-to-end-of-line + delete-char (at eol) + ^K is very complex, has + many cases, worries about + numeric arguments. + +^S string-search forward-search forward-search takes string + as Lisp argument, does not + prompt. Moves "cursor" if + search succeeds; returns + truth or falsity to indicate + result. + +^R reverse-string-search + reverse-search Same as ^S. + +^X^R read-file read-in-file read-in-file takes Lisp + argument for pathname, + does not prompt. + +^X^W write-file write-out-file Same as ^X^R. + +^W wipe-region wipe-point-mark Use local marks, see below. + +ESC-/ regexp-search-command + regexp-search Same arguments as ^S. Takes + Lisp argument, no slashes. + Returns falsity if not found + or moves cursor to after + and returns mark to before + matched string if found. + +^XB select-buffer go-to-or-create-buffer Takes arg, doesn't prompt + +^X^F find-file find-file-subr Ditto. + + This list is probably not complete, but these are the important +ones to know. + + Commands whose behavior is indistinguishable between ESC-5- +and , i.e., ^B, ^D, ^F, ESC-B, ESC-D, ESC-F, +#, ESC-#, etc., are OK to use in extensions; they do not inspect their +arguments. They are invoked multiple times by the Emacs listener if +appropriate. Commands whose names include the word "command" (other than +^G, command-quit) are usually not intended to be used in code. + + The value of the numeric command argument, i.e., "5" in ESC-5-, +is available as the binding of the global variable "numarg"; if there was no +numeric argument given, this variable is set to the symbol "nil" (not to be +confused with the global variable nil, whose binding is the symbol nil) which, +we now disclose, is _t_h_e representation of falsity. + + The normal printing characters are hooked up to the function +self-insert, which inserts the last physical character typed at the current +point in the buffer. This is clearly unusable from code, if your desire is +to insert text into the buffer. For this purpose, the Emacs environment +provides the function "insert-string", whose argument is a string to be +inserted into the buffer at the current cursor. As in typing in text +manually, the cursor is left after the inserted text: + +(defun make-a-point () + (go-to-beginning-of-line) + (insert-string "CASE IN POINT: ")) + + make-a-point, when invoked, goes to the beginning of the line, and +inserts the string "CASE IN POINT: " in the buffer. The cursor is left +after the inserted string. + + When we say "the cursor is moved around" or "a string is inserted" in a +function, we do not imply that the user watching the screen can see all these +things happen. No action on the screen occurs until the entire function has +finished running, at which time, the screen is updated all at once, as +appropriate, showing the total, cumulative effect of what has happened, +regardless of how it happened. + + M__a_r_k_s _a_n_d _t_h_e_i_r M__a_n_a_g_e_m_e_n_t + + A concept of great value is that of the "mark", or, as it is called in +other Emacs-like editors, the editor buffer pointer. Like the cursor, a mark +is a conceptual pointer to the position between two characters in the current +buffer. Marks, like the cursor, have the property that they remain between +the two characters between which they were put regardless of other insertions +or deletions in the same buffer, even on the same line as the mark. Marks +are valuable because regions of text in the buffer are specified as the +extent between the current conceptual cursor, hereafter known as "point", and +a given mark. Marks are a type of data object in the Multics Emacs Lisp +environment, like strings, numbers,and symbols. The value of any variable +may be made to be a mark. The value of many variables might even be the same +mark! The "the-mark" spoken of in the documentation is just one mark, that +is the value of a global variable that many supplied functions know about. +Emacs functions use many temporary marks. + + The function set-mark creates a new mark, which points to the current +"point" in the current buffer. It stays around, and is updated by the editor, +any time text is inserted or deleted in this buffer. Since this is +expensive, we must take care to discard, or _r_e_l_e_a_s_e marks when we are done +using them. This is done by giving them to the function release-mark. Here +is an example of a function which deletes three words and all between them: + +(defun delete-three-words () + (let ((temp-mark (set-mark))) ;make a mark in a temp var. + (do-times 3 (forward-word)) ;3 words forward + (wipe-point-mark temp-mark) ;wipe out the stuff between point + ;and where point was. + (release-mark temp-mark))) + +The variable temp-mark is set to a mark representing the "point" at the time +delete-three-words is entered. "do-times" is a very useful construct in the +Multics Emacs Lisp environment, that repeats the evaluation of one or more +forms a given number of times. Its syntax is: + + (do-times .. ) + +wipe-point-mark is a function which, given a mark, takes all the text between +"point" at the time it is invoked and that mark (i.e., "point" at the time +that mark was created) and deletes it from the buffer. It is, however, +pushed on to the kill ring, so that ^Y can be used to retrieve it. If we +did not want it pushed onto the kill ring, we could have said + + (without-saving (wipe-point-mark temp-mark)) + +instead of + + (wipe-point-mark temp-mark) + +and no saving would have occured. After we perform the computation, we free +up the mark, to keep the performance of the editor up. + + The sequence of setting a mark, using it, and releasing it, is so common +that a special construct in the Multics Emacs Lisp environment is provided +which takes care of all of this, including the creation of a temporary +variable, so no _p_r_o_g or _l_e_t is needed. It is called +"with-mark". The function delete-three-words, rewrtitten to use it, looks +like this: + +(defun delete-three-words () + (with-mark m ;m is usually used for the name of a mark. + (do-times 3 (forward-word)) + (wipe-point-mark m))) + +The with-mark construct is very powerful and useful. Its syntax is +(the word "syntax" is a tip-off to a special form): + + (with-mark + + + ... + ) + +It means: "Where I am now, call that . Evaluate (execute) +the forms to , sequentially, returning the value of the last +one as a value. Before returning anything, however, free up the mark I made". + + A very common use of marks is to remember where you were at the time you +started something, and after some traveling around, get back there when you +are finished doing it. Here is an example of a function which truncates a +line which is longer than 50 print positions, with backspaces and tabs all +considered properly: + +(defun trunc-50 () + (with-mark m ;remember where we started + (go-to-end-of-line) + (if (> (cur-hpos) 50.) ; dot is for decimal, default is octal + (go-to-hpos 50.) + (kill-to-end-of-line)) ;what ^K does not at e.o.l. + (go-to-mark m))) ;return to where we were + + Several things are worth noting here. "cur-hpos" is a very valuable +function which tells you the horizontal position (on a dprint, not on the +screen) of the current "point" (the left margin is considered to be 0). +As can be seen from the from "(cur-hpos)", it takes no arguments. The +function go-to-hpos moves point to a position on the current line whose +horizontal position is its argument, or the end of the line, if the line is +shorter than that. + + Now "(go-to-mark m)" is not some kind of a branch, but tells the editor +to move the current point in this buffer to the point where it was at the time +the mark, to which the variable m is bound, was created. + + Although moving the editor's point to previously saved marks is +extremely common, just using the mark mechanism to remember where you were +before some excursion and get back there is so common that a special +mechanism is provided just for this: it is called save-excursion, and it deals +with all the issues of temporary variables and releasing the mark when done. +Our function trunc-50 recoded to use it looks like this: + +(defun trunc-50 () + (save-excursion + (go-to-end-of-line) + (if (> (cur-hpos) 50.) + (go-to-hpos 50.) + (kill-to-end-of-line)))) + +The semantics of the save-excursion special form are as follows: Remember +where I am, via a mark saved in a secret internal variable. Evaluate all of +the forms within the save-excursion, and return as a value the value of the +last one. Before returning anything however, move the editor point back to +where it was when the save-excursion was first "entered", and release the +mark used to remember this place. + + + Note that if point were at print position 75. at the time trunc-50 +was called, it will wind up at position 50, even though the mark to which it +wants to return points to what was at position 75. No error is indicated, or +has occured. Marks live, even if characters to the right or left of them are +deleted. + + + C__l_e_a_n_u_p H__a_n_d_l_e_r_s + + You may have wondered, in the previous section, what happens if an +extension encounters an error while executing, and never gets to release +a mark it has set. When errors occur (for example, forward-char (^F)'ing +off the end of the buffer), Emacs aborts execution of command functions, +returns to its listener, and beeps (as when a ^G is performed), as you +know, if you have ever tried to ^V off the end of a buffer, or so forth. + + Since the releasing of marks has been pointed out as mildly critical, +there is a need for a "cleanup-handler"-like facility to make sure that +marks get release when code is aborted. Indeed, there is such a facility +in Lisp, and we will explain its use summarily. This cleanup-handler +facility is useful for many other things, too: "save-excursion" returns +the cursor to the point at which it found it, if aborted through, +save-excursion-buffer returns to the buffer where it found the editor +if aborted through, all the mark-handling forms release their mark, +and so forth. These Emacs-environment primitives use the cleanup-handler +facility internally, so we need not worry about cleanup-handlers if we +use them. However, occasionally, there are times (see the code +for columnating the Emacs wall chart, for example) when we must use +cleanup-handlers explicitly. The Lisp form "unwind-protect" +is the primitive cleanup-handler. Here is its syntax: + + (unwind-protect + + + + ... + ) + +The meaning of this is as follows: The is evaluated, i.e., +executed, and then to (any number of cleanup +forms are permissible), and the value of the returned. +So far, unwind-protect is very much like _p_r_o_g2_ or _p_r_o_g_n. The difference, +however, is that to will be executed even if the +execution of fails, and aborts! Similarly, the cleanup forms +will be executed even if diabolically tricky things like a _r_e_t_u_r_n from a _p_r_o_g +inside the causes its execution to terminate prematurely. + + Thus, the cleanup forms are executed after _e_v_e_r_y termination of the +, whether normal or abnormal. The following use of +unwind-protect (which could clearly be done in simpler ways, but is here for +illustrative purposes only) performs "complex-function", and returns the +cursor to the beginning of the buffer, even if "complex-function" +"explodes": + + (unwind-protect + (complex-function) + (go-to-beginning-of-buffer)) + +Note that if you want more than one , you had better use +_p_r_o_g_n to encompass them, and make your this _p_r_o_g_n. + + Unlike Multics/PL/I cleanup handlers, unwind-protect cleanup forms +will be executed upon normal termination of the subject form, too. +A close inspection of most PL/I programs using cleanup handlers shows +that this may be the better idea after all. + + + U__s_e_f_u_l P__r_e_d_i_c_a_t_e_s + + The following predicates in the Multics Emacs environment are basic to +all extension-writing; they are used to test various hypotheses about point, +marks, and the buffer: + + (eolp) ;End of line predicate. True if point is at end of a text + ;line, which is right before the newline character. + + (bolp) ;Beginning of line predicate. True if point is at the + ;start of a text ine, being either before the first + ;character of the buffer, or after a newline. + + (firstlinep) ;First line predicate. True if point is on the first + ;text line of the buffer. + + (lastlinep) ;Last line predicate. True if on last buffer line. + + (at-beginning-of-buffer) + ;True if point is right before the first character in the + ;buffer + + (at-end-of-buffer) + ;True if point is right before the newline on the last + ;line of the buffer. You can't go past it. + + (looking-at ) + ;True if appears in the buffer + ;immediately to the right of point. Restriction: + ; may not contain a newline character, + ;except as its last character. + + (at-white-char) ;True if the character to the right of point is + ;a space, newline, or tab. + + (point>markp ) ;True if the current point is _f_u_r_t_h_e_r in the + ;buffer than the position defined by . + ;This is expensive, and should not be used in loops. + + (mark-reached ) + ;True if the current point is up to or beyond + ;in the buffer. Intended for use in controlling + ;character-by character loops, expects that point + ;starts to the left of and moves toward it. + ;The function (order-mark-last ) may be used + ;to switch point and mark if needed at the start of such + ;loops. Will not terminate unless executed with mark + ;and point on same line. + + (mark-at-current-point-p ) + ;True if the mark represents the exact same + ;position as the current point. + + (mark-on-current-line-p ) + ;True if the mark represents a position on the + ;same line as the current point. + + (mark-same-line-p ) + ;True if two marks which are arguments represent + ;positions on same line. + + (line-is-blank) ;True if current line is all blanks or empty. + + (empty-buffer-p ) + ;True if the buffer identified by is + ;empty, i.e., contains exactly one line with only a + ;newline character in it. The form + ;(empty-buffer-p current-buffer) may be used to test + ;the emptiness of the current buffer. See below + ;for a discussion of buffer symbols. + ------------------------------ + + Now we use some of this. Here is a function that ltrims all the lines in +the buffer. There are easier ways, but we are using the primitives and +constructs we do here for illustrative purposes: + +(defun ltrim-all-lines () + (save-excursion ;be polite, restore point. + (go-to-beginning-of-buffer) + (do-forever ;loop on lines thru buf + (do-forever ;loop thru chars on line + (if (eolp)(stop-doing)) ;stop at eol. + (if (at-white-char)(delete-char) ;do the work + else (stop-doing))) ;non-white char, next line. + (if (lastlinep)(stop-doing)) ;quit when did last line + (next-line)))) ;leaves you at b.o.l. + + + W_H_I_T_E_S_P_A_C_E_ M_A_N_A_G_E_M_E_N_T_ + + Management of whitespace is very important. Neatly formatted editor +output and displays, as well as program and document formatting require this. + + The following functions exist to deal with whitespace: + + skip-over-whitespace + Takes no arguments. Moves point forward over all tabs, blanks, and + newlines until a non-white character or the end of the buffer is + reached to the right of point. + + skip-back-whitespace + Takes no arguments. Moves point backward over all tabs, newlines, + and blanks until the character to the left of point is not one of + these, or the beginning of the buffer is reached. + + skip-to-whitespace + Moves forward until character to right of point is one of tab, + blank, or newline. Since last character in buffer must be + a newline, there is no special end condition. + + skip-back-to-whitespace + Moves backward until the character to the right of point is + one of tab, blank, or newline, or the beginning of the buffer is + reached. + + delete-white-sides + The old standby on ESC-\, this extremely valuable function may be + used to advantage to delete leading or trailing blanks from + anything, or delete space between words. + + skip-over-whitespace-in-line + Same as skip-over-whitespace, but will stop before the newline + character at the end of the line (i.e., stop at the end of the line) + if it gets that far. + + skip-back-whitespace-in-line + Same as skip-back-whitespace, but will not proceed backward + beyond the beginning of the line. + + A very common need is to generate whitespace to reach a given horizontal +position (column). This is good for all kinds of tabbing and page layouts. +The function whitespace-to-hpos performs this service; it generates tabs and +spaces as appropriate, moving point along until the horizontal position which +is its argument is reached. The following toy function moves all lines in +the buffer seven spaces over, regardless of their original indentation, with +just the right amount of tabs and spaces when all is said and done: + +(defun move-over-7 () + (save-excursion + (go-to-beginning-of-buffer) ;all do-for-all-lines + (do-forever ;start like this. + (skip-over-indentation) ;This is ESC-M, which is + ;often useful. Look it up. + (let ((hpos (cur-hpos))) ;let hpos be the curr. pos. + (delete-white-sides) ;close up all original space + (whitespace-to-hpos (+ hpos 7))) ;make just enough + (if (lastlinep)(stop-doing)) + (next-line)))) + + A related need is that to space out to a given position with whitespace, +but leaving a single space if you are already there or beyond. This is +useful for producing columnar output where overlength fields must be +separated (like what ^X^B does). whitespace-to-hpos will not do this; it +stops if it is far enough. This need is fulfilled by format-to-col, which +takes a single argument, a horizontal position to be spaced out to. If the +current point is already that far, it inserts a space. + + E__x_t_r_a_c_t_i_n_g T__e_x_t F__r_o_m _t_h_e B__u_f_f_e_r + + The function point-mark-to-string is used to get a Lisp string whose +value is the string of characters between point and the mark which is its +argument. Let us demonstrate with a function that finds a vertical bar (|) +on a line, deletes it, and swaps the two line-halves around it. For instance, +the line + + An Indian with a zebra | never trips in the snow + +will come out + + never trips in the snowAn Indian with a zebra + +Here is this extremely utilitarian construction: + +(defun swap-around-bar () + (go-to-beginning-of-line) + (if (not (forward-search-in-line "|")) ;check for one at all. + (display-error "Hey, there is no ""|""!")) + (rubout-char) ;what # does + (with-mark m ;m in middle of line + (go-to-end-of-line) + (let ((temp (point-mark-to-string m))) ;get middle to end + (without-saving (wipe-point-mark m)) + (go-to-beginning-of-line) + (insert-string temp)))) ;put in text + + forward-search-in-line is just like forward-search, except that it +indicates failure if it cannot find its search string in the current line. +If we cannot find the vertical bar, we complain and do command-quit, a "^G", +which stops the execution of this function at once and returns to +command level. It is often needed, however, to search for some string +only in a given line, and thus, it is useful in its own right. There is also +a reverse-search-in-line, and a regexp-search-in-line, which are similar in +their relation to ^R and ESC-/. + + T__a_l_k_i_n_g _t_o _t_h_e U__s_e_r + + + We may not use the Lisp I/O system to print out messages and/or query +the user. The Multics Emacs redisplay must manage the screen itself, +entirely. Thus, you may not use "print", or "read", or other Lisp functions +that you may be familiar with. + + A function called minibuffer-print is provided, which prints all the +little messages that Emacs outputs in the minibuffer screen area. It takes +any number of arguments, which must be strings. The useful function +decimal-rep is provided to convert numbers into strings for purposes of +inserting them in the buffer or handing them to display-error. The following +function counts the number of a's in the current line: + +(defun a-counter () + (let ((n 0)) ;initial count + (save-excursion ;why not. + (go-to-beginning-of-line) + (do-forever + (if (not (forward-search-in-line "a")) + (minibuffer-print "I found " (decimal-rep n) " a's.") + (stop-doing)) + (setq n (+ 1 n))))) ;count 'em. + + Note how we take advantage of the fact that forward-search-in-line +moves to the right of what it finds (like ^S, its patron), so that it will not +find it the next time. + + To prompt the user for input, which is always done via the minibuffer +(other than for ESC-?, which is highly special), the function +minibuf-response is used. It takes two arguments. The first is the prompting +string. The second should be specified by the value of one of the global +variables ESC or NL, which are bound to magic symbols that minibuf-response +knows about. If the value of ESC is used, minibuffer input will terminate +on an ESC. If the value of NL is used, (NL, _n_o_t CR), minibuffer input will +terminate on a carriage return. There are no other choices. Thus, + + (minibuf-response "Type new division name: " NL) + +will return the user's response to this question. S/he is expected to +terminate it with a carriage return. The value of minibuf-response is a Lisp +string. The carriage return will not appear in it, nor will the prompt. + + Often one wants to display an error message in the minibuffer, and then +abort execution of an extension, i.e., execute a command-quit (^G). For +example, in checking the arguments to an extended command, checking that a +necessary sequence of previous commands were issued before a certain command, +etc. For this, display-error is provided. display-error is like +minibuffer-print, except that it does NOT return, but aborts to emacs top +level immediately after printing its error message in the minibuffer. Like +minibuffer-print, it takes any number of string arguments. + + Messages printed by minibuffer-print are suppressed during keyboard macro +( ^X(, ^X)) execution, just as search strings are not displayed, and other +gratuitous messages are suppressed. The following set of functions describes +the repertoire of message-printing: + + + display-error + Prints a message in the minibuffer and aborts to editor top + level. It is intended for use in error message pritning. + + display-error-noabort + Prints a message in the minibufer and continues execution. This + function is intended for reporting non-fatal errors such + as "User not accepting messages...". + + + minibuffer-print + Prints a message in the minibuffer. The message is NOT printed + during macro execution. This function is intended for + use by extensions which print messages in the normal process + of their execution such as the line-count from ^X=. For + this function, as well as the others below, in multi-line + minibuffer situations, an appropriate line is chosen based + upon availability of empty lines and several other criteria. + + minibuffer-print-noclear + Prints a message in the minibuffer but does not erase the + previous contents. The message is NOT printed during macro + execution. Output is appended to the last minibuffer line used. + + display-com-error + Prints a message in the minibuffer and aborts to editor top + level. Its first argument is a Multics standard error code. + It remaining arguments are character strings or symbols. + See the section "Multics Error Table" below for the technique + used to get error_table_ values into your program. + + display-com-error-noabort + Prints a message in the minibuffer and continues execution. + Its first argument is a Multics standard error code. + + minibuffer-clear + Clears out the last minibuffer line that was written in, except + during macro execution. This function should be used to clear + out minibuffers written in by minibuffer-print and + minibuffer-print-noclear at the end of subsystem invocation. + + display-error-remark + Identical to display-error-noabort, except that the particular + minibuffer line on which this remark will be printed will be + "targeted" to be the next ine overwritten for any minibuffer + remark or output at all. This function should be used for + "transient" remarks (such as "Writing", "Modified", etc., which + are desired to get off the screen as soon as possible. + + V__a_r_i_a_b_l_e_s + + Many groups of Emacs commands need global variables to communicate +amongst themselves and the functions they call. A global variable is a Lisp +variable which is not the parameter of any particular function; its value may +be accessed or set by any function. Some of the global variables in Multics +Emacs are highly user-visible, for example, "fill-column", which contains the +column number of the fill column as set by ^XF, and used by the filling +commands and fill mode. Similarly, the character string which is the +comment prefix is the binding of the global variable "comment-prefix". +Extensions will often need global variables to communicate among their parts. + + Normally, global variables in Lisp are accessed just line other +variables, i.e., those which are parameters of functions or _p_r_o_g or _l_e_t +variables (_l_e_t will be discussed later.). For instance, a function which +wanted to set the fill column to 30. if it was over 40. now might contain +the code: + + (if (> fill-column 40.)(setq fill-column 30.)) + + When a global variable is used in your program, say one named +"my-global", the "declaration" + + (declare (special my-global)) + +must appear in the program before its first use, to tell the compiler about +this "special" variable (which is the Lisp term for a global variable, +incidentally). The e-macros include file declares many of the provided +global variables, you need not declare them. + + The global variable situation in Multics Emacs is complicated by the +fact that editing activity is usually local to each buffer. +That is to say, if a set of global variables contains a set of values about +what is being edited, it usually pertains to what is going on in only one +editor buffer. If the user switches to a different buffer, and uses the same +editor facility, we do not want to use or change the values of those global +variables which pertained to activity in the other buffer. At first, this +would seem to make global variables unusable, because all functions would +have to keep track of what buffer they are talking about before using any +global variables, and maintaining several sets of them thereby. +Fortunately, it is a lot easier than that. The buffer-switcher in Multics +Emacs is willing to save and restore values of global variables as buffers +are switched if you tell it what variables you want so saved and restored, when +the buffer you are operating in is exited and re-entered, respectively. Such +a variable is called a _p_e_r-_b_u_f_f_e_r _v_a_r_i_a_b_l_e, and the act of telling the +buffer-switcher about it, thereby associating its current value with this +buffer, is called _r_e_g_i_s_t_e_r_i_n_g it. Once a variable has been registered in a +given buffer, the functions which use it can assume that its value will be +what it last was in that buffer whenever the editor enters that buffer. +Another term for a per-buffer variable is a _l_o_c_a_l _v_a_r_i_a_b_l_e. +The following two primitives exist for registering local variables; there are +no primitives for setting or retrieving their values, because the whole point +of this mechanism is to allow them to be accessed as normal Lisp variables. + + register-local-variable + Called with one argument, the symbol whose name is the name of the + local variable we wish to register. Registers it in the current + buffer, if not already registered here. If not already registered + here, the variable initially inherits its "global value"; if + registered, its value is left alone. If it has no global value, + it acquires the symbol "nil" as its value if this is its first + registration in this buffer. + + establish-local-var + Just like register-local-variable, but takes a second argument, + a default value to be initially assigned to the variable the first + time it is registered in this buffer, if it has no global value. + + The global value of a per-buffer-variable is the value it has in buffers +in which it is not registered. It is this value which is set if you set this +variable while in a buffer in which it is not registered. A local variable +"inherits" its global value when it is first registered in a given buffer. +For variables that have no global value (i.e., were never assigned one), +establish-local-var can be used to good effect to provide default +initialization. + + Here are three function which maintain a "problem count" in this buffer. +The user says ESC-Xmonitor-problemsCR to start it up in a given buffer, +and then can say ^X-P to count a problem, and ^X-R to report how many +"problems" he has so noted: + +(defun monitor-problems () ;command-level function + (set-key '^XP 'note-a-problem) ;set the keys needed, only + (set-key '^XR 'report-problems) ;in this buffer + (establish-local-var 'problem-count 0)) ;register the local var, + ;initial value 0 here. + +(defun note-a-problem () ;executed on ^XP + (setq problem-count (+ 1 problem-count))) ;Increment the variable. + +(defun report-problems () ;on ^XR + (minibuffer-print "There have been " (decimal-rep problem-count) + " problems in this buffer.")) + + By calling establish-local-var on the symbol "problem-count", the +programmer here has ensured that the problem-count's in each buffer +in which he counts problems will be maintained separately. + + P__r_o_v_i_d_e_d V__a_r_i_a_b_l_e_s + + The following per-buffer variables are automatically registered by the +editor. Their values may be inspected or set in extension code. The following +table gives their names and meanings: + +buffer-modified-flag + Contains t or nil, indicating that this buffer has or has not been + modified since last read in or written. Set automatically by the + editor. Modification of a buffer executed within the special form + + (without-modifying ...) + + will not set this flag. + +read-only-flag + Contains t or nil indicating whether or not this is read-only buffer. + The editor does not set this flag, it is set only by extensions. + An attempt to modify the text in this buffer will produce an error + and a quit to editor command level if this flag is on, and the + buffer-modified-flag flag is off (nil). The buffer may be modified, + however, successfully, by functions executed from within extension code + within a "(without-modifying ...)". + +fpathname + The full Multics pathname associated with this buffer by the last file + read or written into/out of it, or by find-file. It is nil if there is + none. Changing it from extension code will modify or "forget" the + pathname as you set it. + +der-wahrer-mark (name subject to change, use macros instead) + The mark associated with the user-visible mark that ^X^X etc. see. + Will be nil if no mark ever set by the user in this buffer. Do not set + this variable, call set-the-mark (the ^@ function) to do so. + +current-buffer-mode + The major mode in effect in this buffer. The value is a symbol. To + claim that a major mode of your construction is in effect in a buffer, + simply set this variable. + +comment-column + The comment column, as always, measured from 0. + +comment-prefix + The string, which may be a null string, which is the comment prefix. + +tab-equivalent + The amount of spaces that a tab is worth. Initialized to 10., the Multics + standard, this can be set either in code or by ESC-ESC to edit code + from other operating systems. The redisplay will obey this variable too, + but not in two-window mode. + +buffer-minor-modes + A Lisp list (to be explained) of symbols representing the minor modes + in effect in this buffer. + + L__a_r_g_e S__c_a_l_e O__u_t_p_u_t + + Output of multi-line information, or information longer than about 60 +characters, should not be done via display-error, which prints in the +minibuffer area, but via the _l_o_c_a_l-_d_i_s_p_l_a_y, or _p_r_i_n_t_o_u_t facility. This is the +facility with which buffer listings, global searches, apropos, and other +familiar commands display their output. On display terminals, it displays +lines at the top of the screen, asking for "MORE?" as each screen fills up, +and pausing for the next Emacs command at the end of the display, and +restoring the screen. On printing terminals, the data is simply printed +line by line, with no "MORE?" processing or pausing at the end. +The local display facility is an integral part of the Multics Emacs +redisplay. + + There are three common functions used in generating local displays: + +init-local-displays + is called with no arguments to start a local display. It basically + sets up the necessary redisplay mechanism, initializing it to the top + of the screen. + +local-display-generator + This function is called with a string, whose last character must be a + newline, and displays it as the next line (or lines, if continuation lines + are required) of local output. If you do not have a newline at the end + of your string, calling local-display-generator-nnl instead will provide + one automatically. There must be no embedded newlines in strings for + local output. A null string causes an empty line. + +end-local-displays + Finishes a local display, restoring the screen. Causes + the next redisplay to be suppressed, so the local display remains visible + on the screen. + + The sequence of calls + + (init-local-displays) + (local-display-generator(-nnl) ...) ;perhaps many times + (end-local-displays) + + correctly produces a local display. + + Often, the best way to generate a well-formatted local display is to set +up a temporary buffer (see "Manipulating Buffers" below), build some text in +it, and display its content, in part or in whole, as a local display. Three +functions are provided to facilitate this: + +local-display-current-line + Does a local-display-generator on the current editor line in this buffer. + +display-buffer-as-printout + Does an init-local-displays, and displays all lines of the current + buffer as local output. It does NOT do an end-local-displays; you have to + do that yourself, hopefully _a_f_t_e_r you have gotten out of your + temporary buffer and cleaned up whatever else you had to. + +view-region-as-lines + Displays the entire point-to-user-visible-mark as local display, + making all the necessary calls including end-local-displays. + + While in a function which has a local display in progress, you must never +call the redisplay (see "Calling the Redisplay" below), or call +minibuf-response or any other function which will cause redisplay, for that +will instantaneously restore the screen contents to the windows on display, +obliterating the local display in progress. + + The following function locally displays all lines in the buffer +that contain the string "defun": + +(defun look-for-defuns () ;use ESC-x look-for-defunsCR + (save-excursion ;remember where we are. + (go-to-beginning-of-buffer) + (init-local-displays) ;set up for printout. + (do-forever ;loop the buffer + (if (forward-search-in-line "defun") ;look for "defun" + (local-display-current-line)) ;cause printout of it + (if (lastlinep)(stop-doing)) ;check for EOB. + (next-line))) ;Go to start of next line. + (end-local-displays)) ;wait for user, and next + ;command. + + M__a_n_i_p_u_l_a_t_i_n_g B__u_f_f_e_r_s + + The easiest way to do string processing in the editor environment, i.e., +monkeying around with strings, catenating, searching, etc., is often to use +the primitives of the editor itself, which is, after all, a string-processing +language. To do this, temporary buffers are necessary. To create a buffer, +you should use the primitive "go-to-or-create-buffer", which is what +^XB uses, which goes to a buffer associated with the symbol you give it +as an argument. We will discuss how to make it temporary shortly. + + Lisp symbols are funny things; it was stated before that symbols are +kept in a registry. This is true for most symbols: this registry is called +the _o_b_a_r_r_a_y, and there is only one symbol of any given name in it. +A symbol registered in the obarray is said to be _i_n_t_e_r_n_e_d. There can +only be one interned symbol named "joe", but it is possible to create +many uninterned symbols named "joe". If you refer to a symbol named "joe" +in a program, however, by saying "'joe", you will always be getting the +interned one. + + A major feature of symbols in Lisp is that they can be given _p_r_o_p_e_r_t_i_e_s, +arbitrary user-defined attributes. These attributes are catalogued "in" the +symbol via _i_n_d_i_c_a_t_o_r_s, symbols which indicate what property we want. +The Lisp functions "putprop" and "get" store and retrieve properties. + + (putprop 'Fred 'blue 'eyes) ;Gives the interned symbol named "Fred" + ;an "eyes" property of "blue". + + (get 'Fred 'eyes) ;retrieves the property under the + ;indicator "eyes", and thus returns + ;the interned symbol "blue". + + In Multics Emacs, symbols are used (among other things) to represent +buffers. All of the information associated with a buffer is catalogued as +properties of some symbol whose name is the name of the buffer. +Thus, it is possible to have two buffers of the same name, which would imply +that the of the symbols representing them, only one is interned. ^XB +always uses the interned symbol of the name given; that is why you can ^XB back +to an existent buffer instead of creating a new one each time. + + To create a temporary buffer, we must first create an uninterned symbol, +to make sure that we are not going to switch to a buffer that is already real. +To do this, we give a string to be used in naming the symbol to the +Lisp cliche + + (maknam (explodec "A string")) + +The explodec blows the string apart into a Lisp list of characters, the +maknam builds a symbol out of it. The value of this form is the new symbol. +We can then go to a (guaranteed) new buffer of that name, i.e., + + (go-to-or-create-buffer (maknam (explodec "A string"))) + +and the global variable "current-buffer" will have that symbol as its value. +A _t_e_m_p_o_r_a_r_y _b_u_f_f_e_r is one that is destroyed automatically by the editor upon +switching out of it. To make a buffer temporary, all we have to do is give +the symbol which represents it (the "buffer symbol") a "temporary-buffer" +property of the symbol "t". This can be done by the Lisp form + + (putprop current-buffer t 'temporary-buffer) + +(The variable "t" is always bound to the symbol "t"). Once this has been +done, we must be careful not to switch out of this buffer until we are done +with it. If our code involves manipulating many buffers, some of them +temporary, we must give the temporary buffers their temporary-buffer +properties at the end of our manipulations. + + When a new buffer is created, it contains one line, which consists of +only a linefeed. There are no "truly empty" buffers in Multics Emacs. +The predicate empty-buffer-p may be applied to a buffer symbol to +determine if that buffer is in this state. +When buffers are switched, all information related to the old buffer is stored +as properties of the buffer symbol: this includes not only the local +variables registered in that buffer, but the location of "point", the +user-visible (and all other) marks, etc. Thus, when buffers are switched +back and forth (as can be seen while editing), the cursor retains its +position in each buffer, although the redisplay might choose to display a +screen differently after visiting another buffer and coming back. + + There are some applications which require making a non-temporary +buffer, putting some text in it, and going back there on occasion. For this +reason, we might want to go into a non-temporary buffer of an interned buffer +symbol, as such: + + (go-to-or-create-buffer 'name-and-address-buffer) + +or perhaps keep a global (_n_o_t per-buffer) variable which we set once to an +uninterned symbol as such: + + (setq name-and-address-keep-track + (maknam (explodec "Name and Address Buffer"))) + +and switch into it by saying + + (go-to-or-create-buffer name-and-address-keep-track) + + + The function "buffer-kill" may be called with a buffer symbol to destroy +a buffer. The function "destroy-contents-of-buffer" (no arguments) may be +called to reduce the current buffer to a single "empty" line. + + The following two variables are relevant to buffer manipulation: + +current-buffer + The value of this variable is the buffer symbol of the current buffer. + Do not change it, or incorrect operation will result. Use + go-to-or-create-buffer. + +previous-buffer + The value of this variable is the buffer symbol of the last buffer, + which will be returned to when ^XB-CR is typed. It is acceptable to setq + this variable. + + + go-to-or-create-buffer will accept a buffer-name of "" as meaning +go to that previous buffer. + + The special form save-excursion-buffer is invaluable when writing +functions that switch buffers. It provides for remembering which buffer you +were in, and switching back to it when you are done. It also saves and +restores the state of "previous-buffer". save-excursion-buffer is like +save-excursion, it executes its contained forms while pushing the +buffer-state of the editor on an internal stack, and returns the value of +the last form within it. + + The following program when invoked after typing somebody's name (say we +hook it up to a key) and follows it with his title in parentheses. We assume +the file >udd>Washington>States>personnel_data looks like this: + +Rasputin, G. E. =Chief Lecher +Nietzsche, F. =Antichrist +Mouse, M. =Optimist +Eisenhower, D. D. =Golfer + +(defun insert-person-title () + (let ((name (save-excursion ;save guy's point + (skip-back-whitespace) ;get to end of word + (with-mark m ;m = end of word + (backward-word) ;go to beg. of wd. + (catenate (point-mark-to-string m) ","))))) + ;return the word with a "," after it. + (insert-string ;insert + (catenate " (" ;open paren and sp + (save-excursion-buffer ;save the old buff + (go-to-or-create-buffer 'name-position-records) + ;go to stuff + (if (empty-buffer-p current-buffer) ;read it once + (read-in-file ">udd>Washington>States>personnel_data")) + (go-to-beginning-of-buffer) ;set up for search + (do-forever ;scan lines + (if (looking-at name) ;Are we at "name,"? + (forward-search "=") ;look for the =. + (return (with-mark n ;get to the end. + (go-to-end-of-line) + (point-mark-to-string n)))) + (if (lastlinep)(return "???")) ;couldn't find him + (next-line)) ;move on + ") "))))) + + This function operates by picking out the name you just typed by skipping +back over whitespace, and picking up all between there and the start of the +previous (current) word. It then inserts, between parentheses, the portion of +that line of the data file which contains the sought name at its front after +the equals sign. The buffer name-position-records is read into once, and +contains the data file thereafter. + + The initial save-excursion remembers the user's point location while the +word is collected: The save-excursion-buffer remembers what buffer and where +in it, all its modes, local variables, etc., while we operate in the data +file buffer. + + The function _c_a_t_e_n_a_t_e is an extremely valuable one in the context of +Multics Emacs; it takes any number of strings (or symbols, whose print-name +will be used), builds a string out of catenating them first-to-last, and +returns it. + + + C__a_l_l_i_n_g _t_h_e R_e__d_i_s_p_l_a_y + + The Multics Emacs redisplay is a large and powerful screen-management +system which functions completely automatically. Its function, in simple +terms, is to decide what lines of the current buffer should be shown on the +screen, determine how to modify the current screen to show the contents of +those lines, and update the screen in an optimal manner. It is called +by the editor whenever there is no more input available. It is very simple +to call. It takes no arguments, i.e., one just says + + (redisplay) + + The redisplay does not know or care by what means the buffer was +modified; if you delete several words with ESC-D, ^D, or ^W, it is all the +same to the redisplay, and it will act similarly in updating the screen. + + Normally, the extension writer need not be concerned at all about the +redisplay. It is a major feature of Multics Emacs that only the total effect +of a complex manipulation is displayed, not every small operation that the +manipulation used to achieve its effect. + + There are some situations, however, where it is advantageous to call the +redisplay explicitly from extension code. One example might be a function +which takes a tremendous amount of compute time and might wish to update the +screen every-so-often as it finishes some major section. Note that you do not +tell the redisplay what do display or how to display it; it will display some +excerpt of the current buffer which is guaranteed to contain the current line, +and show the cursor where the current point is. If you call it during a +buffer excursion, i.e., while in some special buffer in a function, it will +thus display that buffer about its "point", and as soon as that function +returns to editor command level, the screen will be overwritten with the +original buffer's lines. Thus, calling redisplay is _n_o_t to be considered a +substitute for local displays (see above). + + The most common need for calling redisplay is in functions that add +text (or change text) on a line, and move to another line. For example, the +"electric semicolon" of electric PL/I mode, which adds a semicolon to the +current line and moves to the next. On a printing terminal, the user would +never see the semicolon unless special action were taken. The text in the +buffer would indeed be right, but by time the next redisplay occurred (the +electric semicolon command returned) the editor would be off that line, and +thus would display the next line, where the electric semicolon command left +it. While this is correct, the user looking at his type-in would, with some +validity, complain that "all the semicolons seem to be missing". Thus, the +electric PL/I semicolon command calls the redisplay immediately after it +executes "(insert-string ";")". + + The following divertissement is a function for a "card-numbering FORTRAN +mode", which when invoked (perhaps hook it up to CR) puts a sequence number +in column 72 (71 from 0) and goes to column 7 of the next line. + + It must call the redisplay, such that on a printing terminal, the card +numbers get shown. + +(defun fortran-next-line () + (whitespace-to-hpos 71.) ;go to col 72. + (insert-string (decimal-rep cardno)) ;cardno is a local buffer var + (setq cardno (+ 1 cardno)) ;up the next card number + (redisplay) ;let printing user see. + (new-line) ;get to next line + (whitespace-to-hpos 6.)) ;6 rel = card col 7. + + + E_I_S_ T__a_b_l_e_s + + + The Multics Emacs environment provides a powerful facility for utilizing +the sophisticated 68/80 processor instructions for scanning for characters in +or not in a particular set of characters. These operations correspond to the +PL/I "search" and "verify" builtins. It is using these facilities that the +word commands operate. + + A set of characters is represented by a "charscan table", a compound +Lisp object occupying about 200 words of storage (i.e., they are not for +free). One can get a charscan table by giving a set of characters, as a +string, to the function charscan-table. It returns a charscan table +representing that set of characters: + + (setq number-verify-table (charscan-table "0123456789+-")) + + Given such a table, there are a set of functions which can be called to +utilize it to search for characters in or out of that set, backward, forward, +whole buffer or only one line. All the following functions take one argument, +a charscan table representing a set of characters we will call S. They +return nil (falsity) if they hit the end of the buffer or line (as +appropriate) without finding what they are looking for. If they succeed, they +move point. If they fail, they don't move point: + +search-for-first-charset-line + Scans current line forward from point. Success is stopping to the + left of a character in S. + +search-for-first-not-charset-line + Same as above, but success is stopping to the left of a character _n_o_t + in S. + +search-back-first-charset-line + Scans current line backward from point. Success is stopping to the right + of a character in S. + +search-back-first-not-charset-line + Same as search-back-first-charset-line, but success is stopping to the + right of a character _n_o_t in S. + +search-charset-forward + Scans the buffer from point to the end of the buffer. Success is + stopping to the left of a character in S. + +search-charset-backward + Scans the buffer backward from point to the beginning of the buffer. + Success is stopping to the right of a character in S. + +search-not-charset-forward + Scans the buffer forward from point to the end. Success is stopping + to the left of a character not in S. + +search-not-charset-backward + Scans the buffer backward from point to the beginning of the buffer. + Success is stopping to the right of a character not in S. + + + + The following function finds the first non-numeric character on the line +it is invoked on: + +(defun find-first-non-numeric () + (establish-local-var numscan-table nil) ;make sure var exists + (if (not numscan-table) ;if nil, i.e., not init yet, + (setq numscan-table (charscan-table "0123456789"))) + (go-to-beginning-of-line) + (if (not (search-for-first-not-charset-line numscan-table)) + (minibuffer-print "Line is O.K.!"))) ;failure is all is in charset + + + O__p_t_i_o_n_s + + The Multics Emacs option mechanism provides for user-settable variables +in the Lisp environment. The only difference between an "option" and any +other global Lisp variable in the editor (basic or extended) is that the +options are listed at the user-visible level by ESC-Xopt listCR, and can be +set or interrogated via the "opt" command. The option mechanism also +provides for checking that numeric variables stay numeric, and those variables +that are restricted to "t" or "nil" as values stay restricted to those values. + + Thus, options may control per-buffer or truly global variables; the +option mechanism does not care about or impose restraints upon the dynamic +scope of the variables managed by it. The option mechanism also provides for +a default global value of variables it manages. + + A global variable is "registered" with the option mechanism by invoking +the function "register-option" upon the Lisp symbol which represents (has the +name of) that variable, and its default global value. If that value is a +number, the option mechanism will restrict the variable's value to numbers; +if it is one of t or nil, the option mechanism will restrict its values to t +or nil (which the user indicates as "on" or "off"). + + The choice of whether a variable should be made an official "option" or +not depends upon whether or not you want the user to see it when an "opt +list" is done, and whether finer control than that provided by the option +mechanism over the values assigned to it is necessary. It is acceptable to +register an option the first time some code is executed; only then will it +appear in the option list. It is usual to have forms invoking +"register-option" at "top-level" in a file full of code, i.e., outside of any +function. Such code is executed when the code is brought into the editor +environment. + + The following code registers an option describing default paragraph +indentation, and shows a function that creates a new paragraph (which should +probably be hooked up to a key). Note that like all Lisp global variables, +options must be declared "special" for the Lisp compiler (see "compilation" +below): + +(declare (special paragraph-indentation)) ;for compiler. + +(register-option 'paragraph-indentation 10.) ;default is ten. + +(defun new-paragraph () + (new-line) ;two new-lines + (new-line) + (whitespace-to-hpos paragraph-indentation)) ;tab out. + + By issuing the command + + ESC-X opt paragraph-indentation 5 CR + +the user can set the amount of indentation inserted by "new-paragraph" to 5. + + + + N__a_m_e S__c_o_p_e I__s_s_u_e_s + + One of the large benefits of Lisp is that all of the functions and +variables in the environment are accessible to all functions running in it. +At times, this can be a problem, as well. When adding your own extensions +to the editor environment, there is nothing to prevent you from choosing a +name for one of your functions which happens to be the name of some internal +(or user-visible) function in Multics Emacs. Occasionally, there may be reason +to do this deliberately , e.g., write your own version of "next-line" that +did something highly special. This is dangerous, and not recommended. + + In the general case, you want to make sure that none of your functions +or variables will conflict with those of the editor. The best way to do this +is to choose some set of names that cannot possibly conflict. Two sure-fire +ways to achieve this are to use capital letters anywhere (such as initial +capitals) or using underscores in your names. No Emacs or Lisp system +functions have leading capitals or trailing underscores. There are a few +Lisp system functions with embedded underscores, but other than make_atom, it +will not hurt you if you accidentally redefine them. The Lisp compiler will +also warn you if you attempt to redefine a system function. No functions in +Multics Emacs contain underscores in their names. + + Another more reasonable way to avoid name scope conflicts is to prefix all +of your names in a given package with some prefix indicative of the facility +that you are trying to implement. For instance, if you are implementing a +SNOBOL edit mode, you might name your functions +"snobol-mode-find-match-string", "snobol-mode-get-branch-target", etc. The +same holds true for global variable names. + + You can also be reasonably certain that names constructed on the fly +(see "Program Development" below) with some degree of ludicrosity in their +names (e.g., "find-third-foo", "Johns-special-tsplp-hack", etc.) will not +conflict. + + One can test for a name being known in the Emacs environment via the +predicate "internedp" (not installed as of 8/16), which tests whether or not +a symbol with the given name is interned on the obarray. You must give it a +string. It will return t or nil for interned or not. From Emacs command +level, + + ESC-ESC internedp "test-string"CR + +will print out + + Value: t + +or + + Value: nil + +as appropriate. This test is not a foolproof method, though, because some +name which is not used now may be used later, as new versions of Multics +Emacs are developed. The rules given above will remain valid for all time. + + + M__o_d_e_s + + The major and minor mode mechanism of Multics Emacs, as it exists today, +is little more than a way for the user to switch in and out large sets of +key-bindings and column settings, and know about it via the mode line. + + The differentiation between major modes and minor modes is vague. The +current convention holds that a major mode involves a large body of optional +code (e.g., PL/I mode), sets up for a editing code written in a particular +language, or sets up a buffer for some highly specialized task where very +common keys (e.g., CR) do non-obvious things (e.g., the Message mode buffers +of the Emacs message facility). Minor modes generally involve the say that +whitespace or delimiters are interpreted, e.g., fill mode and speedtype mode. + + The current convention on major modes is that the major mode is set up by +a user-visible function called "XXX-mode", where XXX is the name of the mode. +This "mode function" establishes key-bindings (using set-key) as necessary, +and sets columns (e.g., fill-column, comment-column) and prefixes as +necessary. The mode function establishes the mode by setting the +per-buffer-variable "current-buffer-mode" to a _s_y_m_b_o_l whose name is +indicative of the mode. The name of the symbol will appear in the mode line +when the redisplay is invoked while in this buffer. The following function +sets up a major mode for editing FORTRAN programs: + +(defun fortran-mode () ;the mode function + (setq current-buffer-mode 'FORTRAN) ;symbol for mode + (setq fill-column 70.) ;set columns + (setq fill-prefix " ") ;six spaces on CR + (set-key 'CR 'fortran-new-line) ;set up CR key + (setq comment-column 1) + (setq comment-prefix "C ")) ;that begins cmts. + +The function fortran-new-line is assumed to be one which does something +appropriate, such as numbering cards. Note that the use of the function +set-key implies that this key binding (of the carriage-return key) is +local to this buffer, and will be reverted when this buffer is exited. + + Minor modes are less straightforward. Minor modes such as speedtype +and fill mode have different actions associated with the keys they affect +(for instance, all the "punctuation" keys), and the minor modes have to have +detailed and specialized interaction between themselves. There is no way to +generalize the interactions between the minor modes; no completely adequate +solution to this problem has been developed. + + Minor modes are asserted and turned off in a given buffer by calling the +functions "assert-minor-mode" and "negate-minor-mode" while in that buffer, +with an interned symbol which identifies that mode (and appears in the mode +line). There is a per-buffer variable called buffer-minor-modes which has a +value a Lisp list of all the symbols identifying the minor modes in effect +in this buffer. The Lisp predicate "memq" can be used to test whether a given +interned symbol is a member of a list, and thus, whether a given minor mode +is in effect n the current buffer: + + (memq 'fill buffer-minor-modes) + +will return the symbol "t" (truth to _i_f) if fill mode is in effect in this +buffer, otherwise it will return "nil" (false). Functions implementing the +actions of keys in minor modes should check in this way to see what other +minor modes are in effect, and what they ought do in that case. This is +admittedly not an easy design problem. + + The global variable fill-mode-delimiters is bound to a Lisp list of keys +that act as punctuation in many minor modes. By use of the Lisp function +"mapc", all punctuation can be set to trigger a given action. "mapc" takes +two arguments, a function, and a Lisp list: the function will be called upon +each element of the list: + +(defun no-punc-mode-word-on-a-line-mode-on () ;mode function + (mapc 'word-on-a-line-setter fill-mode-delimiters) ;set up keys + (assert-minor-mode 'word-on-a-line)) ;get in mode line + +(defun word-on-a-line-setter (key) ;key is the key + (set-key key 'word-on-a-line-responder)) ;set these keys + +(defun word-on-a-line-responder () ;key function + (delete-white-sides) ;get rid of whitesp + (self-insert) ;insert the typed character + (new-line)) ;start a new line. + +This set of functions (very crudely) establishes a minor mode in which +each word goes on a separate line as it is typed. + + C__h_a_r_a_c_t_e_r D__i_s_p_a_t_c_h_i_n_g + + + It is often very useful to make decisions based upon the +identity of the character to the right (or left) of the current point. The +Multics Emacs environment provides several special forms and functions for +facilitating this efficiently. All of these functions and forms accept +either of two ways of describing characters: either a single-character string +(e.g., "."), or a symbol whose name is that character (e.g., 'a, as it would +appear in a program). We will call the first kind the "string form", and the +second kind "character objects". + + The function "curchar", of no arguments, returns the character to the +right of the current point as a character object (this is done for reasons of +storage efficiency: character objects are unique, while strings require +allocation). You can test for two character objects being the same unique +object (or any two objects, in general) via the Lisp predicate "eq": + +(if (eq (curchar) 'a) + (display-error "We are looking at an ""a"".")) + +Note that we could have also done this with the "looking-at" predicate +described above, but for single characters, looking-at is a lot less efficent, +in both time and storage. + + Please note very carefully that you cannot use _e_q to test if two strings +have the same characters in them; Lisp strings are _n_o_t uniquized in the same +way that symbols are uniquized via the obarray. + + In order to facilitate the use of "messy" characters (tabs, linefeeds, +spaces, quotes, etc.) in this way, the Emacs environment provides several +global variables with values of the character objects for these "messy" +characters: + +ESC ASCII ESC, Ascii 033. +CRET ASCII Carriage return (Ascii 015) +NL ASCII Newline (linefeed), Ascii 012. +SPACE ASCII blank, Ascii 040. +TAB ASCII tab, Ascii 011. +BACKSPACE ASCII backspace, Ascii 010. +DOUBLEQUOTE ", Ascii 042. +SLASH /, Ascii 057, hard to type in Lisp code. + +Note that (eq (curchar) NL) is equivalent to (eolp). + + There is a special form to test if the current (to the right of point) +character is a given character: it is called if-at: + +(if-at "&" (display-error "You can't have an ampersand here!")) + +Its syntax is the same as _i_f, i.e., it has one or none or many "then" clauses +and "else" clauses, separated by the keyword "else" if there are any "else" +clauses. However, instead of a predicate, _i_f-__a_t takes either a +single-character string or a character object to be compared against the +current character. If the current (to right of point) character is that +character, the _t_h_e_n forms are evaluated, etc. _i_f-__a_t will convert the +character string to a character object at Lisp compile time, if necessary. +The specification of the character must be a form which evaluates to +the character of interest (e.g., "a", 'a, variable-bound-to-an-a): + +(if-at TAB (delete-char) + (whitespace-to-hpos next-field)) ;tab to next field. + + The exact effect (and actual implementation) of _i_f-__a_t is as though +it were a shorthand for + + (if (eq (curchar) ....) ..... ..... ..... ) + + There is similarly a function called "lefthand-char", which is like +_c_u_r_c_h_a_r except that it returns the character to the _l_e_f_t of the current +point; if the current point is at the beginning of the buffer, it returns +a character object for a newline (which is almost always what you want). +Similarly, there is an "if-back-at" special form, whose syntax and semantics +are identical to "if-at", except that it deals with the character to the +_l_e_f_t of the current point. + + Ther are two special forms for dispatching on the current (lefthand or +righthand) character. They are called dispatch-on-current-char +and dispatch-on-lefthand-char, and dispatch upon the character to the +_r_i_g_h_t and the _l_e_f_t of the current point respectively: + +(declare (special parentable)) ;global var. +(setq parentable nil) ;done when code is loaded into editor + +(defun count-parens-in-buffer () + (if (not parentable) ;if not initialized + (setq parentable (charscan-table "()"))) ;init it. + (let ((leftcount 0)(rightcount 0)) ;init the counts. + (save-excursion ;be nice + (go-to-beginning-of-buffer) + (do-forever + (if (not (search-charset-forward parentable)) ; look for ( or ). + (stop-doing)) ;exit the do. + (dispatch-on-current-char ;see which. + ( "(" (setq leftcount (+ 1 leftcount))) + ( ")" (setq rightcount (+ 1 rightcount)))))) + (minibuffer-print (decimal-rep leftcount) " opens, " + (decimal-rep rightcount) "closes."))) + +The general syntax of dispatch-on-current-char and dispatch-on-lefthand-char +is as follows: + +(dispatch-on-current-char + (CH1 + + ........... + ) + (CH2 + + ........... + ) +............................... + (CHk + + ........... + ) + (else + + ............ + )) + + The CHi's can be any form which evaluates to a single-character string +or to a character object. When the current character (left or right as +appropriate) matches a CHi, all of the 's in that clause are +evaluated sequentially, and the value of the last returned as the value +of the dispatch-on-current-char (nil is returned if there are no +'s). If no CHi's match, the else clause is evaluated as though it +were a matching clause. The else clause is optional; if omitted, and no +CHi matches, nil is returned. + + + P__r_o_g_r_a_m D__e_v_e_l_o_p_m_e_n_t + + The editor itself provides many powerful tools for developing extension +code and testing it while editing it. The following is a typical scenario +in the development of an extension: + + The user decides to write an extension. He sits down and thinks about +it, and decides to code it. He enters Multics Emacs. He does a +^X^Fshaver.lispCR, to go into a new buffer with a proper file name +and select Lisp major mode (assuming that he has, as all sophisticated users +should, opt for find-file-set-modes "on"). He should then type the form + + (%include e-macros) + +at the top of his file; this will be necessary to compile it (see +"Compilation" below), or to use the "loadit" command, as we will describe. +The file e-macros.incl.lisp should be in the translator search rules for +your process. A good way to to do this is put a link to it in the directory +in which you do Emacs extension development; the file is found in the same +directory as the editor. Now we begin to type in a function: + +(%include e-macros) + +(defun shave-line () + (go-to-beginning-of-line) + +At this point, to type the next line, lining it up with the last +Lisp form, we use the indent-to-lisp command, which is on ESC-CR +on Lisp mode, and the next form will automatically indent properly: + + (delete-white-space) + +(We deliberately gave the wrong name here). When typing in Lisp in general, +ESC-CR (in Lisp mode) will indent you on the next line the right amount. + + (go-to-end-of-line) + (delete-white-space) + +Now we are looking at the buffer with the code for "shave-line" in front of +us. We wish to try it. The best way to do this is to load the code in the +buffer into the editor. ESC-^Z in Lisp mode does this. No sooner do we do +this then we get the message: + + Unbalanced parentheses. + +What this means is that there were not enough close parentheses somewhere: +Emacs could not find the boundaries of the Lisp form. Now we fix the program +problem. We are on the last line, so we just type the close paren: + + (delete-white-space)) + +Now we do the ESC-^Z again. It works, the cursor returns to the function we +are trying to edit. Now to see if it works, we invoke it from Lisp: + + ESC-ESC shave-line CR + +ESC-ESC puts parens around what you type, evaluates it, and types out the +Lisp value so returned. However, we find the message + + lisp: undefined function: delete-white-space + +printed in the minibuffer, with the terminal bell rung. In fact, this is the +case. So we realize, that we must have the wrong function name. We know it's +on a key, so we + + ESC-X apropos white CR + +and learn about delete-white-sides. Now we go to the first line that +has the bad function name, with ^P's, do an @ to clear the line out, +ESC-^I to line up to re-type the form, and + + (delete-white-sides) + +We fix the other bad line, too. Now again we type + + ESC-ESC shave-line CR + +and to our surprise it says + + lisp: undefined function: delete-white-space + +as though we hadn't changed anything. Indeed, fixing it in the buffer is not +good enough. We must reload it into the editor environment, so we use +ESC-^Z again, after fixing the screen. Now we try it again: + + ESC-ESC shave-line CR + +and immediately our function on the screen changes appearance, all the +whitespace on the ends of the last line of the function we edited disappears. +Indeed it works, but it has messed up its own face! This is a problem with +editing what you are testing: It must either be innocuous, i.e., do +something harmless, or you must be prepared to reconstruct damage your +nascient function perpetrates, or switch to a test buffer before running it. + + So we fix our function, and we are done. Wrong! It exists in an editor +buffer, and in the editor Lisp environment, but we must remember to write it +out: + + ^X^S + +will indeed write it out to shaver.lisp as we had set up for initially. Now +we have an operative Lisp program that we can use again. If in a future +invocation of the editor, we need to use it, we can type + + ESC-X loadfile shaver.lisp CR + +and get it into the environment. There are two problems with this, however: + + 1) Whoever loadfile's it will have to have e-macros.incl.lisp in his + translator search rules + + 2) The code will be executed interpretively by the Lisp interpreter in + the Lisp subsystem; Multics Emacs is compiled Lisp, and compiled + Lisp runs up to 100 times fster than interpreted Lisp and has fewer + problems. + +The file shaver.lisp should be compiled. Then, the compiled object segment +can be loaded into the editor with + + ESC-Xloadfile shaver + + Some other problems are of immediate interest to the extension writer. +It is possible to write loops that do not terminate, or that generate infinite +garbage. This is par for the course. If you invoke your command, and the +cursor never leaves the minibuffer, and ^G seems to have no effect, you are +in a loop. Hit QUIT, and use the "pi" Multics command to reenter Emacs. +If you are really unfortunate, you will get + + lisp: (nointerrupt t) mode, cannot accept interrupt + +in which case you were stuck in the process of generating infinite garbage. +In this case, you must release, and your editing session is lost. If you are +more fortunate, you will get your screen back, with the cursor at the place +your buggy function left it. Often, by looking at exactly where it left it, +you can get a good idea of what kind of thing was giving your program a hard +time. + + If you get messages from Multics which tend to indicate that there is no +more room in your process directory, you are probably generating an infinite +number of lines, i.e., an infinite buffer. Again, if you are up to this, you +must be aware of this. + + Another thing that can happen is you might expose some bug, or what you +believe to be bug, in Multics Emacs, or worse yet, Multics Lisp. If this +happens, please let us know via the trouble-report forwarding mechanism +described in emacs.info, describing what you encountered and why you think +it's a bug. + + It is also possible to destroy the editor environment by bad coding. +This is particularly true in running compiled code which was not checked out +interpretively (i.e., via ESC-^Z). Storing into "nil" is one common way to do +this. If the entire editor seems broken, and the redisplay won't even show the +screen, this is what you have done. Quit and release and start all over again. + + There is a function called debug-e, callable as + + ESC-X debug-e CR + +which will set "(*rset t)" mode and other Lisp debugging aids, and unsnap all +"lisp links". IT will also revert to native Maclisp QUIT/pi handling. To use +this, however, you must be familiar with the debugging features of Multics +Maclisp. + + To get the value of a global variable to be printed out, say, +fill-column, fool ESC-ESC into doing it by saying + + ESC-ESC progn fill-column CR + +Be careful, for values typed out are in octal. + + Now there exists an entire Lisp code debugging facility within +Emacs over and above this; it is called LDEBUG, or Lisp Debug +mode. It allows for the setting of breakpoints, dialogue with Lisp +within Emacs, tracing, and so forth. See ldebug-mode.info, +or the appropriate part of CJ52, Emacs Extension Writer's Guide. + + C__o_m_p_i_l_a_t_i_o_n + + All production Multics Lisp programs are compiled. This results in a +tremendous performance improvement, both for the user and the system. Compiled +Lisp programs are executed directly by the Multics processor; interpreted +programs are interpreted by the Lisp interpreter. Multics Emacs is compiled +Lisp. + + The Lisp compiler is a Multics program that can be invoked from command +level. It has the names lcp and lisp_compiler on it. To compile a program +named myfuns.lisp, you say + + lcp myfuns + +to Multics, and you will get, if all goes well, an object program named +"myfuns", which can be loadfile'd, in the working directory. + + The compiler diagnoses Lisp syntax errors. It warns you of implied +special variables (if you did not declare a variable special, and it is not +a local variable in the function in which it was referenced, there is a good +chance you either made mistake or a typo. All global variables should be +declared for this reason: e-macros declares the provided ones.) + + At the end of compilation, the compiler prints out the names of functions +referenced in the code but not defined in the file. This is normal; however, +you should scan the list it prints out to see if any are ones that you +thought you defined; if so, you have a problem. Check also for ones that +are obvious typos for what you meant. + + It is possible to do extravagantly complex things with the compiler; +especially, via the constructs known as L__i_s_p M__a_c_r_o_s (via which, incidentally, +the E__m_a_c_s environment special forms are implemented) to construct your +own special forms. We will not go into any of that here. Consult other +documents on Multics Maclisp. + + It is sometimes desireable, while editing a large extension program, +to load only one function, the one you are looking dead at on the screen, +into the editor environment. The powerful function compile-function, +on ESC-^C in Lisp mode, will compile the function you are looking at +(whose start is found by ESC-^A from where you are now) out of a temporary +segment in the process directory, load the object segment, and display the +compiler diagnostics via local printout. It should be used with care by +any except experienced Emacs extension coders. Be careful, when using it, +to remember to write out your changes, and recompile your whole program, +because a program incrementally debugged in this mode gives the impression +that it is working properly when it is only doing so in the current editor +environment. + + + D__o_c_u_m_e_n_t_i_n_g C__o_m_m_a_n_d_s + + One of the most attractive features of the Emacs environment is the +automatic documentation system (apropos, ESC-?), which provides customized +Emacs command documentation on request. Documentation for supplied +commands is kept in a special file in the Emacs environment directory. +Extension writers may provide documentation for their own commands by +placing a string, which is that documentation, as the "documentation" +property of the symbol which is the command being documented. For instance, +if the symbol "remove-every-other-word" has the "documentation" property +of + + "Removes every other word from the sentence in which the cursor appears." + +this information will be displayed by ESC-? when used on some key which had +been set-key'ed to remove-every-other-word, or by + + ESC-X describe remove-every-other-word + + Documentation properties are assigned most conveniently via the +Lisp special form "defprop", whose general syntax is: + + (defprop SYMBOL WHAT PROPERTY) + +which gives the symbol SYMBOL a PROPERTY property of WHAT. "defprop" +is a special form because the actual symbols appearing in the form +are used, they are not variables, as in "(+ a b c)". Thus, + + (defprop Joe Fred father) + +indeed gives the symbol "Joe" a "father" property of "Fred". +("defprop" is a special-form way of doing the same thing as the +"putprop" function, but it is a special form because is "arguments" +are NOT forms to be evaluated to produce symbols whose properties +are to be dealt with, but the symbols themselves). To use +"defprop" to establish Emacs command documentation, place forms like + +(defprop remove-every-other-word + "Removes every other word from the current sentence. +Will not work on sentences ending in ""?"". For indented +sentences, use $$remove-other-word-from-indented-sentences$. +$$$ is a very powerful, dangerous, command." + documentation) + +Note several things about the documentation string: + + 1. It does not need to end in a newline, and may contain newlines. + + 2. Quotes (") inside of it must be doubled. + + 3. The string "$$$" will be replaced by the key being asked about + (e.g., "ESC-^Z" or "ESC-X remove-every-other-word") at the time + the documentation is displayed. + + 4. The keys used to invoke other commands may be referenced by stating two + dollar signs, the name of the command, and one dollar sign. Thus, + $$go-to-end-of-line$ will appear as "^E" in most environments; the point + of this and the previous paragraph is to make documentation expansion + independent of a user's key-bindings. + +The entire documentation string will be "filled" (ESC-Q'ed) _a_f_t_e_r all +command-name substitutions are made; thus, the placement of newlines in the +documentation string is basically ignored. Two consecutive newlines, however, +will be preserved, and thus, lines may be set off for "examples", etc., by +surrounding them with blank lines. + + It is slightly more efficient, but clearly less readable, to place the +defprop's documenting a command _b_e_f_o_r_e the "defun" defining the command +itself. The "defcom" facility may also be used to document commands; +See "Defining commands with defcom" below. + + W__i_n_d_o_w M__a_n_a_g_e_m_e_n_t + + Although buffers appear in windows on user request, and are switched +between automatically by the redisplay when the user switches windows with the +^X^O, ^X4, and so forth, there are times when extension writers may +want to take advantage of multiple windows explicitly. Good +examples in supplied code are RMAIL reply mode and comout (^X^E). + + Most of the extensions of interest are ones in which the extension +writer wants to place some information in a buffer, or else prepare +some buffer to have information placed in it (e.g., RMAIL reply) +and then display that information in a window. Normally, all that +is required is to "go to" that buffer (e.g., with go-to-buffer or +go-to-or-create-buffer), and the redisplay will "find" the editor +in that buffer at the time of the next redisplay, and it will +replace the contents of the selected window on the screen. +We will call such commands "autophanic" (self-showing). Examples +are ^XB (select-buffer), ^X^F (find-file), etc. + + However, there are commands that wish to set up buffers in some +_o_t_h_e_r window than the current window, usually for multi-window +operations such as mail reply, so as not to disturb the contents +of the current window. We will call them "heterophanic" (other-showing). +The standard examples are dired-examine, mail reply, and comout (^X^E). +Note that all the examples given are sub-commands of larger, +autophanic commands. + + Heterophanic buffer behavior is provided by the function +find-buffer-in-window, whose purpose is mentioned in windows.info (CH27 Sec. +XVI). It takes as an argument a buffer-symbol (Lisp symbol representing a +buffer). That buffer will be created if it does not now exist, and will be +"gone to", as if go-to-buffer had been used. If Emacs is in single-window +mode, the effect will be the same as that of go-to-or-create-buffer. In +two-window mode, that buffer will be put on display in one window or some +other as follows: + + If it is already on display in some window, it will be left there. + If it is _n_o_t, it will be put on display in some _o_t_h_e_r window, + meaning the one in which the cursor is _n_o_t, and the cursor + will move to that window, as if a ^X^O had been done. The + least-recently used window will be chosen. + + Thus, on printing terminals and in single-window mode, the effect +of find-buffer-in-window is indistinguishable from that of +go-to-or-create-buffer. In multi-window mode, it is equivalent to +"go-to-or-create-buffer and show it someplace else on the screen." + + You must not use find-buffer-in-window to place a buffer on the +screen once you have already gone to it; if you think of +find-buffer-in-window as a fancy kind of go-to-or-create-buffer you +will find no need for doing so. IF, however, you encounter this very +rare need (Emacs uses it only once!), how to do it will be +described below. + + It is an extension's responsibility to establish multiple windows if it +_n_e_e_d_s them; no current Emacs code _r_e_q_u_i_r_e_s multiple windows, although the +facilities mentioned above are more utile when already in it. + + Variables, predicates, and other functions to determine or +effect the window organization (number of windows present, etc.) +are presented below. + + Most extensions that place an auxiliary buffer on display via +find-buffer-in-window provide some command to return to the "main" +buffer (e.g., the RMAIL Incoming Message buffer, the buffer from which +^X^E was issued, etc.). It is the case that if you entered a buffer +via find-buffer-in-window, you should probably return to the buffer +from whence you came via find-buffer-in-window as well; the effect of this +is to restore not only the original buffer, but the original window +as well. Thus, save-excursion-buffer _c_a_n_n_o_t be used effectively +to effect returns from trips into buffers entered via find-buffer-in-window; +an attempt to use save-excursion-buffer will result in both windows showing +the same buffer, as the "selected window" (i.e., the cursor-bearing window) +is now changed and a new buffer selection means a new buffer in that window. + + It is the intended standard that ^X^Q be used to exit auxiliary buffers +used by extensions to return to their "main buffer", and usually switch +windows as well, if the multiple-window strategy outlined above is used. + + Pop-up window mode is in essence making all commands heterophanic. +Commands or subcommands that are naturally heterophanic need not worry about +pop-up window mode, because find-buffer-in-window, takes the appropriate +action in either pop-up or non-pop-up mode. However, if proper heterophanic +behavior under pop-up windows is desired, naturally autophanic commands and +subcommands must call a window-management primitive to obtain +heterophanic behavior in pop-up window mode. The primitive +of interest is called select-buffer-window, which takes two arguments +a buffer-symbol, and a "key" which gives pop-up window management +some clue to what size window would be wanted if awindow had to be created. + + In non-pop-up window mode, select-buffer-window is equivalent to +go-to-or-create-buffer, and the key is ignored. In pop-up mode, it is +equivalent to find-buffer-in-window, with the key suggesting the +new window size. + + The following values for the key argument to select-buffer-window +are accepted. They specify the window size in pop-up mode if the +window does not exist already: + + any number That many lines. + 'cursize Make a choice based on + the current number of lines in + the buffer. + nil Choose some reasonable fraction + of the screen. + 'cursize-not-empty Same as nil if the buffer is empty + but same as 'cursize if it's not> + For example, ^X^F uses this, because + you will type into a new buffer. + 'default-cursize If this buffer has never been displayed + before, make some decision based on the + number of lines. Otherwise, use + what size was chosen last time.. + + As we mentioned, find-buffer-in-window may not be used to place +the "current buffer" heterophanically. If you attempt to do this, i.e., + + (find-buffer-in-window current-buffer) + +you will find it appearing in both the old and new windows, for the +window manager will find that you were in this buffer in the +current window (a truth) before you went to another one (you had +to go to another one, as per heterophanic behavior), and +will indicate that the current buffer is to be displayed in the old window +as well, for that was the last buffer you were in in that window. +To avoid this, use select-buffer-find-window (of two arguments, +the buffer and a key as for select-buffer-window) if heterophanic +display of the current buffer is needed, i.e., + + (select-buffer-find-window current-buffer nil) + +It is very rare that this is needed; it is very rare to go to a buffer +and then want to find-buffer-in-window it; in supplied Emacs, only +^X^E does this. + + As all things that would want to use these features are of necessity +moderately sophisticated, only an outline of an extension using them +is given here. It is a typical sub-subsystem (e.g., dired) which +sets itself up in an autophanic buffer display, with specific +key bindings, etc., and has a heterophanic sub-display by which +it displays a "menu" in addition to the main display: + +(defun unusual-mode () ;Setup function for this + ........... ;mode. + (go-to-or-create-buffer (maknam (explodec "Unusual buffer"))) + (set-key 'ESC-^S 'unusual-mode-show-menu) + (select-buffer-window current-buffer nil) + (register-local-var 'unusual-mode-buffer-to-return-to) + ...........) + + ............ +(declare (special unusual-mode-buffer-to-return-to)) ;for compiler. +(defun unusual-mode-show menu () + (setq unusual-mode-buffer-to-return-to current-buffer) ;save buff + (find-buffer-in-window 'Unusual-Menu) ;Display menu + (set-key 'r 'unusual-mode-select-item) ;Set key bindings + (set-key '^X^Q 'unusual-mode-menu-return) + (insert-string "Unusual menu delicacies") ;Fill it up + ;; Will not actually be displayed until command finishes. + ....... + (go-to-beginning-of-buffer) + (setq current-buffer-mode 'Unusual/ Menu buffer-modified-flag nil + read-only-flag t) + .........) + +(defun unusual-mode-menu-return () + (find-buffer-in-window unusual-mode-buffer-to-return-to)) + ;;Return to calling buffer. + + There are several more primitives the window-sensitive +extension writer should be aware of. They deal with windows by "window +number". The topmost window on the screen is window number 1; The +next one down, if any, is number 2, and so forth down (the minibuffer and +mode line do not count as windows in this consideration). The concept +of selected-window (and selection of windows) is as in windows.info +(or CH27, Section XVI.) + + selected-window + This _v_a_r_i_a_b_l_e contains the number of the currently + selected window. Do _n_o_t attempt to setq it to select a window; + Use select-window instead. + + nuwindows + This _v_a_r_i_a_b_l_e contains the number of windows on the + screen; do _n_o_t attempt to setq it to create or delete + windows; use delete-window and the ^X2 and ^X3 functions + to do these things. + + select-window + This _f_u_n_c_t_i_o_n (of one argument, a window number) + does what ^X4 does (with an argument), i.e., selects that + window. + + delete-window + This _f_u_n_c_t_i_o_n of one argument, a window number, + removes that window from the screen, dividing up its space + to adjacent windows. + + buffer-on-display-in-window + This _p_r_e_d_i_c_a_t_e function of one argument, a buffer-symbol, + and returns truth/falsity, truth if and only if the specified + buffer is on display in some window currently on the screen. + If used as a _f_u_n_c_t_i_o_n, i.e., the value returned + is inspected, it will be found to be the window number in which + the specified buffer is on display (if it is _n_o_t on display, the + symbol "nil", via which Lisp represents falsity, is returned). + + window-info + This is a function of one argument, a window number, which + returns information about that window. The information + is in the form of a piece of Lisp list structure, which may be + decomposed by the Lisp list destructuring functions; assuming + that "info" has the result of window-info, the following forms + return the information as follows: + + (caar info) => The top line-number on the screen of the + window. The topmost is #0. + (cdar info) => The number of lines in the window. + (caddr info) => The buffer-symbol of the buffer on + display in the window. + (cadddr info) => A string duplicating the contents of the + "cursor line" of the window, including + its new-line character. The cursor + line of a buffer is that line where the + cursor is (if it is in the selected + window) or would be if that window + became selected (e.g., ^XO). + + window-adjust-upper + A function of two arguments, the first a window number, and + the second a _s_i_g_n_e_d number of lines to move its + upper divider-line _d_o_w_n (negative is up). + + window-adjust-lower + Same as window-adjust-upper, but deals with lower divider line. + + W__r_i_t_i_n_g S__e_a_r_c_h_e_s + + There are several useful functions provided for the extension writer +to aid in providing search-type commands. These functions prompt +for the search string, defaultify the search string, and announce +search failure in a standardized way which causes all Emacs search +commands to behave in a uniform fashion. All supplied Emacs searches +use them. + + get-search-string + Takes one argument, the prompt. The prompt ought contain + the word "search" somehwere, so that the user might know + that a search is being prompted for. get-search-string will + prompt the user for a search string, which the user must + terminate with a CR, and return it as a string. + If the user gives a null string, the last search string + will be used and echoed. The last search string will be set + to the returned string for the next defaulting. + + search-failure-annunciator + Causes the "Search Fails." message to appear in the minibuffer, + and a command-quit (^G) to be performed. Note that this will + abort any keyboard macro collection or execution in progress. + + The writer of a search-type command should provide two interfaces, +a "command", which deals in calling the above two primitives, and a +"search primitive", also called by the "command". The search primitive +should return t (truth) if the search succeeds, leaving "point" +at the proper place as the search defines. If the search fails, +the primitive must return nil (falsity), and leave point where it +was when the primitive was invoked. + + Here is a simple implementation of a "wraparound search", like +the default search in the QEDX editor. It first looks from point to +the end of the buffer for the search string, and if that fails, it goes +to the top and searches again. It is not optimal because the it need not +scan farther than the original point when starting from the top. Using +"point>markp" and searching a line at a time would be very expensive, +due to point>markp's expense. Searching a line at a time using +forward-search-in-line an mark-on-current-linep would be acceptable, but +more complex than this example need be. For a search which is probably +going to be used only as a user interface (i.e., not internally), this +implementation is probably adequately efficient. + + Here is the internal primitive for wraparound search: + + (defun wraparound-search-primitive (string) + (with-mark m ;Remember starting point + (if (forward-search string) ;Look to end of buffer + t ;Return truth. + else + (go-to-beginning-of-buffer) + (if (forward-search string) ;Look from top. + t + else + (go-to-mark m) ;Return to orig. place. + nil))))) ;Return falsity + ;; with-mark and this function, will + ;; return the value of the outer "if". + + Now here is the command for calling the primitive: + + (defun wraparound-search () + (if (not (wraparound-search-primitive + (get-search-string "Wraparound Search: "))) + (search-failure-annunciator))) + + wraparound-search is the command to which some key should be bound +if this type of search is to be made available from the keyboard. + + + C__a_l_l_i_n_g M__u_l_t_i_c_s C__o_m_m_a_n_d_s + + There is a common need in extensions, especially those like DIRED, +which manipulate the Multics Environment, to call Multics commands, +or, more generally, execute Multics command lines. + + The issue of calling PL/I-coded subroutines is a separable one. The +Lisp defpl1 facility is used for that, and we have not documented this yet. +See extant extensions (and e_defpl1_.lisp) for examples and usage until then. + + There are two primitives provided for executing Multics command lines. +Multics command lines are strings submitted to cu_$cp for execution. +This is the Multics agency to which the "e" requests of EDM and QEDX, +the ".." requests of read_mail, send_mail, and debug, and other subsystems +submit command lines. These are they: + + e_cline_ + Takes one argument, a string, which is passed to cu_$cp for + execution. No reattachment of output takes place. If the + command line produces output, it will mess up the screen. + This should only be used when no output is anticipated, and + indeed should be used then in preference to comout-get-output, + as it is much faster. + + comout-get-output + Takes any number of arguments, which may be strings or symbols, + and catenates them with one space between them to form a + Multics command line (facilitating things like + + (comout-get-output 'dl this-seg '-bf) + + ). Reattaches user_output and error_output during the + execution, rerouting them to a process directory file. When + the command execution completes, the contents of the current + buffer is obliterated (!) and the temporary file read in to it. + This is the primitive that Comout (^X^E) uses. e_cline_ + is used by comout-get-output internally. + + These primitives set up a condition handler that catches all "abnormal" +Multics signals and returns. A very major deficiency at this point, which is +not likely to be remedied in the near future, is that requests for input by +these command lines cannot be dealt with reasonably at all. In the case of +e_cline_, the user will get the query in raw teletype modes, and will have to +answer it in raw, nonedited teletype modes. In the case of comout-get-output, +the query will never appear in any form at all, having been routed to the +temporary segment, and the user's process will hang infinitely, the user +not knowing to respond having never seen the query. + + M__u_l_t_i_c_s E__r_r_o_r T__a_b_l_e + + Sometimes it is necessary to get the value of standaard Multics error +codes, from error_table_, into a program, to be able to see if a given +Multics interface has in fact returned it. The function "error_table_" +(spelled the usual way with underscores, not hyphens) is used for this +purpose. Its single argument is a symbol, whose name is the name +of the error_table_ entry whose value is sought, and the returned +result is that value, or 1 if it is not a valid entry. + + The error_table_ function optimizes finding the same name over +and over again, so the extension writer need not go through machinations +to "save" an error_table_ value computed by these means. +Here is an example of the use of error_table_: + + (let ((status-result (hcs_$get_user_effmode dir entry ""))) + (if (not (= (cadr status-result) 0) ;the return code + (if (= (cadr status-result)(error_table_ 'incorrect_access)) + (display-error-noabort "Warning: not checking access") + else + (display-com-error (cadr status-result) dir ">" entry)))) + + + Defining commands with defcom + _____________________________ + + The "Defcom" (short for _d_e_f_i_n_e-_c_o_m_m_a_n_d) facility is a fairly new addition +to Emacs (and thus many internal functions are not converted to use it) for +simplifying the definition of Lisp functions to be used as Emacs commands, +either keystroke requests, or extended commands. Defcom cooperates +with the Emacs command-reader to provide prompting and defaulting +of unspecified arguments, range-checking of numeric arguments, +automatic repetition for numeric arguments, if desired, cross-connecting +symmetrical functions via negative arguments, and other features. + + Defcom should only be used for defining functions actually to +be used as Emacs commands; internal and auxiliary +functions to be used by these functions should still be defined with +defun. Emacs commands defined with defun will continue to work, but +those defined with defcom produce much better diagnostics and +offer more features. Defcom is actually a technique whereby +the necessary "defun"'s are generated automatically, so functions +defined with defcom may be called from other functions, as well. + + To define a function with defcom, one uses defcom instead of defun, +and supplies no Lisp argument list, i.e., + + (defcom one-word-from-beginning + (go-to-beginning-of-buffer) + (forward-word)) + +This is the simplest form of defcom; optional features are supplied by +placing, between the function name and the function code, various keywords, +all of which begin with the "&" character, and some of which take optional +arguments, expressed as lists. + + The most common optional specification is &numeric-argument, +(or &na for short), which specifies what to do with a supplied numeric +argument, if any. The keyword &numeric-argument must be followed by +a list of specifications, which must include one of the following +maJor processing types: + + &reject Any numeric argument is rejected as invalid. + Clearly, no other specifications are valid + in this case. This is the default if + &numeric-argument is not given. + &ignore A numeric argument is ignored. + &repeat If the argument is positive, the + command is repeated that many times. + &pass The value of the Lisp variable "numarg" + is set, as in non-defcom commands. + + In addition to the major processing type, optional bounds may +be specified by the keywords &upper-bound (&ub) or &lower-bound (&lb). +These, in turn, must be followed by either an integer being the bound, or the +keyword &eval followed by an expression to evaluate at the time command +execution is attempted, which will then produce a value (such an expression +will be called an "&eval expression".) Here are some examples of +&numeric-argument specifications: + + &numeric-argument (&pass) + &numeric-argument + (&repeat &lower-bound 1 &upper-bound &eval (+ max-foos 2)) + &numeric-argument + (&pass &upper-bound 15.) + + A command defined with defcom may elect to receive Lisp arguments, +that is to say, values which are to be prompted for or supplied as +extended command arguments can be provided automatically, and prompted +for, by the Emacs command reader, and supplied as Lisp arguments to the +command function. Instead of a normal Lisp argument list, the +keyword &arguments (or &args or &a), followed by list of argument +specifications, one for each Lisp argument to be supplied. + + Each argument specification consists of the Lisp name of the argument, +i.e., the name of the variable which will be referred to inside the function, +and any number of "argument qualifiers", separated by spaces. Each +argument qualifier may consist of several tokens, as necessary. Argument +qualifiers specify the prompts, defaults, etc. for an argument. +An argument specification may also be given as the name of the variable +alone, as opposed ot a list of it and qualifiers. In this case, +it is equivalent to having its own name as a prompt for its value. + + When a defcom-defined commands is invoked as an extended command, +(i.e., via ESC-X), the Emacs command reader will check the type and +number of command arguments supplied and necessary, and prompt for those not +supplied or default them as specified. When a defcom-defined +command which has arguments is invoked from a key, it is as if +it were invoked as an extended command with no command arguments given, +and all are either prompted for or defaulted. + + Here are the valid argument qualifiers: + + &string + &symbol + &integer Specify how the argument, when read + by ESC-X or prompted for is to be converted + before being passed. Only one at a time + of these are valid in a given argument + specification, and &string (i.e., no + conversion) is the default. + + &default Must be followed by either a string, + symbol, or integer, as consistent with + the expected data type for this argument, + or an &eval expression. Specifies the + default value to be used if this argument + is not supplied, or a null response + is given to a prompt for this argument, + if any. + + &prompt Specifies the prompt for this argument, if + not supplied via ESC-X. Prompts will be + put to the user before defaults are evaluated + or used; A null string causes the &default + value to be used. &prompt is followed by + a prompt string (in quotes)(or an &eval + expression), and one of the two optional keywords + NL or ESC, specifying the prompt terminator + (ESC is obsolete, use NL in all cases). + If neither NL or ESC is given, + NL is assumed as the default. + + &rest-as-list Valid only for the last argument. Causes + this variable to be given as a value a + list of all of the remaining supplied + arguments, however many they may be. If + &rest-as-list is used, the caller of this + function from Lisp (including start-up's written + by possibly not-Lisp-conscious users) + must know that the number and organization + of Lisp arguments is therefore different + from the apparent argument array given to + ESC-X. + + &rest-as-string Valid only for the last argument, causes + all remaining arguments to be supplied as + a single string to the function, a single + argument, as they appeaed to ESC-X, with + spaces and so forth included. Same cautions + as &rest-as-list apply. + + Here is a function definition which accepts three arguments: + +(defcom replace-n-times + &arguments + ((oldstring &string &default &eval (get-search-string "Old: ")) + (newstring &string &prompt "New String: " NL) + (count &integer &prompt "How many times? " NL &default 1)) + + (do-times count + (if (not (forward-search oldstring))(search-failure-annunciator)) + (do-times (stringlength oldstring)(rubout-char)) + (insert-string newstring))) + +Note that it can be invoked as + + ESC-X replace-n-times Washington Lincoln 2 CR + +or + + ESC-X replace-n-times CR + +in which case all arguments will be prompted for, or + + set-perm-key ^Z9 replace-n-times + +followed by striking that key at some time, will prompt for +all arguments, too. This function is so defined that it may +be called from Lisp as + + (replace-n-times "this" "that" 17) + +or whatever, i.e., it is a Lisp function of three arguments. + + When defcom-defined commands are re-invoked by ^C, they are +repeated with identical arguments. This is what makes search-repetition +by ^C work. + + Other than numeric arguments and command arguments, defcom +may be used to spceify prologues, documentation, and negative-functions +of command functions. Documentation is specified by the +keyword &documentation (or &doc) followed by a documentation +string subject to the same rules as given above under "Documenting +Commands". Prologues are functions or code to be executed +before any arguments are prompted for, perhaps to check for legal +circumstances for calling this command. Negative functions are +functions or code to be executed if the command is supplied a negative +numeric argument: the negative function is given the negative numeric +argument made positive. Prologues and negative functions are +speicifed by the keywords &prologue, or &negative-function +(short, &nf), followed by the name of the appropriate function, +or forms, terminated by &end-code. Here is an example of the +use of some of these features: + +(defcom forward-topic + &doc "Goes forward one or more topics. See also $$backward-topic$." + &numeric-argument (&repeat) + &negative-function backward-topic + (with-mark m + (forward-search "Topic::"............ + + + +Yet to be documented: + +Lisp macro catalogue. +Emacs interrupt system. + + + As this document is extended and augmented, it may not approach true +"completion" in any given length of time. Thus, there are still "tricks" +and functions that are not documented above. The extension writer should +study the supplied extensions, such as Fortran Mode (fortran-mode.lisp) +and RMAIL (rmail.lisp), as well as the "fundamental mode extensions" +in e_macops_.lisp. These programs are found in the Emacs source archive. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/fortran-mode.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/fortran-mode.info new file mode 100644 index 0000000..898312f --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/fortran-mode.info @@ -0,0 +1,193 @@ +01/31/79 Multics EMACS Fortran mode. Paul Schauble + DVCP M.S. C34 + 602-866-4531 + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + This is the second edition of EMACS Fortran mode. This +mode is intended to aid in the construction and debugging of +Fortran programs using EMACS. Commands are provided for +producing comment and continuation cards and for other commonly +used formatting operations. + + Fortran major mode is entered via the following command: + + ESC-X fortran-mode CR + + This mode may also be entered by Find File'ing any file +with a last component name of ".fortran" when the +find-file-set-modes option is selected. + + The current list of special commands in Fortran mode is: + +CR Carriage Return has been changed so that the cursor will + return to column 7, rather than to column 1. This will + also insert comment prefixes ("c ") in the appropriate + places. If desired, the cursor may be moved back by hand + to delete spaces or comment prefixes. + +^I Tab has been changed so that a tab done in column 1 will + tab to column 7. Subsequent tabs will tab to the normal + places. The sequence for successive tabs is 7,10,20,30... + +ESC-^M Or ESC-CR ends the current line when the next line is a + continuation. A new line will be done, unless the current + line is blank or empty, and the prefix " & " will be + inserted, leaving the cursor in column 9. This is the + continuation for standard Fortran rather than for + Multics. + +ESC-; Begins a single comment line. A new line is done, unless + the current line is blank or empty, and the prefix + "c " inserted, leaving the cursor in column 7. This + may be used to end a line when the next line is a comment. + +^XC Begins a block of comments. The current line, if any, will + be ended and a comment block header line inserted. Any + future lines added will be prefixed by the standard + comment prefix "c ". This minor mode is exited by a + second ^XC. Notice that ^X^C exits the editor. Don't miss! + +ESC-: Positions a fortran label. Since a line usually starts in + column 7, this command is provided to correctly position + statement numbers. Type the statement number, then ESC-: + to place the label in column 1. + +ESC-^C Compile program. The current buffer, if changed, is written + out to its default pathname (as for ^X^S), and then + compiled. Compiler diagnostics are displayed, in the other + window if in two-window mode. The extended commands + set-compiler and set-compile-options may be used to select + the compiler and options to be used. + +^X^D Find next error. This command is used following a + compilation in two-window mode. It scans the compiler output + and the source buffer in parallel, pointing a simulated + cursor to consecutive errors and placing the real cursor on + the line referred to in the error message. This mode will + terminate itself when you advance past the last error, when + you do another compilation, or when you exit it by keying + ^XT. Since this mode locks the buffer used for + compilations, you are strongly advised to exit it when you + are finished. + +' Abbreviation expander. The two characters immediately + preceeding the cursor when this character is struck + are taken as an abbreviation and expanded. The + character ' may itself be inserted by quoting it with + \ or ^Q. These abbreviations are initially supplied: + in integer su subroutine + di dimension co continue + fu function re return + eq equivalence ex external + au automatic cn common + fo format im implicit + Note that, with the exception of cn for common, all of + these abbreviations are the first two characters of + the word. Other abbreviations may be defined using the + extended command set-fortran-abbrev. + The abbreviations co (continue) and re (return) are very + special. Since these words almost always have a label + and sit on a line by themselves, these abbreviations have + been hacked to do an ESC-: and a new-line, so that + typing (in column 7) + 123co' + will expand to + 123 continue + leaving you on the next line. The abbrev fo for format + hacks labels, but not new lines. Try them. + + In addition, several extended commands have been provided to set +various parameters. These are: + +For comment blocks: +ESC-X fortran-set-begin-comment CR to set the begin line, and +ESC-X fortran-set-end-comment CR to set the end line. + + Both of these commands prompt for the line in the minibuffer. +The line supplied is inserted exactly as given, and must therefore +include the "c" at the beginning. Default values for these lines are + "c ========================================". +These are set by buffer. + +For compilations: + ESC-X set-compiler compiler-name CR + to set the compiler to be used. Default is "ft". + ESC-X set-compile-options options CR + to set compile options. These are given as on the + compiler command. The default is "-tb". These are + set by buffer. + +And, for abbreviations, + ESC-X set-fortran-abbrev abbrev expansion label eol + may be used to define new abbreviations. abbrev must + be a two character abbreviation that will be replaced + with expansion. Arguments must be enclosed in quotes + if they contain special characters, including spaces. + The optional arguments label and eol will cause this + abbrev to hack labels and new lines, respectively, just + like co and re. The label option does not require a + label, but processes it if it is present. + Abbreviations are defined globaly and apply to all + buffers in fortran mode. For example, + ESC-X set-fortran-abbrev as "common /xyz/ y(100)" eol + defines an abbrev as that expands to + common /xyz/ y(100) + and does a new-line, but does not believe in labels. + + + As mentioned above, this is an early edition and there may +still be problems. Any difficulties, comments, suggestions, etc. +may be mailed to Schauble.fso (on System M, Phoenix) for action. +(MIT-Multics and other ARPANET users continue to send bug/comment +mail to emacs.bugs at MIT-Multics as usual, they will be forwarded). +In fact, I would like to know if anyone is using this thing. + + Intended for future implementation are: + +Debugging mode - Fortran debugging using probe integrated with + the editor. For now, the recommended debugging method + is to do a ^Z and run your program one level up. + Return to emacs with a pi command. + + + Any suggestions on these or other features should be mailed to +the above address. + + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/fundamental-mode.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/fundamental-mode.info new file mode 100644 index 0000000..e15faa0 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/fundamental-mode.info @@ -0,0 +1,1416 @@ +Multics Emacs Commands (Fundamental mode) 7/22/90 + + K__e_y_s _a_n_d _t_h_e_i_r _b_i_n_d_i_n_g_s + (Extended (esc-X) commands are listed at the end.) + +# rubout-char + + Deletes the previous character (before the cursor, which is usually the + last character typed, like in normal Multics.) Note that # deletes the + character to the left of the cursor, while ^D deletes the character at the + cursor. + +@ kill-to-beginning-of-line + + Kills all the text on the current line to the left of the cursor. The text + killed is saved on the kill ring, and may be retrieved with ^Y. + +CR new-line + + Inserts a newline character into the buffer at the current point, ending + the current line, and starting a new one. If entered in the middle of a + line, breaks the line at the current point. If the next line is empty, + i.e., was made by a single CR or ^O, CR will just go to it, and will not + insert a newline. However, the last empty line before a non-empty line + will be left empty. If there is a fill prefix (see ^X.), CR will insert it + after any newline character it inserts. + +ESC escape + + Used to enter two-keystroke key sequences, and to supply numeric arguments + to commands. For example, to enter the esc-K command, type ESC then a K. + To supply a numeric argument to a command, type ESC, the number, and the + command. For example, ESC 3 ^D deletes 3 characters. + +\ escape-char + + \NNN where NNN are 1 to 3 octal digits, inserts the character whose value + is NNN into the buffer. For example, \14 inserts a form-feed (^L). \\ + inserts a \; \# inserts a #; \@ inserts a @. \ followed by any other + character inserts \ and that character (except \ CR, which inserts a + newline). + +\177 rubout-char + + Deletes the previous character (before the cursor, which is usually the + last character typed, like in normal Multics.) Note that \177 deletes the + character to the left of the cursor, while ^D deletes the character at the + cursor. + +^@ set-or-pop-the-mark + + With no argument, i.e., ^@, sets the-mark in this buffer where the cursor + is now, and leaves it there. The current value of the-mark, if any, and + different than the current point, will be pushed on the mark ring. It will + move around properly if the text around the-mark is deleted. See ^X^X to + verify where the-mark is. With an argument, i.e., ^U ^@, pops a mark off + the mark ring, and positions to it. Successive ^U ^@'s will "try" all + marks on the mark ring. + +^A go-to-beginning-of-line + + Position to the beginning of the current line of the buffer. That is to + say, right before the first character. + +^B backward-char + + Move backward one character in the buffer. Tabs, and the newline + characters at the ends of lines count as one character. Will command-quit + at the beginning of the buffer. + +^C re-execute-command + + Re-execute the last keystroke (command), other than ^J or ^C. If used to + repeat a search, the search will be repeated with the same search string. + Useful for skipping successive words, etc. + +^D delete-char + + Delete the character to the right of the current point. This is the + character on which the cursor sits. Move the rest of the line one to the + right, closing up the space. Deleting a newline at the end of a line + merges lines. + +^E go-to-end-of-line + + Position to the end of the current line: that is, after the last character + and before the linefeed. On an empty line, this is the same as the + beginning of the line. + +^F forward-char + + Move forward one character. Tabs and newlines count as one character each. + Will command-quit at the end of the buffer. + +^G command-prompt-abort + + Quit out of the current minibuffer prompt if any, and ring the bell (or + beep). May be used to exit a minibuffer you did not intend to get into, or + just to tell when Emacs has "caught up." + +^J noop + + Linefeed; ignored. See also ^L. Good for exiting displays (such as ^X^B, + apropos, etc.) + + +^K kill-lines + + Kill to end of line, except when already at end of line, delete the + linefeed (merge lines). If on an empty line, delete it. If given a + numeric argument, deletes that many lines, starting from the current point + on the current line. + +^L redisplay-command + + Clear the screen, and display the current window of the current buffer, + centered about the current line. Useful if your screen is messed up by + messages (although see accept-msgs), non-Emacs output, etc. With a numeric + argument, moves current line to that line from the top of screen; ESC-1 ^L + moves current line to top, for example. With a negative argument, a line + counting from the bottom of the screen will be used. + +^N next-line-command + + Position to the next line of the buffer. If on the last line now, append a + new empty line to the bottom of the buffer, and position to the beginning + (and end) of it. Successive ^N's and ^P's try to maintain the same + horizontal position. + +^O open-space + + Open up space by putting a newline AHEAD of the current point. Pushes all + lines of the buffer below the current line down one. For instance, ^U^U^O + will open up 16 lines. See ^X^O to remove (extra) blank lines. + +^P prev-line-command + + Move to previous line of the buffer. Will command-quit if on first line of + the buffer. Attempt to maintain the same horizontal position. Successive + ^P's and ^N's will try to maintain the original horizontal position. + +^Q quote-char + + "Quote" the next character, i.e., insert it into the buffer literally. + This is used to enter control characters and other "funny" characters into + the buffer, i.e., ^Q# to insert a pound sign. ^Q CR, however, inserts a + single Newline chaacter (Newline characters separate lines in Multics + files.) + +^R reverse-string-search + + Reverse search. Leave cursor positioned before matching string, don't move + cursor if not found. Prompts for search string in minibuffer, which must + be ended with CR. + +^S string-search + + Search for a character string, from current point in buffer to end. + Prompts for string in minibuffer, and leaves point, if search succeeds, + after the matched string. End search string with CR. ^SCR re-uses last + search string. If search fails, point will not move. + +^T twiddle-chars + + Twiddle (transpose, interchange) the last two characters typed, like, I + like Mutl^Tics becua^Tse... etc. + + +^U multiplier + + Multiplier. When not followed by a number, multiplies the next command by + 4 for each use. i.e., ^U^D deletes 4 chars. ^U^U^D deletes 16. With a + number, uses that, i.e., ^U13x inserts 13 x's. + +^V next-screen + + Display next screenful of this buffer. Leave cursor at upper left hand + corner of screen. With an argument, displays that many screens ahead. + +^W wipe-region + + Wipe (kill) all text between cursor and the-mark. Succeeding kill commands + (like ^K, NOT ^W) will merge killed text. The killed text is saved on the + kill ring, and can be retrieved with ^Y. + +^X# kill-backward-sentence + + Kill backwards to the beginning of this sentence: kill as much of the + sentence as thus far typed. Successive kills via ^X# and other + reverse-killing commands (e.g., esc-#) merge, and may be retrieved with one + ^Y. + +^X( begin-macro-collection + + Start learning all which follows as a macro, until ^X) or an error occurs. + All commands and input between ^X( and ^X) will be remembered as a "macro", + which can be executed by ^XE, or saved and assigned to a key by save-macro, + and displayed by ^X*. + + +^X) end-macro-collection + + End a macro definition. The commands and input typed since ^X( become the + "last macro defined" for ^XE, which see. If given a numeric argument, + re-executes the defined macro as ^XE does (see that command). See ^X( for + what a macro is. + +^X* show-last-or-current-macro + + Display the commands (as keystrokes, i.e., ^A, ESC-B, etc.) in the last + macro defined (see ^X(). If given a numeric argument, i.e., ^U^X*, display + the keystrokes and command names. + +^X. set-fill-prefix + + Set "fill prefix" in this buffer to be whatever is between the beginning of + the line and the cursor. The "fill prefix" is inserted automatically by + CR, autofill, and runoff-paragraph. If the cursor is at the beginning of + the line when ^X. is issued, the fill prefix is reset (i.e., there will be + no fill prefix). It may be used to establish a "left margin". + +^X0 remove-window + + Removes a window from the screen; only valid if there is more than one + window on the screen. With no argument, ^X0 removes the current window. + With a numeric argument, it removes the window specified by the argument. + The uppermost window is window 1. + +^X1 expand-window-to-whole-screen + + The window in which the cursor appears will be expanded to fill the whole + screen; all other windows will be removed. This in essence returns to "one + window mode" from having any number of windows. The cursor will retain its + position in the text. See ^Z^W. + +^X2 create-new-window-and-go-there + + Creates a new window at the bottom of the screen, redividing the screen + equally among the windows there. The cursor will be moved to the new + window, which will have a buffer name created from its window number. See + ^Z^W. + +^X3 create-new-window-and-stay-here + + Create a new window at the bottom of the screen, redividing the screen + equally among all the windows. The cursor remains where it is. The new + window, which has a default buffer name created from its window number, + becomes the "least recently used window". See ^X4 and ^Z^W. + +^X4 select-another-window + + The cursor is moved to the least-recently visited window on the screen. + That window then becomes the most-recently visited. Thus, successive + applications of ^X4 will visit all windows on the screen. ^X4 is a good + command to use when you want to visit some new buffer or file, but not + overwrite windows containing information you have been looking at recently. + With an argument, i.e., ESC 3 ^X4, goes to that window, e.g., window 3. + + +^X; set-comment-column + + Make the "comment-column" in this buffer be the horizontal position where + the cursor is now.. With an argument, sets the comment column to that + number, counting from the left as column 1. See esc-;. + + +^X= linecounter + + Display in the minibuffer area the number of lines in this buffer, the line + number (the first line is line 1) of the line the cursor is on, and the + horizontal column position (on a dprinted line, not the screen). + +^XB select-buffer + + Switch to another buffer. Prompts for the name of that buffer, terminate + with CR. If that buffer does not already exist, it will be created. All + key bindings, fill column, comment column, comment prefix, etc., associated + with that buffer will be put in effect. The last point that you were at in + that buffer becomes the current point. ^XBCR goes to the last buffer you + were in. + +^XCR eval-multics-command-line + + Prompt for a Multics command line. Terminate it with CR. Multics commands + that produce output may well ruin your screen; if this occurs, use ^L. Use + ^X^E if you expect output. + +^XD edit-dir + + Enter the directory editor, editing the working directory. With an + argument, i.e., ^U^XD, prompts for other directory name. Position to a + line with some segment's name on it, and the following commands (keys) may + be used (lower case O.K.): + + D Delete this segment when the directory editor is exited. + U Undelete, i.e., cancel previous D on this line. + E Examine (i.e., take a look at) this segment, in a separate + buffer. Use ^X^Q to get back, and the examine + buffer will disappear of its own accord. + Q Quit the directory editor. A list of files will be shown, + and you will be queried if you want to delete them + or not. To exit without any action use ^XB. + R Rename this segment. The new name is prompted for. + N Same as ^N. + P Same as ^P. + +^XE execute-last-editor-macro + + Execute the last macro defined (via ^X( ), one or many times depending on + the numeric argument to this command: + + No argument: Execute it once. + 0( i.e., ESC-0^XE) Execute it over and over, pausing after each + execution. Type a space to go on to the next, + CR or ^G to stop repeating. + 1-9999 Do it that many times. + 9999-infinity Do it forever until an error happens. + +^XESC escape-dont-exit-minibuf + + ^XESC is the same as ESC, and may be used for all ESC-... commands and + numeric arguments, but may be used in the minibuffer when typing ESC would + terminate the minibuffer, as in search strings. + +^XF set-fill-column + + Sets the fill column in the current buffer to be the horizontal position + where the cursor is now. The fill column is the "right margin" used by + esc-Q to fill and adjust text, by fill mode to fill and adjust text, and by + esc-S to determine where to center. The fill column is the first column in + which text is NOT to be placed. The new value of the fill column is + printed out in the minibuffer. If a numeric argument is given, e.g., ^U 72 + ^XF, the fill column is set to that value. + +^XG get-variable + + Get back a "variable" stored by ^XX. The name of the variable will be + prompted for; the cursor will be put after it, and the-mark before it. + +^XH mark-whole-buffer + + Put the-mark at the end of the buffer and the cursor at the beginning. + This "marks" the whole buffer, so that ^W will delete it, etc. The + linefeed at the end of the buffer is NOT in the marked region, but ^XH ^W + ^XB ... ^Y will effectively move a whole buffer. + +^XI insert-file + + Insert file. Prompts for a filename, terminated by CR. Reads that file + into the current buffer without destroying the previous contents of the + buffer. The file is read in to the left of the cursor and the cursor is + left after the contents of the file just read. The default file for the + buffer is not changed. (See ^X^S.) + + Archive component pathnames are accepted. Starnames are accepted, but no + more than one segment or archive component can match the starname. + +^XK kill-buffer + + Kill (destroy) a buffer. Prompts for the buffer's name. End with CR. + Buffers may be killed to conserve storage, or not to appear in buffer + listings or to prevent quitting (see ^X^C). If you kill the current + buffer, prompts for another buffer to go to, as in ^XB. + +^XM send-mail + + Enter the Emacs mailer (RMAIL) to compose a letter of outgoing mail. ^XM + will prompt for the mail subject, end the subject with a carriage return. + For full information on reading and sending mail, see rmail.info. + +^XO select-other-window + + When in two-window mode, (see ^X2) move the cursor to the other window, + implicitly (usually) switching buffers. The mode line will be updated to + reflect the new buffer. The cursor will appear at the last point it was in + the new window. In general, the cursor will enter the window used last, + immediately before the current window was entered. + +^XQ macro-query + + Query. Only usable while macros are being collected: when the macro is + run, ^XQ will query the user for a character: space will continue execution + of the macro. ^G will stop the macro altogether. CR or other random + characters will restart the macro from the beginning. In this way, + + ^X( ^S f o o ESC ^XQ esc-U ^X) + +will "query replace", i.e., interrogatively upper-case all foo's. + +^XR rmail + + Enters the Emacs RMAIL subsystem to read mail. Without an argument, that + is, ^XR, your default mailbox is used. With an argument, that is, ^U ^XR, + the mailbox name, which may take any reasonable form (such as + Washington.States, Palter, >udd>m>abc>abc, etc) is prompted for. The first + message in the mailbox is placed in a buffer in RMAIL mode. Type "q" to + exit RMAIL and delete all mail queued for deletion during RMAIL. Refer to + rmail.info for full info on RMAIL and reading and sending mail. + +^XS global-print + + Global print all lines a la QEDX. Prompts for a string. With a numeric + argument, i.e., ^U^XS, takes a QEDX-like regular string. End in either + case with CR. Prints all lines containing that string. Type ^J or + continue editing to restore buffer display. + +^XV view-lines + + View lines or region, for printing terminals. The optional numeric + argument is how many lines to print- leaves you after them, unless argument + is 1 or not supplied, in which case it leaves you on current line, after + printing it. ESC-0^XV views the region (between cursor and the-mark), thus + ^XH ESC-0^XV prints the whole buffer. With a negative argument, prints + lines starting that many back. + +^XW multi-word-search + + Multi-word search. Prompts for one or more words, terminated by CR. (this + is a search string; just CR re-uses last). Searches from current point to + end for those words appearing in order, regardless of case of letters, + underlining, intervening punctuation, whitespace, or line breaks. Finds + whole words, not parts of words. A word that ends in * will match the rest + of a word to *. With a numeric argument, (^U^XW), goes to beginning of + buffer before searching. + +^XX put-variable + + Store away point/mark region to a "variable", whose name will be prompted + for. Use ^XG to retreive this value, and list-variables to get it back. + +^X\177 kill-backward-sentence + + Kill backwards to the beginning of this sentence: kill as much of the + sentence as thus far typed. Successive kills via ^X\177 and other + reverse-killing commands (e.g., esc-#) merge, and may be retrieved with one + ^Y. + +^X^B list-buffers + + Produces listing of buffers and their pathnames. ">" marks buffer you came + from, "*" says buffer is modified since it was last read or written. + Proceed with editing, or type ^J to refresh screen. + +^X^C quit-the-editor + + Exit the editor. If modified buffers exist, they are listed as if by ^X^B; + ^X^C then asks you if you really want to exit the editor. + +^X^E comout-command + + Executes a Multics command line (prompted for, end with CR), and places the + output in a buffer; if the command line is empty this request is aborted. + The output is placed in the buffer "file_output"; however, if the command is + given a numeric argument (e.g. ^U^X^E) the "comout-command-to-buffer" + command (see below) is executed. The file_output buffer is made the current + buffer. + +^U^X^E comout-command-to-buffer + + This is like "comout-command", except the user is prompted for the name of a + buffer (which is used instead of "file_output"). This can be made the + normal operation of ^X^E by placing the following line in the start_up.emacs + (see Appendix G for more information on the start_up.emacs): + (set-permanent-key "^X^E" comout-command-to-buffer) + +^X^F find-file + + Find file. Prompts for a filename, terminated by CR. If the file is + already in a buffer, ^X^F goes to that buffer (see ^XB). If the file is in + more than one buffer, you will be queried about which one (or a new one) to + use. If the file is not in any buffers, it will be read into a new, + appropriately-named buffer. This is the standard way to read in a file or + create a buffer for a new file. + + If no such buffer exists, ^X^F reads the file into the buffer whose name is + the first component of the entry portion of the filename, and sets the + default file of this buffer to the file just read. If the + find-file-set-modes option is on, ^X^F will set the major mode of the + buffer according to the last component of the entry portion of the + filename. (For example, for the filename ">ldd>include>sst.incl.pl1", the + buffer chosen is "sst" and the major mode is "PL/1".) + + ^X^F will accept archive component pathnames (archive::component). ^X^F + also accepts star names (including stars in the archive and component + names). When more than one star match is found, a ^X^F is done for each + segment/archive component selected. + +^X^G ignore-prefix + + Flush a prefix character. Used when a prefix character such as ESC is + entered by accident; causes an audible signal to indicate that the ^X^G has + been executed. Unlike ^G, does not exit the minibuffer. + +^X^I indent-rigidly + + Re-indents all lines in the region defined by the cursor and the mark by + the amount specified by the numeric argument. The numeric argument may be + negative to unindent. All lines that have any characters between the + cursor and the mark will be re-indented; thus, a line with the region + ending at its beginning will not be re-indented. + +^X^L lower-case-region + + Lower-case all letters between the cursor and the mark. + +^X^O delete-blank-lines + + Delete blank lines around cursor: get rid of vertical whitespace. If + issued on a blank line, leave one blank line. Otherwise, delete all blank + lines after this line's end. See ^O. + +^X^R read-file + + Read file. Prompts for a filename, terminated by CR. Reads that file into + the current buffer destroying anything which was in the buffer, and sets + this buffer's default file to the file read. The cursor is left at the + first position of the first line of the file read. If a blank response is + given for the filename, the buffer's default file is read. The default + file is set by ^X^R, ^X^F, and ^X^W. + + Archive component pathnames are accepted. Starnames are accepted too, but + no more than one segment or archive component must match. + +^X^S save-same-file + + Save file. Writes the contents of the current buffer to its default file. + This command is equivalent to ^X^WCR. + +^X^T toggle-redisplay + + Turns off all screen updating until the next ^X^T, command-quit, or error + happens. ^X^T may be used on slow terminals with no insert/delete + facilities to avoid excessive printing time for operations such as typing + in the middle of a line. + +^X^U upper-case-region + + Upper-case all characters between the cursor and the mark. + +^X^W write-file + + Writes the current buffer out to a file, whose relative pathname will be + prompted for in the minibuffer. Terminate response with a CR. If a blank + or null response is given, write it out to this buffer's default file. The + file specified becomes the buffer's default file. See ^X^S. + +^X^X exchange-point-and-mark + + Exchange the cursor and the-mark, to verify what you are getting into + before typing ^W or similar. Puts the cursor where the-mark is and vice + versa. ^X^X ^X^X quickly verifies the extent of the "point-mark region" + visually and puts things back. Use ^U ^@ to visit older settings of + the-mark in this buffer. + +^X_ underline-region + + Underlines the region between the point and the mark. If the option + underline-whitespace is On, underline the spaces also (Default is Off). + With a numeric argument, removes the underlining from the region. + +^Y yank + + Yank (retrieve) killed text to cursor. Unkills last killed word, line, or + region (^W). With a numeric argument, goes that many killings down the + 10-position kill ring. Leaves the-mark at the front of the retrieved text, + and the point at the end. + +^Z; kill-comment + + Removes the comment and the whitespace preceding it from the current line. + The deleted text is saved on the kill ring, accessible to ^Y. The text is + saved in such a way that folowing ^K's and other forward-killing commands + will merge properly with the deleted text. + +^ZG go-to-named-mark + + Prompt for the name of a "named mark", and move the cursor to the point + where that mark was saved. Use ^Z^@ to set a named mark. + +^Z^@ set-named-mark + + Prompt for the name of a "named mark", and set that named mark to be where + the cursor is now. Named marks are valid only in the buffer in which they + were created. Use ^ZG to go to a named mark. + +^Z^B edit-buffers + + Enters the buffer editor. If given no argument, i.e., ^Z^B, the buffer + editor will set up its display in the current window. If given an + argument, i.e., ^U ^Z^B, the buffer editor will find some other appropriate + window (if in two-or-more-window mode) to set itself up in. See + windows.info for full information on the buffer editor. + +^Z^F get-filename + + Inserts the pathname (as seen in the mode-line below) of the current buffer + at the cursor. With an argument, inserts the entryname portion of the + pathname only. If the pathname is an archive component pathname, the + componentname is inserted. + +^Z^G ignore-prefix + + Flush a prefix character. Used when a prefix character such as ESC is + entered by accident; causes an audible signal to indicate that the ^Z^G has + been executed. Unlike ^G, does not exit the minibuffer. + +^Z^V scroll-current-window + + Scrolls the current window (or whole screen, in one-window mode) up or down + a specified number of lines. The cursor remains on the same line of the + buffer. The numeric argument tells how many lines to scroll it up; the + default is one line up. A negative numeric argument indicates scrolling it + down. Thus, ESC - 3 ^Z^V scrolls the current window three lines down. + +^Z^W edit-windows + + Enter the window editor to create, realign, destroy, or visit windows. If + given no argument, i.e., ^Z^W, the window editor will set up its display in + the window where the cursor currently sits. If given an argument, i.e., ^U + ^Z^W, the window editor will find some appropriate window in which to set + up shop. See windows.info for full information on the window editor. + +^Z^Z signalquit + + Signals QUIT to Multics. Restores normal tty modes before so doing, and + sets them back as Emacs needs them after having typed start. + +^Z_ remove-underlining-from-word + + Remove underlining from the current or previous word: the rules for + selecting which word are the same as those used by uppercase-word. + +^_ help-on-tap + + Gets help/documentation at any time. This feature is now only partially + complete. The current repertoire is: + + ^_ H Find out where to get more help. + ^_ ? Display the current repertoire of ^_ + ^_ A Prompt for a string to search for appropriate + commands (same as esc-X apropos). + ^_ C Prompt for a key sequence to document (same as + esc-?). + ^_ D Prompt for the name of an extended command to + document (same as esc-X describe). + ^_ L Display the last 50 characters typed in. + ^_ ^G Do a command-quit as usual. + +esc-# rubout-word + + Delete the word to the left of the current point. More specifically, + delete going backwards, deleting characters until the beginning of a word. + Successive words deleted with esc-# are merged and may be retrieved with + one ^Y. + +esc-% query-replace + + Interactively replaces all occurences of one string with another. The + command prompts for both strings in the minibuffer, and then searches + forward for each occurrence of the first string. Terminate the strings + with CR. It positions the cursor immediately after this string and waits + for one of the following responses: + + space -- replaces this particular occurrence of the first string + with the second. Then searches for the next occurrence of + the first string and waits for a response again. + , -- same as space, but redisplays before searching on. + Normally, esc-% redisplays only before prompting. + return -- leaves this occurrence of the first string alone and searches + for the next occurrence of the first string. + period -- replaces this occurrence of the first string with the second + and terminates the query replace. + ! -- Replaces this and all succeeding occurences of the + first string by the second, without asking. + ^G -- terminates the query replace without modifying this + occurrence of the first string. + ESC -- same as ^G. + +esc-/ regexp-search-command + + Search forward regular expression, `a la "QEDX". Terminate the regular + expression by CR, we supply the slashes. All rules for QEDX regular + expressions apply. Searches forward from cursor, and can find many + occurences of the regular expresion on one line. Leaves the cursor and + the-mark around the string it finds, so that + + s/(fo.*)/(a b & )/ (QEDX) + = esc-/(fo.*) CR ^W( a b ^Y ) (EMACS) + + +esc-; indent-for-comment + + Searches for this line's comment. If one exists, indents it to the comment + column in this buffer (see ^X;). If one does not exist, start one at the + comment column on this line. Uses the "comment-prefix" to search for an + old one or start a new one. See also set-comment-prefix. + + +esc-< go-to-beginning-of-buffer + + Move to the beginning of the current buffer, i.e., before the first + character in the buffer, that is, the top of the document being edited. + +esc-> go-to-end-of-buffer + + Move to the end of the current buffer, i.e., before the newline on the last + line of the current buffer. In other words, go to the bottom of the + document being edited. There is no way to position beyond that newline. + +esc-? describe-key + + Display the documentation for a given key sequence. To find out what a + Control D does, type esc-? and a Control D. With a numeric argument, + i.e., ^U esc-?, just the command name to which the key is currently + connected will be displayed in the minibuffer. + +esc-A backward-sentence + + Go to the beginning of the current sentence, i.e., just before the first + letter. If already at the beginning of a sentence, go to the beginning of + the previous sentence. The beginning of the first word after a blank line + always counts as the beginning of a sentence. + +esc-B backward-word + + Go backward one word. If in the middle of a word, go to before the + beginning of that word. Skips backwards over all whitespace to get to the + next word. Underscores and backspaces count as parts of words. + +esc-C capitalize-initial-word + + Capitalize a word, leading capital, rest of word lower-case, like "Word". + If the cursor is in a word or immediately after a word,capitalize that word. + Otherwise, do the next word. With a numeric argument, do that many words; + with a negative numeric argument, to that many backward. Leaves cursor + immediately after the last word (or before the first word) capitalized. + +esc-CR cret-and-indent-relative + + Does a CR and a indent-relative. Basically, this means finish this line, + and start a new line, indented the same as the previous line. If the + original line was not indented, note that this will line up with the second + word on the first line. This is the command you want to terminate a line + of an indented body of text. + +esc-D delete-word + + Delete the word to the right of the current point. More specifically, + delete going forward, deleting all whitespace and punctuation and + characters until the end of the next word. + +esc-E forward-sentence + + Move forward to the end of this sentence. If at the end of a sentence, + move forward to the end of the next sentence. Ends of paragraphs are + implicitly ends of sentences, whether or not an end-of-sentence punctuation + (period, question mark, exclamation point) appears. + +esc-ESC eval-lisp-line + + Prompt for a string for Lisp to evaluate; put a pair of parens around it, + evaluate it in Lisp (with ibase = 8) and print out the Lisp value in the + minibuffer (base = 8, *nopoint nil). To get a variable value, use esc-ESC + progn CR. + +esc-F forward-word + + Go forward one word. If in the middle of a word, move to the end of the + current word. Leaves point immediately after that word. All punctuation + and whitespace before the word are moved over. Underscores and backspaces + count as parts of words. + +esc-G go-to-line-number + + Goes to a given line, given by line number, from the top of the buffer. + The numeric argument specifies the line number. For instance, ESC 25 esc-G + goes to line 25. If the line number is not specified, prompts for a line + to go to. + +esc-H mark-paragraph + + Put the-mark at the beginning of the current paragraph. Put the cursor at + the end of the current paragraph. See esc-[ for a definition of + paragraphs. + +esc-I tab-to-previous-columns + + Indent the current point on this line (where the cursor is) to line up with + the next non-whitespace item on the previous non-blank line. Successive + invocations of esc-I cause attempts to line up with succeeding + non-whitespace items. This is ideal for building columnated tables, etc. + Type in the first line by hand, and use esc-I to get to each new field, + column, etc. on succeeding lines. Typed on an empty line, or at the end + of a line, it positions for the next text to be entered. With a numeric + argument, esc-I uses previously undented lines (other than the last line) + for a model, thus facilitating typing in outlines, etc. + +esc-K kill-to-end-of-sentence + + Delete text going forward from the cursor to the end of the current + sentence. If at the end of a sentence, delete forward to the end of the + next sentence. Sentences and other text killed consecutively in this + fashion are merged, and may be retrieved with a single ^Y. + +esc-L lower-case-word + + Convert a word to all lower-case, like "word". If the cursor is in a word + or immediately after a word, lower-case that word. Otherwise, do the next + word. Convert a word to all upper-case, like "WORD". If the cursor is in + a word or immediately after a word, upper-case that word. Otherwise, do + the next word. With a numeric argument, do that many words; with a negative + numeric argument, to that many backward. Leaves cursor immediately after + the last word (or before the first word) lower-cased. + +esc-M skip-over-indentation + + Move the cursor to the first non-whitespace (i.e., not tab, blank, + formfeed, or vertical tab) position on this line. In other words, skip + over the indentation on this line. + +esc-N down-comment-line + + Properly indents the comment on the next line, or puts a comment on the + next line, if there is not one there already. Effectively the same as + ^Nesc-;. See esc-;. + +esc-P prev-comment-line + + Indent the comment on the previous line properly. If there is no comment + on the previous line, put one there, indented properly. Effectively the + same as ^Pesc-;. See esc-;. + +esc-Q runoff-fill-paragraph + + "Fill" the current paragraph, like runoff/compose with ".na". With + argument (i.e., ESC-1 esc-Q), fill and adjust like runoff/compose with .fi + and .ad. Right margin is determined by fill column, left margin by fill + prefix. Runoff/compose control lines count as their own paragraphs. See + ^XF to set fill-column, and ^X. to set fill prefix. + +esc-R move-to-screen-edge + + Move to top, bottom, or other point on screen. ESC-1 esc-R is the top line + of the screen, ESC 6 esc-R is the 6th line from the top, ESC - 4 esc-R is + the fourth line from the bottom. A very large number is also the bottom. + Leaves the cursor on the start of the selected line. + +esc-S center-line + + Center the current line, according to fill-column (see ^XF). + + +esc-T twiddle-words + + Twiddle (transpose, interchange) the last two words typed, like: like I + esc-T Multics because... If you are currently in the middle of a word, + goes to the end of the word first. + + +esc-U upper-case-word + + Convert a word to all upper-case, like "WORD". If the cursor is in a word + or immediately after a word, upper-case that word. Otherwise, do the next + word. With a numeric argument, do that many words; with a negative numeric + argument, to that many backward. Leaves cursor immediately after the last + word (or before the first word) uppercased. + +esc-V prev-screen + + Display the previous screen (one back) of this buffer, leaving cursor at + the top of it. With an argument, displays that many screens backward. + +esc-W copy-region + + Copies the text between the cursor and the-mark on to the top of the kill + ring. This means that the next ^Y will copy the text now between the + cursor and the-mark to wherever the cursor is when the ^Y is issued. + +esc-X extended-command + + Prompt for the name and arguments of an extended commands in the + minibuffer. Terminate with CR. To find out about an extended command, + type + + esc-X describe CR + +esc-Y wipe-this-and-yank-previous + + I don't like what I just ^Y'ed. Get rid of it and yank the previous thing + in its place. Used to retrieve the previous "kill" when you find that the + thing that you just ^Y'ed was the wrong thing. In more detail, delete the + text between the cursor and the-mark without saving it, rotate the kill + ring one position, and ^Y. + +esc-[ beginning-of-paragraph + + Move to the beginning of the current paragraph. If already at the + beginning of a paragraph, move to the beginning of the previous paragraph. + The beginning of a paragraph is the beginning of the first line of the + paragraph. The definition of paragraphs is controlled by the + paragraph-definition-type option; if 1, blank lines separate paragraphs. + If 2, an indented line starts a paragraph. Runoff and compose control + lines count as paragraphs. + +esc-\ delete-white-sides + + Delete all whitespace characters on the current line surrounding the + cursor. In this context, a whitespace character is a space, a tab, a + formfeed, or a vertical tab. + +esc-\177 rubout-word + + Delete the word to the left of the current point. More specifically, + delete going backwards, deleting characters until the beginning of a word. + Successive words deleted with esc-\177 are merged and may be retrieved with + one ^Y. + +esc-] end-of-paragraph + + Move to the end of the current paragraph. If at the end of a paragraph, + move to the end of the next paragraph. The end of a paragraph is the end + of the last line of the paragraph. The definition of paragraphs is + controlled by the paragraph-definition-type option; if 1, blank lines + separate paragraphs. If 2, an indented line starts a paragraph. Runoff + and compose control lines count as paragraphs. + +esc-^ delete-line-indentation + + Without a numeric argument, i.e., esc-^, delete all whitespace at the + beginning of this line and then merge it with the previous line. With an + argument, i.e., ^Uesc-^, does a ^N first, so that ^Uesc-^ in effect + "connects" the next line into this one, without the next line's + indentation. + +esc-^B balance-parens-backward + + Skip backward over one set of balanced parentheses. Will search backwards + until a set of parentheses is found. Does not handle quoting or any + programming language conventions. + +esc-^C compile-buffer + + Compiles the buffer. Writes the current buffer out to its default pathname + (as for ^X^S), and then compiles it. Compiler diagnostics are placed in the + buffer "Compilation Errors" if the option "one-error-scan-buffer" is On (the + default); if it is Off then the diagnostics are placed in the buffer " + Errors", where is replaced with the name of the buffer being + compiled. (This allows several buffers to be compiled without overwriting + each other's error messages.) If in two-window mode, the error buffer is + displayed in another window; if the option "compile-two-windows" is On (the + default is Off) then this command will automatically enter two-window mode + if necessary. If the "compile-local-display" option is On (default is Off) + and "compile-two-windows" is Off, the error messages will be displayed as a + local display (in addition to being put in a buffer). If neither is set + (the default), a one-line local display will indicate whether the + compilation was successful. The extended requests "ESC X set-compiler" and + "ESC X set-compile-options" can be used to select the compiler and options + to be used. + +esc-^F balance-parens-forward + + Skip forward over one set of balanced parentheses. Will search forward + until a set of parentheses is found. Does not handle quoting, or any other + programming language conventions. + +esc-^G ignore-prefix + + Flush a prefix character. Used when a prefix character such as ESC is + entered by accident; causes an audible signal to indicate that the esc-^G + has been executed. Unlike ^G, does not exit the minibuffer. + +esc-^I indent-to-fill-prefix + + Delete the indentation (leading whitespace) of the current line, and + replace it with the fill prefix in this buffer. See ^X.. + +esc-^O split-line + + Break the line at this point, shear it vertically. Puts the text to the + right of the cursor on the next line, with enough indentation so that it is + still in the same place horizontally. This can be undone by ^Uesc-^. See + esc-^. + +esc-^V page-other-window + + Valid only when more than one window exists. With no argument, causes a ^V + to be done on the other window (i.e., the one the cursor is not now in); + with an argument, pages the other window that many screens backward or + forward; thus, ESC - esc-^V pages the other window one backward. Very + useful for "paging" compiler diagnostics while editing a program. When + more than two windows are in use, the "next most recently visited" window + will be considered to be the "other window". + +esc-^W merge-last-kills-with-next + + Causes the next kill-type commands (example, ^K, esc-D) which must follow + immediately, to merge what they kill with the last saved kill on the kill + ring, in the same direction as the next command kills. For instance, ^A ^K + ^K ^N ^N esc-^W ^K ^K catenates two disjoint lines on the kill ring. + +esc-^Y yank-minibuf + + Yank back the last content of the minibuffer, without prompt string. The + mark will be set in the minibuffer, so ^X^X may be used to position around + it, and ^W to delete it. The real mark in the main buffer will not be + destroyed. + +esc-_ underline-word + + Canonically underscore the current or previous word. Although it will look + peculiar on the screen, it will be correct, and runoff-paragraph and fill + and dprint correctly. The rules for selecting which word to do are the + same as those used by uppercase-word. + +esc-~ unmodify-buffer + + Marks the current buffer as not modified. Emacs will not mention this + buffer when querying because of a ^X^C. esc-~ is useful after accidently + modifying a buffer which you only intended to examine. + + + + + + E__x_t_e_n_d_e_d C__o_m_m_a_n_d_s + +Type esc-X followed by the command name, and a carriage return to invoke these +commands. + +esc-X accept-messages + + Accept Multics interactive console messages into Emacs buffers, one buffer + per correspondent. Causes messages to be displayed as local output as they + arrive. All correspondence to and from each correspondent is maintained in + a buffer named "Messages from ", in which carriage return is + bound to respond-from-buffer, which causes messages to be transmitted when + a line is typed by you into that buffer. In these buffers, conversations + "transcript" as with send_message in "input mode". The following key + bindings are set up globally by accept-msgs: (see their documentation): + + ^X: message-response-command (responds to last sender from + minibuffer). + ^X' go-to-new-message-buffer (goes to a message buffer). + With an argument, lists message buffers (conversations) + ^X` send-a-message (prompts for user name and then message) + ^X~ repeat-last-message (reprints last interactive message) + +esc-X accept-messages-path + + Accepts messages on some other mailbox than the user's default mailbox. Up + to 50 mailboxes may be accepting messages at once in a process. The + argument to esc-X accept-messages-path is either a mailbox pathname + (containing >'s or <'s) or a user-name (for sites using the ARPANet Mail + Daemon) or a pair of the form User.Project. The effect is the same as + esc-X accept-messages. + +esc-X alm-mode + + Enter ALM major mode in this buffer. ALM mode consists of many commands + and variable settings suitable for the creation and editing of ALM + programs. + +esc-X apropos + + Lists all commands and extended commands that "mention" a given string in + their names, and tell what, if any, keys invoke them in the current buffer. + For instance, + + apropos forw + + will list forward-word, forward-char, etc. This is the most common way to + "find" a command that does something you are looking for. + +esc-X compose-mode + + Mode for editing compose text files. Turns on fill mode automatically. + Equivalent to the text-mode and runoff-mode commands; entered automatically + for files with a last component of ".runoff" or ".compin" if the option + find-file-set-modes is On (Default is Off). + +esc-X describe + + Display the documentation for an extended command. The command name is the + argument describe. For example, + + esc-X describe apropos CR + +to find out about the "apropos" extended command. + +esc-X edit-macros + + Produces a symbolic file of all keyboard macros defined in the current + buffer and places it in a new buffer. The keyboard macros may then be + written out for later loading, edited, redefined, or compiled into Lisp + code. See macro-edit.info for full information. + +esc-X electric-alm-mode + + Enters ALM mode, with several commands for automatically formatting ALM. + +esc-X electric-pl1-mode + + Enters Electric PL/I mode in the current buffer. Electric PL/I mode is a + variant of PL/I mode in which semicolons and colons have violent automatic + "electric" action which may be disturbing to some, but useful to others. + See pl1-mode.info. + +esc-X filloff + + Turns off fill mode in this buffer, if it is on. + +esc-X fillon + + Turn on Fill Mode (a minor mode) in this buffer. In Fill Mode, text will + be wrapped around lines so as not to extend past the fill column (see ^XF + to set that). When a space, tab, or punctuation mark is placed after a + word which passes the fill column, the line will be broken at the first + whitespace from the end of the line. filloff turns it off. To insert a + character to cause a line deliberately to extend pass the fill column, + either type CR or precede the character with ^Q. + +esc-X fortran-mode + + Enter Fortran major mode in this buffer. Fortran mode consists of many + commands and variable settings suitable for the creation and editing of + Fortran programs. See fortran-mode.info for a list of the commands and a + description of this mode. You can issue the command esc-X apropos fortran + CR in a Fortran mode buffer for a list of relevant commands in this mode. + +esc-X fundamental-mode + + Enters the mode (set of key bindings and variable settings) that all + buffers start out in. This can be used to "undo" any other major mode that + you may have set. + +esc-X ldebug + + Enters a "Lisp Top Level" buffer in Lisp Debug mode. Forms typed into this + buffer are evaluated and the value is displayed by placing it in this + buffer. When esc-X ldebug has been used, all Lisp errors in Emacs trap + into this buffer. ESC-P restarts a break. See ldebug.info for more + information. + +esc-X lisp-mode + + Enter Lisp major mode in this buffer. Lisp mode consists of many commands + and variable settings suitable for the creation and editing of Lisp + programs. See lisp-mode.info for a list of the commands and a description + of this mode. + +esc-X list-named-marks + + Display a list of all of the named marks in the current buffer. Use ^Z^@ + to create a named mark, and ^ZG to go to one. + +esc-X loadfile + + Loads a private Emacs extension package into the editor. The argument is + its pathname. + +esc-X loadlib + + Load an "uninstalled" extension package into Emacs. Normally, such + packages are "autoloaded" when commands in them are invoked, but from time + to time, new, experimental, or highly specialized packages may require + being loaded in this way. The single argument is the name of the package + to be loaded. Loading a package makes the commands in it available. + +esc-X lvars + + Display the names and lengths of all "variables" saved by ^XX. Type ^J to + resume, or just continue editing. See ^XX and ^XG. + +esc-X make-wall-chart + + Puts into a buffer a "Wall Chart", describing all the currently defined + commands and what keys invoke them in the current buffer. The resultant + buffer is intended for dprinting. + +esc-X opt + + Also "option". Sets non-obvious internal flags and defaults, each of which + have names. Takes three forms, + + opt list List all options and settings. + opt NAME VALUE Set option value. + opt status NAME Report setting of one option. + + Values may be on, off, or numbers, depending on the option. Code, such as + startups, can simply set these Lisp variables. (on/off => t/nil). Current + options are: + + display-ctlchar-with-^ Causes control characters to print as + ^P instead of \020. + suppress-ctlchar-display Don't show control characters. Any character + which would print as \NNN (except \177) is not + displayed. + suppress-rubout-display Don't show rubout characters. Causes \177 to + never be displayed. Usefull when reading ALM + listing segments. + suppress-backspace-display Don't show backspaces. Causes underlined + "foo" to print as "_f_o_o". + rdis-whitespace-optimize Avoid printing whitespace when clever + terminal control would go faster. Currently + on by default, but adds a little expense. + rdis-wosclr-opt Wipe Out Screen lines before filling screen. + Try it both ways to see what this means. + paragraph-definition-type 1 (default) = blank lines precede + paragraphs. 2 = indented line starts one. + find-file-set-modes When on, find-filing foo.pl1 sets pl1 mode, etc. + track-eol-opt When on, ^N, ^P at eol stick to ends of lines. + default-fill-column Fill column for new buffers. + default-comment-column Comment column for new buffers (0 origin). + pop-up-windows When on, ^XB, ^X^F, ^X^E, etc., find an + appropriate place on the screen to put up + a window as opposed to replacing contents + of current window (highly experimental). + +esc-X pl1-mode + + Enter PL/I major mode in this buffer. PL/I mode consists of many commands + and variable settings suitable for the creation and editing of PL/I + programs. See pl1-mode.info for a list of the commands and a description + of this mode. You can issue the command esc-X apropos pl1 CR in a PL/I + mode buffer for a list of relevant commands in this mode. + +esc-X replace + + Global replace of one string with another, from the current point to the + end of the buffer. Prompts for two strings, which must be terminated by + CR. If the first string is not found, esc-X replace will not prompt for + the second string, and will not move the cursor. + +esc-X reset-minibuffer-size + + Resets the size of the minibuffer/prompting area to its default of two + lines. See set-minibuffer-size. + +esc-X reset-screen-size + + reset-screen-size + + Resets the size of the main editing area of the screen to its default, + namely, all of the space above the mode line. See set-screen-size. + +esc-X runoff-fill-region + + Fills/adjusts an entire region in the same way as esc-Q does to a + paragraph. It does not respect paragraph breaks: this makes it only + marginally useful. + +esc-X runoff-mode + + Mode for editing runoff text files. Turns on fill mode automatically. + Equivalent to the text-mode and compose-mode commands; entered automatically + for files with a last component of ".runoff" or ".compin" if the option + find-file-set-modes is On (Default is Off). + +esc-X save-macro + + Saves a macro, assigning it to a key. Invoke it after a macro has been + defined. Will prompt for a command name to assign to the macro, and a key. + When a key has been assigned, this key will invoke that macro- it will take + arguments identical to ^XE. + +esc-X set-comment-prefix + + Set the "comment prefix" in this buffer. This is usually set automatically + by entering a major mode. The comment prefix is given as an argument to + this command, in quotes. The comment prefix is used by esc-;, esc-N, and + esc-P to find comments, and start them. + +esc-X set-compile-options + + In language modes that support ESC-^C for "compile buffer", and similar + (e.g., PL/I, FORTRAN), sets non-default compilation options to be given to + the appropriate compiler. + +esc-X set-compiler + + Sets the name of the compiler to be used by the compile-buffer command + (usually ESC-^C) in those language modes that compile buffers this way + (e.g., PL/I, FORTRAN). The single argument to esc-X set-compiler is the + compiler name. + +esc-X set-key + + Assigns key bindings in the current buffer. Takes two arguments, the "Key + name" and the command name. Makes that key execute that command in this + buffer. The command name is what describe-command or apropos or + make-wall-chart give; the key name can be anything like the names in this + documentation, e.g., ^X, ^x, ESC-ESC, ^Xq, control-p, c-p, meta-f, esc-^f, + CR, ^X-^F, ^X-CR, \177, #, A, ^P, etc. For instance, you might want to say + + set-key ^Z quit-the-editor + +if you want the privilege of quitting in one keystroke. + +esc-X set-minibuffer-size + + Sets the size of the minibuffer/prompting area on the screen to any value. + The single argument to esc-X set-minibuffer-size is the decimal number of + how many lines should be devoted to this function. The default is two. + With many-line minibuffers, many messages and errors may appear at once. + Use reset-minibuffer-size to reset the minibuffer size to its default of + two lines. Valid sizes are 1 to 6. + +esc-X set-permanent-key + + Used to set permanent (default in all buffers) key bindings. Otherwise, + works exactly like set-key. See set-key. + +esc-X set-screen-size + + Set the size of the main editing area (the area above the Mode Line) to + other than its default. The default is all of the area above the mode + line. The decimal argument to esc-X set-screen-size is the number of lines + in the main editing area. reset-screen-size may be used to reset the main + editing area size to its default value. esc-X set-screen-size is usually + used to reduce the amount of redisplay at low terminal speeds. + +esc-X set-search-mode + + Sets the bindings of ^S and ^R to invoke several different forms of + searching. The argument is the search mode. + + The known search modes are: + + string Searches for the exact character + string typed (the default). + regular-expression The string typed is interpreted as a + or regexp QEDX regular expression. + character Searches for the single character + typed. Control characters control + sophisticated options. + ITS-string A type of search popularized by + Dave Moon and Dan Weinreb on MIT-AI, + having many sophisticated features. + incremental Searches for a string showing the + state of the search as each character + is entered. + + All searches prompt telling the type of search that has been invoked. To + find out more about these different kinds of searches, set the search mode + of interest, and do an esc-? ^S. + +esc-X setab + + Define one word as an abbreviation for another for Speedtype mode, for + instance, + + setab edr editor + + Will accept multiple pairs of arguments. If the second string (the thing + being abbreviated) is many words, or has special characters in it, put it + in quotes. + +esc-X show-macro + + Displays an editor macro (defined with ^X() the same as + show-last-editor-macro does, but takes the name assigned to the macro (by + save-macro) as an argument. + +esc-X speedtype + + Enter speedtype minor mode in this buffer. Speedtype allows words to be + used as abbreviations for other words. setab is used to define + abbreviations; When a space, newline, tab, or punctuation mark is typed + after an abbreviation, the abbreviation is removed from the text and its + expansion is used instead. Precede punctuation or spaces with ^Q to + deliberately avoid speedtype expansion when in this mode. + +esc-X speedtypeoff + + Turn off speedtype mode in this buffer, if it is on. + +esc-X text-mode + + Mode for editing text files. Turns on fill mode automatically. Equivalent + to the runoff-mode and compose-mode commands; entered automatically for + files with a last component of ".runoff" or ".compin" if the option + find-file-set-modes is On (Default is Off). + + + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/ldebug-mode.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/ldebug-mode.info new file mode 100644 index 0000000..e1ce6e3 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/ldebug-mode.info @@ -0,0 +1,348 @@ +10/10/79 - Emacs Lisp Debug Mode + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + Multics Emacs LDEBUG mode (Lisp Debug) provides an +interactive Lisp environment designed for the debugging of Emacs +extension code. Facilities are provided for tracing the Lisp +stack, breakpointing code, and interacting with the native +MacLisp "trace" facility. LDEBUG mode is specifically optimized +for multiple-window interaction. + + LDEBUG Buffers + +The heart of the LDEBUG mode facilities is the "LDEBUG" buffer. +The buffer named "LDEBUG", when created by ldebug-mode +(either in response to a breakpoint being executed, a trapped +Lisp error, or the explicit "ldebug" extended command) +evaluates any Lisp form typed into it when Carriage Return is +struck after it. The form must be all on one line- an error will +occur if the form has syntactic errors (e.g., miscounted +parentheses). The result of the evaluation is placed in the +LDEBUG buffer on the next line, following the sign "=>", which +indicates the result of such an evaluation. The Lisp variable +"*" will be set to the result of each successive evaluation, +as at raw Lisp top level: this may be used to reference the last +printed result. + + Random Lisp forms such as "(+ 2 3)" or "current-buffer" can +be typed at LDEBUG buffers, and the resulting buffer contents +will in effect be a dialogue of an interaction with Lisp. Such +buffers are often dprintable for later perusal. The values of +variables may be set by evaluating the normal Lisp setq form, +e.g., (setq var (+ foo 27)). As lines are +placed into the LDEBUG buffer by the LDEBUG facility, the +window (if any) containing it will scroll if necessary. + + Lisp values "printed" into the LDEBUG buffer are by default +limited in length to ten and depth to six. The values of the +option variables "ldebug-prinlength" and "ldebug-prinlevel" +may be set to alter these defaults. The default input and output +radices are both 8: these may be altered as the option +variables "ldebug-ibase" and "ldebug-base". + + Most Emacs requests can be used in LDEBUG buffers; they are +in "Lisp Debug" mode, which is an extension of ordinary Lisp +mode, with commands differing as detailed below. + + + Emacs and Lisp Debug Mode + + The "ldebug" (ESC-X ldebug CR) extended command can be +invoked at any time, in the normal way Emacs extended commands +are invoked. It places Emacs in the LDEBUG buffer as described +above, but also, more significantly, it sets up a system of Lisp +error handlers "under" a new invocation of the Emacs request +loop. Should any Lisp error happen while these handlers exist, +the LDEBUG buffer will be entered, placed on display if not +already on display, the terminal's bell will be feeped, and the +Lisp error message will be entered in the LDEBUG buffer. You +will then be at a "second (or greater) level" of LDEBUG, similar +to what happens at Multics Command level when an error occurs. +The level number will be part of the message entered in the +LDEBUG buffer. + + Recursive (level greater than 1) LDEBUG buffers may be +released (aborting all executing code between the LDEBUG level +being released and the previous level) via the ESC G +(ldebug-return-to-emacs-top-level) request, the analogue +of the Multics "release" command. It will beep and type "$g" +in the LDEBUG buffer. The value of the variable "ldebug-level" +tells the current level of LDEBUG buffers. + + ESC P (for proceed) is the analogue of the Multics "start" +command; there is more to know about its meaning for each +different type of entry to an LDEBUG buffer, and this +will be described below. In general, it restores the +buffer and window from which the LDEBUG buffer were entered. + + + Error trap entries to LDEBUG + + When an "error trap entry" to the LDEBUG buffer has +occured, the Lisp stack may be traced via the ESC-T +(ldebug-trace-stack) request, and the value of variables may be +inspected simply by typing their names (as they are Lisp forms) +at the LDEBUG buffer. + + A value may be "returned" to the Lisp error handler by +typing it on a line, and instead of ending the line with +carriage return (which would evaluate and "print" the result), +end it with ESC P. Note that Lisp error handlers often want a +list of the value to replace some erroneous value. For +instance, in the following dialogue, an LDEBUG trap was entered +because of the unbound variable "stuff": the programmer returned +the symbol "value-i-wanted" as the intended value of the unbound +variable: + + (myfun huff stuff) + + Lisp breakpoint unbnd-vrbl at level 1 in buffer LDEBUG: + lisp: undefined atomic symbol stuff + + ('value-i-wanted)$p + +All "correctable" Lisp error breakpoints will accept a "retry" +value to be used to retry the failing operation; the undefined +function breakpoint ("undf-fnctn") also accepts a list of a new +value, in this case a function to be used instead. The MacLisp +manual must be consulted for the exact format of other retry +values. + + The "$p" is always printed by ESC P, to remind the user of the $p +which is used in raw Multics MacLisp to restart breaks (the "$p" +is in fact derived from ESC P on the ITS operating system, which +is used to restart jobs in general). + + ESC P may also be used alone on a line (i.e., no value to be +returned preceding it) to restart a break and let Lisp's default +action occur. + + ESC G may be used as usual to release a level of errors to +the next lower LDEBUG level; note that ^G (command-quit) only +does not release past LDEBUG levels. + + + Code Breakpoints + + Breakpoints may be set in interpreted extension code being +debugged by typing ESC & in a Lisp Mode buffer with the cursor +pointing at the point in some function being debugged where you +would like this break set. The LDEBUG mechanism will create +this breakpoint by putting a call to a tracing function ("%%") +in the code in the buffer, and evaluating the function +definition it is looking at. This "break code" will be left +in the function to let you know that it is there: it includes +a "break number" (they are assigned sequentially) by which +this breakpoint can be referred to by requests yet to +be described. + + You should be in at least one level of LDEBUG buffers +before setting a break: this means that you should have said +"ESC X ldebug CR" some time before setting breaks. + + Having set a break, you can run the code being debugged. +When the breakpoint is entered, the LDEBUG buffer will be +entered, at a new, higher level. A message of the form + + Break 4 in function testfun + +will be put in the buffer, and the LDEBUG buffer will be put on +display if not already on display. As in all LDEBUG buffers, +arbitrary forms can be evaluated (including inspecting +variables), and ESC T can be used to trace the Lisp stack. +Again, ESC G releases a level of LDEBUG buffers. + + ESC P is used to restart code breakpoints, as well. A given +breakpoint can be set for some number of proceeds (i.e., "3" means +proceed, and proceed this breakpoint the next two times it is +encountered automatically) by giving that number as a numeric +argument to ESC P (i.e., ESC 3 ESC P). A message indicating the +number of proceeds will be inserted in the LDEBUG buffer. +ESC P should be used alone on a line (i.e., no "retry value") +when restarting code (or trace) breaks. + + When in a code break, ESC R (ldebug-reset-break) may be +used to reset the current breakpoint, before restarting or +releasing. The break code will be removed from the function +definition (visibly, if it is on display), and the function +definition will be reevaluated. ESC R with a numeric argument +can be used to reset a break by number. + + When in an LDEBUG buffer, ESC L (ldebug-list-breaks) may be +used to list all the known code breakpoints: their numbers, the +function in which the break appears, the buffer the function +appears in, and the status of the break. + + The source for the current breakpoint may be shown by +issuing the request ESC S (ldebug-show-bkpt-source). It is +placed in an available window (if in multiple windows or +pop-up-window mode), and the cursor moved to the break code. +(use ^XO to get back, or in one-window mode ^XB CR). + + A common need during function breakpointing is to determine +where the editor was (i.e., what was the current buffer, and +where was the current point) at the time the breakpoint was +encountered. The ESC ^S (ldebug-display-where-editor-was) +request serves this need; it selects the appropriate buffer, +moving the cursor to the point in it where the current point was +when the breakpoint was taken. If the buffer is already on +display in some window (or pop-up windows are being used), +that window will be selected (i.e., receive the cursor), and ^XO +can be used to return to the LDEBUG buffer for further probing +or restarting. In one-window mode, the correct buffer will +be switched to, and ^XB can be used to get back. +Note that if the cursor (current point) is moved +by you explicitly (i.e., via normal Emacs requests) while +visiting the buffer where the breakpoint was taken, it will have +its new position when the breakpoint is restarted. This is +analogous to setting a variable before restarting with usual +Multics debugging. + + Using two or three windows to contain the LDEBUG buffer, the +breakpoint source (function being debugged), and the buffer the +functions being debugged are working on is highly effective and +recommended. + + + Function tracing with LDEBUG + + The standard MacLisp trace package can be used while in +Emacs; extensibility features of the former allow LDEBUG to +take control of the trace output and breakpointing provided by +it. + + All the facilities of the standard trace package can be +used, by invoking trace from ESC ESC minibuffers. The trace +package allows tracing of entries and exits to functions, +arguments, and return values, and breakpoints when functions are +entered. Some sample forms to trace the function "testfun" are +given here: these are the in Lisp syntax, and may be typed as +such to LDEBUG mode. When typed to an ESC-ESC minibuffer, the +outer set of parentheses should not be supplied. + + (trace testfun) Trace the input arguments and + return value of testfun each time + it is invoked. + + (trace (testfun break (< x 3))) + Trace input and return value of + testfun, enter a breakpoint when + entered and x (x can be an argument + to testfun) is less than 3. + (trace (testfun break t)) + Same, but breakpont at every + entry to testfun. + (trace (testfun entry (a b) exit (c))) + Trace input args and return value, + also print out the values of a and b + when testfun is entered and the value + of c when it is exited. + + The general syntax of trace invocations is (brackets are +indicating optional clauses, angle brackets are syntactic +variables): + + (trace ... ) + +where is either a function name to be traced +for only input args and return value, or + + ( [break ] [entry ()] + [exit ()]) + +There are other options documented in the MacLisp reference +manual. + + When a function is traced within Emacs (it is not +recommended to trace internal Lisp or Emacs primitives, and any +part of the redisplay should definitely not be traced in this +way), trace output for entry and exit tracings will be placed +(and scrolled) directly into the LDEBUG buffer if it is on +display; if it is not on display, this output will be put in the +LDEBUG buffer, AND local-display'ed as it is produced. +Note that the -- * * * * * * * * * -- of local displays will NOT +be produced, as it cannot be known when the "end" of trace +output has been reached. Thus, traced functions invoked from +the minibuffer may often leave the cursor in the minibuffer +awaiting clearing the local display via linefeed or ^L. + + Trace output generally looks like + + (3 enter testfun (3 5 (a . b)) /|/| (4 5)) + +The indentation level gives the depth in currently active +traced functions. The "3" is the recursion depth of the +given function (e.g., testfun) being traced. "enter" +is the type of trace (enter vs. exit), (3 5 (a . b)) +is the list of arguments (in this case, three arguments). +/|/| sets off the "entry values" and "exit values" +optionally selectable by the "entry" and "exit" keywords +in the trace-invoking form. Exit traces look like + + (3 exit testfun 17) + + If trace is used to set an entry breakpoint, the LDEBUG +buffer will be trapped to at the time the traced function is +entered, in a way very much like a Lisp error break to LDEBUG. +A message such as + + Entry breakpoint to function testfun + +will be "printed" into the LDEBUG buffer, and the terminal +feeped. As with LDEBUG code breaks, ESC G releases, ESC P +restarts, ESC R resets, and ESC ^S shows where the editor was +at the time the break was taken. When in entry breakpoints to +interpreted functions, the arguments may be inspected by name. +ESC-T may be used to trace the Lisp stack, but unless +*rset t mode was in effect (setting up an LDEBUG level does this +automatically), trace information may not be present. + + It is not necessary to have invoked ldebug before invoking +trace in Emacs; LDEBUG will be invoked automatically if an +attempt is made to use trace in Emacs. If some critical +mechanism is being debugged and normal trace handling (i.e., +breakpointing/tracing to user_i/o from Lisp, not the Emacs +handling just described is necessary, the variables +trace-printer and trace-break-fun should be made unbound (e.g., +ESC ESC makunbound 'trace-printer) before the first reference to +trace in a given invocation of Emacs. + +(END) + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/lisp-mode.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/lisp-mode.info new file mode 100644 index 0000000..67946f4 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/lisp-mode.info @@ -0,0 +1,242 @@ +09/14/78 -- Multics Emacs Lisp Mode. + Last updated 11/7/80 + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + Lisp mode facilitates the construction and editing of Lisp +programs in Multics Emacs. Commands for positioning over Lisp +expressions, and indenting and commenting Lisp code are available, +as well as commands to facilitate the testing of Lisp programs in the +Emacs environment. + + Lisp major mode is entered via the command + + ESC-X lisp-mode CR + +or by Find File'ing any file with a last component name of ".lisp" when +the find-file-set-modes option is selected. When in Lisp major mode, the +comment column is set to 50 (column 51), and the comment prefix to ";". +The normal comment commands, ESC-P, ESC-N, ESC-;, will act according to +these settings. If lisp-mode-hook is bound, it will be called. + + The following is the current command repertoire of Lisp mode: + +^I (TAB) indent-to-lisp + + On a blank or empty line, creates enough leading whitespace + so that the first S-expression typed on this line will line + up properly according to conventional Lisp indenting rules. + Normally, this means line it up with the start of the + previous S-expression, but in other circumstances other + actions may be taken. On a non-blank line, re-adjusts the + line's indentation to effect conventional Lisp indenting. + +ESC-Q lisp-indent-function + + Put point and mark around the current Lisp function (see + ESC-^A). For all lines other than the first, re-indent them + according to conventional Lisp indentation. + +ESC-^A begin-defun + + Move point to the beginning of the current "function". The + beginning of a function is defined as right before the last + open parenthesis at the left margin. + +ESC-^B backward-sexp + + Move backwards over exactly one balanced S-expression. All + comments, quoted strings, and slashified characters are + considered properly. Will abort (and beep) if unbalanced. + AVOID invoking this from inside comments or quoted strings. + Skips trailing open parens. Accepts numeric arg for + repetition count. + +ESC-^C compile-function + + Effects compilation and loading of the current Lisp function + via the Multics Lisp Compiler (lcp). Does this by loading lcp + into the Emacs environment (the first time it is used in an + Emacs invocation), utilizing it, and loadfiling the result. + Will automatically incorporate/compile the correct version of + e-macros.incl.lisp into your environment (the first time) as + well. Puts the name of the function compiled on the kill + stack, so it can be yanked into an ESC-ESC minibuffer for + trial. Displays compiler diagnostics as local display. Be + careful to WRITE OUT changes you make and debug via this + facility; this is a common trap: you see what you have in front + of you "working", and you think you are done. + + Forms ESC-^C'ed will be treated as though they had been + encountered at top level by the compiler; macro definitions, + declarations, and side-effects from compilation to compilation + are all handled correctly. Declarations, macro definitions, + and reader macro definitions other than those in + e-macros.incl.lisp must be ESC-^C'ed explicitly. Information + produced during any ESC-^C stays around for all future ESC-^C's + in an Emacs invocation: the regnant Emacs environment will be + used as the compile AND LOAD time environments. Thus, macro + and other definitions ESC-^Z'ed or ESC-ESC'ed are seen by the + compiler. + +ESC-^D down-list-level + + Go down one level of list structure. Basically the same as + looking forward for an open parenthesis, but it is + intelligent about Lisp comments, quotes, etc. + +ESC-^E end-defun + + Go to right after the last close-paren of the current + function. See "begin-defun" for a definition of the current + function. Useful to see if function balances parens + correctly. + +ESC-^F forward-sexp + + Skip forward over exactly one S-expression, positioning to + after the appropriate close parenthesis, or before the + appropriate whitespace. Accepts numeric arg for repetition + count. Skips leading close parens. Avoid invoking inside + quoted strings or comments. + +ESC-^H mark-defun + + Put point and mark around the current function. See + begin-defun for a definition of the current function. + +ESC-^K kill-sexp + + Kill one (or many) S-expressions forward, i.e., from point + to the point after that many complete S-expressions. + Argument is how many. Merges kills forward. + +ESC-^M (ESC-CR) lisp-cret-and-indent + + Identical to a CR (new-line) followed by indent-to-lisp; + this is the normal way to terminate an input line in Lisp + mode. It puts you on a new line and indents in correctly for + the next S-expression. Done in the middle of a line, breaks + the line at that point, correctly indenting the S-expression + which was to the right of point on the new line. + +ESC-^N forward-list + + Move to right after the end of current Lisp list. Basically + the same as searching for a close paren, but intelligent + about Lisp comments, quoting, etc. + +ESC-^P backward-list + + Move to right before the beginning of the current Lisp list. + Basically the same as searching backwards for an open paren, + but intelligent about Lisp comments, quoting, etc. + +ESC-^Q lisp-indent-region + + Re-indent all lines (other than the first) in the + point-to-mark region for conventional Lisp indentation. + +ESC-^R move-defun-to-screen-top + + Move the current function (see begin-defun for definition) to + the top of the current screen, leaving point at function + beginning. + +ESC-^T mark-sexp + + Set point and mark around the current S-expression. If point + is currently before the close paren of a list, set point and + mark around that list. If point is before whitespace, mark + the next S-expression. + +ESC-^V view-defun + + Print out current function: put point and mark around the + current Lisp function (see begin-defun for a definition), and + display it (print it out on printing terminals) as local + output. + +ESC-^Z eval-top-level-form + + Evaluates the current top level form and displays its value + in the minibuffer. A top level form has the same definition + as a function. (See begin-defun for the definition). Loads + the file "e-macros.incl.lisp" to ensure the presence of the + Emacs macros. (See extensions.info). This facility is + intended for use in debugging extensions, as is + compile-function, but will run your code interpreted rather + than compiled which aids in debugging. Be careful to WRITE + OUT changes you make and debug via this facility. + +ESC-( lisp-one-less-paren + + Removes one close parenthesis from the end of the last + S-expression prior to this line, and reindents this line. + Implements "This automatically-indented Lisp line is indented + one level too few. There must be an extra close paren on the + last line. Fix it and let's see." + +ESC-) lisp-one-more-paren + + Adds one close parenthesis to the end of the last S-expression + prior to this line, and reindents this line. Implements "This + automatically-indented Lisp line is indented one level too + many. There must be a missing close paren on the last line. + Fix it and let's see." + + + + The following extended commands invoked via ESC-X are available in +Lisp mode: + +eval-buffer + + Evaluates the contents of the buffer and displays the value + of the last form in the buffer via the minibuffer. Loads the + file "e-macros.incl.lisp" to insure the presence of the Emacs + macros. This command is used to "load" a buffer of Lisp code + into the Emacs environment for debugging. The + eval-top-level-form function (ESC-^Z) may then be used to + "re-load" any functions whose definition you change while + debugging. Be careful to WRITE OUT changes you make and + debug via these facilities. + + + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/macro-edit.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/macro-edit.info new file mode 100644 index 0000000..7314117 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/macro-edit.info @@ -0,0 +1,147 @@ +2/22/79 -- Macro edit mode. + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + +This package allows you to + 1) Get printed representations of all keyboard macros defined + in an environment into a buffer for + a) Editing them. + b) Re-defining them from the edited version + c) Writing them out to a file, for later + I) Dprintng + II) Getting those macros automatically defined in a later + invocation of Emacs. + +1. Getting printed representations of all your macros into a buffer. + + Make sure all your macros are hooked up to keys, or at least were at + some time given names, then, + + ESC-x edit-macros CR + + will put you in a buffer in "Macro Edit" mode with all the macros + defined in that buffer in editable form. + + a. Editing them. + +In Macro Edit mode, the following functions exist, on these keys: + +esc-^A macedit-find-beginning-of-macdef + + Move to the beginning of the current macro defintion. + +esc-^B macedit-backward-term + + Move backward one term in the keyboard macro. + +esc-^C macedit-compile-to-lisp + + Still under development, works a little bit, but impressive + even for the little bit it works. Compiles the macro being + pointed at into lisp. + +esc-^E macedit-find-end-of-macdef + + Move to the end of the current macro definition. + +esc-^F macedit-forward-term + + Move forward one term in the current macro definition. + +esc-^H macedit-mark-whole-macro + + Put point and mark around the macro definition. + +esc-^K macedit-kill-term + + Kill forward to the end of the current (or next) term in + the current macro definition. + +esc-^N macedit-forward-macdef + + Move forward to the beginning of the next macro definition. + +esc-^P macedit-backward-macdef + + Move backward to the beginning of the previous macro definition. + +esc-^S macedit-state-keyboard-macro + + Prompt for a key; place the definition of the keyboard macro on + that key into the buffer at the current point. + +b) Redefining them from the edited version: + +esc-^Z macedit-take-up-definition + + Take up into the editor, as a live definition, the current macro + definition being pointed at. Use this after editing a macro + definition to redefine it thusly. + + +ESC-X load-these-macros + + Accept all the macro definitions in the buffer, redefine them + all. + +c) Writing them out. + + Use ^x^w as normal, any file you want, but if it has the suffix + ".emacro", it will be automatically find-filed'd into Macro Edit + mode when it is next find-file'd. + +Macro language has PL/I like comments (/* comment... */). ESC-;, +ESC-P, and ESC-N do the right thing. The comment column is 51. +Quoted strings are double-quoted. Macro definitions look like + + macro foo-the-bar on ^q + ^S "bar" ESC ESC-# "foo" + end-macro foo-the-bar + +The "on ^q" is optional. If present, it will cause a set-perm-key +to that macro. + +The command + + ESC-X load-macrofile PATHNAME CR + +may be issued at any time to take up one of these macro files and define +all the keyboard macros in it. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/nl.changes.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/nl.changes.info new file mode 100644 index 0000000..e60c7a4 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/nl.changes.info @@ -0,0 +1,135 @@ +12/8/81 11.10 Further changes to Emacs newline handling. + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + +An incompatible change, generally deemed to be an improvement, was made to the +definitions of the "last line" and "end of the buffer" in Multics Emacs in +Release 9. The goal of these changes was to allow processing of files which +do not end in newline, which were not supported, and to allow searches to +search for embedded newlines. + +There is a potentially dangerous effect on extension code. This is discussed +later in this document. + +This change is felt to be a correction of an earlier design bug, a major +improvement in consistency of Emacs' character handling, and compatible with +the way TECO and other character-oriented tools process text. + +The essence of the change is to allow you to position your cursor BEYOND the +last newline of a file. Previously, you could not do this (Emacs would ^G at +you tried.) This means that if you had read in a file containing only three +lines (in 8.0 Emacs) + + First line + Second line + Third line + +each line ending in a newline, as is usual, doing an ESC-> would put you on the +FOURTH line of the window, under the T of "Third Line". If you then wrote this +file out, it would have been written out exactly as it was read in. + +(Previously, ESC-> would have gooten you after the word "line" of the line +that says "Third line", and it will would get written out as it had been read +in). + +If now (in the new scheme), you type #, the NL at the end of "Third line" will +be deleted, and the cursor will be left after the "line" of "Third line". +ESC-> will subsequently get you to this place. If you write the file out, in +the new scheme, it will be written out WITHOUT a trailing NL, and the cursor +will remain where it is. + +(This operation is impossible to describe or execute under the old scheme, +which is one of the reasons for implementing the new scheme). + +The substance of the change is as follows: Emacs previously REMOVED the last +newline of a file being read in, and ADDED an extra newline to a file being +written out. This behavior has been eliminated, nothing more and nothing +less. The original motivation for this behavior was to put you in a "Buffer +with one line in it" when you started, and prevent people from writing out +files that didn't end in newline. + +Deletion of newlines on input has been entirely eliminated. However, it was +felt that too many users would be confused if non-newline-ending files were +allowed (in addition, many system programs do not support files that do not +end in a newline). Therefore, there are two new options: + +(1) add-newline, when On, automatically adds a newline to the buffer when +writing it out ONLY when the buffer DOES NOT end in a newline. Default is +On. + +(2) check-newline, when On, asks the user whether or not he really wishes to +write out the buffer if it does not end in a newline. Default is Off. + +------------------------------------------------------------------------- + +Extension writers: This change does have a potentially significant effect on +all loops which process files line by line. "lastlinep" will continue to +respond to the last line of the BUFFER, which is to say, that line whose +newline cannot be gone past, that line whose newline will never be written +out, that line that, in an empty buffer is the only line. + +Suppose you have an extension that reads in some file, and does some +processing, line by line. It might have a loop: + + (go-to-beginning-of-buffer) + (do-forever + (process-stuff-on-this-line) + (if (lastlinep)(stop-doing)) + (next-line)) + +Previously, this worked. Now, it will attempt to (process-stuff-on-this-line) +on the line beyond the last newline of the file, if any file was +involved at all. This may well cause problems. Cases and coding +techniques that will NOT have problems: + + 1. Programs processing data they themselves generated, that + did NOT put a newline: this means most cases of programs + scanning program output today, if you think about it, because + the only REAL change we have perpetrated is in file reading + and writing. + + 2. Programs processing files they read in that look for things + and ignore blank lines. All programs that look at files + they read in should do this anyway, and be "suspicious" + of data read in in this fashion. + +Thus, we believe that most things will continue to work. Look +over all your code, and if it is in category (2), make it suspicious +and blank-line checking. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/pl1-mode.changes.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/pl1-mode.changes.info new file mode 100644 index 0000000..476054a --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/pl1-mode.changes.info @@ -0,0 +1,250 @@ +05/15/80 Emacs PL/I Mode Changes + +The following changes have been made to Emacs pl1-mode and +electric-pl1-mode. + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + +1) New pl1-line-length option. +2) Setting pl1-mode options. +3) Enhancements for pl1dcl (ESC-^D) request. +4) New pl1-skip-to-dcl-column (ESC-SPACE) request. +5) New pl1-backward-statement (ESC-^A) and pl1-forward-statement + (ESC-^E) requests. +6) New pl1-comment-xxx requests. +7) Enhancements to pl1-comment-box (^XC) request. +8) New pl1-refill-comment-box-region (^ZC) request. +9) New pl1-line-between-procs (^ZD) request. +10) New pl1-include-file-comment-start-end (^ZI) request. +11) New pl1-compile-options option. + + +pl1-line-length option: +A new option called pl1-line-length controls the length of lines +generated by pl1dcl (ESC-^D) and several other requests. The line +length is specified in terms of column positions, with a default +length of 112 columns. + + +Setting pl1-mode options: +Several new options have been added. pl1-line-length is desribed +above, and others are described in the sections below. Use ESC-X opt +to list or set pl1-mode options. When in a pl1-mode buffer, setting +the value changes only the value for the current buffer. When not in +a pl1-mode buffer, setting the value changes the default value +associated with all new pl1-mode buffers. Setting these values in a +start_up.emacs segment sets the defaults for all pl1-mode buffers. + + +pl1dcl (ESC-^D): +The pl1dcl request has several new features. It uses the +get_entry_point_dcl_$emacs subroutine to get the declaration. This +subroutine first looks in one or more declaration files for the name +being declared. These files are listed in the "declare" or "dcl" +search paths, which can be set using add_search_paths, etc. Thus, the +user can define his own declaration files which override or add +declarations in the standard file without duplicating other entries in +the standard file. + + +If the name is not found in one of these declaration files, then an +attempt is made using object search rules to find the name. If the +name is a procedure entry point, its entry parameter descriptors +(compiled into the object segment itself) are used to create a +declaration. + + +The declaration is then formatted according to a new pl1-mode option +called pl1-dcl-style. This option can have the following values. + + +0 no formatting is performed. The declaration appears on a single + line with one space between tokens. + +1 formatting similar to that of the indent command. It assumes that + the word "dcl" is in column 1, followed by 2 spaces and the + name. Lines longer than pl1-line-length are folded, being + continued from column 11. + + +2 formatting similar to the experimental format_pl1 command with + indattr mode. It assumes that dcl is located somewhere between + columns 1 and 10, and that the name is in column 11. The + declaration begins in pl1-dcl-column (a new options). Lines longer + than pl1-line-length are folded, being continued from + pl1-dcl-column+5. + +The default value for pl1-dcl-style is 1. + + +Entries in the declaration files have one of two forms. Standard +declarations begin with a name followed by the attributes to be +associated with that name. Folding can occur after any comma (or +after whitespace if no commas are found). No trailing punctuation +should be given. For example: + +ioa_ entry options(variable) +cu_$arg_ptr entry (fixed bin, ptr, fixed bin(21), fixed bin(35)) +iox_$user_output ptr ext static +code fixed bin(35) + + +A second form declares abbreviations to be used in typing PL/I +programs. They have the form + +name ==> abbrev_value + +When ESC-^D is used with such a name, the name is REPLACED by the +abbrev_value. No reformatting occurs. Typical abbreviations might be: + +es ==> ext static +esi ==> ext static init( +fb ==> fixed bin +is ==> int static +isi ==> int static init( +isoc ==> int static options(constant) +isoci ==> int static options(constant) init( + + +pl1-skip-to-dcl-column (ESC-SPACE): +This new request moves the cursor to the column specified by the +pl1-dcl-column option. If the statement already extends beyond this +column, the cursor is moved to the pl1-dcl-column on a new line +following the current line. This request is useful for indenting +attributes in declare statements when ESC-^D cannot be used and +pl1-dcl-style = 2. + + +pl1-backward-statement (ESC-^A), pl1-forward-statement (ESC-^E): +Two new requests move forward and backward in increments of PL/I +statements. Both take a numeric argument to indicate how many +statements to move over. + + +pl1-comment-xxx requests: +A new option pl1-comment-style controls how comments are handled when +text extends into the pl1-comment-column (another new option). The +pl1-comment-column defaults to column 61. If text extends beyond the +comment column when one of the line comment requests is given, then +the placement of the comment depends upon the pl1-comment-style. + + +pl1-comment-style can have the following values. + +1 Comment is place on the current line following the text. + +2 If text extends beyond pl1-commnt-column + pl1-comment-column-delta + (a new option), then the comment is placed on a new line below the + current line. Otherwise, it is placed on the current line. The + default value of pl1-comment-column-delta is 10. + +3 Comment is placed on a new line following the current line. + +The default value for pl1-comment-style is 1. + + +The following comment requests observe pl1-comment-style. + +ESC-; pl1-comment-current-line +ESC-N pl1-comment-next-line +ESC-P pl1-comment-prev-line + +ESC-N and ESC-P take a numeric argument to indicate how many lines +forward or backward the cursor should move before commenting the line. + + +A new pl1-comment-end (ESC-*) request moves the cursor to the end of +the line (according to the pl1-line-length option) and places a +comment suffix (*/) at the end of a comment line. + + +pl1-comment-box (^XC): +This request has been significantly enhanced. When a new comment box +is created, fill-mode is entered to facilitate typing of prose text. +The pl1-line-length is used to control the filling of comment lines. +When a subsequent (^XC) is entered to exit comment minor-mode, the +comment box is completed by placing comment-suffix (*/) at the ends of +all box lines. + + +Fill-mode can be exited and re-entered during the creation of a +comment box using + ESC-X filloff + ESC-X fillon + + +If (^XC) is typed to enter comment minor-mode while the cursor is +positioned inside an existing comment box, then new comment lines are +inserted above the line on which the cursor is positioned. Filling +occurs for only the new lines. The old lines remain unchanged. + + +pl1-refill-comment-box-region (^ZC): +This new request complements the enhancements made to the +pl1-comment-box request. It refills the comment box lines between +(and including) the lines containing the cursor and the-mark. + + +pl1-line-between-procs (^ZD): +This new request generates a dividing line between major blocks of +code in a PL/I program to provide visual separation of the code. A +line of the form: + +/* * * * * * .... * */ + +which extends through the pl1-line-length column. If the cursor is +positioned at the beginning of a dividing line, ^ZD causes a new +divider plus a newpage to be inserted. Similarly, ^U^ZD causes a +divider, a new page and another divider to be inserted. + + +pl1-include-file-comment-start-end (^ZI): +This new request generates a starting and ending comment line for PL/I +include files. The lines have the form: + +/* START OF: xxx.incl.pl1 * * * */ + +/* END OF: xxx.incl.pl1 * * * */ + + +New pl1-compile-options option: +The pl1-compile-options option can be set to specify the default +compilation options used by ESC-^C to compile the program. The +default compiler option is "-table". + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/pl1-mode.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/pl1-mode.info new file mode 100644 index 0000000..89fe232 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/pl1-mode.info @@ -0,0 +1,142 @@ +4/11/79 - Multics Emacs PL/I mode + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + +PL/I mode provides an automatic assistance in PL/I progam formatting in the +real-time editing context of Multics EMACS. The basic facility provided at +this time is that of lining up untyped PL/I statements, although on a +one-for-one basis it will line up typed ones, too. + + Enter PL/I mode by issueing ESC-Xpl1-mode. It will take a couple of +seconds to "load itself". When in PL/I mode, which shows up on the Mode line +as "PL/I" as a major mode, the following non-default key bindings apply: + + TAB (^I) Indent this PL/I statement properly (if not yet + typed in, tab out to it; otherwise, readjust its + indentation properly). + ESC-CR (ESC-^M) Like CR and TAB. + ESC-^C Compile buffer. Write this buffer to its default pathname + and compile it, using the compiler "pl1" and assuming + "-tb" for options. These may be changed with the + extended commands set-compiler and set-compile-options. + Highly effective in two-window mode. + (See fortran-mode.info for more on this). + ESC-^D Try to find a declaration for the entry-point whose + name is to the left of the cursor, and insert it. + There exists a library of such. + If the declaration is not in the library, + ESC-^D will attempt to figure it out from inbound + parameter descriptors in an object segment + responding to that name. + error_table_$xxx can be declared by ESC-^D, too. + ESC-^H (ESC-Backspace) Delete 5 columns of indentation. + Intended for undenting END's. + ESC-^I (ESC-TAB) Add 5 columns of indentation. + Intended for asserting your own style. + ^X^D (Control X-Control D) Find next error. When used after + an ESC-^C, will search for errors and place the cursor + on them in the source. Highly effective in two window + mode. See fortran-mode.info for more information on + the compilation error facility. + ^XC (Control X-C) Start or end a comment. Text following + this will be set off as a comment. A second ^XC ends + the comment. + + All the standard commentation commands (ESC-;, etc.) do the PL/I + thing. Word commands (ESC-F, etc.) in PL/I mode buffers consider + the dollar sign to be part of a word. + + The indentation rules which are followed are such: + + Any fragment of an incomplete statement gets lined up 5 after the +start of that statement. The statement after a DO or BEGIN gets indented 5 +times one less than the number of IF's in the DO or BEGIN. In "inding style +2", the statement after an END gets lined up 5 LESS than the END statement; +the first statement in a program gets lined up at col. 11 (Multics +reckoning). OTHERWISE, each statement lines up with the previous one. + + There are two styles available; the default is 1, you can get 2 by saying + ESC-Xopt pl1-inding-style 2 CR + +(i.e., it is managed by the EMACS option mechanism). + + In style 1, you get; + + if x = 6 then do; + bar = 5; + foo = 6; + end; + +In style 1, you are expected to line the END up yourself (use ESC-^H) because +it is impossible in realtime to predict that an untyped statement is going to +be an END. You must undent the end yourself, because the next statement will +line up with it. + + In style 2 you get + + if x = 6 then do; + bar = 5; + foo = 4; + end; + next = 17; + +Obviously, emacs is happier with this, because it can figure out the next +statement after the END once you have typed it. + + There are no known bugs in the mode's PL/I parsing: it pretentiously +claims to be able to parse any legal PL/I statement, with the following +exception: Multi-dimensional label constants not supported (not a big +problem, multics PL/I doesnt support them either). + + There is also a minor mode called "electric PL/I mode", which can be +obtained by ESC-Xelectric-modeCR once in PL/I mode, or ESC-X electric-pl1-mode +CR. To get it by default as your mode for PL/I programs, put the statement + + (defprop pl1 electric-pl1-mode suffix-mode) + +in your start_up.emacs. Some users have found electric PL/I mode overly +violent, so it remains an option. It connects semicolon to a function which +automatically indents for the next statement after inserting a semicolon; use +\; to get a semi in without the electric action. Also, this action is +suppressed if there is a next line, and it is not empty. The "electric +semicolon" also moves "end"'s back for you (in inding-style 1), when you type +the ";" of the "end" statement. (Be careful to "\" ;'s in strings, there are +problems there). Electric PL/I mode also gives ":" electric action, i.e., +indenting after labels. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/rmail.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/rmail.info new file mode 100644 index 0000000..c8efec6 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/rmail.info @@ -0,0 +1,266 @@ +10/19/80 RMAIL- Emacs mail reading/sending subsytem + + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command ** + + + + + + The Emacs mail system provides a facility for reading, sending, and +responding to Multics mail within Emacs, utilizing the standard Emacs features +and the interfaces of the Multics mail system. Known deficiencies/misfeatures +will be detailed below. RMAIL is modeled after ITS RMAIL. + + ------------------------------ ------------------------------ + + There are two basic functions, sending mail and reading mail. The Emacs +command for sending mail is + + ^XM send-mail + +Issuing this command will prompt for a "Subject", which should be supplied, +terminated by a carriage return. This subject will be incorporated into the +buffer name, so it should be short. A buffer will be formatted up with the +mail in it, header prefabricated. The buffer will be placed in an available +window (like ^X^E (comout) does). Fill mode will be turned on with a fill +column of 72. The buffer is now in MAIL mode, which defines the following +commands: + + ^XA mail-append. Go to the end of the body of the mail. Use this to + start inputting the text after you have set the destination, or + to go back to the text after editing some header field. + + ^XT mail-to. Go to the end of the "To:" line, to add a recipient. + You will be left here when the MAIL buffer is entered, to enter + the first recipient. Then use ^XA to continue. Separate + recipients (like all header fields) with commas, i.e., + + To: Washington.States, Consultant.c + + ^XF mail-from. Go to the end of the "From:" line, to edit it, or + add more sender's names. + + ^XJ mail-subject. Go to the end of the "Subject:" line, to edit it. + + ^XC mail-cc. Go to the end of the "Cc:" (carbon copy recipients) + line, making one if there is none, so that you can type in the + destination of a carbon copy recipient. + + ^XY mail-reply-to. Generate a "Reply-To" field, if none exists, + and go to it. The destination put here will be used for replies + if a recipient of your mail uses RMAIL (or another mail system) to + automatically reply to your message. + + ^X^S send-the-mail. Send the buffer to the recipients specified in the + header. The relative success of the sendings will be displayed as + local output (2 linefeeds to restore display). + + ESC-^F forward-mail-field. Move forward one recipient, cc recipient, etc. + on this (header) line. Circles around at end. + + ESC-^B backward-mail-field. Move backward one recipient, cc recipient, + etc. on this (header) line. Circles around at end. + + ESC-^D delete-mail-field. Delete, including necessary commas, the + single header item (recipient, etc.) that the cursor is on. + + ^XL rmail-logger-append. Log the message into a file, placing it at + the end, separated by a formfeed. With an argument, or the first + time, the pathname of the log file is prompted for. Otherwise, + the same file last used by ^XL or ^XP is used. + + ^XP rmail-logger-append. Same as ^XL, but puts message at the front + of the file. + + Three forms of recipient (or cc recipient) destinations are accepted: + + Jones.States (standard Multics person.project) + Jones (link mailbox in Daemon mailbox dir) + Mxyptlk at KRYPTON-KL10 (ARPANET address, PERSON at SITE) + + Parenthetical comments in destinations are ignored, thus: + + Muhammad (I am the Greatest) Ali at (the) WBA + +gets set to "Muhammad Ali" at Site WBA, as per RFC 733. Quote processing +is done, too, and a field between <> brackets makes all outside it +(in a given address) a comment (as per RFC 733, which is visible +on Multics as mail_format.gi.info). + + Net mail sending is done via the Network Mailer Daemon; net connect +access is NOT required; you should be prepared for an acknowledgement message +from the Mailer Daemon. + + Your name will be given as + + From: Destructo.CHAOS + +or, if this site is on the ARPANET + + From: Destructo.CHAOS at RANDUM-MULTIX + +If RMAIL knows your real name, you will get + + From: Myron P. Destructo + +RMAIL knows your name if either your site Emacs expert has placed it in the +"rmail-full-name-table" in the "emacs environment directory" (see him or her +about this) or if you have a form setting "my-personal-name" in your startup, +e.g., + + (setq my-personal-name "Myron P. Destructo") + + If the Lisp variable "mail-mode-hook" is bound by the user, the atomic +symbol to which it is bound will be called as a function with no arguments +whenever a mail-mode buffer is created. This be used to set mail-mode key +bindings. + + ------------------------------ ------------------------------ + + Mail reading is performed via the command + + ^XR rmail + +By default, mail is read in your personal default mailbox, +>udd>your-project>you>you.mbx. If ^XR is given an argument, e.g., ^U^XR, the +"mailbox name" is prompted for. This may take any of the forms + + Person.Project + (with or without ".mbx" suffix) + Person (if a link to Person.mbx exists in the ARPANET + mailbox link directory) + +If you have no mail in the selected mailbox, a message will be issued to this +effect. Otherwise, the first message in the mailbox will be displayed in a +buffer, in RMAIL mode. This buffer is read-only; the following extra +commands (all normal commands are here too) apply in RMAIL mode: NB: these +are mostly NOT control characters, but regular characters!: (note also +that numeric araguments may be typed directly, e.g., 3 g to go +to message 3, without ESC or ^U): + + + n Move on to the next message. + p Move back to the previous message. + l Move to the last message in your mailbox. + g Move to message number (argument), i.e., + 3 g to go to message # 3. + j Same as g. + d Delete (i.e., queue for deletion when rmail is exited) + this message, move on to next undeleted message. + D Same as d, but moves backward. + u Undelete the last (stacked) deleted message. + c Copy the message to some other mailbox. A mailbox name will + be prompted for; anything acceptable to ^XR (as above) is ok. + q Quit out of rmail, returning to buffer from which + rmail was invoked, deleting all messages marked for + deletion. + s Summarize (as local output) all undeleted messages. + May take a little time for full mailboxes. + ^XL Log the message to an ASCII file, at the end of the file. + See the description above under the mail-sending commands. + ^XP Same as ^XL, but "prepends" to the front. See the description + above under mail-sending commands. + + m Send mail, not necessarily a reply (see r). Indentical to + ^XM, send-mail, but ESC-^Y, ^X^Q and ^X^S are defined as below + for the r command, for convenience while RMAIL'ing. + + r Reply to sender, via MAIL mode. Formats up a MAIL mode buffer to + reply to the current message, copying the subject (if any), or + making one up, and setting up as a destination the sender's address + that he/she would like to be responded to at. With a numeric + argument, i.e, 1r, responds to other recipients as well: + we do not do so by default. This command is EXTREMELY effective + in 2-window mode, in which case the response will be put in the + other window, and ESC-^V (page-other-window) may be used to "page" + the letter you are responding to as you respond. When in RMAIL + reply mode, (variant of MAIL mode set up for this purpose), the + following three ADDITIONAL commands apply, other than the normal MAIL + mode commands and the standard Emacs commands: + + ESC-^Y rmail-yank-mail + + Yanks the text and header of the original piece of + mail being responded to, indented, by default, by + 4 (opt rmail-original-yank-indent controls this number). + + ^X^Q return-to-rmail + + returns to RMAIL, and its window without sending the + message. + + ^X^S send-from-rmail + + Actually sends the reply, and returns to RMAIL and its + window. + + + + + It is important to quit (q) out of RMAIL before leaving Emacs; Messages +do not actually get deleted unless you quit out of RMAIL (or, equivalently, +answer "yes" to "All messages deleted. Quit RMAIL?"). + + If the Lisp variable "rmail-mode-hook" is bound by the user, +the atomic symbol to which it is bound will be called as a function with +no arguments before the first message is displayed. This can +be used to set RMAIL-mode key bindings. + + ------------------------------ ------------------------------ +People who receive a lot of mail from a lot of people and or +ARPAnet sites may want to set the variable "rmail-names-for-me" +in their startup. This variable is set to a list of valid +addresses which should NOT be included among recipients of any +piece of mail generated by rmail-reply with an argument. +This is to prevent sending yourself mail. Project names of +"*" as well as host names of "*" are permitted. + + Example: + (setq rmail-names-for-me + '("bsg.*" "Greenberg.*" "BSG1.*" "Greenb1 @ Foo-Unix" + "BSG @ *")) + +By default, rmail-reply will suppress responding the the same +name as would be put in the From field by send-mail (^XM). +---------------------------------------------------------------------- + Current lossages, deficiencies, and unimplementeds (3/17/79) + +1. We don't send mail acknowledgements. + +2. We currently have no facility for forwarding mail. + + (END) + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/sample_start_up.emacs.lisp b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/sample_start_up.emacs.lisp new file mode 100644 index 0000000..166c4bd --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/sample_start_up.emacs.lisp @@ -0,0 +1,52 @@ +;;; +;;; Sample start_up.emacs, Lisp source +;;; Must be compiled to get start_up.emacs +;;; Last modified 10/16/80 + +(declare (special rmail-mode-hook my-personal-name)) ;Global variables + +(defun Jones/'s-start-up () ;Compilation => efficiency + (opt 'find-file-set-modes 'on) ;foo.pl1 => pl1 mode, etc. + (setq rmail-mode-hook 'Jones-rmail-mode-hook) + ;Like to read msgs backwards + (accept-messages) ;Accept console messages + (opt 'suppress-backspace-display 'on) ; _\010A => _A + (setq my-personal-name "Harvey B. Jones")) ;For RMAIL + +(defun Jones-rmail-mode-hook ()(setq rmail-msgx rmail-msgcount)) + +(Jones/'s-start-up) +;; +;; +;; +;; ----------------------------------------------------------- +;; +;; +;; Historical Background +;; +;; This edition of the Multics software materials and documentation is provided and donated +;; to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. +;; as a contribution to computer science knowledge. +;; This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +;; Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull +;; and Bull HN Information Systems Inc. to the development of this operating system. +;; Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +;; renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +;; of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +;; for managing computer hardware properly and for executing programs. Many subsequent operating systems +;; incorporated Multics principles. +;; Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +;; as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . +;; +;; ----------------------------------------------------------- +;; +;; Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +;; fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +;; and that both the copyright notice and historical background and this permission notice appear in supporting +;; documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining +;; to distribution of the programs without specific prior written permission. +;; Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. +;; Copyright 2006 by Bull HN Information Systems Inc. +;; Copyright 2006 by Bull SAS +;; All Rights Reserved +;; \ No newline at end of file diff --git a/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/windows.info b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/windows.info new file mode 100644 index 0000000..5262e04 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/doc/subsystem/emacs/windows.info @@ -0,0 +1,356 @@ +4/16/79 -- Information on new window and buffer management system + in Multics Emacs. (Last update 11/4/79) + +**This file is intended to be perused via dprint, print, or via an** +**editor. It is not intended to be perused with the help command** + + + + + + The latest version of Multics Emacs contains a new "menu"-type scheme to +manipulate buffers and windows, and supports as many windows as can be fit on +the screen without any window going to less than 3 lines. + + First, some definitions: + + o buffer - a body of text in Emacs identified by a buffer + name. This concept has not changed. + + o window - an area of the screen delimited by "boundary lines" + (lines of "-----"), the top of the screen, or the modeline. + A window is said to be displaying a buffer if the text of that + buffer can be seen in that window. + + o "on display in" - a buffer is on display in a given window + if the text of that buffer can be seen in that window. + + o topline - the boundary line on the top of a window. + The uppermost window has no topline. + + o bottomline - the boundary line on the bottom of a window. + The bottom-most window has no bottomline. + + o Selected window - the window in which the cursor now appears + (when not in the minibuffer). + + o Current buffer - the buffer on display in the selected window. + The modeline gives the name of the current buffer. + + o LRU window - the least-recently used window, i.e., the + window which has been the selected window least recently. + + o Previous window - the next-most recently used window other than the + selected window itself. The selected window is always the + most recently used. + + + There are several basic techniques for manipulating windows. The simple +keyboard commands ^XO, ^X0, ^X1, ^X2, ^X3, and ^X4 may be used to create, +destroy, and select windows in a manner roughly analogous to the old use +of ^XO, ^X1, ^X2, and ^X3. At low speed, this may be the only convenient way. +Alternatively, the "window editor" may be used. The window editor, invoked by +^Z^W, puts up a display of the numbers, positions, sizes, and contents of all +extant windows, and allows destruction, selection, and size-adjustment of +windows by positioning to the line describing the window to be dealt with and +issuing commands. + + First we describe the simple keyboard commands, beginning with the ones +which had been used previously: + + ^X2 creates a new window on the screen, and selects that window. If there + was only one window on the screen, this is the same as it had been + before. If there are any number of windows on the screen, ^X2 will make + one more, and select it. The buffer placed on display in that window + will be one whose name is constructed as "Window ## Default" (where ## + is the window number, the top one being window 1), no longer + "alternate". Arguments may no longer be used to ^X2 to specify the top + window size; the window editor must be used for this purpose. + + ^X3 Creates a new window at the bottom of the screen, but keeps the + currently selected window selected. The name of the buffer placed in + that window is constructed as described above. The new window becomes + the LRU window, so ^X4 ^X^E (command) CR will put file output in a new + window (see below). Note that if there is only one window on the screen + this is compatible with what it had done before. Again, arguments are + ignored. + + ^X1 Gets rid of all windows except the currently selected window, which then + grows to occupy the whole screen. This is compatible with what it did + before. Getting rid of a window does NOT mean getting rid of the text + or buffer which is on display in that window, it just means taking the + window off the screen. + + ^XO Selects the previous window, which is the window you had last been in + before you were in this window. Note that this makes the window you + issue the ^XO in the previous window, so successive ^XO's will switch + windows back and forth like it has always done. Selecting a window, of + course, may potentially (and usually does) switch buffers, too. The + modeline always tells you what buffer is current, the cursor tells you + what window is selected. + + The following two new commands augment the repertoire of the above: + + ^X0 (control x zero, as opposed to control x "oh".) Removes the selected + window from the screen, giving the space it occupied to the windows + that were on either side of it. The previous window will become + the new selected window. With an argument, deletes the specified + window (the top window is number 1). + + ^X4 Selects the LRU window. The idea of this is to implement "Get me a + window I haven't looked at recently for the thing I'm about to do + (such as a ^XB or ^X^F)". You would want to do this if you had + several (at least 2) windows on the screen, cared about some of them, + didn't care about some other of them, and wanted to find one you didn't + care about to do some new thing in. + + Note that selecting the LRU window makes it the MOST recently used + (i.e., selected). So some other window is now LRU, and another ^X4 will + select _t_h_a_t window. Thus, successive ^X4's (or ^X4 ^C ^C ...) + will cycle through all windows on the screen. + + Several Emacs commands always switch into a new buffer to present +their goods, and leave you in it. For example, the directory editor, ^X^E +(comout), which leaves you in file_output, and RMAIL (both inbound and +outbound). Some of these commands (and this is surely an area for debate) +think they know that what you ask of them is not what you are "really doing". +For instance, send-mail (^XM) believes that when you wish to send mail, it is +on a spur-of-the-moment impulse, and you wish to keep what you were doing on +the screen. Similarly, comout (^X^E) believes that you are looking at +file_output just to see how the "results" of your editing suceeded, and you do +not wish to obliterate what you are editing from the screen. + + These commands perform what is called a "find buffer in window" (which, +incidentally, is available to the extension programmer by that name with +hyphens in it). What this means is that if the buffer they wish to go +to/display (e.g., "file_output" for ^X^E (comout)) is already on display in +some window, they will select that window. If the buffer is not on display, +they will select the LRU window in which to _p_u_t it on display, and so do. The +directory editor will put its "examine" buffer on display with a "find buffer +in window", replacing the content of the LRU window if its examine buffer is +not already on display. Ditto the RMAIL reply buffer. + + -------------------------------------------------- + + The window editor provides an interactive way to manipulate windows in an +integrated fashion, allowing the screen to be conveniently reorganized. The +window editor puts a formatted display in a dedicated buffer, which will +appear on the screen, in the selected window. ^Z^W causes this to happen. If +you want it to do a find-buffer-in-window on itself (e.g., you want to see the +effect of reorganizing the screen on the material in the selected window), +give it an argument, i.e., ^U^Z^W. A typical window editor display looks like +this: + + 1 0 0 12 term-paper appear on + 2* 2 13 3 WINDOWSTAT 2* + 3 4 17 2 Messages from COMSAT + +Each line speaks of the contents of one window on the screen at the time +the window editor was entered. There are as many lines as there are windows. +You may not use normal Emacs commands to change the content of the display; it +is read-only. You may, however, use normal Emacs commands (e.g., searches, +etc.) to position around in it. The cursor, when in the window-editor's +buffer, is always on some line of the buffer (beware, the buffer may be larger +than the window it is in, like most Emacs buffers!). That line speaks of some +window; the window's window-number from the top of the screen is the first +number on that line. The window designated by the line on which the cursor is +will be called the "designated window (do not confuse this with the selected +window, which will always be the window containing the window editor's +display). + + The window number will be followed by a star for the window that was the +selected window at the time the window editor was entered. The next number +on each line is called the "internal window number", and is usually not of +interest. The remaining two numbers on each line are the position and size of +each window, the position being the starting line-number on the screen (the +top line is 0) and the number of lines in it. + + Following the position and size is the buffer name of the buffer +currently on display in that window. Following the buffer name are the first +ten characters of the "point line" in that window. The "point line" is the +line in the window that the cursor will go to if that window is selected. + + One operates the window editor by invoking it, positioning to some line, +thus designating some window, and issuing commands to affect that window. +The following requests are recognized: note that they are "printing" (i.e., not +control) characters, for ease of typing, since you may not enter text into a +read-only buffer (like that of the window-editor or DIRED). They are: + + g Go to, or select that window, leaving the window editor, and + moving the cursor to that window. given window in a many-window + situation, as opposed to a large number of ^X4's. + + f same as g, for compatibility with the buffer editor. + + k Kill, i.e., remove this window from the screen. This will be done + immediately, and the buffer editor display will be updated to + reflect the new screen layout. The space occupied by that window + will be distributed among its neighbors. + + d same as k, for DIRED compatibility. + + ^ (think of the shape of this character, "pushing up"). Move the + topline of the designated window up by one, increasing the size + of this window, and deducting one from its upstairs neighbor. + With a numeric argument, do that many lines instead of one. + The buffer editor display will be updated to reflect the new + screen layout. + + v (think of the shape of this character, "pushing down".) Moves the + bottomline of the designated window down. Same rules and features + as ^. + + a (think of the shape of a capital A). Bring the topline of this + window down, same rules and features as ^. + + u (think of the shape of a U). Pull the bottomline of this window + up, same rules and features as ^. + + The following requests do not deal with the designated window, and may be +issued at any time in the window editor: + + n Go to the next line of the window editor display. Although you + could use ^N as always, n is easier here, since this is a read-only + buffer. If on the last line, goes to the first. + + p Same rationale and idea as n, except goes to the previous line (or + the last if issued on the first). + + b Exits the window editor by entering the buffer editor in the + window now occupied by the window editor's display. + + c Creates a new window (like ^X3), except leaves you in the + window editor's display, with the display updated to reflect the + new state of the screen, with the new window as designated window. + + 3 Same as c, for mnemonic ease with ^X3. + + The window editor is normally exited by selecting some other window with +the "g" request; indeed, one may often enter the window editor for no other +reason than to do this! Once can also exit via the "b" request to the buffer +editor, or just ^XB or ^X^F of whatever one normally does to go wherever one +wants to go. Beware of window editor windows left lying around on the screen: +while attractive and interesting, they are NOT updated dynamically by Emacs +if windows and buffers are changed around. + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + The buffer editor provides a facility for cleaning out, examining, and +selecting buffers, similar to DIRED and the window editor. Like both of these +other menu-type editors, the buffer editor creates a read-only display in a +special buffer, and selects it in a window of your choice. Again as with these +others, printing-character requests are use to select options to deal with the +buffer whose name appears on the line with the cursor on it. + + The buffer editor is entered via ^Z^B. It will put its display in the +window in which it was invoked. If you want it to find-buffer-in-window itself +(e.g., it is on the screen already, or you don't want to overwrite the current +window), do a ^U^Z^B. + + Each line of the buffer-editor's display contains a buffer's name, a +pathname, if the buffer has a pathname associated with it, and possible flags. +The flags appear at the left margin, and they are: + + * The buffer is "modified" (needs writing out) + > The buffer that was current when the buffer editor was entered. + X The buffer editor has marked this buffer for deletion. + + There may be more buffers (i.e., lines in the buffer editor's display) +than are on display in the window in which this display appears; like any +other Emacs buffer on display, ^V, ESC-V, or any other standard Emacs +technique may be used to position around in it. + + Buffers may be killed (as ^XK normally does) with the buffer editor +"k" (or "d") request. Buffers so killed are not actually destroyed until the +buffer editor is exited via a g, w, f, q (or ^X^Q) request, at which time you +will be asked (if you have marked buffers for deletion) if you really want to +delete them (they will be listed as local display). + + The following requests are known to the buffer editor: + + n Go to next line (see window editor's similar request for the + rationale for this ^N substitute) or first if now on last. + + p Go to previous line (or last if now on first). + + k Mark the designated buffer for deletion when the buffer editor + is exited, move to the next line. + + d same as k, for DIRED compatibility. + + u Undelete, i.e., unmark for deletion, the designated buffer. + The X will be removed from the display, and the cursor will + be positioned to the next line. + + e Examine the designated buffer. In one-window mode, this is + kind of worthless, you should just go there. But with two or more + windows, a find-buffer-in-window is done on the designated buffer, + putting it on display if not already on display. A message will + be printed in the minibuffer about where (in what window) it + appears. + + These next requests cause the buffer editor to be exited: you will be + interrogated about pending deletions if you have any: + + g Go to the designated buffer, exiting the buffer editor, replacing + its display in the current (selected) window, with this buffer. + This is just like doing a ^XB: as matter of fact, the buffer editor + may be used for just seeing what buffers there are and going to + one, to save typing! This may also be useful for buffers with + long and complex names, like "Messages from Brzezinski". + + f Find-buffer-in-window the designated buffer. Since the buffer + editor makes its own window LRU when it exits, if you "f" + a buffer not currently on display in any window, it is the same + as "g"ing it, replacing the buffer editor's window. + + However, if the designated buffer is on the screen somewhere, the + cursor will simply be moved into that window (and thus, into + that buffer). If you use multiple windows, you will find that you + will use "f" all the time, and will rarely use "g". + + s Writes out, i.e., saves the designated buffer to its default + pathname, unmarking it as modified. + + w Exit the buffer editor to the window editor in the current window. + + q Exit the buffer editor to the buffer from which it was invoked, in + the current window, if it was invoked via ^Z^W, or find-buffer-in-window + the buffer from which you came if the buffer editor was invoked + by beargumented ^Z^B, i.e., was find-buffered-in-windowed + itself. + + ^X^Q Same as q. + + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL +and BULL HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture +for managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by BULL HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_ctls_.s.archive b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_ctls_.s.archive new file mode 100644 index 0000000..dba45ca Binary files /dev/null and b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_ctls_.s.archive differ diff --git a/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_full_.s.archive b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_full_.s.archive new file mode 100644 index 0000000..d7720d7 --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_full_.s.archive @@ -0,0 +1,1860 @@ + + + + + e_macops_.lisp 03/25/87 1031.0rew 03/25/87 1028.9 509922 + + + +;;; *********************************************************** +;;; * * +;;; * Copyright, (C) Honeywell Information Systems Inc., 1982 * +;;; * * +;;; * Copyright (c) 1978 by Massachusetts Institute of * +;;; * Technology and Honeywell Information Systems, Inc. * +;;; * * +;;; *********************************************************** + +;;; +;;; +;;; EMACS extended functions +;;; BSG, archy, GMP, RSL, RMSoley, etc +;;; +;;; How about some journalization: + +;;; HISTORY COMMENTS: +;;; 1) change(84-01-30,Margolin), approve(), audit(), +;;; install(86-08-20,MR12.0-1136): +;;; pre-hcom history: +;;; Modified: June 1982 by Barmar - to install JSL's new string-search +;;; and global-print commands, using all his new hairy +;;; defcom features. +;;; Modified: 31 August 1982 by Barmar - to move query-replace here from +;;; emacs-extended-searches. +;;; Modified: 1 November 1983 by Barmar - to fix replace to not fill up the +;;; kill-ring with the old string, and fix replace and query-replace +;;; to use backward-char instead of reverse-search. +;;; Modified: 25 November 1983 by Barmar - to fix the read-only bug in +;;; word-operator, also converting macros to defmacro. +;;; Modified: ?? January 1984 by Barmar - to rewrite underlining code. +;;; 2) change(84-12-25,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; to move iox_$control out to e_defpl1_.lisp, changed lambda into let. +;;; 3) change(84-12-30,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; to move fillon, fill-mode-off, and +;;; filloff to e_basic_, with fill-mode; changed speedtype to +;;; interact with previous key bindings better. +;;; 4) change(84-12-31,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; change comout-get-output to check +;;; read-only-flag, add unwind-protect to comout, comout-get-output, +;;; and eval-multics-command-line; move reset_more +;;; from comout-command to eval-multics-command-line; changed +;;; comout-get-output to use "file_output -truncate" rather than +;;; calling hcs_$set_bc. +;;; 5) change(85-01-27,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; add some *expr declarations. +;;; 6) change(85-02-03,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; changed speedtype to special-case +;;; CR, rather than expecting it to be in fill-mode-delimiters. +;;; 7) change(85-02-24,Margolin), approve(87-01-27,MCR7607), +;;; audit(87-02-13,RBarstad), install(87-03-25,MR12.1-1014): +;;; added comout-to-buffer, changed comout to use it. Added +;;; (%include defun), and changed comout to use &rest. Changed +;;; comout-command to turn off read-only-flag (with a warning in the +;;; prompt), added comout-command-to-buffer. +;;; 8) change(86-11-22,Margolin), approve(87-01-27,MCR7607), +;;; audit(87-02-13,RBarstad), install(87-03-25,MR12.1-1014): +;;; Changed comout-command and comout-command-to-buffer to check whether +;;; the output buffer contains an unwritten nonempty buffer, and to use +;;; local displays for the warnings. Changed comout-to-buffer to support +;;; the comout-local-display option. +;;; END HISTORY COMMENTS + +(%include e-macros) +(%include defmacro) +(declare (macros nil)) +(%include defun) +(%include other_other) + +(defmacro defkill (name type) `(defprop ,name ,type kills)) + +(declare (genprefix /!e_macops_)) +(declare (*lexpr ncline comout minibuffer-remark gratuitous-mark-setter + report-error report-error-noabort)) +(declare (*expr autofill-self-insert buffer-kill close-line iox_$control + e_pl1_$set_emacs_tty_modes e_pl1_$set_multics_tty_modes + ed-cv-fixnum-check extended-command forward-regexp-search + get-buffer-state + go-to-hpos hcs_$set_bc hcs_$truncate_file e_pl1_$get_iocb + intern-minibuf-response mark-at-current-point-p mark-tag-fun + local-display-buffer-info delete-word search-charset-forward + minibuffer-response push-mark-ring search-charset-backwards + self-insert skip-to-whitespace-in-line exists-buffer + search:numeric-prompt set-the-mark-here backward-n-chars + check-read-only get-key-binding parse-key-description)) +(declare (special curpointpos good-word-charactertbl whitespace-charactertbl + iocb_ptr null-pointer non-speedtype-bindings + CRET last-input-char current-buffer-mode buffer-minor-modes + pdir-temp-ename suppress-redisplay-flag two-window-mode + number-of-lines-in-buffer known-buflist fpathname + buffer-modified-flag read-only-flag fill-prefix NLCHARSTRING + tab-equivalent comment-column comment-prefix firstline + lastline curline pdir-temp-pathname hard-enforce-fill-column + varlist fill-column fill-mode-delimiters minibufferp + OPEN-PAREN CLOSE-PAREN SEMI SINGLEQUOTE DOUBLEQUOTE SLASH + sexp-searcher-mark-list MCS-editing-characters mark-ring + MCS-escape-character process-dir named-mark-list + macro-execution-in-progress tty-no-upmotionp damaged-flag + last-minibuf-response previous-command e-lisp-error-mode + completion-list)) + +(defvar ((comout-local-display nil) + (*comout-command-default-buffer* 'file_output) + *comout-buffer-force* + *comout-command-buffer*)) + +;;; +;;; Named mark management +;;; + + +(defun get-named-mark (name) + (let ((m (let ((tag (mark-tag-fun current-buffer))) + (get name tag)))) + (and (null m) + (report-error 'no-named-mark " " name)) + m)) + + +(defun set-named-mark- (markname) + (let ((tag (mark-tag-fun current-buffer))) + (let ((current (get markname tag))) + (cond (current (set-mark-here current)) + (t (setq current (set-mark)) + (putprop markname current tag) + (setq named-mark-list + (cons markname named-mark-list)))) + current))) + + +(defcom delete-named-mark + &arguments ((markname &symbol &prompt "Delete named mark: " + &default &eval (report-error 'need-mark-name))) + (let ((m (get-named-mark markname))) + (setq named-mark-list (delq markname named-mark-list)) + (release-mark m) + (remprop markname (mark-tag-fun current-buffer)))) + +(defun produce-named-mark-list () + (let ((tag (mark-tag-fun current-buffer))) + (mapcar '(lambda (x)(list x (get x tag))) named-mark-list))) + +;;; Character-oriented commands. + +(defcom twiddle-chars + &undo-function twiddle-chars + (backward-char) + (backward-char) + (insert-char (prog2 0 (curchar) (delete-char) (forward-char)))) + +;;; Word-oriented commands. + +(defcom replace + &arguments ((original &default + &eval (get-search-string "Replace old string")) + (new &prompt "Replace new string: " NL)) + (if (not (forward-search original)) + (search-failure-annunciator)) + (let ((old-length (stringlength original))) + (do-forever + (with-mark m ;have already searched, flush it + (backward-n-chars old-length) + (without-saving (wipe-point-mark m))) + (insert-string new) + (if (not (forward-search original)) ;look again + (stop-doing))))) ;not found, done + +(defcom twiddle-words + &undo-function twiddle-words + (save-excursion + (and (charset-member (curchar) good-word-charactertbl) + (forward-word)) + (search-charset-backwards good-word-charactertbl) + (with-mark bow + (backward-word) + (let ((second (point-mark-to-string bow))) + (without-saving (wipe-point-mark bow)) + (search-charset-backwards good-word-charactertbl) + (cond ((at-beginning-of-buffer) + (insert-string second) + (command-quit))) + (let ((in-between (point-mark-to-string bow))) + (without-saving (wipe-point-mark bow)) + (backward-word) + (insert-string second) + (insert-string in-between) + (forward-word)))))) + +(defcom underline-word + &undo-function remove-underlining-from-word + (or (bolp)(backward-char)) + (forward-word) + (with-mark m + (backward-word) + (underline-point-mark m))) + +(declare (special underline-whitespace)) +(defcom underline-region + &numeric-function de-underline-region + &undo-function de-underline-region + (let ((point-at-end)) + (with-the-mark-last done + (setq point-at-end + (mark-at-current-point-p der-wahrer-mark)) + (underline-point-mark done)) + (or point-at-end (exchange-point-and-mark)) + (cond ((and (looking-at BACKSPACE) + (alphalessp (lefthand-char) "_")) + (forward-char) (forward-char))) + (or point-at-end (exchange-point-and-mark)))) + +(defun underline-point-mark (mark) + (do ((this (curchar) (curchar))) + ((mark-reached mark)) + (cond ((and (samepnamep this TAB) underline-whitespace) + (insert-string + (gen-repetitive + (- tab-equivalent (\ (cur-hpos) tab-equivalent)) + "_")) + (delete-char)) + ((and (samepnamep this SPACE) underline-whitespace) + (delete-char) (insert-string "_")) + ((or (samepnamep this "_") ;don't underline underscore + (samepnamep this "ÿ") ;skip control chars + (alphalessp this SPACE)) ; "" "" "" + (forward-char)) + ((and (charset-member this whitespace-charactertbl) + (not underline-whitespace)) + (forward-char)) + ((alphalessp this "_") + (forward-char) + (cond ((samepnamep (curchar) BACKSPACE) ;already overstruck + (forward-char) (forward-char)) + (t (insert-string BACKSPACE) + (insert-string "_")))) + ((samepnamep (lefthand-char) BACKSPACE) ;already overstruck + (forward-char)) + (t (insert-string "_") + (insert-string BACKSPACE) + (forward-char))))) + +(defcom de-underline-region + &undo-function underline-region + (with-the-mark-last done + (de-underline-point-mark done))) + +;;; Removes underlining from the point to a given mark. +;;; Caller must ensure that mark is beyond point. +(defun de-underline-point-mark (mark) + (do-forever + (if (mark-reached mark) (stop-doing)) + (cond ((or (looking-at "_") + (looking-at "_")) + (delete-char) (delete-char)) + ((and underline-whitespace + (looking-at "_")) + (delete-char) (insert-string SPACE)) + ('else (forward-char))))) + +(defcom remove-underlining-from-word + (or (bolp) + (backward-char)) + (forward-word) + (with-mark m + (backward-word) + (de-underline-point-mark m))) + +;;; Line-oriented commands. + +(defcom open-space + &numeric-argument (&repeat &lower-bound 0) + (insert-char NL) + (backward-char)) + + +(defcom set-fill-prefix + &arguments ((new-prefix &default + &eval + (with-mark m + (go-to-beginning-of-line) + (prog2 nil + (point-mark-to-string m) + (go-to-mark m))))) + (setq fill-prefix new-prefix)) + + +(defcom center-line + (save-excursion + (go-to-beginning-of-line) + (delete-white-sides) + (go-to-end-of-line) + (delete-white-sides) + (let ((hp (cur-hpos))) + (go-to-beginning-of-line) + (and (< hp fill-column) + (whitespace-to-hpos (// (- fill-column hp) 2)))))) + +(defcom split-line + (let ((hpos (cur-hpos))) + (save-excursion + (insert-char NL) + (whitespace-to-hpos hpos)))) + +(defcom delete-line-indentation + &numeric-argument (&pass) + (if numarg (next-line)) + (go-to-beginning-of-line) + (delete-white-sides) + (rubout-char)) + +(defcom mark-whole-buffer + (go-to-end-of-buffer) + (set-the-mark) + (go-to-beginning-of-buffer)) + +;;; Speedtype + +(defcom speedtype-expander + &numeric-argument (&repeat &lower-bound 0) + (prog (the-word) + (backward-char) + (cond ((not (charset-member (curchar) good-word-charactertbl)) + (forward-char)) + (t (forward-char) + (with-mark m + (backward-word) + (setq the-word + (internedp (point-mark-to-string m))) + (if (symbolp the-word) + (setq the-word (get the-word 'speedtype)) + else (setq the-word nil)) + (if the-word (wipe-point-mark m) + (insert-string the-word) + else (go-to-mark m))))) + (let ((old-binding + (or (cdr (assq last-input-char non-speedtype-bindings)) + 'self-insert))) + (funcall old-binding)))) + + +;;; Hack to check obarray for a "word" without interning it +(defun internedp (string) + (cond ((= (stringlength string) 1) + (ascii (getcharn string 1))) + (t (do ((l (obarray (\ (sxhash string) 509.)) (cdr l))) + ((null l) string) + (and (samepnamep (car l) string) + (return (car l))))))) + +(defun setab n ;reverted to old-command + (do ((arg-list (listify n)(cddr arg-list))) + ((null arg-list)) + (let ((name (intern (make_atom (e_lap_$trim (car arg-list))))) + (value (cadr arg-list))) + (if (nullstringp value) + (display-error "No expansion supplied for " name ".")) + (putprop name value 'speedtype)))) + +(defcom speedtype + (assert-minor-mode 'speedtype) + (register-local-var 'non-speedtype-bindings) + (setq non-speedtype-bindings nil) + (mapc '(lambda (x) + (push (cons x + (get-key-binding (parse-key-description x))) + non-speedtype-bindings) + (set-key x 'speedtype-expander)) + (cons CRET fill-mode-delimiters))) + +(defcom speedtypeoff + (negate-minor-mode 'speedtype) + (mapc '(lambda (x) + (set-key (car x) (cdr x))) + non-speedtype-bindings)) + +;;; Uncle-and-aunt indenter, BSG 12/10/78 + +(defcom indent-relative + &numeric-argument (&pass) + (go-to-beginning-of-line) + (tab-to-previous-columns)) + +(defcom tab-to-previous-columns + &numeric-argument (&pass) + (skip-over-whitespace-in-line) + (and (bolp) (eolp) (setq numarg nil)) + (let ((orighpos (cur-hpos))) + (with-mark m + (delete-white-sides) + (do-forever + (if (firstlinep) (stop-doing) + else (prev-line)) + (if (line-is-blank) + else (if numarg + (skip-over-indentation) + (if (< (cur-hpos) orighpos) + (stop-doing)) + else + (stop-doing)))) + (if (not numarg) + (go-to-hpos orighpos) + (if (at-white-char) + (skip-over-whitespace-in-line) + (if (eolp) (go-to-beginning-of-line)) + else + (if (not (> (cur-hpos) orighpos)) + (skip-to-whitespace-in-line) + (skip-over-whitespace-in-line)))) + (setq orighpos (cur-hpos)) + (go-to-mark m) + (whitespace-to-hpos orighpos)))) + + +(defcom cret-and-indent-relative + &numeric-argument (&pass) + (cond (minibufferp (insert-string NLCHARSTRING)) + (t (new-line) (indent-relative)))) + +;;; +;;; Adapted from Killian, BSG 10/15/80 +;;; + +(defcom indent-rigidly + &numeric-argument (&pass) + (setq numarg (or numarg 0)) + (save-excursion + (with-the-mark-last m + (do-forever + (if (mark-at-current-point-p m)(stop-doing)) + (if (not (line-is-blank)) + (skip-over-indentation) + (let ((hpos (cur-hpos))) + (delete-white-sides) + (whitespace-to-hpos + (max 0 (+ hpos numarg))))) + (if (mark-on-current-line-p m)(stop-doing)) + (next-line))))) + +;;; +;;; Variable managers +;;; + +(setq varlist nil) + +(defcom put-variable + &prologue &eval (if der-wahrer-mark + else (report-error 'mark-not-set)) + &arguments ((x &symbol &prompt "Set variable: " + &default &eval (display-error-noabort + "You must supply a variable name."))) + (or (memq x varlist) (setq varlist (cons x varlist))) + (wipe-region) + (putprop x (kill-pop) 'editvalue)) + +(defcom get-variable + &arguments ((x &symbol &prompt "Get variable: " + &default &eval (display-error-noabort + "You must supply a variable name."))) + (let ((stuff (get x 'editvalue))) + (if stuff (set-the-mark) (insert-string stuff) + else (display-error x " has no value.")))) + +(defcom list-variables + (prog () + (if (not varlist) (display-error "No variables to list.")) + (save-excursion-buffer + (go-to-or-create-buffer (maknam (explodec "Variable list"))) + (putprop current-buffer t 'temporary-buffer) + (insert-string "Current string variables") + (new-line)(new-line) + (insert-string "Name") + (format-to-col 10.) + (insert-string "#Chars") + (new-line)(new-line) + (do l varlist (cdr l)(null l) + (let ((v (car l)) + (s (get (car l) 'editvalue))) + (insert-string v) + (format-to-col 10.) + (insert-string (decimal-rep (stringlength s)))) + (new-line)) + (display-buffer-as-printout)) + (end-local-displays))) + +(defcom-synonym lvars list-variables) + +;;; +;;; Buffer lister +;;; + +(declare (special previous-buffer)) + +;;; Got rid of old horrible crock, replaced using local-display-buffer-info +;;; Richard Mark Soley, 5 August 1981 +(defcom list-buffers + (init-local-displays) + (local-display-generator-nnl "Listing of Current Buffers") + (local-display-generator-nnl "") + (do ((buffer known-buflist (cdr buffer))) + ((null buffer)) + (local-display-buffer-info (car buffer))) + (end-local-displays)) + +(defun format-to-col (x) + (cond ((not (< curpointpos x))(insert-char SPACE)) + (t (whitespace-to-hpos x)))) + +;;; Case changing commands and primitives. + +(defmacro word-operator (count &body forms) + `(progn + (cond ((or (null ,count) + (and (charset-member (curchar) good-word-charactertbl) + (plusp ,count))) + (or (and (not (charset-member (lefthand-char) + good-word-charactertbl)) + (charset-member (curchar) good-word-charactertbl)) + (backward-word))) + ((minusp ,count) + (do-times (abs ,count) (backward-word))) + (t (search-charset-forward good-word-charactertbl))) + (do ((n (abs (or ,count 1)) (1- n)) (word) (quit)) + ((or quit (zerop n)) (and quit (ring-tty-bell))) + (setq word + (with-mark here + (forward-word) + (prog1 (point-mark-to-string here) + (go-to-mark here)))) + (protect ,@forms + &success (without-saving (delete-word))) + (or (= n 1) + (search-charset-forward good-word-charactertbl) + (setq quit t))) + (cond ((and (fixp ,count) (minusp ,count)) + (do-times (abs ,count) (backward-word)) + (or (at-beginning-of-buffer) (backward-char)))))) + +(defcom capitalize-initial-word + &numeric-argument (&pass) + (word-operator numarg + (insert-char (uppercase (substr word 1 1))) + (insert-string (lowercase (substr word 2))))) + +(defcom upper-case-word + &numeric-argument (&pass) + (word-operator numarg + (insert-string (uppercase word)))) + +(defcom lower-case-word + &numeric-argument (&pass) + (word-operator numarg + (insert-string (lowercase word)))) + +(defun uppercase (string) + (maknam + (mapcar '(lambda (x) (cond ((and (> x (1- (CtoI "a"))) + (< x (1+ (CtoI "z")))) + (- x 40)) + (t x))) + (exploden string)))) + +(defun lowercase (string) + (maknam + (mapcar '(lambda (x) (cond ((and (> x (1- (CtoI "A"))) + (< x (1+ (CtoI "Z")))) + (+ x 40)) + (t x))) + (exploden string)))) + +(defun upper-case-char (c) + (let ((cn (getcharn c 1))) + (cond ((and (< cn (1+ (CtoI "z"))) + (> cn (1- (CtoI "a")))) + (ascii (- cn 40))) + (t c)))) + +(defun lower-case-char (c) + (let ((cn (getcharn c 1))) + (cond ((and (< cn (1+ (CtoI "Z"))) + (> cn (1- (CtoI "A")))) + (ascii (+ cn 40))) + (t c)))) + +(defcom lower-case-region + (with-the-mark-last m + (do-forever + (if (mark-reached m)(stop-doing)) + (insert-char (lower-case-char (curchar))) + (delete-char)))) + + +(defcom upper-case-region + (with-the-mark-last m + (do-forever + (if (mark-reached m)(stop-doing)) + (insert-char (upper-case-char (curchar))) + (delete-char)))) + +;;; +;;; Auto-documenting features +;;; BSG and archy 5/24/78 +;;; BSG moved 'em all to e_self_documentor_ 10/7/78, leaving +;;; only the following pieces that sort of gotta stay around. +;;; + +(defcom find-key + &arguments ((fun &symbol &prompt "Function name: " + &default &eval (display-error-noabort "You must supply a function name."))) + (prog (env) + (setq env (ncons fun)) + (map-over-emacs-commands + '(lambda (symbol suspect arg) + (cond ((eq suspect (car arg)) + (rplacd arg symbol)))) + env) + (cond ((cdr env) + (minibuffer-print fun " is on " (printable (cdr env)))) + (t (minibuffer-print fun " is not on any key."))))) + + +(defun display-buffer-as-printout () + (save-excursion + (init-local-displays) + (go-to-beginning-of-buffer) + (do-forever + (local-display-generator (curline-as-string)) + (if (lastlinep) (stop-doing)) + (next-line)))) + + +(defcom skip-over-indentation + (go-to-beginning-of-line) + (do-forever + (if (eolp)(stop-doing)) + (if (not (at-white-char))(stop-doing)) + (forward-char))) + +;;; +;;; Hirsute blank line deleter, 6/12/78 +;;; + +(defcom delete-blank-lines + (prog (orig-was-blank eobp) + (setq orig-was-blank (line-is-blank)) + (if (not orig-was-blank)(go-to-end-of-line) + (delete-white-sides) + (insert-char NL) + else (skip-back-whitespace) + (go-to-end-of-line) + (if (not (bolp))(forward-char))) ;bolp => bobp + (with-mark m + (skip-over-whitespace) + (setq eobp (at-end-of-buffer)) + (or eobp (go-to-beginning-of-line)) + (without-saving (wipe-point-mark m))) + (if (and eobp (not orig-was-blank))(rubout-char)) + (if (and (not eobp) orig-was-blank)(insert-char NL)))) + +;;; +;;; Sentence hackery, 5/78, converted by bsg & archy +;;; from a noble attempt by Margulies. +;;; + +(defun at-end-of-sentence () + (prog () + (if (at-white-char) + (dispatch-on-lefthand-char + ("." (return t)) + ("?" (return t)) + ("!" (return t)))) + (if (or (at-end-of-buffer)(at-beginning-of-buffer)) + (return t)) + (if (and (eolp)(save-excursion (next-line)(line-is-blank))) + (return t)))) + +(defcom forward-sentence + &numeric-argument (&repeat) + &negative-function backward-sentence + (skip-over-whitespace) + (if (at-end-of-buffer)(command-quit)) + (do-forever + (skip-over-whitespace) + (skip-to-whitespace) + (if (at-end-of-sentence) (stop-doing)))) + + +(defcom backward-sentence + &numeric-argument (&repeat) + &negative-function forward-sentence + (skip-back-whitespace) + (if (at-beginning-of-buffer)(command-quit)) + (skip-back-to-whitespace) ;in case we ARE are end-of-sentence + (do-forever + (if (at-end-of-sentence) + (skip-over-whitespace) + (stop-doing)) + (skip-back-to-whitespace) + (skip-back-whitespace))) + + +(defprop kill-to-end-of-sentence forward kills) +(defcom kill-to-end-of-sentence + &numeric-argument (&repeat) + &negative-function kill-backward-sentence + (with-mark m + (forward-sentence) + (kill-backwards-to-mark m) + (merge-kills-forward))) + + +(defprop kill-backward-sentence reverse kills) +(defcom kill-backward-sentence + &numeric-argument (&repeat) + &negative-function kill-to-end-of-sentence + (with-mark m + (backward-sentence) + (kill-forward-to-mark m) + (merge-kills-reverse))) + +;;; +;;; Comments, anyone? +;;; BSG 6/25/78 +;;; + +(defcom set-comment-column + &arguments ((column &integer + &default &eval (if numarg numarg + else (1+ (cur-hpos))))) + &numeric-argument (&pass) + (setq comment-column (1- column)) + (minibuffer-print "Comment column = " (decimal-rep (1+ comment-column)))) + + +(defcom set-comment-prefix + &arguments ((prefix &prompt "Comment prefix: ")) + (setq comment-prefix prefix)) + + +(defcom prev-comment-line + (cond ((firstlinep)) + (t (prev-line) + (indent-for-comment)))) + + +(defcom down-comment-line + (cond ((lastlinep)) + (t (next-line) + (indent-for-comment)))) + + +(defun indent-to-fill-prefix () + (go-to-beginning-of-line) + (delete-white-sides) + (insert-string fill-prefix)) + + +(defcom indent-for-comment + (go-to-beginning-of-line) + (if (nullstringp comment-prefix)(indent-for-nondelimited-comment) + else (if (forward-search-in-line comment-prefix) ;already got one) + (do-times (stringlength comment-prefix)(backward-char)) + (if (= (cur-hpos) comment-column) nil + else (delete-white-sides) + (do ((column comment-column (+ column 5))) + ((> column (cur-hpos)) + (whitespace-to-hpos column)))) + (do-times (stringlength comment-prefix)(forward-char)) + else (go-to-end-of-line) + (delete-white-sides) + (insert-string comment-prefix) + (indent-for-comment)))) + + +(defun indent-for-nondelimited-comment () + ;;at bol from above. + (if (go-to-hpos comment-column) ;line at least that long. + (if (get (lefthand-char) 'whiteness) ;last was whitespace + (if (> (cur-hpos) comment-column) ;tab or such + (rubout-char) + (insert-string " ") + (indent-for-nondelimited-comment) + else ;we are right at it. + (do-forever + (if (eolp)(stop-doing)) + (if (at-white-char)(delete-char) + else (stop-doing)))) + else ; foo|__com + (skip-to-whitespace-in-line) + (if (not (eolp))(delete-white-sides)) + (insert-char " ")) + else ;line not that long + (whitespace-to-hpos comment-column))) + + +(defprop kill-comment forward kills) +(defcom kill-comment + (go-to-beginning-of-line) + (if (nullstringp comment-prefix) + (if (go-to-hpos comment-column) + (if (not (get (lefthand-char) 'whiteness)) + (skip-to-whitespace))) + (skip-back-whitespace-in-line) + (with-mark m (go-to-end-of-line)(wipe-point-mark m)) + else + (if (forward-search-in-line comment-prefix) + (reverse-search-in-line comment-prefix) + (skip-back-whitespace-in-line) + (with-mark m (go-to-end-of-line)(wipe-point-mark m)) + else + (killsave-string "")))) + +;;; +;;; Stuff grabbed from old start_up +;;; + +(defun ncline n ;lexprish cline + (e_cline_ (apply 'catenate + (mapcan '(lambda (x)(append '(" ") (explodec x))) + (listify n))))) + + +(defcom dp + (ncline 'dp fpathname)) + + +(defcom loadit + (let ((fpathname nil)) + (write-out-file pdir-temp-pathname) + (loadfile pdir-temp-pathname) + (hcs_$truncate_file process-dir pdir-temp-ename 0))) + +(defun comout-get-output n + (check-read-only) + (unwind-protect + (progn (ncline "file_output" pdir-temp-pathname + "-ssw user_output -ssw error_output -truncate") + (apply 'ncline (listify n))) + (e_cline_ "revert_output -ssw user_output -ssw error_output")) + (let ((fpathname nil)) + (read-in-file pdir-temp-pathname)) + (hcs_$truncate_file process-dir pdir-temp-ename 0)) + +(defun comout (&rest command) + (apply 'comout-to-buffer (cons 'file_output command))) + +(defun comout-to-buffer (buffer &rest command) + (unwind-protect + (progn (go-to-or-create-buffer buffer) + (apply 'comout-get-output command)) + (cond (comout-local-display + (display-buffer-as-printout) + (go-to-buffer previous-buffer)) + (t (select-buffer-find-window current-buffer 'cursize))))) + +(defcom comout-command + &numeric-function comout-command-to-buffer + &arguments ((command-line + &prompt &eval + (progn (setq *comout-buffer-force* + (comout-buffer-warning + *comout-command-default-buffer*)) + "Multics command: "))) + (comout-command-internal *comout-command-default-buffer* *comout-buffer-force* + command-line)) + +(defun comout-command-internal (buffer force-flag command) + (setq command (e_lap_$trim command)) + (unless (nullstringp command) + (when force-flag + (save-excursion-buffer + (go-to-buffer buffer) + (setq fpathname nil) + (setq read-only-flag nil))) + (comout-to-buffer buffer command))) + +(defcom comout-command-to-buffer + &numarg &ignore + &arguments ((buffer &symbol + &default &eval + (let ((completion-list known-buflist)) + (setq *comout-command-buffer* + (make_atom (minibuffer-response "Buffer: "))))) + (command-line + &prompt &eval + (progn (setq *comout-buffer-force* + (comout-buffer-warning + *comout-command-buffer*)) + "Multics command: "))) + (comout-command-internal buffer *comout-buffer-force* + command-line)) + +(defun comout-buffer-warning (buffer) + (and (exists-buffer buffer) + (let ((ro (get-buffer-state buffer 'read-only-flag)) + (not-empty (not (empty-buffer-p buffer))) + (path (get-buffer-state buffer 'fpathname)) + (force)) + (setq force (or ro path)) + (setq path (and not-empty path)) + (when (or ro path) + (ring-tty-bell) + (init-local-displays) + (when ro + (local-display-generator-nnl + (catenate "Output buffer '" buffer "' is READ ONLY."))) + (when path + (local-display-generator-nnl + (catenate "Output buffer '" buffer + "' contains unwritten changes to ")) + (local-display-generator-nnl + (catenate " " path "."))) + (local-display-generator-nnl "It will be overwritten if you continue (type ^G to abort).") + (end-local-displays)) + force))) + +(defcom linecounter + (let ((lineno 1) + (curlineno 0) + (nnlp (save-excursion + (go-to-end-of-buffer) + (not (and (eolp)(bolp)))))) + (save-excursion + (with-mark m + (go-to-beginning-of-buffer) + (do-forever + (if (mark-on-current-line-p m) + (setq curlineno lineno) + (stop-doing)) + (if (lastlinep) (stop-doing)) ;just in case + (setq lineno (1+ lineno)) + (next-line)))) + (setq lineno (if nnlp number-of-lines-in-buffer + else (1- number-of-lines-in-buffer))) + (minibuffer-remark + (decimal-rep lineno) + (if (= lineno 1) " line" else " lines") + (if nnlp " (NO NEWLINE)" else "") + ", current = " + (decimal-rep curlineno) ", column = " + (decimal-rep (1+ (cur-hpos)))))) + +;;; +;;; Global Print command. +;;; New version by JSL - June 1982 + +(defcom global-print + &numeric-function global-regexp-print + &arguments ((string &string &default + &eval (get-search-string "Global print"))) + (let ((foundflag) + (line-count 0)) + (save-excursion + (go-to-beginning-of-buffer) + (do-forever + (if (not (forward-search string)) (stop-doing)) + (if (not foundflag) + (setq foundflag t) + (with-mark m + (reverse-search string) + (do-forever + (if (mark-on-current-line-p m) + (stop-doing)) + (setq line-count (1+ line-count)) + (next-line))) + (init-local-displays)) + (do-times line-count (prev-line)) + (do-times line-count + (local-display-current-line) + (next-line)) + (local-display-current-line) + (if (lastlinep) (stop-doing)) + (next-line))) + (if foundflag (end-local-displays) + else (search-failure-annunciator)))) + +;;; +;;; Option manager +;;; BSG 7/29/78 +;;; + +(defprop option opt expr) + +(declare (special list-of-known-options)) + +(defun opt n ;lexpr + (cond ((= n 0) ;noargs + (display-error "Usage: opt list/opt status XXX/opt XXX ")) + ((= n 1) + (if (eq (arg 1) 'list) + (save-excursion-buffer + (go-to-or-create-buffer (intern (make_atom "Opt List"))) + (putprop current-buffer t 'temporary-buffer) + (insert-string "Options in effect")(new-line) + (new-line) + (mapc '(lambda (x) + (insert-string x)(format-to-col 33.) + (insert-string (option-value-string x))(new-line)) + list-of-known-options) + (display-buffer-as-printout)) + (end-local-displays) + else (opt))) ;barfo + ((= n 2) + (if (eq (arg 1) 'status) + (if (memq (arg 2) list-of-known-options) + (minibuffer-print "Option " (arg 2) ": " (option-value-string (arg 2))) + else (display-error "Unknown option: " (arg 2))) + else (if (memq (arg 1) list-of-known-options) + (option-set-value (arg 1)(arg 2)) + else (opt 'status (arg 1))))) + ((= n 3) ; opt register foo bar + (cond ((eq (arg 1) 'register) + (register-option (arg 2)(arg 3))) + (t (opt)))) + (t (opt)))) + + +(defun option-value-string (x) + (cond ((not (boundp x)) 'Off) + ((numberp (setq x (symeval x)))(decimal-rep x)) + ((eq x 'nil) 'Off) + ((eq x 't) 'On) + ((stringp x) x) + ((symbolp x) x) + (t "-- ???? ---"))) + + +(defun option-set-value (sym val) + (if (stringp val) (setq val (intern (make_atom val)))) + (cond ((or (and (boundp sym) (numberp(symeval sym))) + (get sym 'value-must-be-numeric)) + (if (numberp val) (set sym val) + else (display-error "Value for " sym " must be numeric."))) + ((or (and (boundp sym)(memq (symeval sym) '(t nil))) + (get sym 'value-ok-true-false)) + (cond ((memq val '(t T True true ok Ok On ON on y yes Yes)) + (set sym t)) + ((memq val '(nil no No Off OFF off false)) + ;; I thank Bawden for this randomness + (set sym nil)) + ((get sym 'value-ok-anything) + (set sym val)) + (t (display-error "The value for " sym + " must be either ""on"" or ""off"".")))) + (t (set sym val)))) + +;;; +;;; The printing-tty-man's friend, +;;; BSG 08/06/76 +;;; + +(defcom view-lines + &numeric-argument (&pass) + (if numarg (if (= numarg 0) (view-region-as-lines) + else (init-local-displays) + (if (< numarg 0) + (setq numarg (- numarg)) + (do y numarg (1- y)(= y 0) + (if (firstlinep) + (setq numarg (1- numarg)) + else + (prev-line)))) + (do x numarg (1- x) (< x 1) ;lisp do + (local-display-current-line) + (if (or (lastlinep) (= numarg 1)) (stop-doing) + else (next-line))) + (end-local-displays)) + else (setq numarg 1) (view-lines))) + + +(defcom view-region-as-lines + (with-the-mark-last m + (init-local-displays) + (do-forever + (local-display-current-line) + (if (mark-on-current-line-p m) (stop-doing)) + (next-line)) + (end-local-displays))) + +;;; +;;; Word Searches. +;;; BSG 8/26/78 +;;; + +(defun compare-word-to-list-rep-word (list) + (prog (text-char) +a (cond ((null list) ;no more source + (do-forever + (if-at (ascii 10)(forward-char) ;run out trailing _ BS + else (if-at "_" (forward-char) + else (stop-doing)))) + (cond ((charset-member (curchar) good-word-charactertbl) + (search-for-first-not-charset-line good-word-charactertbl) + (return nil)) ;lost + (t (return t)))) + ((= (car list) 52) ;star + (search-for-first-not-charset-line good-word-charactertbl) + (return t))) + (if (eolp) ;lost + (return nil)) + (setq text-char (getcharn (curchar) 1)) + ;; Quick check for good case. + + (if (and (< text-char (1+ (CtoI "Z")))(> text-char (1- (CtoI "A")))) + (setq text-char (+ 40 text-char))) ;lower case it. + (if (= text-char (car list)) ;local winnage + (setq list (cdr list)) + (forward-char) + (go a)) + (if (or (= text-char 10)(= text-char 137)) ;BS or US + (forward-char) + (go a)) + ;; Wholesale mismatch. + (search-for-first-not-charset-line good-word-charactertbl) + (return nil))) + + +(defun word-search (word) + (setq word (listify-word word)) + (with-mark m + (if (do-forever + (if (not (search-charset-forward-nosavepos good-word-charactertbl)) + (return nil)) + (if (compare-word-to-list-rep-word word) + (return t)) + (if (at-end-of-buffer) + (return nil))) + else (go-to-mark m) + nil))) + + +(defun listify-word (w) + (mapcar '(lambda (x) + (cond ((and (< x (1+ (CtoI "Z"))) (> x (1- (CtoI "A")))) (+ x 40)) + (t x))) + (exploden w))) + + +(defcom multi-word-search + &arguments ((wordlist &default + &eval (string-to-list-of-strings (get-search-string "Word Search")))) + &numeric-argument (&pass) + (let ((bjflag numarg)) + (setq wordlist (mapcar 'listify-word wordlist)) + (with-mark m + (if bjflag (go-to-beginning-of-buffer)) + (if + (prog (trials temp-list) + (return + (do-forever + (if (not (search-charset-forward-nosavepos good-word-charactertbl)) + (go-to-mark m) + (search-failure-annunciator)) + (setq trials 0 temp-list wordlist) +a (cond ((null temp-list) + (return t))) + (cond ((compare-word-to-list-rep-word (car temp-list)) + (setq temp-list (cdr temp-list)) + (cond ((null temp-list)(return t))) + (setq trials (1+ trials)) + (if (search-charset-forward-nosavepos good-word-charactertbl) + else (go-to-mark m) (search-failure-annunciator)) + (go a))) + ;; Has failed. Found 2 good words, 1 bad one. trials = 2. + ;; Back up 2 words. + (do-times trials (backward-word))))) + else (go-to-mark m) + (search-failure-annunciator))))) + + +(defun string-to-list-of-strings (instr) + (prog (answer locanswer ch1) + (setq instr (exploden instr)) +a (do-forever + (if (null instr)(stop-doing)) + (setq ch1 (car instr)) + (if (or (= ch1 40)(= ch1 11)(= ch1 12)) ;blank, tab newline + (setq instr (cdr instr)) + else (stop-doing))) + (if (null instr) ;all done + (return (nreverse answer))) + ;; collect one string + (setq locanswer nil) + (do-forever + (if (null instr)(stop-doing)) + (setq ch1 (car instr) instr (cdr instr)) + (if (or (= ch1 40)(= ch1 11)(= ch1 12)) + (stop-doing) + else + (setq locanswer (cons ch1 locanswer)))) + (setq answer (cons (maknam (nreverse locanswer)) answer)) + (go a))) + + +(defun search-charset-forward-nosavepos (charset) + (do-forever + (cond ((search-for-first-charset-line charset) + (return (curchar))) + ((lastlinep) + (return nil)) + (t (next-line))))) + +;;; Not L I S P mode. +;;; Things dealing with parenthese balancing to placate those +;;; who miss native Lisp mode. +;;; BSG 9/11/78 + +(defun unwind-sexp-searchers-marks-and-nlgoto () + (mapc 'release-mark sexp-searcher-mark-list) + (setq numarg nil) + (setq sexp-searcher-mark-list nil) + (command-quit)) + + +(defcom balance-parens-forward + &numeric-argument (&repeat) + &negative-function balance-parens-backward + (let ((count nil)) + (save-excursion-on-error + (do-forever + (dispatch-on-current-char + ("(" (if (not count)(setq count 1) + else (setq count (+ 1 count)))) + (")" (if count (setq count (- count 1))) + (if (and count (= count 0)) + (forward-char) (stop-doing)))) + (if (at-end-of-buffer) + (display-error "Unbalanced Parentheses")) + (forward-char))))) + +(defcom balance-parens-backward + &numeric-argument (&repeat) + &negative-function balance-parens-forward + (let ((count nil)) + (save-excursion-on-error + (do-forever + (dispatch-on-lefthand-char + (")" (if (not count)(setq count 1) + else (setq count (+ 1 count)))) + ("(" (if count (setq count (- count 1))) + (if (and count (= 0 count)) + (backward-char) (stop-doing)))) + (if (at-beginning-of-buffer) + (display-error "Unbalanced Parentheses")) + (backward-char))))) + +;;; +;;; Page-other-window copped from Larry Johnson +;;; BSG 12/11/78 .. ditto go-to-line-number +;;; + + +(declare (special selected-window)) + +(defcom page-other-window + &numeric-argument (&pass) + (if (not two-window-mode) + (display-error "Not in 2 window mode") + else + (let ((origwindow selected-window)) + (unwind-protect + (progn + (select-other-window) + (if (null numarg)(next-screen) + else (if (> numarg 0)(next-screen) + else (setq numarg (- numarg)) + (prev-screen)))) + (select-window origwindow))))) + + +;;; New non-losing go-to-line-number 22 April 1981 RMSoley +;;; Prompt for line number if wasn't given. +(defcom go-to-line-number + &numeric-argument (&pass) + (let ((count numarg)) + (cond ((null count) + (setq count + (1- + (integer-minibuf-response + "Go to line number: " NL)))) + ('else + (setq count (1- count)))) + (and (< count 0) (setq count 0)) + (go-to-beginning-of-buffer) + (do-times count + (and (lastlinep) (command-quit)) + (next-line)))) + +(defun integer-minibuf-response (Question Char) + (let ((ans (minibuf-response Question Char))) + (or (ed-cv-fixnum-check ans) + (display-error "Non-numeric answer: " ans ".")))) + +;;; +;;; Untabifiers, moved from Rmail 1/18/79 +;;; + +(defcom untabify + &arguments ((x &default + &eval (if numarg numarg + else tab-equivalent))) + &numeric-argument (&pass) + (let ((tab-equivalent x)) + tab-equivalent + (save-excursion + (go-to-beginning-of-buffer) + (do-forever + (if (forward-search TAB) + (let ((hp (cur-hpos))) + (rubout-char) + (let ((nhp (cur-hpos))) + (do ((x nhp (1+ x)))((= x hp)) + (insert-char " ")))) + else + (stop-doing)))))) + +(defcom-synonym mmuntabify untabify) + +;;; +;;; Mark commands. +;;; + +(defkill wipe-region ambiguous) +(defcom wipe-region + (cond ((not der-wahrer-mark) + (report-error 'mark-not-set) + (setq previous-command nil)) ;be sure not accidently repeated + (t (wipe-point-mark der-wahrer-mark)))) + +(defcom copy-region + (cond (der-wahrer-mark (killsave-string + (point-mark-to-string der-wahrer-mark))) + (t (report-error 'mark-not-set)))) + +;;; +;;; Named mark routines -- BSG 8/19/79 +;;; + +(defcom set-named-mark + &arguments ((markname &symbol &prompt "Set named mark: " + &default &eval (display-error "You must supply a mark name."))) + (set-named-mark- markname) + (minibuffer-print "Set " markname)) + + +(defcom go-to-named-mark + &arguments ((mn &symbol &prompt "Go to named mark: " + &default &eval (display-error "You must supply a mark name."))) + (let ((m (get-named-mark mn))) + (set-the-mark) + (go-to-mark m))) + + + +(defcom list-named-marks () + (let ((ml (produce-named-mark-list))) + (if (null ml)(display-error "No named marks in this buffer.")) + (init-local-displays) + (local-display-generator-nnl "Line # Mark name") + (local-display-generator-nnl "") + (save-excursion + (let ((lnno 1)) + (go-to-beginning-of-buffer) + (do-forever + (mapc '(lambda (x) + (if (mark-on-current-line-p (cadr x)) + (local-display-generator-nnl + (catenate (decimal-rep lnno) TAB (car x))))) + ml) + (if (lastlinep)(stop-doing)) + (setq lnno (1+ lnno)) + (next-line)))) + (end-local-displays))) + +(defun date () ;general utility BSG 10/31/79 + (let ((statdate (mapcar 'decimal-rep (status date)))) + (catenate (cadr statdate) + "/" + (caddr statdate) + "/" + (car statdate)))) + +;;; Buffer commands. + +;;; Command to switch buffers +;;; Fixed 17 April 1981 RMSoley to prompt with default. +;;; Added &completions 6 August 1981 RMSoley +(defcom select-buffer + &prologue insure-intelligent-previous-buffer + &arguments ((buffer &symbol + &prompt &eval (catenate "Select buffer (" + previous-buffer + "): ") + &completions known-buflist)) + (select-buffer-window buffer 'default-cursize)) + +;;; Make sure that previous-buffer isn't nil or same as current +;;; buffer for select-buffer and kill-buffer. +;;; 6 Aprill 1982 Richard Soley +(defun insure-intelligent-previous-buffer () + (or (exists-buffer previous-buffer) + (setq previous-buffer + (cond ((eq (car known-buflist) current-buffer) + (cadr known-buflist)) + ('else (car known-buflist))))) + (and (eq previous-buffer current-buffer) + (setq previous-buffer 'main)) + (or previous-buffer (setq previous-buffer 'main))) + +;;; Command to delete a buffer +;;; Fixed 17 April 1981 RMSoley to prompt with default. +;;; Fixed 6 August 1981 RMSoley for &completions +(defcom kill-buffer + &arguments ((buffer &symbol &prompt "Kill buffer: " + &completions known-buflist + &default &eval current-buffer)) + (cond ((not (memq buffer known-buflist)) + (display-error "Buffer does not exist: " buffer)) + ((eq buffer current-buffer) + (insure-intelligent-previous-buffer) + (do nil (nil) + (ring-tty-bell) + (let ((newbuf + (let ((completion-list known-buflist)) + (intern-minibuf-response + (catenate + "Killing current buffer. " + "Select new buffer (" + previous-buffer + "): ") + NL)))) + (and (nullstringp newbuf) + (progn (setq newbuf previous-buffer) + (minibuffer-print-noclear newbuf))) + (cond ((eq buffer newbuf) + (display-error-noabort "Killing buffer " + buffer + ". Can't go there.")) + (t (select-buffer-window newbuf 'default-cursize) + (buffer-kill buffer) + (return nil))))) + (setq previous-buffer + (cond ((eq (car known-buflist) current-buffer) + (cadr known-buflist)) + (t (car known-buflist)))) + (or previous-buffer (setq previous-buffer current-buffer))) + (t (buffer-kill buffer)))) + +;;; Command to mark the current buffer unmodified +(defcom unmodify-buffer + (setq buffer-modified-flag nil + damaged-flag t) ;makes redisplay happy + (close-line) ;lest this, nobody'd check + (minibuffer-remark "Not modified.")) + +;;; Yank and search commands and esc-esc. + +(defkill merge-last-kills-with-next ambiguous) +(defcom merge-last-kills-with-next nil) + +(defcom yank-minibuf + (set-the-mark) + (insert-string last-minibuf-response)) + +;;; JSL's new searching commands - June 1982 +;;; These are changed to lowercase the noninitial words in the prompt, +;;; and to only set gratuitous marks when the search succeeds. +;;; If the search succeeds partially, the mark is always set. + +(defcom string-search + &cleanup search:command-cleanup + &prologue search:command-prologue + &epilogue search:command-epilogue + &inverse reverse-string-search + &negative-function reverse-string-search + &numeric-argument &repeat + &arguments ((search-string &string &default + &eval (get-search-string + (search:numeric-prompt + "String search")))) + (forward-search search-string)) + + +(defcom reverse-string-search + &cleanup search:command-cleanup + &prologue search:command-prologue + &epilogue search:command-epilogue + &inverse string-search + &negative-function string-search + &numeric-argument &repeat + &arguments ((search-string &string &default + &eval (get-search-string + (search:numeric-prompt + "Reverse string search")))) + (reverse-search search-string)) + +(defun search:command-prologue () + (cons 0 (set-mark))) + + +(defun search:command-cleanup (prologue-info) + (if prologue-info + (if (cdr prologue-info) + (go-to-mark (cdr prologue-info)) + (release-mark (cdr prologue-info))))) + + +(defun search:command-epilogue (prologue-info result last-time) + (cond (result + (rplaca prologue-info (1+ (car prologue-info))) + (and last-time + (or (gratuitous-mark-setter (cdr prologue-info)) + (release-mark (cdr prologue-info))) + (rplacd prologue-info nil))) ; For cleanup. + ((zerop (car prologue-info)) + (search-failure-annunciator)) + (t (set-the-mark-here (cdr prologue-info)) + (rplacd prologue-info nil))) ; For cleanup. + (or result (search:announce-partial-failure (car prologue-info)))) + + + +(defun search:announce-partial-failure (count) + (display-error "Search failed after " (decimal-rep count) + " successful search" + (cond ((= count 1) "") (t "es")) + ". Mark set at start.") + (and macro-execution-in-progress (command-quit))) + +(defun search-failure-annunciator () + (display-error "Search fails.") + (and macro-execution-in-progress (command-quit))) + + + +(defcom regexp-search-command + &arguments ((search-string &default + &eval (get-search-string "Regexp Search"))) + (setq search-string (forward-regexp-search search-string)) + (cond ((null search-string) (search-failure-annunciator)) + (t ;found it set mark around it + (let ((y (set-mark))) ;save-excursion + (go-to-mark search-string) + (set-the-mark) + (go-to-mark y) + (release-mark search-string) + (release-mark y))))) + +;;; +;;; Query replace by Carl Hoffman +;;; + + +;;; read macro 12/3/78 by BSG +(eval-when (compile eval) +(setsyntax '/# 'macro + '(lambda () + (cond ((= (tyipeek) 57) + (tyi) + (tyi)) + ((= (tyipeek) 136) + (tyi) + (- (boole 1 137 (tyi)) 100))))) +);;;end of eval-when + +(defcom query-replace + &arguments ((old &default + &eval (get-search-string "Query replace old string")) + (new &prompt "Query replace new string: " NL)) + (assert-minor-mode '|query replace|) + (if (not (forward-search old)) + (minibuffer-print "No occurrences of old string found.") + else + (query-replace-execute old new) + (minibuffer-print "Done.")) + (negate-minor-mode '|query replace|)) + +; This function does all of the work. When it is invoked, the point +; is to the right of the first occurrence of the old string. + +(defun query-replace-execute (old new) + (catch (do-forever + (redisplay) + (query-replace-dispatch old new (get-char)) + (if (not (forward-search old)) (stop-doing))) + done)) + +(defun query-replace-dispatch (old new response) + (do-forever + (cond ((= response #/,) + (query-replace-swap-strings old new) + (redisplay) + (stop-doing)) + ((= response #/ ) + (query-replace-swap-strings old new) + (stop-doing)) ;don't redisplay 10/15/80 + ((or (= response #^M) ;return = 15 + (= response 177)) ;rubout = 177 + (stop-doing)) + ((= response #/!) ;! is replace to end + (query-replace-swap-strings old new) + (do-forever + (if (forward-search old) (query-replace-swap-strings old new) + else (throw t done)))) + ((= response #/.) + (query-replace-swap-strings old new) + (throw t done)) + ((or (= response #^G) (= response 33)) ;altmode + (throw t done)) + ((= response #^J)) ;newline = 12 + ((= response #^L) + (redisplay)) + ((or (= response #/?) (= response #^_)) + (query-replace-documentation)) + (t (display-error-noabort "Unknown query replace response.") + (redisplay))) + (setq response (get-char)))) + +(defun query-replace-swap-strings (old new) + (with-mark m + (backward-n-chars (stringlength old)) + (without-saving (wipe-point-mark m)) + (insert-string new))) + +(defun query-replace-documentation () + (init-local-displays) + (mapc 'local-display-generator-nnl + '("Query replace options:" "" + "SPACE Replace this occurrence and go on" + "CR, DEL Skip this occurrence and go on" + ". (period) Replace this occurrence and stop" + "^G, ESC Stop now" + ", (comma) Replace this occurrence, redisplay, and go on" + "! Replace all following occurrences without querying" + "LF Nothing" + "^L Redisplay" + "?, ^_ Print this description" + "" "Type any character to remove this display.")) + (end-local-displays) + (redisplay) + (get-char)) + +(defcom eval-multics-command-line + &arguments ((command-line &prompt "Multics: ")) + (let ((e-quit-transparency 'transparent)) + e-quit-transparency + (unwind-protect + (progn (e_pl1_$set_multics_tty_modes) + (e_cline_ command-line)) + (iox_$control (e_pl1_$get_iocb) "reset_more" null-pointer) + (e_pl1_$set_emacs_tty_modes)))) + +(declare (special eval:eval eval:assume-atom eval:correct-errors + eval:prinlevel eval:prinlength + - *)) + +(defcom eval-lisp-line + &numeric-argument (&pass) + (cond ((not eval:eval) + (extended-command (minibuffer-response "Command: "))) + (t (eval:internal (minibuffer-response "Eval: "))))) + +(defun eval:internal (lisp-form) + (let ((prinlevel eval:prinlevel) (prinlength eval:prinlength)) + (eval:evaluate + (let ((e-lisp-error-mode 'read-lisp-fun-lossage-handler)) + e-lisp-error-mode + (read-from-string (evl-parenify lisp-form)))))) + +(defun eval:evaluate (form) + (setq - form) + (setq * (let ((e-lisp-error-mode 'eval-lisp-line-lossage-handler)) + (eval form))) + (setq + form) + (minibuffer-print "Value: " (maknam (explode *)))) + +(defun paren-counter (string) + (let ((left 0) + (right 0) + (balanced nil) + (quote-open nil) + (bar-open nil) + (spacep nil) + (skip-this-char nil) + (in (explodec string)) + (len (stringlength string))) + (do ((sofar in (cdr sofar)) + (a 1 (1+ a))) + ((> a len)) + (let ((this (car sofar)) + (open (or bar-open quote-open))) + (cond (skip-this-char (setq skip-this-char nil)) + ((eq this '/" ) + (or bar-open + (setq quote-open (null quote-open))) + (or open (setq spacep t))) + ((eq this '/| ) + (or quote-open + (setq bar-open (null bar-open))) + (or open (setq spacep t))) + ((eq this '/ ) + (or open (setq spacep t))) + ((eq this '// ) + (or open (setq skip-this-char t))) + ((eq this '/; ) + (or open (setq a len))) + ((eq this '/' ) + (or open (setq spacep t))) + ((eq this '/( ) + (or open (setq left (1+ left)))) + ((eq this '/) ) + (or open (setq right (1+ right)))))) + (cond ((not (or (= a 1) (= a len))) + (setq balanced (or balanced (= left right)))))) + (cons left + (cons right + (cons balanced + (cond (quote-open + (list 'error + "unbalanced quotes.")) + (bar-open + (list 'error + "unbalanced vertical bars.")) + (skip-this-char + (list 'error + "too much slashification.")) + (t spacep))))))) + +(defun evl-parenify (string) + (let ((parens (paren-counter string))) + (let ((l>r (> (car parens) (cadr parens))) + (dif (abs (- (car parens) (cadr parens)))) + (symbol (and (not (cadddr parens)) + (= (car parens) 0) + (= (cadr parens) 0) + eval:assume-atom)) + (balanced (caddr parens))) + (cond ((not (or eval:correct-errors (zerop dif))) + (display-error "Error in syntax of Lisp form - " + "unbalanced parentheses.")) + ((eq (cadddr parens) 'error) + (or eval:correct-errors + (display-error + "Error in syntax of Lisp form - " + (car (cddddr parens)))) + (evl-parenify ;fix user's error + (catenate + string + (let ((kludge (substr (car (cddddr parens)) + 12. + 1))) + (cond ((samepnamep kludge "q") """") + ((samepnamep kludge "v") "|") + (t " ")))))) + (t (let ((intermediate + (cond ((= dif 0) string) + (l>r + (catenate string + (gen-repetitive dif ")"))) + (t (catenate (gen-repetitive dif "(") + string))))) + (cond (symbol string) + (balanced + (catenate "(" intermediate ")")) + (t intermediate)))))))) + +(defun gen-repetitive (number string) + (and (nullstringp string) (setq string SPACE)) + (and (minusp number) (setq number 0)) + (do ((string string (catenate string string))) + ((not (< (stringlength string) number)) + (substr string 1 number)))) + +(defun eval-lisp-line-lossage-handler x x (command-quit)) + +(defun read-lisp-fun-lossage-handler (arg) + arg + (display-error "Syntax error in Lisp form.")) + + + + + emacs_tv_.pl1 11/30/82 1503.8rew 11/30/82 1332.3 9117 + + + +/* *********************************************************** + * * + * Copyright, (C) Honeywell Information Systems Inc., 1982 * + * * + * Copyright (c) 1981 by Massachusetts Institute of * + * Technology and Honeywell Information Systems, Inc. * + * * + * Copyright (c) 1972 by Massachusetts Institute of * + * Technology and Honeywell Information Systems, Inc. * + * * + *********************************************************** */ + + +emacs_tv_: procedure (); +emacs: entry (); + +dcl emacs_$emacs entry options (variable); +dcl cu_$arg_list_ptr entry (ptr); +dcl cu_$generate_call entry (entry, ptr); +dcl arg_list_ptr pointer; + + call cu_$arg_list_ptr (arg_list_ptr); + call cu_$generate_call (emacs_$emacs, arg_list_ptr); + return; + end emacs_tv_; + + + + + + + bull_copyright_notice.txt 08/30/05 1008.4r 08/30/05 1007.3 00020025 + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull +and Bull HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for +managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by Bull HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_macros_.s.archive b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_macros_.s.archive new file mode 100644 index 0000000..b33193f --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_macros_.s.archive @@ -0,0 +1,1304 @@ + + + + + e_macros_.lisp 08/20/86 2309.2rew 08/20/86 2244.6 84483 + + + +;;; *********************************************************** +;;; * * +;;; * Copyright, (C) Honeywell Information Systems Inc., 1982 * +;;; * * +;;; * Copyright (c) 1978 by Massachusetts Institute of * +;;; * Technology and Honeywell Information Systems, Inc. * +;;; * * +;;; *********************************************************** + +;;; Macros for Programming in EMACS Environment + +;;; HISTORY COMMENTS: +;;; 1) change(85-01-01,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; Extracted from e-macros.incl.lisp, removed all the qwerty and macro-helper +;;; stuff, and changed it to use defmacro; I actually ended up rewriting +;;; many macros, either for efficiency or readability. +;;; Previous journalization from e-macros.incl.lisp: +;;; Written by BSG. +;;; Added without-line-control, cleaned up a bit. 25 June 1981 RMSoley +;;; Added protect, save-excursion-on-error 10 November 1981 RMSoley +;;; 2) change(85-01-27,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; removed (%include other_other), +;;; added local push defmacro, and removed extraneous "macro" in +;;; at-white defmacro. +;;; 3) change(86-02-24,Margolin), approve(86-02-24,MCR7325), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; Fixed "protect" macro expansion to return the value of the body. +;;; END HISTORY COMMENTS + +;;; Added by BSG 4/28/80: Include backquote in compilation. +(%include backquote) + +(%include defmacro) + +(declare (macros nil)) +(defmacro push (val var) ;Can't %include other_other, + `(setq ,var (cons ,val ,var))) ;as it defines the wrong IF. +(declare (macros t)) + +(defmacro bolp () + '(= curpointpos 0)) + +(defmacro eolp () + '(= curpointpos (1- curlinel))) + +(defmacro at-white-char () + '(get (curchar) 'whiteness)) + +(defmacro with-mark (mark &body forms) + `(let ((,mark nil)) + (unwind-protect + (progn (setq ,mark (set-mark)) + . ,forms) + (and ,mark (release-mark ,mark))))) + +(defmacro save-excursion (&body forms) + (let ((mark (gensym))) + `(with-mark ,mark + (unwind-protect + (progn .,forms) + (go-to-mark ,mark))))) + +(defmacro save-excursion-on-error (&body forms) + (let ((mark (gensym))) + `(with-mark ,mark + (protect (progn ,.forms) + &failure (go-to-mark ,mark))))) + +(defmacro save-excursion-buffer (&body forms) + (let ((buffer (gensym))) + `(let ((,buffer current-buffer) + (previous-buffer previous-buffer)) + (unwind-protect + (progn . ,forms) + (go-to-or-create-buffer ,buffer))))) + +(defmacro protect-excursion (&body forms) + (let ((buffer (gensym)) + (prevbuf (gensym)) + (mark (gensym))) + `(with-mark ,mark + (let ((,buffer current-buffer) + (,prevbuf previous-buffer) + (value)) + (protect + (setq value (progn . ,forms)) + &failure + (go-to-or-create-buffer ,buffer) + (setq previous-buffer ,prevbuf) + (go-to-mark ,mark)) + value)))) + +(defmacro do-forever (&body forms) + `(do nil (nil) . ,forms)) + +(defmacro with-the-mark-last (mark &body forms) + `(and (or der-wahrer-mark + (display-error "There is no true mark.")) + (save-excursion + (with-mark ,mark + (cond ((point>markp der-wahrer-mark) + (go-to-mark der-wahrer-mark)) + (t (move-mark ,mark der-wahrer-mark))) + (progn . ,forms))))) + +(defmacro if-at (char &body forms) + `(Multics-Emacs-if (at ,char) . ,forms))) + +(defmacro at-white () + '(get (curchar) 'whiteness)) + +(defmacro stop-doing () + '(return nil)) + +(defmacro dispatch-on-current-char (&body forms) + (do ((gs (gensym)) + (clauses forms (cdr clauses)) + (outs nil (cons s outs)) + (s)) + ((null clauses) + `(let ((,gs (curchar))) + (cond . ,(nreverse outs)))) + (let ((thing (caar clauses)) + (result (cdar clauses)) + (condition)) + (cond ((eq thing 'else) + (setq condition 't)) + (t (cond ((stringp thing) + (setq thing `',(getchar thing 1)))) + (setq condition `(eq ,gs ,thing)))) + (setq s `(,condition .,result))))) + +(defmacro Multics-Emacs-if (condition &rest forms) + (do ((ifs) + (elses) + (l forms (cdr l))) + ((null l) + (cond (elses + `(cond (,condition .,(nreverse ifs)) + (t .,(cdr (nreverse elses))))) + (t `(cond (,condition .,(nreverse ifs)))))) + (let ((form (car l))) + (cond ((eq form 'else) + (setq elses (list nil))) + (elses (push form elses)) + (t (push form ifs)))))) + +;;; See Bawden "if" treaty of 5/9/80 -BSG +(or (getl 'if '(macro expr subr)) + (putprop 'if (get 'Multics-Emacs-if 'macro) 'macro)) + +(defmacro at-end-of-buffer () + '(and (eolp) (lastlinep))) + +(defmacro at-beginning-of-buffer () + '(and (bolp) (firstlinep))) + +(defmacro walk-through-region (&body forms) + (let ((mark (gensym))) + `(with-the-mark-last + ,mark + (do () + ((mark-reached ,mark)) + . ,forms)))) + +(defmacro without-saving (&body forms) + `(let ((dont-stash t)) + dont-stash ;keep lcp from complaining + .,forms)) + +(defmacro do-times (howmany &body forms) + (let ((dovar (gensym))) + `(do ,dovar ,howmany (1- ,dovar) (< ,dovar 1) + . ,forms))) + +(defmacro if-back-at (thing &body forms) + `(Multics-Emacs-if (back-at ,thing) . ,forms)) + +(defmacro at (thing) + (cond ((stringp thing) + (setq thing `',(getchar thing 1)))) + `(eq (curchar) ,thing)) + +(defmacro back-at (thing) + (cond ((stringp thing) + (setq thing `',(getchar thing 1)))) + `(eq (lefthand-char) ,thing))) + +(defmacro dispatch-on-lefthand-char (&body forms) + (do ((gs (gensym)) + (clauses forms (cdr clauses)) + (outs nil (cons s outs)) + (s)) + ((null clauses) + `(let ((,gs (lefthand-char))) + (cond . ,(nreverse outs)))) + (let ((thing (caar clauses)) + (result (cdar clauses)) + (condition)) + (cond ((eq thing 'else) + (setq condition 't)) + (t (cond ((stringp thing) + (setq thing `',(getchar thing 1)))) + (setq condition `(eq ,gs ,thing)))) + (setq s `(,condition .,result))))) + +(defmacro without-modifying (&body forms) + `(let ((read-only-flag nil) + (buffer-modified-flag t)) + read-only-flag buffer-modified-flag ;so lcp doesn't complain + .,forms)) + +(defmacro display-as-printout (&body forms) + `(progn + (save-excursion-buffer + (go-to-or-create-buffer (gensym)) + (putprop current-buffer t 'temporary-buffer) + (init-local-displays) + (progn . ,forms) + (display-buffer-as-printout)) + (end-local-displays))) + +(defmacro defvar (var-specs &optional (single-value nil value-given)) + (let ((specials nil) + (inits nil) + (nothing (ncons nil))) + (cond ((atom var-specs) ;(defvar {}) + (setq var-specs + `((,var-specs ,(cond (value-given single-value) + (t nothing))))))) + (mapc '(lambda (spec) + (let ((v) (init)) + (cond ((atom spec) + (setq v spec + init nothing)) + ((null (cdr spec)) + (setq v (car spec) init nil)) + (t (setq v (car spec) + init (cadr spec)))) + (push v specials) + (or (eq init nothing) + (push `(or (boundp ',v) (setq ,v ,init)) + inits)))) + var-specs) + (setq specials (nreverse specials)) + (cond ((null inits) `(declare (special . ,specials))) + (t + `(progn 'compile + (declare (special .,specials)) + . ,(reverse inits)))))) + +;;; Macro to invisibly (and temporarily) turn off line control +;;; 25 June 1981 Richard Mark Soley +(defmacro without-line-control (&body forms) + `(let ((read-only-flag nil) (line-control:buffer 0)) + read-only-flag line-control:buffer ;so lcp won't complain + . ,forms)) + + +;;; Macro to be more useful than unwind-protect. +;;; (protect stuff to do &success stuff &failure stuff &always stuff) +;;; 10 November 1981 Richard Mark Soley +(defmacro protect (&body forms) + (do ((form forms (cdr form)) + (body ()) + (success ()) + (failure ()) + (always ()) + (current 'body)) + ((null form) + (protect/ MACRO/ build + (nreverse body) (nreverse success) (nreverse failure) + (nreverse always))) + (let ((this (car form))) + (cond + ((eq this '&success) (setq current 'success)) + ((eq this '&failure) (setq current 'failure)) + ((eq this '&always ) (setq current 'always)) + ((eq current 'body) (push this body)) + ((eq current 'success) (push this success)) + ((eq current 'failure) (push this failure)) + ('else (push this always)))))) + +(defun protect/ MACRO/ build (body success failure always) + (cond ((and (null success) (null failure)) + `(unwind-protect + (progn ,.body) + ,.always)) + (t (let ((protect-done-variable (gensym))) + `(let ((,protect-done-variable nil)) + (unwind-protect + (prog1 (progn .,body) + (setq ,protect-done-variable t)) + (cond (,protect-done-variable . ,success) + (t . ,failure)) + . ,always)))))) + +(sstatus feature e-macros) + + + + + e_internal_macros_.lisp 08/20/86 2309.2rew 08/20/86 2244.6 38223 + + + +;;; *********************************************************** +;;; * * +;;; * Copyright, (C) Honeywell Information Systems Inc., 1985 * +;;; * * +;;; *********************************************************** + +;;; Macros used internally in Emacs. + +;;; HISTORY COMMENTS: +;;; 1) change(85-01-05,Margolin), approve(86-02-24,MCR7186), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; Created. Mark and eline definitions taken from e_basic_.lisp, and +;;; turned into defstructs. +;;; 2) change(86-02-24,Margolin), approve(86-02-24,MCR7325), +;;; audit(86-08-12,Harvey), install(86-08-20,MR12.0-1136): +;;; Added file-object, pathname, and packed-pointer structures, and +;;; associated macros. +;;; END HISTORY COMMENTS + +(%include sharpsign) +(%include defstruct) +(%include defmacro) +(declare (macros t)) + +;;; The "eline" (editor-line) datatype is constructed as such: +;;; +;;; (line-contents . (previous-line . next-line)) +;;; +;;; previous-line and next-line are other editor lines; line-contents +;;; is either a Lisp string or a "filecons", which is constructed +;;; as follows: +;;; +;;; (char-ptr . linel) +;;; +;;; char-ptr is a fixnum-encoded pointer to the starting character +;;; of a line in a temp-seg into which e_pl1_ copied a file at read-in +;;; time. linel is the length of that line, including the mandatory +;;; newline at the end. +(defstruct (eline + (:type tree) + (:conc-name)) + (contents nil) + (previous nil) + (next nil)) + +;;; Some special cases +(defmacro prevline () + '(eline-previous curline)) +(defmacro nextline () + '(eline-next curline)) +;;; No need for the old curelevator, it was only directly referenced in +;;; one place, and that was fixed. + +;;; If this format ever changes, e_lap_.lap will have to be changed. +;;; It expects a cons. +(defstruct (filecons + (:type tree) + (:conc-name)) + pointer + length) + +;;; The format of a mark is (eline . position) +(defstruct (mark + (:type tree) + (:conc-name)) + eline + position) + +;;; +;;; The Multics file interface in EMACS operates on a "file-object". A +;;; file-object is the following list: +;;; +;;; (CONTENTS ABSPATH UID FCB_PTR) +;;; +;;; where: +;;; +;;; CONTENTS +;;; a list of fileconses (ptr .length) to the segments that +;;; make up the file (one if it is an archive component or SSF, +;;; multiple if it is an MSF), +;;; ABSPATH +;;; is the absolute pathname of the Multics file (segment), +;;; UID +;;; is the Multics unique-id of the file and is used by find-file, +;;; FCB_PTR +;;; is a pointer to the msf_manager_ file control block for the file. +;;; DTCM +;;; is a fixnum representing the time the file was last modified. +;;; ORIGINAL-ACCESS +;;; if non-nil is a pointer to a data structure used to restore +;;; access after it was forced. + +(defstruct (file-object + (:type list) + (:conc-name fobj-)) + contents + path + uid + (fcb-ptr nil) + dtcm + (original-access nil)) + +;;; A couple of special cases for segment 0 +(defmacro fobj-seg0 (file-object) + `(first (fobj-contents ,file-object))) +(defmacro fobj-pointer (file-object) + `(filecons-pointer (fobj-seg0 ,file-object))) +(defmacro fobj-length (file-object) + `(filecons-length (fobj-seg0 ,file-object))) +;;; And a common combination +(defmacro fobj-abs-path (file-object) + `(absolute-pathname (fobj-path ,file-object))) + +;;; A PATHNAME consists of a directory, an entryname, and an archive component +;;; name. If it isn't an archive component, pn-component is the null string. +;;; The expand-pathname and absolute-pathname functions in e_multics_files_ +;;; translate from and to a single character string. Absolute-pathname +;;; encaches the absolute pathname in the abs-path component, to speed up +;;; repetitive calls. + +(defstruct (pathname + (:type list) + (:conc-name pn-)) + (directory "") + (entry "") + (component "") + (abs-path nil)) + +;;; + +;;; The packed-pointer defstruct is usable for manipulating +;;; pointers expressed as a Lisp fixnum. + +(defstruct (packed-pointer + (:type fixnum) + (:conc-name pptr-)) + ((bit-offset #o3606) + (seg-number #o2214) + (word-offset #o0022))) + + + + + e_define_command_.lisp 08/20/86 2309.2rew 08/20/86 2249.1 248544 + + + +;;; *********************************************************** +;;; * * +;;; * Copyright, (C) Honeywell Information Systems Inc., 1982 * +;;; * * +;;; * Copyright (c) 1979 by Massachusetts Institute of * +;;; * Technology and Honeywell Information Systems, Inc. * +;;; * * +;;; *********************************************************** + +;;; +;;; +;;; Emacs Command Definition Macro +;;; +;;; +;;; Initial coding: August-September 1979 by GMP. +;;; Modified: 7 May 1981 Soley to fix minor bugs. +;;; Modified: Fall 1981 Soley for &nobreak and &completions. +;;; Modified: 31 March 1982 Soley for &undo-function, clean up. +;;; Modified: 15 May 1982 by J. Spencer Love for &epilogue, &cleanup. +;;; +;;; +;;; Syntax: +;;; (define-command function-name +;;; forms) +;;; +;;; (defcom function-name forms) +;;; +;;; Keywords in forms: +;;; +;;; &arguments ARGS, &args ARGS, &a ARGS +;;; +;;; &cleanup FUNCTION +;;; +;;; &documentation STRING, &doc STRING +;;; +;;; &epilogue SYMBOL +;;; +;;; &negative-function FUNCTION, &nf FUNCTION +;;; +;;; &numeric-argument SPEC, &numarg SPEC, &na SPEC +;;; +;;; &numeric-function SYMBOL +;;; +;;; &no-break +;;; +;;; &prologue SYMBOL +;;; +;;; &undo-function SPEC, &undo SPEC, &inverse SPEC +;;; +;;; Terms: +;;; ARGS is a list of argument specifications. +;;; STRING is a character string in doublequotes. +;;; SYMBOL is the name of a function. +;;; FUNCTION is either a SYMBOL, or &code FORMS &end_code. +;;; VALUE is either a CONSTANT or &eval FORM. +;;; CONSTANT is either a STRING, a number, or a quoted FORM. +;;; FORM is something for lisp to evaluate. +;;; +;;; Format of an argument specification: +;;; +;;; Format of &numeric-argument FORM: +;;; &numeric-argument is followed by a keyword or by a list which +;;; contains one or more keywords. The keywords which may appear +;;; after &numeric-argument are &pass, &ignore, &reject and &repeat. +;;; The additional keywords which may appear in the list are +;;; &lower-bound (&lb) and &upper-bound (&ub). These two keywords +;;; are followed by a VALUE. &reject is the default unless bounds +;;; are specified, in which case &pass is the default. +;;; + +(declare (macros t) + (*lexpr dc-error dc-error-argument dcev-error) + (special encoded-values)) + +(%include backquote) + +;;; Macro to define an Emacs command + +(defprop define-command define-command/ MACRO macro) +(defprop defcom define-command/ MACRO macro) + +;;; Macro to define a synonym of an Emacs command +;;; Syntax: (defcom-synonym synonym command) + +(defun define-command-synonym macro (form) + (let ((synonym (cadr form)) + (command (caddr form))) + `(progn 'compile + (defprop ,synonym ,command editor-command) + (defprop ,synonym ,command expr)))) + +(defprop defcom-synonym define-command-synonym macro) + +;;; +;;; Function that parses a command definition +;;; + +(defun define-command/ MACRO (the-form) + (let ((function-name (cadr the-form)) ;first arg must be name + (the-function) + (prologue-function) + (epilogue-function) + (numeric-function) + (negative-function) + (cleanup-function) + (undo-function) + (undo-info) + (argument-info) + (numeric-arg-info) + (documentation)) + + (or (symbolp function-name) + (dc-error "" "Function name must be a symbol.")) + (setq encoded-values nil) + + (do ((form (cddr the-form) rest-of-form) + (current) + (no-break nil) + (rest-of-form)) + ((null form) ;until nothing left + (dc-build-result-list function-name (nreverse the-function) + prologue-function epilogue-function + numeric-function negative-function + argument-info numeric-arg-info + documentation no-break undo-function + undo-info cleanup-function)) + + (setq current (car form) rest-of-form (cdr form)) + + (cond + + ;; Prologue function. + ((eq current '&prologue) + (and prologue-function + (dc-error-duplicate-key function-name current)) + (let ((x (dc-parse-encoded-value function-name 0 + rest-of-form current + 'symbolp + "a function name"))) + (setq prologue-function (cadar x) ;want the symbol + rest-of-form (cdr x)))) + + ;; Epilogue function. + ((eq current '&epilogue) + (and epilogue-function + (dc-error-duplicate-key function-name current)) + (let ((x (dc-parse-encoded-value function-name 0 + rest-of-form current + 'symbolp + "a function name"))) + (setq epilogue-function (cadar x) ;want the symbol + rest-of-form (cdr x)))) + + ;; Cleanup function. + ((eq current '&cleanup) + (and cleanup-function + (dc-error-duplicate-key function-name current)) + (let ((x (dc-parse-encoded-value function-name 0 + rest-of-form current + 'symbolp + "a function name"))) + (setq cleanup-function (cadar x) ;want the symbol + rest-of-form (cdr x)))) + + ;; Numeric function. + ((eq current '&numeric-function) + (and numeric-function + (dc-error-duplicate-key function-name current)) + (let ((x (dc-parse-encoded-value function-name 0 + rest-of-form current + 'symbolp + "a function name"))) + (setq numeric-function (cadar x) ;want the symbol + rest-of-form (cdr x)))) + + ;; Negative function. + ((memq current '(&negative-function &nf)) + (and negative-function + (dc-error-duplicate-key function-name + '&negative-function)) + (cond ((symbolp (car rest-of-form)) + (cond ((eq (car rest-of-form) '&code) + (setq rest-of-form (cdr rest-of-form)) + (do ;get the function body + ((nf (car rest-of-form) + (car rest-of-form))) + ((or (null nf) + (and (symbolp nf) + (samepnamep (substr nf 1 1) + "&"))) + (and (eq nf '&end-code) + (setq rest-of-form + (cdr rest-of-form)))) + (setq negative-function + (nconc negative-function + (list nf)) + rest-of-form (cdr rest-of-form)))) + ((samepnamep (substr (car rest-of-form) + 1 1) + "&") + (dc-error function-name + "Unknown keyword after " + "&negative-function: " + (car rest-of-form))) + (t ;function name + (setq negative-function + (car rest-of-form) + rest-of-form (cdr rest-of-form))))) + (t ;bad syntax + (dc-error function-name + "&negative-function must be followed " + "by a function name or &code.")))) + + ;; Undo function. + ((memq current '(&undo-function &undo &inverse)) + (and (or undo-function undo-info) + (dc-error-duplicate-key function-name current)) + (cond ((member (car rest-of-form) '(&pass (&pass))) + (setq undo-info '&pass + rest-of-form (cdr rest-of-form))) + ((member (car rest-of-form) '(&ignore (&ignore))) + (setq undo-info '&ignore + rest-of-form (cdr rest-of-form))) + ((or (eq (car rest-of-form) '&reject) + (equal (car rest-of-form) '(&reject))) + (setq undo-info '&reject + rest-of-form (cdr rest-of-form))) + ((not (symbolp (car rest-of-form))) + (dc-error + function-name + "&undo-function must be followed " + "by a function name, &pass, &reject, " + "&ignore, or &code.")) + ((eq (car rest-of-form) '&code) + (setq rest-of-form (cdr rest-of-form)) + (do ;get the function body + ((nf (car rest-of-form) + (car rest-of-form))) + ((or (null nf) + (and (symbolp nf) + (samepnamep (substr nf 1 1) "&"))) + (and (eq nf '&end-code) + (setq rest-of-form + (cdr rest-of-form)))) + (setq undo-function + (nconc undo-function (list nf)) + rest-of-form (cdr rest-of-form)))) + ((samepnamep (substr (car rest-of-form) 1 1) "&") + (dc-error function-name + "Unknown keyword after " + "&undo-function: " + (car rest-of-form))) + (t ;function name + (setq undo-function (car rest-of-form) + rest-of-form (cdr rest-of-form))))) + + ;; Numeric argument. + ((memq current '(&numeric-argument &numarg &na)) + (and numeric-arg-info + (dc-error-duplicate-key function-name + '&numeric-argument)) + (setq numeric-arg-info + (dc-parse-numeric-arg-info function-name + (car rest-of-form)) + rest-of-form (cdr rest-of-form))) + + ;; Signal echnego that this doesn't cause a break. + ((eq current '&no-break) (setq no-break t)) + + ;; Arguments. + ((memq current '(&arguments &args &a)) + (and argument-info + (dc-error-duplicate-key function-name '&arguments)) + (setq argument-info + (dc-parse-arguments function-name (car rest-of-form)) + rest-of-form (cdr rest-of-form))) + + ;; Documentation. + ((memq current '(&documentation &doc)) + (and documentation + (dc-error-duplicate-key function-name '&documentation)) + (setq documentation (car rest-of-form) + rest-of-form (cdr rest-of-form)) + (or (stringp documentation) + (dc-error function-name + "&documentation must be followed " + "by a string."))) + + ;; Unknown. Might be the actual function..... + ((and (symbolp current) + (samepnamep (substr current 1 1) "&")) + (dc-error function-name "Unrecoginzed keyword: " current)) + + ;; Yup, it's the function. + (t (setq the-function (cons current the-function))))))) + +;;; +;;; Parse an encoded value: an encoded value is either a constant or +;;; &eval followed by a form to evaluate at runtime +;;; + +(defun dc-parse-encoded-value (function-name arg-no rest-of-form + qualifier-name value-typep value-name) + (let ((type 'quote) ;just a value + (value (car rest-of-form))) + (cond ((eq value '&eval) + (let ((eval-name + (make_atom (catenate function-name "-$-" + (dc-decimal arg-no) + "-$-" qualifier-name))) + (function)) + (or (cdr rest-of-form) ;if nothing follows it + (dcev-error function-name arg-no qualifier-name + " &eval must be followed by a form " + "or &code.")) + (cond ((eq (cadr rest-of-form) '&code) + (setq rest-of-form (cddr rest-of-form)) + (do ;construct the function + ((nf (car rest-of-form) (car rest-of-form))) + ((or (null nf) ;either nothing left + (and (symbolp nf) + (samepnamep (substr nf 1 1) "&"))) + (and (eq nf '&end-code) + (setq rest-of-form (cdr rest-of-form)))) + (setq function (nconc function (list nf)) + rest-of-form (cdr rest-of-form)))) + ((and (symbolp (cadr rest-of-form)) + (samepnamep (substr (cadr rest-of-form) + 1 1) + "&")) + (dcev-error function-name arg-no qualifier-name + " Unknown keyword following &eval: " + (cadr rest-of-form))) + (t (setq function (list (cadr rest-of-form)) + rest-of-form (cddr rest-of-form)))) + (setq encoded-values + `(,.encoded-values + (defun ,eval-name () + . ,function)) + type 'eval + value eval-name))) ;get name in right place + (t ;simple value, check type + (or (funcall value-typep value) + (dcev-error function-name arg-no qualifier-name + " must be followed by " value-name + " or &eval.")) + (setq rest-of-form (cdr rest-of-form)))) + (cons (list type value) rest-of-form))) + +;;; +;;; Parse specifications for handling of numeric argument by this command. +;;; + +(defun dc-parse-numeric-arg-info (function-name the-form) + (do ((form the-form rest-of-form) + (processing-type) + (lower) (upper) + (phrase) (rest-of-form)) + ((null form) ;until all parsed + (and (eq processing-type '&ignore) ;ignore the argument + (or lower upper) + (dc-error function-name + "&ignore may not be used with other " + "&numeric-argument qualifiers.")) + (and (eq processing-type '&reject) ;reject numeric arguments + (or lower upper) + (dc-error function-name + "&reject may not be used with other " + "&numeric-argument qualifiers.")) + (and lower (eq (car lower) 'quote) + upper (eq (car upper) 'quote) + (< (cadr upper) (cadr lower)) ;invalid range + (dc-error function-name + "Invalid numeric argument range " + (dc-decimal (cadr lower)) + ":" (dc-decimal (cadr upper)))) + (and (null processing-type) + (or lower upper) + (setq processing-type '&pass)) + (cons (or processing-type '&reject) ;supply default if needed + (and (or lower upper) (cons lower upper)))) + ;; + ;; Find next token to be digested. + ;; + (cond ((not (atom form)) + (setq phrase (car form) + rest-of-form (cdr form))) + ((not (eq form the-form)) + (dc-error function-name + "Malformed list following &numeric-argument.")) + (t (setq phrase form + rest-of-form nil))) + ;; + ;; Analyze token. + ;; + (cond ((memq phrase '(&pass &repeat &ignore &reject)) + (and processing-type + (dc-error function-name + "Only one of &pass, &repeat, &ignore, or " + "&reject may appear after " + "&numeric-argument.")) + (setq processing-type phrase)) + ((memq phrase '(&lower-bound &lb)) + (and lower + (dc-error function-name + "The key &lower-bound may only appear once " + "after &numeric-argument.")) + (let ((x (dc-parse-encoded-value function-name 0 rest-of-form + '&lower-bound 'fixp + "an integer"))) + (setq lower (car x) rest-of-form (cdr x)))) + ((memq phrase '(&upper-bound &ub)) + (and upper + (dc-error function-name + "The key &upper-bound may only appear once " + "after &numeric-argument.")) + (let ((x (dc-parse-encoded-value function-name 0 rest-of-form + '&upper-bound 'fixp + "an integer"))) + (setq upper (car x) rest-of-form (cdr x)))) + (t (dc-error function-name + "Unrecognized keyword following " + "&numeric-argument: " phrase))))) + +;;; +;;; Parse the list of argument specifications. +;;; + +(defun dc-parse-arguments (function-name the-form) + (do ((form the-form (cdr form)) + (argument-list) + (arg-no 1 (1+ arg-no))) ;for error messages + ((null form) ;done when out of forms + (nreverse argument-list)) + (let ((phrase (car form))) + (let ((x (dcpa-single-argument function-name + (null (cdr form)) + arg-no phrase))) + (setq argument-list (cons x argument-list)))))) + +;;; +;;; Parse a single argument specification. +;;; + +(defun dcpa-single-argument (function-name last-argp arg-no specification) + (let ((name) ;argument symbol + (data-type) ;datatype of argument + (default-value) ;default value + (prompt-info) ;prompt string and terminator + (range-info) ;range for integers + (completion-info) ;for completer command + (validation-info)) ;acceptable values of symbols + (cond ((symbolp specification) ;simple case + (setq name specification)) + (t ;more complex + (setq name (car specification)) + (or (symbolp name) + (dc-error-argument function-name arg-no + "No name specified.")) + (do ((qualifiers (cdr specification) rest-of-qualifiers) + (current) (rest-of-qualifiers)) + ((null qualifiers)) ;until nothing left + (setq current (car qualifiers) + rest-of-qualifiers (cdr qualifiers)) + (cond + ((or (not (symbolp current)) + (not (samepnamep (substr current 1 1) "&"))) + (dc-error-argument function-name arg-no + "An & construct was expected, " + "but not found."))) + (cond + ((memq current '(&rest-as-string &rest-as-list)) + (and (or data-type prompt-info default-value + range-info completion-info validation-info + rest-of-qualifiers) + (dc-error-argument + function-name arg-no current + " may not appear with any other argument " + "qualifiers.")) + (or last-argp + (dc-error-argument function-name arg-no + "The argument with " + current " must be last.")) + (setq data-type current)) + ((memq current '(&completions &completion &comp)) + (and completion-info + (dc-error-argument-duplicate-key + function-name arg-no '&completions)) + (setq completion-info (car rest-of-qualifiers) + rest-of-qualifiers (cdr rest-of-qualifiers))) + ((memq current '(&string &symbol &integer)) + (and data-type + (dc-error-argument + function-name arg-no + "Only one of &string, &symbol, and " + "&integer may be used.")) + (setq data-type current)) + ((eq current '&prompt) ;prompt string + (and prompt-info + (dc-error-argument-duplicate-key + function-name arg-no '&prompt)) + (let ((x (dcpa-parse-prompt function-name arg-no + rest-of-qualifiers))) + (setq prompt-info (car x) + rest-of-qualifiers (cdr x)))) + ((eq current '&default) ;default value + (and default-value + (dc-error-argument-duplicate-key + function-name arg-no '&default)) + (let ((x (dc-parse-encoded-value + function-name arg-no rest-of-qualifiers + '&default 'atom "a value"))) + (setq default-value (car x) + rest-of-qualifiers (cdr x)))) + (t + (dc-error-argument function-name arg-no + "Unrecognized keyword: " + current)))))) + + ;; Perform consistency checks and construct value + (or data-type (setq data-type '&string)) + (and validation-info (not (eq data-type '&symbol)) + (dc-error-argument function-name arg-no + "&valid may only be specified for " + "&symbol arguments.")) + (and range-info (not (eq data-type '&integer)) + (dc-error-argument function-name arg-no + "Numeric ranges may only be specified " + "for &integer arguments.")) + (or prompt-info default-value + (setq prompt-info (cons (list 'quote (catenate name ": ")) + (ascii 012)))) ;end with newline + (cons name + (list + (boole 7 ;fixnum describing argument + (cond + ((eq data-type '&string) 0) + ((eq data-type '&symbol) (lsh 100000 18.)) + ((eq data-type '&integer) (lsh 200000 18.)) + ((eq data-type '&rest-as-string) (lsh 300000 18.)) + ((eq data-type '&rest-as-list) (lsh 400000 18.)) + (t (lsh 700000 18.))) + (cond (prompt-info (lsh 040000 18.)) ;have prompt + (t 0)) + (cond (default-value (lsh 020000 18.)) (t 0)) + (cond ((or range-info validation-info) + (lsh 010000 18.)) + (t 0))) + prompt-info + default-value + (cond ((eq data-type '&integer) range-info) + (t validation-info)) + completion-info)))) + +;;; +;;; Parse prompt specification +;;; + +(defun dcpa-parse-prompt (function-name arg-no rest-of-qualifiers) + (let ((x (dc-parse-encoded-value function-name arg-no rest-of-qualifiers + '&prompt 'stringp "a string"))) + (let ((string (car x)) + (rest (cdr x)) + (term)) + (setq term (car rest)) ;get possible terminator + (cond ((and term ;there's something + (symbolp term) + (not (samepnamep (substr term 1 1) "&"))) + (cond ((memq term '(NL ESC)) + (setq term (cond ((eq term 'NL) (ascii 012)) + (t (ascii 033))) + rest (cdr rest))) + (t + (dc-error-argument function-name arg-no + "Prompt terminator must " + "be NL or ESC.")))) + (t (setq term (ascii 012)))) + (cons (cons string term) + rest)))) + +;;; Create result of define-command macro +(defun dc-build-result-list (function-name the-function prologue-function + epilogue-function numeric-function + negative-function argument-info numeric-arg-info + documentation no-break undo-function undo-info + cleanup-function) + ;; + ;; Check numeric function conflicts. + ;; + (and numeric-function negative-function + (dc-error-conflict function-name "&numeric-function" + "&negative-function")) + (and numeric-function numeric-arg-info + (dc-error-conflict function-name "&numeric-function" + "&numeric-argument")) + (and numeric-function + (setq numeric-arg-info '(&pass))) + ;; + ;; Check for negative function conflicts. + ;; + (and negative-function + (null numeric-arg-info) + (dc-error-required function-name "&negative-function" + "&numeric-argument")) + (and negative-function + (eq (car numeric-arg-info) '&ignore) ;But ignore argument! + (dc-error-conflict function-name "&negative-function" + "&numeric-argument (&ignore)")) + (and negative-function + (eq (car numeric-arg-info) '&reject) ;But reject argument! + (dc-error-conflict function-name "&negative-function" + "&numeric-argument (&reject)")) + ;; + ;; Default numeric argument handling. + ;; + (or numeric-arg-info (setq numeric-arg-info '(&reject))) + ;; + ;; Construct flag word for execute-new-command. + ;; + (let ((result ()) + (editor-command-value + (boole 7 ;Logical OR. + (cond (argument-info + (boole 7 ;Logical OR. + (lsh 400000 18.) + (boole 1 (length argument-info) 777777))) + (t 0)) ;No arguments. + (cond (negative-function (lsh 200000 18.)) (t 0)) + (cond ((cdr numeric-arg-info) (lsh 100000 18.)) (t 0)) + (let ((type (car numeric-arg-info))) + (cond ((eq type '&pass) 0) + ((eq type '&repeat) (lsh 010000 18.)) + ((eq type '&ignore) (lsh 020000 18.)) + ((eq type '&reject) (lsh 030000 18.)) + (t ;Unknown type. + (lsh 070000 18.)))) + (cond (prologue-function (lsh 004000 18.)) (t 0)) + (cond (epilogue-function (lsh 002000 18.)) (t 0)) + (cond (numeric-function (lsh 001000 18.)) (t 0)) + (cond (undo-function (lsh 000400 18.)) (t 0)) + (cond ((eq undo-info '&pass) (lsh 000200 18.)) (t 0)) + (cond ((eq undo-info '&ignore) (lsh 000100 18.)) + (t 0)) + (cond (cleanup-function (lsh 000040 18.)) (t 0))))) + ;; + ;; Build output structure. + ;; + (setq result + `((putprop ',function-name ,editor-command-value + 'editor-command) + . ,result)) + + (and no-break + (setq result + `((setq nobreak-functions + (cons ',function-name nobreak-functions)) + . ,result))) + + (setq result + `((defun ,function-name + ,(mapcar '(lambda (x) (car x)) argument-info) + . ,the-function) + . ,result)) + + (and prologue-function + (setq result + `((putprop ',function-name ',prologue-function + 'ed-prologue-function) + . ,result))) + + (and epilogue-function + (setq result + `((putprop ',function-name ',epilogue-function + 'ed-epilogue-function) + . ,result))) + + (and cleanup-function + (setq result + `((putprop ',function-name ',cleanup-function + 'ed-cleanup-function) + . ,result))) + + (and numeric-function + (setq result + `((putprop ',function-name ',numeric-function + 'ed-numeric-function) + . ,result))) + + (and negative-function + (cond ((symbolp negative-function) + (setq result + `((putprop ',function-name ',negative-function + 'ed-negative-function) + . ,result))) + (t (let ((nf-name + (make_atom + (catenate function-name + "-$-negative-function")))) + (setq result + `((defun ,nf-name + ,(mapcar '(lambda (x) (car x)) + argument-info) + . ,negative-function) + (putprop ',function-name + ',nf-name + 'ed-negative-function) + . ,result)))))) + + (and undo-function + (cond ((symbolp undo-function) + (setq result + `((putprop ',function-name ',undo-function + 'ed-undo-function) + . ,result))) + (t (let ((un-name + (make_atom + (catenate function-name + "-$-undo-function")))) + (setq result + `((defun ,un-name + ,(mapcar '(lambda (x) (car x)) + argument-info) + . ,undo-function) + (putprop ',function-name + ',un-name + 'ed-undo-function) + . ,result)))))) + + (let ((range (cdr numeric-arg-info))) + (and range + (setq result + `((putprop ',function-name ',range + 'ed-numeric-range) + . ,result)))) + + (and argument-info + (setq result + `((putprop ',function-name + ',(mapcar '(lambda (x) (cdr x)) + argument-info) + 'ed-argument-list) + . ,result))) + + (and encoded-values + (setq result (nconc result encoded-values))) + + (and documentation + (setq result + `((putprop ',function-name ,documentation + 'documentation) + . ,result))) + + `(progn 'compile . ,result))) + +;;; Error reporting functions + +(defun dc-error n + (cond ((= (stringlength (arg 1)) 0) + (error + (apply + 'catenate + (cons "define-command: " (listify (- 1 n)))))) + (t (error + (apply + 'catenate + (cons (catenate + "define-command: In definition of " (arg 1) ". ") + (mapcar 'dc-decimal (listify (- 1 n))))))))) + +(defun dc-error-duplicate-key (function-name key-name) + (dc-error function-name + "The key " key-name " may only appear once.")) + + +(defun dc-error-conflict (function-name key-1 key-2) + (dc-error function-name + "The keys " key-1 " and " key-2 " are mutually exclusive.")) + + +(defun dc-error-required (function-name given-key missing-key) + (dc-error function-name + "Use of the key " given-key " requires that the key " + missing-key " also be specified.")) + + +(defun dc-error-argument n + (error (apply 'catenate + (cons (catenate + "define-command: In definition of argument #" + (dc-decimal (arg 2)) " of " (arg 1) ". ") + (listify (- 2 n)))))) + + +(defun dc-error-argument-duplicate-key (function-name arg-no key-name) + (dc-error-argument function-name arg-no + "The key " key-name " may only appear once.")) + + +(defun dcev-error n + (cond ((= (arg 2) 0) (apply 'dc-error (listify n))) + (t (apply 'dc-error-argument (listify n))))) + + +(defun dc-decimal (x) + (let ((base 10.) (ibase 10.) (*nopoint t)) + (maknam (exploden x)))) + + + + bull_copyright_notice.txt 08/30/05 1008.4r 08/30/05 1007.3 00020025 + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull +and Bull HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for +managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by Bull HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_packages_.s.archive b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_packages_.s.archive new file mode 100644 index 0000000..af0a09c Binary files /dev/null and b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_packages_.s.archive differ diff --git a/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_rmail_.s.archive b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_rmail_.s.archive new file mode 100644 index 0000000..72f5f0a --- /dev/null +++ b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_emacs_rmail_.s.archive @@ -0,0 +1,2213 @@ + + + + + e_mail_pl1_.pl1 04/24/89 1350.4rew 04/24/89 1340.5 232281 + + + +/****^ *********************************************************** + * * + * Copyright, (C) Honeywell Bull Inc., 1988 * + * * + * Copyright, (C) Honeywell Information Systems Inc., 1982 * + * * + *********************************************************** */ + + +/****^ HISTORY COMMENTS: + 1) change(88-03-22,Blair), approve(88-03-22,MCR7842), + audit(88-06-29,Lippard), install(88-07-26,MR12.2-1069): + Add a new entry to expand the savebox pathname after searching the mlsys + searchlist for the user supplied savebox name. + 2) change(89-02-09,Flegel), approve(89-03-16,MCR8076), audit(89-03-30,Lee), + install(89-04-24,MR12.3-1035): + Moved system procedure, support, and parameter declarations out of entry + points and into the main procedure declaration. + phx16782 - created entries emacs_get_address_list and + emacs_redistribute_message for rmail-forward support + 3) change(89-02-16,Flegel), approve(89-03-16,MCR8076), audit(89-03-30,Lee), + install(89-04-24,MR12.3-1035): + phx21262 - support for getting and modifying the "seen" switch on messages + END HISTORY COMMENTS */ + + +/* + * 83/07/19 Jon A. Rochlis - RMAIL pl1 interface to MR10.2 mail_system_ + * 83/01/06 B. Margolin - to not set deliver_options.queue_mailing_lists. + */ + +e_mail_pl1_: + proc(); + +/* PARAMETERS */ +dcl a_addr char (*) parameter; /* Addresses to parse */ +dcl a_addr_ptr ptr parameter; /* Address list created */ +dcl a_code fixed bin (35) parameter; /* Error code */ +dcl a_comments char (*) parameter; /* Comments to add */ +dcl a_recipients_ptr ptr parameter; /* Forward addresses */ +dcl a_acknowledge_flag bit (1) parameter; /* Ack requested */ +dcl a_error_ptr ptr parameter; /* Pointer to error structures */ +dcl a_seen_sw bit (1) parameter; /* Message seen switch */ +dcl a_mbx_dir char (*) parameter; +dcl a_mbx_entry char (*) parameter; +dcl a_mailbox_ptr ptr parameter; +dcl a_salvaged bit(1) aligned parameter; +dcl a_msgcount fixed bin parameter; +dcl a_message_ptr ptr parameter; +dcl a_buffer_ptr ptr parameter; +dcl a_envelope_format char(*) parameter; +dcl a_header_format char(*) parameter; +dcl a_redistributions_list_format char(*) parameter; +dcl a_body_length fixed bin(21) parameter; +dcl a_line_length fixed bin parameter; +dcl a_message_number fixed bin parameter; +dcl a_subject char(*) parameter; +dcl a_original_message_ptr ptr parameter; +dcl a_new_message_ptr ptr parameter; +dcl a_include_authors bit(1) parameter; +dcl a_include_recipients bit(1) parameter; +dcl a_include_self bit(1) parameter; +dcl a_message_text char(*) parameter; +dcl a_parse_error_list_ptr ptr parameter; +dcl a_request_ack bit(1) parameter; +dcl a_pathname char (*) parameter; +dcl a_dirname char (168) parameter; +dcl a_entryname char (32) parameter; + +/* SYSTEM CALLS */ +dcl mail_system_$redistribute_message entry (ptr, char (*), ptr, ptr, + fixed bin (35)); +dcl mail_system_$open_mailbox entry (char (*), char(*), ptr, char(8), ptr, + fixed bin(35)); +dcl mail_system_$acknowledge_message entry (ptr, fixed bin (35)); +dcl mail_system_$read_message entry (ptr, fixed bin, fixed bin(35)); +dcl mail_system_$close_mailbox entry (ptr, ptr, fixed bin(35)); +dcl mail_system_$free_address_list entry (ptr, fixed bin (35)); +dcl mail_system_$create_message entry (char (8), ptr, fixed bin(35)); +dcl mail_system_$create_address_list entry (char (8), ptr, fixed bin(35)); +dcl mail_system_$add_address entry (ptr, ptr, char(8), fixed bin(35)); +dcl mail_system_$replace_subject entry (ptr, char (*), fixed bin(35)); +dcl mail_system_$replace_from entry (ptr, ptr, fixed bin(35)); +dcl mail_system_$deliver_message entry (ptr, ptr, ptr, fixed bin(35)); +dcl mail_system_$free_message entry (ptr, fixed bin(35)); +dcl mlsys_utils_$format_message entry (ptr, ptr, ptr, fixed bin (21), + fixed bin (21), fixed bin (35)); +dcl mlsys_utils_$parse_address_list_text entry (char (*), ptr, char (8), ptr, + ptr, fixed bin (35)); +dcl mlsys_utils_$create_reply_message entry (ptr, ptr, ptr, fixed bin(35)); +dcl mlsys_utils_$format_message_header entry (ptr, fixed bin, fixed bin, ptr, + fixed bin(21), fixed bin(21), fixed bin(35)); +dcl mlsys_utils_$parse_message_text entry (char (*), ptr, char (8), ptr, ptr, + fixed bin(35)); +dcl mlsys_utils_$free_delivery_results entry (ptr, fixed bin(35)); +dcl mlsys_utils_$print_delivery_results entry (ptr, bit(1) aligned, ptr, + fixed bin(35)); +dcl user_info_$login_data entry (char(*), char(*), char(*), fixed bin, + fixed bin, fixed bin, fixed bin(71), char(*)); +dcl get_system_free_area_ entry() returns(ptr); +dcl com_err_$suppress_name entry options (variable); +dcl ssu_$standalone_invocation entry (ptr, char(*), char(*), ptr, entry, + fixed bin(35)); +dcl ssu_$destroy_invocation entry (ptr); +dcl expand_pathname_$add_suffix entry (char(*), char(*), char(*), char(*), + fixed bin(35)); +dcl suffixed_name_$make entry (char(*), char(*), char(32), fixed bin(35)); +dcl search_paths_$find_dir entry (char(*), ptr, char(*), char(*), char(*), + fixed bin(35)); + +/* SYSTEM CALL SUPPORT */ +dcl error_table_$noentry fixed bin(35) ext static; +dcl mlsys_et_$cant_parse_irt_field fixed bin(35) ext static; +dcl sys_info$max_seg_size fixed bin(35) ext static; +dcl mlsys_data_$user_default_mailbox_address ptr ext static; +dcl mlsys_data_$user_mail_table_address ptr ext static; + +/* EXTERNAL CALLS */ +dcl e_mail_pl1_$get_user_default_address entry returns(ptr); + +/* BUILTINS */ +dcl (addr, index, length, null, reverse, rtrim, translate, + substr, unspec, search) builtin; + +/* CONDITIONS */ +dcl clean_up condition; + + return; + +/* Open a mailbox for later reading. Pass back a pointer to the mailbox + structure to be used during later reads */ + +emacs_mailbox_open: + entry(a_mbx_dir, a_mbx_entry, a_mailbox_ptr, a_salvaged, a_msgcount, a_code); + +dcl 1 auto_open_options aligned like open_options; + + a_code = 0; + + unspec (auto_open_options) = ""b; + + auto_open_options.version = OPEN_OPTIONS_VERSION_2; + auto_open_options.message_selection_mode = ORDINARY_MESSAGES; + auto_open_options.sender_selection_mode = ACCESSIBLE_MESSAGES; + auto_open_options.message_reading_level = READ_KEYS; + + call mail_system_$open_mailbox (a_mbx_dir, a_mbx_entry, addr(auto_open_options), MAILBOX_VERSION_2, a_mailbox_ptr, a_code); + if a_code ^= 0 then return; + + a_salvaged = a_mailbox_ptr -> mailbox.flags.salvaged; + a_msgcount = a_mailbox_ptr -> mailbox.n_messages; + + return; + +/* end emacs_open_mailbox; */ + +/* Read one message. We are given a pointer to a mail system message, and + we use the mail system to format it. RMAIL will expect to find the + formatted message in a black magic string pointed to by a_buffer_ptr */ + +emacs_read_message: + entry (a_message_ptr, a_buffer_ptr, a_line_length, a_acknowledge_flag, + a_envelope_format, a_header_format, a_redistributions_list_format, + a_body_length, a_seen_sw, a_code); + +dcl buffer_position fixed bin(21); + +dcl 1 auto_format_options aligned like format_message_options; +dcl chrsused fixed bin(35) based; /* ugh, ugh ... shades of Scribe */ + + + a_code = 0; + + unspec (auto_format_options) = ""b; + + auto_format_options.version = FORMAT_MESSAGE_OPTIONS_VERSION_1; + auto_format_options.line_length = a_line_length; + auto_format_options.include_body = "1"b; + + call parse_formatting_mode (a_envelope_format, auto_format_options.envelope_formatting_mode, a_code); + if a_code ^= 0 then do; a_code = -1; return; end; + + call parse_formatting_mode (a_header_format, auto_format_options.header_formatting_mode, a_code); + if a_code ^= 0 then do; a_code = -2; return; end; + + call parse_formatting_mode (a_redistributions_list_format, auto_format_options.redistributions_list_formatting_mode, a_code); + if a_code ^= 0 then do; a_code = -3; return; end; + + buffer_position = 4; /* 4 chars = 1 word, leaves room for the bmstr length */ + + call mlsys_utils_$format_message (a_message_ptr, addr (auto_format_options), a_buffer_ptr, (sys_info$max_seg_size-1)*4, buffer_position, a_code); + if a_code ^= 0 then return; + + a_buffer_ptr -> chrsused = buffer_position - 4; + + a_body_length = a_message_ptr -> message.body.total_lines; + + if a_message_ptr -> message.flags.must_be_acknowledged & a_acknowledge_flag + then call mail_system_$acknowledge_message (a_message_ptr, a_code); + + a_seen_sw = a_message_ptr -> message.flags.seen; + + return; + +parse_formatting_mode: + proc (a_formatting_mode, a_mlsys_formatting_mode, a_code); + +dcl a_formatting_mode char(*) parameter; +dcl a_mlsys_formatting_mode fixed bin parameter; +dcl a_code fixed bin (35) parameter; + + a_code = 0; + + a_formatting_mode = translate (a_formatting_mode, "_", "-"); /* allow either underscrose or dashes */ + + if a_formatting_mode = "none_formatting_mode" + then a_mlsys_formatting_mode = NONE_FORMATTING_MODE; + else if a_formatting_mode = "brief_formatting_mode" + then a_mlsys_formatting_mode = BRIEF_FORMATTING_MODE; + else if a_formatting_mode = "default_formatting_mode" + then a_mlsys_formatting_mode = DEFAULT_FORMATTING_MODE; + else if a_formatting_mode = "long_formatting_mode" + then a_mlsys_formatting_mode = LONG_FORMATTING_MODE; + else a_code = -1; /* this will be special cased by RMAIL */ + +end parse_formatting_mode; + +/* end emacs_read_message; */ + +/* Given a pointer to a mailbox, and a message number, return a pointer + to that message (reading it if need be). */ + +emacs_get_message_ptr: + entry (a_mailbox_ptr, a_message_number, a_message_ptr, a_code); + + a_code = 0; + + a_message_ptr = a_mailbox_ptr -> mailbox.messages(a_message_number).message_ptr; + + if a_message_ptr = null then do; + call mail_system_$read_message (a_mailbox_ptr, a_message_number, a_code); + if a_code ^= 0 then return; + a_message_ptr = a_mailbox_ptr -> mailbox.messages(a_message_number).message_ptr; + end; + + return; + +/* Close a mailbox */ + +emacs_mailbox_close: + entry (a_mailbox_ptr, a_code); + +dcl 1 auto_close_options aligned like close_options; + + a_code = 0; + + unspec (auto_close_options) = ""b; + + auto_close_options.version = CLOSE_OPTIONS_VERSION_2; + auto_close_options.flags.perform_deletions = "1"b; + auto_close_options.flags.report_deletion_errors = "0"b; /* I'm not about to set up a sub_err_ handler */ + + call mail_system_$close_mailbox (a_mailbox_ptr, addr (auto_close_options), a_code); + + return; + +/* end emacs_mailbox_close; */ + +get_user_default_address: + entry returns(ptr); + +dcl anonymous fixed bin; + + call user_info_$login_data ("", "", "", anonymous, (0), (0), (0), ""); + + if anonymous = 1 + then return (mlsys_data_$user_default_mailbox_address); + else return (mlsys_data_$user_mail_table_address); + +/* end get_user_default_address; */ + +get_user_default_mbx_address: + entry returns (ptr); + + return (mlsys_data_$user_default_mailbox_address); + +/* end get_user_default_mbx_address; */ + +/* Create an address list from a character string representation of a list of + addresses. */ + +emacs_get_address_list: + entry (a_addr, a_addr_ptr, a_error_ptr, a_code); + +dcl 01 pt_ops like parse_text_options aligned; + +/* Prepare for cleanup condition */ + + a_code = 0; + a_addr_ptr = null; + a_error_ptr = null; + on clean_up begin; + if a_addr_ptr ^= null then + call mail_system_$free_address_list (a_addr_ptr, (0)); + if a_error_ptr ^= null then + call free_parse_text_error_list (a_error_ptr); + end; + +/* Parse the forwarding destination addresses */ + + pt_ops.version = PARSE_TEXT_OPTIONS_VERSION_1; + pt_ops.area_ptr = get_system_free_area_ (); + pt_ops.list_errors = "1"b; + pt_ops.validate_addresses = "1"b; + pt_ops.include_invalid_addresses = "0"b; + pt_ops.mbz = ""b; + + call mlsys_utils_$parse_address_list_text ((a_addr), addr (pt_ops), + ADDRESS_LIST_VERSION_2, a_addr_ptr, a_error_ptr, a_code); + if a_code ^= 0 then do; + if a_addr_ptr ^= null then do; + call mail_system_$free_address_list (a_addr_ptr, (0)); + a_addr_ptr = null; + end; + return; + end; + + return; + +/* end emacs_get_address_list */ + +emacs_create_message: + entry (a_subject, a_message_ptr, a_code); + +dcl from_list ptr; + + + a_code = 0; + + call mail_system_$create_message (MESSAGE_VERSION_2, a_message_ptr, a_code); + if a_code ^= 0 then return; + + call mail_system_$replace_subject (a_message_ptr, a_subject, a_code); + if a_code ^= 0 then return; + +/* Do the from field hacking to insure that we see the from field in the + buffer. mail_system_ would wait until delivery time to fill it in. */ + + call mail_system_$create_address_list (ADDRESS_LIST_VERSION_2, from_list, a_code); + if a_code ^= 0 then return; + + call mail_system_$add_address (from_list, e_mail_pl1_$get_user_default_address(), ADDRESS_LIST_VERSION_2, a_code); + if a_code ^= 0 then return; + + call mail_system_$replace_from (a_message_ptr, from_list, a_code); + return; + +/* end emacs_create_message; */ + +emacs_create_reply_message: + entry (a_original_message_ptr, a_include_authors, a_include_recipients, a_include_self, a_new_message_ptr, a_code); + + +dcl 1 auto_reply_options aligned like reply_options; + + a_code = 0; + + unspec (auto_reply_options) = ""b; + + auto_reply_options.version = REPLY_OPTIONS_VERSION_2; + auto_reply_options.to = null; /* no extra recipients */ + auto_reply_options.cc = null; + auto_reply_options.bcc = null; + auto_reply_options.flags.include_authors = a_include_authors; + auto_reply_options.flags.include_recipients = a_include_recipients; + auto_reply_options.flags.include_self = a_include_self; + + call mlsys_utils_$create_reply_message (a_original_message_ptr, addr (auto_reply_options), a_new_message_ptr, a_code); + +/* See create_message for the explanation of why we do this */ + + call mail_system_$create_address_list (ADDRESS_LIST_VERSION_2, from_list, a_code); + if a_code ^= 0 then return; + + call mail_system_$add_address (from_list, e_mail_pl1_$get_user_default_address(), ADDRESS_LIST_VERSION_2, a_code); + if a_code ^= 0 then return; + + call mail_system_$replace_from (a_new_message_ptr, from_list, a_code); + + return; + +/* end emacs_create_reply_message; */ + +emacs_format_header: + entry (a_message_ptr, a_line_length, a_buffer_ptr, a_code); + + + a_code = 0; + + buffer_position = 4; /* see emacs_read_message for black magic string hacking */ + + call mlsys_utils_$format_message_header (a_message_ptr, DEFAULT_FORMATTING_MODE, a_line_length, a_buffer_ptr, (sys_info$max_seg_size-1)*4, buffer_position, a_code); + if a_code ^= 0 then return; + + a_buffer_ptr -> chrsused = buffer_position - 4; + + return; + +/* end emacs_format_header; */ + +emacs_parse_message_text: + entry (a_message_text, a_message_ptr, a_parse_error_list_ptr, a_code); + +dcl 1 auto_parse_options aligned like parse_text_options; + + a_code = 0; + + unspec(auto_parse_options) = ""b; + + auto_parse_options.version = PARSE_TEXT_OPTIONS_VERSION_1; + auto_parse_options.area_ptr = null; /* system_free_area_ is fine */ + auto_parse_options.flags.list_errors = "1"b; + auto_parse_options.flags.validate_addresses = "1"b; /* ???? */ + auto_parse_options.flags.include_invalid_addresses = "1"b; /* ???? */ + + call mlsys_utils_$parse_message_text (a_message_text, addr (auto_parse_options), MESSAGE_VERSION_2, a_message_ptr, a_parse_error_list_ptr, a_code); + +/* If the only error was not being able to parse the In-Reply-To: field, + we pretend everything was okay, since RMAIL will add the reply reference + itself and considers parse errors to be fatal. */ + + if a_parse_error_list_ptr = null then return; + + if a_parse_error_list_ptr -> parse_text_error_list.n_errors = 1 + then do; + if a_parse_error_list_ptr -> parse_text_error_list.errors(1).code = mlsys_et_$cant_parse_irt_field + then a_code = 0; + end; + + return; + +/* end emacs_parse_message_text; */ + +/* display the parse error list (from above) via com_err_ */ + +display_parse_errors: + entry (a_parse_error_list_ptr, a_message_text); + +dcl 1 ptel aligned like parse_text_error_list based (a_parse_error_list_ptr); + +dcl i fixed bin; + + begin; + dcl code fixed bin(35), + (start, length) fixed bin(21); + + do i = 1 to ptel.n_errors; + code = ptel.errors(i).code; + start = ptel.errors(i).text_start; + length = ptel.errors(i).text_lth; + if code ^= mlsys_et_$cant_parse_irt_field then + call com_err_$suppress_name (code, "emacs (rmail)", substr (a_message_text, start, length)); + end; /* do */ + end; /* begin */ + + return; + +/* end display_parse_errors; */ + +free_parse_text_error_list: + entry (a_parse_error_list_ptr); + + dcl free_area area based; + + free ptel in (get_system_free_area_() -> free_area); + + return; + +/* end display_parse_errors; */ + + +/* Deliver a message and print the delivery results on user_i/o (RMAIL has + set up a file output) */ + +emacs_deliver_message: + entry (a_message_ptr, a_request_ack, a_code); + +dcl sci_ptr ptr; +dcl delivery_code fixed bin (35); + +dcl 1 auto_deliver_options aligned like deliver_options; + + delivery_code = 0; + + sci_ptr, recipients_info_ptr = null; /* for cleanup handler */ + + unspec (auto_deliver_options) = ""b; + + recipients_info_n_lists = 3; + + on clean_up call free_structures("1"b); + + allocate recipients_info set (recipients_info_ptr); + + recipients_info.header.version = RECIPIENTS_INFO_VERSION_2; + recipients_info.header.area_ptr = get_system_free_area_ (); + recipients_info.header.expanded_recipients_result_list_ptr = null; + recipients_info.lists.recipients_result_list_ptr = null; + recipients_info.lists.address_list_ptr(1) = a_message_ptr -> message.header.to; + recipients_info.lists.address_list_ptr(2) = a_message_ptr -> message.header.cc; + recipients_info.lists.address_list_ptr(3) = a_message_ptr -> message.header.bcc; + + auto_deliver_options.version = DELIVER_OPTIONS_VERSION_2; + auto_deliver_options.delivery_mode = ORDINARY_DELIVERY; + auto_deliver_options.queueing_mode = ALWAYS_QUEUE_FOREIGN; + auto_deliver_options.queued_notification_mode = NOTIFY_ON_ERROR; + auto_deliver_options.flags.abort = "1"b; + auto_deliver_options.flags.send_if_empty = "1"b; /* ???? */ + auto_deliver_options.flags.recipient_notification = "1"b; + auto_deliver_options.flags.acknowledge = a_request_ack; + auto_deliver_options.flags.queue_mailing_lists = "0"b; /* ???? */ + + call mail_system_$deliver_message (a_message_ptr, recipients_info_ptr, addr (auto_deliver_options), delivery_code); + + if delivery_code ^= 0 then + call com_err_$suppress_name (delivery_code, "", ""); /* print_delivery_results will yield more info */ + +/* Now it's time to print the results */ + + call ssu_$standalone_invocation (sci_ptr, "", "", null, ssu_abort_deliver, a_code); + if a_code ^= 0 then do; + call com_err_$suppress_name (a_code, "", "While creating an ssu_ stand alone invocation."); + call free_structures("1"b); + return; + end; + + call mlsys_utils_$print_delivery_results (sci_ptr, "0"b /* print all results */, recipients_info_ptr, a_code); + if a_code ^= 0 then do; + call com_err_$suppress_name (a_code, "", "While printing delivery results."); + end; + + a_code = delivery_code; /* at this point a_code must be 0, but we want to make sure RMAIL knows something happened if deliver message got an error */ + +ERROR_DELIVER_RETURN: + call free_structures ("1"b); + + return; + +ssu_abort_deliver: /* ssu wants a proc which really aborts */ + proc; + + goto ERROR_DELIVER_RETURN; + + end ssu_abort_deliver; + +ssu_abort_redistribute: + proc; + + goto ERROR_REDIST_RETURN; + + end ssu_abort_redistribute; + +free_structures: + proc (a_message_flag); + +dcl a_message_flag bit (1) parameter; /* If a message is to be cleaned */ + + if a_message_flag then + call mail_system_$free_message (a_message_ptr, (0)); + + if recipients_info_ptr ^= null then do; + call mlsys_utils_$free_delivery_results (recipients_info_ptr, (0)); /* only frees expanded lists in the structure */ + free recipients_info; + end; + + if sci_ptr ^= null then + call ssu_$destroy_invocation (sci_ptr); + + return; + + end free_structures; + +/* end emacs_deliver_message; */ + +/* Redistribute the message, with the comments provided and the appropriate + acknowledgement to the provided list of address(es). */ + +emacs_redistribute_message: + entry (a_message_ptr, a_comments, a_recipients_ptr, a_acknowledge_flag, + a_code); + +dcl 01 dv_ops like deliver_options aligned; +dcl system_free_area_ptr ptr; +dcl system_free_area area based (system_free_area_ptr); +dcl redist_code fixed bin (35); + + +/* Prepare for cleanup condition */ + + system_free_area_ptr = get_system_free_area_ (); + recipients_info_ptr = null; + sci_ptr = null; + on clean_up call free_structures ("0"b); + +/* Set up the recipients info structure (those to forward to) */ + + recipients_info_n_lists = 1; + allocate recipients_info set (recipients_info_ptr) in (system_free_area); + + recipients_info.header.version = RECIPIENTS_INFO_VERSION_2; + recipients_info.header.area_ptr = system_free_area_ptr; + recipients_info.header.expanded_recipients_result_list_ptr = null; + recipients_info.n_recipients = 0; + recipients_info.n_unique_recipients = 0; + recipients_info.n_failed_recipients = 0; + recipients_info.n_lists = 1; + recipients_info.lists(1).address_list_ptr = a_recipients_ptr; + recipients_info.lists(1).recipients_result_list_ptr = null; + + dv_ops.version = DELIVER_OPTIONS_VERSION_2; + dv_ops.delivery_mode = ORDINARY_DELIVERY; + dv_ops.queueing_mode = ALWAYS_QUEUE_FOREIGN; + dv_ops.queued_notification_mode = NOTIFY_ON_ERROR; + dv_ops.abort = "1"b; + dv_ops.flags.send_if_empty = "1"b; + dv_ops.flags.recipient_notification = "1"b; + dv_ops.flags.acknowledge = a_acknowledge_flag; + dv_ops.flags.queue_mailing_lists = "0"b; + dv_ops.flags.mbz = ""b; + + call mail_system_$redistribute_message (a_message_ptr, a_comments, + recipients_info_ptr, addr (dv_ops), redist_code); + + if redist_code ^= 0 then + call com_err_$suppress_name (redist_code, "", ""); /* print_delivery_results will yield more info */ + +/* Now it's time to print the results */ + + call ssu_$standalone_invocation (sci_ptr, "", "", null, ssu_abort_redistribute, a_code); + if a_code ^= 0 then do; + call com_err_$suppress_name (a_code, "", "While creating an ssu_ stand alone invocation."); + call free_structures("0"b); + return; + end; + + call mlsys_utils_$print_delivery_results (sci_ptr, "0"b /* print all results */, recipients_info_ptr, a_code); + if a_code ^= 0 then do; + call com_err_$suppress_name (a_code, "", "While printing delivery results."); + end; + + a_code = redist_code; /* at this point a_code must be 0, but we want to make sure RMAIL knows something happened if deliver message got an error */ + +ERROR_REDIST_RETURN: + call free_structures ("0"b); + + return; + +/* end emacs_redistribute_message */ + +/* Expand the name of the savebox the user types in. If there are no "<>" + characters in the pathname, then look in the "mlsys" searchlist for the + entryname. */ + +emacs_expand_svbx_pathname: + entry (a_pathname, a_dirname, a_entryname, a_code); + +dcl pathname char (168); +dcl dirname char (168); +dcl entryname char (32); +dcl code fixed bin (35); + + a_code, code = 0; + pathname = a_pathname; + entryname, dirname = ""; + +/* strip off the .sv if necessary */ + if index (reverse (rtrim(pathname)), reverse (".sv")) = 1 then + pathname = substr (pathname, 1, length(rtrim(pathname)) - length(".sv")); + + if search (pathname, "<>") = 0 then do; + call suffixed_name_$make (rtrim(pathname), "sv.mbx", entryname, code); + if code ^= 0 then do; + call com_err_$suppress_name (code, "", "Expanding savebox pathname."); + goto EXIT_SVBX_PATHNAME; + end; + call search_paths_$find_dir ("mlsys", null, rtrim(entryname), "", dirname, code); + if code ^= 0 then + if code = error_table_$noentry then do; + call expand_pathname_$add_suffix (pathname, "sv.mbx", dirname, entryname, code); + if code ^= 0 then do; + call com_err_$suppress_name (code, "", "Expanding savebox pathname."); + goto EXIT_SVBX_PATHNAME; + end; + end; + else call com_err_$suppress_name (code, "", "Searching ""mlsys"" searchlist."); + else; + end; + else do; + call expand_pathname_$add_suffix (pathname, "sv.mbx", dirname, entryname, code); + if code ^= 0 then call com_err_$suppress_name (code, "", "Expanding savebox pathname."); + end; + +EXIT_SVBX_PATHNAME: + a_dirname = dirname; + a_entryname = entryname; + a_code = code; + return; +/* end emacs_expand_svbx_pathname; */ + +%include mlsys_open_options; +%include mlsys_mailbox; +%include mlsys_format_options; +%include mlsys_close_options; +%include mlsys_message; +%include mlsys_parse_txt_options; +%include mlsys_deliver_info; +%include mlsys_reply_options; +%include mlsys_address_list; +%include rdm_switch_types; + +end e_mail_pl1_; + + + + + emacs_rmail_.lisp 04/24/89 1350.4rew 04/24/89 1341.0 470979 + + + +;;; ****************************************************** +;;; * * +;;; * Copyright, (C) Honeywell Bull Inc., 1988 * +;;; * * +;;; * Copyright (c) 1978 by Massachusetts Institute of * +;;; * Technology and Honeywell Information Systems, Inc. * +;;; * * +;;; ****************************************************** + + +;;; HISTORY COMMENTS: +;;; 1) change(88-03-22,Blair), approve(88-03-22,MCR7842), +;;; audit(88-06-29,Lippard), install(88-07-26,MR12.2-1069): +;;; Change the expand_pathname_ to a call to +;;; e_mail_pl1_$emacs_expand_svbx_pathname on a copy request so that we +;;; can search the mlsys searchlist to locate the savebox. +;;; 2) change(89-02-02,Flegel), approve(89-02-28,MCR8066), +;;; audit(89-03-30,Lee), install(89-04-24,MR12.3-1035): +;;; phx20937, phx21049 - Changed "create-file" calls to "open-file" calls. +;;; phx17317 - rmail-reply to change the Ack minor mode to the appropriate +;;; value when reusing a reply buffer. +;;; 3) change(89-02-13,Flegel), approve(89-03-16,MCR8076), +;;; audit(89-03-30,Lee), install(89-04-24,MR12.3-1035): +;;; phx18781 - addition of rmail-help bound to the "?" key in order to +;;; provide internal help to rmail. +;;; phx16782 - addition of rmail-forward bound to the "L" key in order +;;; to provide an interface for mail forwarding +;;; phx19704 - addition of support for rmail-quit so that if a rmail +;;; command has has been entered after new mail has arrived, then do not +;;; query. +;;; phx21262 - addition of rmail-toggle-seen bound to "X" key in order +;;; to provide an interface into changing the "seen" switch. +;;; END HISTORY COMMENTS + + +;;; +;;; Emacs nuntio, BSG 10/10/78, 12/15/78, 3/17/79 +;;; Major rewrite of whole emacs_rmail_ 10/19/80 BSG for real header parse +;;; To CAH's mlsys, BSG 10/31/82, reformat headers BSG 11/6/82 +;;; For MR10.2 mlsys by Jon Rochlis, July 1983 (for psr) +;;; To comment out register-option forms, and move them to e_option_defaults_, 1/19/84 Barmar. +;;; To make send-mail-beargumented trim the buffer name, 1/19/84 Barmar. +;;; To remove "rmail-check-if-in-rmail" from rmail-logger-*pend, as they +;;; are callable from send-mail, too. 2/15/85 Barmar + +;;; Here begins Emacs send mail (SMAIL?) + +(defprop rtrim e_lap_$rtrim expr) + +(declare + (*expr e$get_temporary_seg e$release_temporary_seg uppercase + e_lap_$make-dat-ol-black-magic-string open-file + execute-command exists-file fill-mode indent-rigidly + save-same-file untabify exists-buffer delete-white-sides + get-key-binding get-key-name describe)) + +(declare (*lexpr send-mail-beargumented)) + +(declare (special rmail-original-buffer mail-header-buffer fill-column + mail-original-message-ptr mail-mark mail-request-ack + screenlinelen rmail-request-acknowledgement null-pointer + mail-address-ptr rmail-commands-since-new-mail)) + +(%include e-macros) +(%include defun) ; for send-mail-beargumented + +(defvar mail-mode-hook nil) +(defvar rmail-initialized nil) + + +;;; defpl1's for the send mail side + +(declare (defpl1 mail_system_$set_message_switch "" + (ptr) (char (4) aligned) (bit (1) aligned) + ;; message-ptr switch-name ("SEEN") switch-value + (return fixed bin (35.)))) + ;; code + +(declare (defpl1 e_mail_pl1_$emacs_redistribute_message "" + (ptr) (char (*)) (ptr) (bit (1)) + ;; message-pointer comments recipients ack + (return fixed bin (35.)))) + ;; code + +(declare (defpl1 e_mail_pl1_$emacs_get_address_list "" + (char (*)) (return ptr) (return ptr) + ;; address list address-pointer list of address errors + (return fixed bin (35.)))) + ;; code + +(declare (defpl1 e_mail_pl1_$emacs_parse_message_text "" + (char (*)) (return ptr) (return ptr) + ;; message message-pointer parse error pointer + (return fixed bin(35.)))) + ;; code + +(declare (defpl1 e_mail_pl1_$display_parse_errors "" + (ptr) (char (*)))) + ;; parse error list ptr message text + +(declare (defpl1 e_mail_pl1_$emacs_deliver_message "" + (ptr) (bit (1)) (return fixed bin(35.)))) + ;; message-ptr request-ack code + +(declare (defpl1 e_mail_pl1_$emacs_create_message "" + (char (*)) (return ptr) (return fixed bin(35.)))) + ;; subject message-ptr code + +(declare (defpl1 e_mail_pl1_$emacs_expand_svbx_pathname "" + (char (*)) (return char (168.)) (return char (32.)) (return fixed bin (35.)))) + ;; pathname dirname entryname code + +(declare (defpl1 e_mail_pl1_$emacs_format_header "" + (ptr) (fixed bin) (ptr) + ;; message ptr line length temp seg/bmstring + (return fixed bin(35.))))) + ;; code + +(declare (defpl1 e_mail_pl1_$free_parse_text_error_list "" + (ptr))) + ;; parse_error_list ptr + +(declare (defpl1 mail_system_$free_message "" (ptr) (return fixed bin(35.)))) + +(declare (defpl1 mail_system_$free_address_list "" (ptr) (return fixed bin (35.)))) + +(declare (defpl1 mail_system_$add_reply_reference "" + (update ptr) (ptr) (fixed bin) + ;; new-message-ptr original-message-ptr position + (return fixed bin(35.)))) + ;; code + + +(defcom send-mail + (send-mail-beargumented (trim-minibuffer-response "Mail subject: "))) + +;;; Here we make life easy for any applications which may wish to call us +;;; We can be called with a subject string, addresses string, and even some +;;; initial text (any or which may be omited and default to ""). +;;; The application can ignore mail_system_ totally ... we do all of the work + +(defun send-mail-beargumented (&optional (subject "") + (additional-to-recipients "") + (initial-text "")) + (let ((result (e_mail_pl1_$emacs_create_message subject))) + (let ((msg (car result)) + (code (cadr result))) + (if (not (= code 0)) + (display-com-error code "While creating new message.") + else + (setq rmail-original-buffer nil) ;go back to most recent buffer when done + (find-buffer-in-window + (make_atom (rtrim (catenate "Mail about " subject)))) + (send-mail-beargumented-1 msg + additional-to-recipients + initial-text))))) + +(defun send-mail-beargumented-1 (message-ptr + additional-to-recipients + initial-text) + (if (not rmail-initialized) + (mail-init)) + (if (empty-buffer-p current-buffer) + (let ((code (e_mail_pl1_$emacs_format_header + message-ptr screenlinelen mail-header-buffer)) + (free-code (mail_system_$free_message message-ptr))) + (if (not (= code 0)) + (display-com-error code "While formating header.") + else + (if (not (= free-code 0)) + (display-com-error-noabort "While freeing message.")) + (insert-string (e_lap_$make-dat-ol-black-magic-string + mail-header-buffer)))) + (mapc '(lambda (x)(set-key (car x)(cadr x))) + '((^X^S send-the-mail) + (ESC-^B backward-mail-field) + (ESC-^F forward-mail-field) + (ESC-^D delete-mail-field) + (ESC-CR continue-mail-field) + (^XF mail-from) + (^XT mail-to) + (^XA mail-append) + (^X^A mail-toggle-ack) + (^ZB mail-bcc) ; everything else is taken + (^XC mail-cc) + (^XJ mail-subject) + (^XL rmail-logger-append) + (^XP rmail-logger-prepend) + (^XY mail-reply-to))) + (setq current-buffer-mode 'Mail) + (fill-mode) + (setq fill-column 72.) ;protocol + (register-local-var 'mail-mark) + (register-local-var 'mail-request-ack) + (setq mail-request-ack rmail-request-acknowledgement) + (if mail-request-ack (assert-minor-mode 'Ack) + else (negate-minor-mode 'Ack)) ;phx17317 + (mail-clean-up-from) + (go-to-beginning-of-buffer) + (if (not (forward-search (catenate NL "To:"))) + (go-to-end-of-buffer) + (mail-init-header-field "To:" additional-to-recipients) + (setq mail-mark (set-mark)) + (mail-to) + else (go-to-end-of-buffer) + (setq mail-mark (set-mark))) + (if mail-mode-hook (funcall mail-mode-hook)) + (insert-string initial-text) + else + (mail-append))) + +(defun mail-clean-up-from () ; let's be pretty + (save-excursion + (go-to-beginning-of-buffer) + (if (forward-search "From:") + (delete-white-sides) + (insert-string TAB)))) + +(defun mail-init () ;Once per loading + (setq mail-header-buffer (e$get_temporary_seg)) + (set-emacs-epilogue-handler '(rmail-cleanup) nil) + (setq rmail-initialized t)) + +(defun mail-find-first-blank-line () + (go-to-beginning-of-buffer) + (do-forever + (if (or (lastlinep)(line-is-blank))(stop-doing)) + (next-line))) + +(defcom continue-mail-field + (go-to-end-of-line) + (delete-white-sides) + (if (not (back-at ",")) + (insert-char ",")) + (insert-char NL) + (insert-string " ") + (save-excursion + (mail-find-header-end) + (backward-char) + (set-mark-here mail-mark))) + +(defcom mail-to + (mail-header-field-finder "To:")) + +(defcom mail-reply-to + (mail-header-field-finder "Reply-To:")) + +(defcom mail-from + (mail-header-field-finder "From:")) + +(defcom mail-cc + (mail-header-field-finder "cc:")) + +(defcom mail-bcc + (mail-header-field-finder "bcc:")) + +(defcom mail-subject + (mail-header-field-finder "Subject:")) + +(defun mail-header-field-finder (arg &aux uc-arg arg-len) + (setq uc-arg (uppercase arg) + arg-len (stringlength arg)) + (go-to-beginning-of-buffer) + (do-forever + (cond ((or (looking-at arg) + (samepnamep uc-arg ;case insensitive header match + (uppercase + (substr (curline-as-string) 1 arg-len)))) + (go-to-end-of-line) + (stop-doing)) + ((or (lastlinep) (point>markp mail-mark)) + (mail-header-add-new-line arg) + (stop-doing)) + (t (next-line))))) + +(defun look-for-mail-header-field (arg) + (go-to-beginning-of-buffer) + (do-forever + (if (looking-at arg) + (if (point>markp mail-mark)(return nil) + else (forward-search arg)(return t))) + (if (lastlinep)(return nil)) + (next-line))) + +(defun mail-header-add-new-line (arg) + (mail-find-header-end) + (insert-string arg) + (insert-string TAB) + (insert-string NL) + (set-mark-here mail-mark) + (backward-char)) + +(defun mail-init-header-field (key value) + (insert-string key) + (insert-string TAB) + (insert-string value) + (new-line)) + +(defcom mail-append + (mail-find-header-end) + (if (lastlinep) (new-line) + else (go-to-end-of-buffer))) + +(defun mail-find-header-end () + (go-to-beginning-of-buffer) + (if (lastlinep) nil ;close enuf + else + (do-forever + (if (lastlinep) (return nil)) ;global punt + (if (line-is-blank)(next-line) + else (stop-doing))) + (do-forever ;At header start? + (if (forward-search-in-line ":") + (do-forever + (if (lastlinep) ;only headers? + (stop-doing) + else + (next-line) + (if (or (not (at-white-char)) ;Another header field + (line-is-blank)) ;end of header + (stop-doing)))) + (if (or (lastlinep) (line-is-blank)) + (stop-doing)) + else + (stop-doing))) ;not a header field, maybe generate error in the future? + (if (not (line-is-blank)) + (go-to-end-of-line) + (insert-char NL)))) + +(defcom delete-mail-field + (do-forever + (if (or (back-at ":") (back-at ",") (bolp)) + (stop-doing)) + (backward-char)) + (with-mark bof + (delete-white-sides) + (if (forward-search-in-line ",") + (rubout-char) + else + (go-to-end-of-line)) + (delete-white-sides) + (wipe-point-mark bof) + (if (eolp)(delete-white-sides) + (if (back-at ",") + (rubout-char) + (delete-white-sides)) + else + (insert-string " "))) + (if (< (cur-hpos) 10.) + (delete-white-sides) + (whitespace-to-hpos 10.))) + +(defcom forward-mail-field + (if (eolp) (go-to-beginning-of-line)) + (if (bolp) (forward-search-in-line ":") + else (if (forward-search-in-line ",") + else + (go-to-beginning-of-line) + (forward-mail-field))) + (skip-over-whitespace-in-line)) + +(defcom backward-mail-field + (if (back-at ",") (backward-char)) + (if (reverse-search-in-line ",") + (forward-char) + else + (if (back-at ":") + (go-to-end-of-line) + (if (save-excursion (reverse-search-in-line ",")) + (backward-mail-field) + else + (reverse-search-in-line ":") + (forward-char)) + else + (reverse-search-in-line ":") + (forward-char))) + (skip-over-whitespace-in-line)) + +(defcom mail-toggle-ack + (setq mail-request-ack (not mail-request-ack)) + (minibuffer-print (catenate + "An acknowledgement will" + (if mail-request-ack "" else " not") + " be requested for this message.")) + (if mail-request-ack + (assert-minor-mode 'Ack) + else + (negate-minor-mode 'Ack))) + + +;;; Now its time to send the message + +(defcom send-the-mail + (let ((message-text (rmail-buffer-to-string))) + (let ((msg-ptr nil)) + (protect + (setq msg-ptr (rmail-parse-message-text message-text)) + (if msg-ptr ;nil if there were parse errors + (rmail-deliver-message msg-ptr)) + &always + (if msg-ptr (mail_system_$free_message msg-ptr)))))) + +(defun rmail-buffer-to-string () + (save-excursion + (go-to-beginning-of-buffer) + (with-mark start-of-buffer + (go-to-end-of-buffer) + (point-mark-to-string + start-of-buffer)))) + +;;; Turn the current buffer into a message (puf, like magic) + +;;; Note: we hack adding the reply reference here if we are a reply message, +;;; because mail_system_ can't parse In-Reply-To: fields. (grumble, grumble) + +(defun rmail-parse-message-text (message-text + &aux error-ptr message-ptr code) ;initialized to nil + (protect + (let ((result (e_mail_pl1_$emacs_parse_message_text message-text))) + (setq message-ptr (first result) + error-ptr (second result) + code (third result)) + (if (not (= code 0)) + (if (not (= code (error-table 'mlsys_et_ 'text_parse_failed))) + (display-com-error code "While parsing message.") + else + (display-as-printout + (rmail-display-parse-errors + error-ptr message-text))) + (setq message-ptr nil) ;it will be returned as the function value + else + (if mail-original-message-ptr + (let ((result (mail_system_$add_reply_reference + message-ptr mail-original-message-ptr -1))) + (let ((new-message-ptr (car result)) + (code (cadr result))) + (if (= code 0) + (setq message-ptr new-message-ptr))))))) + &always + (and error-ptr + (not (= error-ptr null-pointer)) + (e_mail_pl1_$free_parse_text_error_list error-ptr))) + message-ptr) + +(defun rmail-display-parse-errors (error-ptr message-text) + (protect + (rmail-set-up-file-output) + (e_mail_pl1_$display_parse_errors error-ptr message-text) + &always (rmail-clean-up-file-output)) + (insert-string "Message will not be delivered.") ; this will appear at the top of the buffer + (new-line) + (new-line)) + +;;; And now we deliver the message ... + +(defun rmail-deliver-message (message-ptr) + (let ((request-ack-flag mail-request-ack) ; make sure we are in the right buffer + (code 0)) + (display-as-printout (setq code + (rmail-display-delivery-results + message-ptr + request-ack-flag))) + (if (= code 0) ;happy? + (rmail-restore-original-buffer)))) + +(defun rmail-display-delivery-results (message-ptr request-ack-flag &aux code) + (protect + (rmail-set-up-file-output) + (setq code (e_mail_pl1_$emacs_deliver_message + message-ptr (if request-ack-flag -1 else 0))) + &always (rmail-clean-up-file-output)) + code) + +(defun rmail-restore-original-buffer () + (setq buffer-modified-flag nil) ;unmodify the buffer + (cond ((null rmail-original-buffer) + (find-buffer-in-window previous-buffer)) + ((exists-buffer rmail-original-buffer) + (find-buffer-in-window rmail-original-buffer)))) + +(defcom forward-the-mail + (let ((message-ptr mail-original-message-ptr) + (comment-text (rmail-buffer-to-string)) + (address-ptr mail-address-ptr) + (request-ack-flag mail-request-ack) + (code 0)) + (protect + (display-as-printout + (setq code (rmail-display-redistrib-results + message-ptr comment-text + address-ptr request-ack-flag))) + (if (= code 0) (rmail-restore-original-buffer)) + &always (and address-ptr + (mail_system_$free_address_list address-ptr))))) + +(defun rmail-display-redistrib-results (message-ptr comments-text address-ptr request-ack-flag &aux code) + (protect + (rmail-set-up-file-output) + (setq code (e_mail_pl1_$emacs_redistribute_message + message-ptr (if comments-text comments-text else "") + address-ptr (if request-ack-flag -1 else 0 ))) + (if (not (= code 0)) + (display-com-error code "Forwarding mail.")) + &always (rmail-clean-up-file-output)) + code) + + +;;; Emacs merry mailman +;;; BSG 12/16-17/78, 3/17-18/79 +;;; Dedicated to Ray Heatherton of old. + +;;; Here starts Emacs read mail (RMAIL) + +(declare (special error-table fpathname rmail-message-buffer FF + rmail-msgx rmail-mailbox-path read-only-flag rmail-seen + rmail-deleteq rmail-msgcount last-input-char + rmail-original-yank-indent mail-original-message + rmail-open-state rmail-buffer-to-go-back-to + rmail-mailbox-ptr rmail-send-acknowledgement + rmail-reply-include-authors rmail-reply-include-recipients + rmail-reply-include-self rmail-header-format start-up/.rmail)) + +(defvar rmail-mode-hook nil) + +;;; (register-option 'rmail-original-yank-indent 4) ;moved to e_option_defaults_ + +;;; (register-option 'rmail-send-acknowledgement t) ;moved to e_option_defaults_ +;;; (register-option 'rmail-request-acknowledgement nil) ;moved to e_option_defaults_ + +;;; (register-option 'rmail-reply-include-authors t) ;moved to e_option_defaults_ +;;; (register-option 'rmail-reply-include-recipients nil) ;moved to e_option_defaults_ +;;; (register-option 'rmail-reply-include-self nil) ;moved to e_option_defaults_ + +;;; (register-option 'rmail-header-format 'default-formatting-mode) ;moved to e_option_defaults_ + +;;; the MCR boards felt this was too complicated, so we won't make them +;;; offical options --- JR 09/02/83 + +(defvar envelope-format-var nil) +(defvar header-format-var nil) +(defvar redistributions-list-format-var nil) + +;;; defpl1's for the read mail side + +(declare (defpl1 e_mail_pl1_$emacs_mailbox_open "" + (char (*)) (char (*)) (return ptr) (return bit (1)) (return fixed bin) + ;; directory entry mailbox ptr salvaged count + (return fixed bin (35.)))) + ;; code + +(declare (defpl1 e_mail_pl1_$emacs_read_message "" + (ptr) (ptr) + ;; message ptr temp seg ptr + (fixed bin) (bit (1)) + ;; line length acknowledge + (char (*)) (char (*)) (char (*)) + ;; envelope-format header-format redistributions-format + (return fixed bin (21.)) (return bit (1)) + ;; number of lines in body seen switch + (return fixed bin (35.)))) + ;; code + +(declare (defpl1 e_mail_pl1_$emacs_get_message_ptr "" + (ptr) (fixed bin) (return ptr) + ;; mailbox-ptr message-number message-ptr + (return fixed bin(35.))))) + ;; code + +(declare (defpl1 e_mail_pl1_$get_user_default_mbx_address "" + (return ptr))) + +(declare (defpl1 e_mail_pl1_$emacs_mailbox_close "" (ptr) (return fixed bin))) + +(declare (defpl1 e_mail_pl1_$emacs_create_reply_message "" + (ptr) (bit (1)) (bit (1)) (bit (1)) + ;; orig msg include-authors include-recip include self + (return ptr) (return fixed bin(35.)))) + ;; new msg code + +(declare (defpl1 mail_system_$read_new_messages "" + (update ptr) (return fixed bin) (return fixed bin) + ;; mailbox-ptr new-messages new-regular messages + (return fixed bin) (return fixed bin(35.)))) + ;; new-interactive-messages code + +(declare (defpl1 mail_system_$get_address_pathname "" + (ptr) (return char (168.)) (return char (32.)) + ;; address directory entryname + (return char (32.)) (return fixed bin (35.)))) + ;; componentname code + +(declare (defpl1 mail_system_$mark_message_for_deletion "" + (ptr) (return fixed bin(35.)))) + ;; message ptr code + +(declare (defpl1 mail_system_$unmark_message_for_deletion "" + (ptr) (return fixed bin(35.)))) + ;; message ptr code + +(declare (defpl1 mail_system_$save_message "" + (ptr) (char (*)) (char (*)) (bit (1)) + ;; message ptr dir name entry name create flag + (return fixed bin(35.)))) + ;; code (surprise, surprise) + +(declare (defpl1 mlsys_utils_$parse_address_text "" + (char (*)) (return ptr) (return fixed bin (35.)))) + ;; text-address mlsys-address code + +(declare (defpl1 mlsys_utils_$parse_mailbox_text "" + (char (*)) (return char (168)) (return char (32)) + ;; mbx-name mbx-path-dir mbx-path-entry + (return fixed bin (35.)))) + ;; code + +(declare (defpl1 mlsys_utils_$print_message_summary_header "" + (fixed bin) (ptr) (return fixed bin (35.)))) + ;; line length output iocb code + +(declare (defpl1 mlsys_utils_$print_message_summary "" + (ptr) (fixed bin) (bit (1) aligned) + ;; message ptr message number current message flag + (fixed bin) (ptr) (return fixed bin (35.)))) + ;; line length output iocb code + +(declare (defpl1 mail_system_$free_address "" + (ptr) (return fixed bin (35.)))) + ;; address code + +(declare (defpl1 expand_pathname_ "" (char (*)) (return char(168.)) (return char(32.)) (return fixed bin(35.)))) + +(declare (defpl1 pathname_ "" (char (*)) (char (*)) (return char (168)))) + + +(defun rmail-init () + (setq rmail-open-state nil) ;Signifies initted + (if (not rmail-initialized) + (mail-init)) + (setq rmail-message-buffer nil)) + +(defun rmail-cleanup () ;In case he leaves without closing + (if rmail-open-state + (e_mail_pl1_$emacs_mailbox_close rmail-mailbox-ptr))) + + +(defcom rmail &numarg &pass + (if (not (boundp 'rmail-open-state))(rmail-init)) + (if rmail-open-state (go-to-buffer 'Incoming/ mail) + else + (rmail-open-mbx + (if numarg + (rmail-get-address-pathname-from-user) + else + (rmail-get-address-pathname (rmail-get-default-address)))) + (setq rmail-message-buffer (e$get_temporary_seg)) + (setq rmail-buffer-to-go-back-to current-buffer) + (go-to-or-create-buffer 'Incoming/ mail) + (setq current-buffer-mode 'RMAIL) + (setq fpathname rmail-mailbox-path) + (setq buffer-modified-flag t rmail-open-state t) + (minibuffer-clear) + (mapc '(lambda (x)(set-key (car x)(cadr x))) + '((/0 rmail-argument) + (/1 rmail-argument) + (/2 rmail-argument) + (/3 rmail-argument) + (/4 rmail-argument) + (/5 rmail-argument) + (/6 rmail-argument) + (/7 rmail-argument) + (/8 rmail-argument) + (/9 rmail-argument) + (/- rmail-minus) + (? rmail-help) + (m send-mail-from-rmail) + (c rmail-copy) + (D rmail-queue-delete-backward) + (d rmail-queue-delete-forward) + (j rmail-go-command) + (g rmail-go-command) + (l rmail-go-last-msg) + (n rmail-go-forward) + (p rmail-go-backward) + (x rmail-toggle-seen) + (q rmail-quit) + (^X^Q rmail-quit) + (r rmail-reply) + (f rmail-forward) + (s rmail-summarize) + (u rmail-undelete) + (^XL rmail-logger-append) + (^XP rmail-logger-prepend))) + (rmail-unbind-word-commands-kludge) + (without-modifying (destroy-buffer-contents)) + (setq read-only-flag t buffer-modified-flag nil) + (if (= rmail-msgcount 0) + (rmail-quit) + (display-error "No messages in " rmail-mailbox-path)) + (setq rmail-msgx 1 rmail-deleteq nil) + (if (boundp 'start-up/.rmail) + (mapc 'eval start-up/.rmail)) + (if (and (boundp 'rmail-mode-hook) + rmail-mode-hook) + (funcall rmail-mode-hook)) + (rmail-display-current-msg) + (select-buffer-window current-buffer 'cursize)) + (minibuffer-print "Type ""?"" for a list of rmail commands.") + &doc "$$$ is an emacs interface into the mail system. By default, +mail is read from your personal default mailbox. With a positive numeric +argument (e.g. ^U), $$$ prompts for the ""mailbox name"". Commands available +to $$$ are: + + $$rmail-help$ Displays this information. + $$rmail-go-forward$ Moves on to the next message. + $$rmail-go-backward$ Moves back to the previous message. + $$rmail-go-last-msg$ Moves to the last message in your mailbox. + $$rmail-go-command$ Moves to the message number specified by the numeric argument. + $$rmail-queue-delete-forward$ Queue the current message for deletion - move to next message. + $$rmail-queue-delete-backward$ Same as d, but moves backward. + $$rmail-undelete$ Brings back the last (stacked) deleted message. + $$rmail-copy$ Copies the message to some other mailbox. + $$rmail-quit$ Quits out of rmail returning to the original buffer. + $$rmail-summarize$ Summarizes (in a local display) all undeleted messages. + $$rmail-toggle-seen$ Toggles the ""Seen"" switch of the current message. + $$rmail-logger-append$ Log the message to an ASCII file, placing it at the end of the file. + $$rmail-logger-prepend$ Same as ^XL, but ""prepends"" to the front. + $$rmail-forward$ Forward the current message to a list of addresses. + $$rmail-reply$ Formats a MAIL mode buffer to reply to the current message. + $$send-mail-from-rmail$ Sends mail that is not necessarily a reply (see $$rmail-reply$). +") + +(defcom rmail-help + &prologue rmail-check-if-in-rmail + &na (&reject) + (if (samepnamep current-buffer-mode 'RMAIL) + (minibuffer-remark "Please wait...") + (describe 'rmail) + (minibuffer-clear) + else + (display-error "Not in RMAIL mode"))) + +(defun rmail-unbind-word-commands-kludge () ;they forced me + (rmail-unbind-if-bound '(1 125 nil) 'upper-case-word) ;esc-U + (rmail-unbind-if-bound '(1 114 nil) 'lower-case-word) ;esc-L + (rmail-unbind-if-bound '(1 103 nil) 'capitalize-initial-word)) ;esc-C + +(defun rmail-unbind-if-bound (key-list function) ;unbind key-list if bound to function + (if (eq (get-key-binding key-list) function) + (set-key (get-key-name key-list) 'undefined-command))) + + +(defun rmail-open-mbx (mbxpath) ;mbxpath is (dir . entry) + (let ((result (e_mail_pl1_$emacs_mailbox_open (car mbxpath) (cdr mbxpath)))) + (let ((mailbox-pointer (car result)) + (salvaged (cadr result)) + (msgcount (caddr result)) + (code (cadddr result))) + (if (not (= 0 code)) + (display-com-error code (rtrim (pathname_ (car mbxpath) (cdr mbxpath))))) + (if (not (= 0 salvaged)) + (minibuffer-print "Mailbox has been salvaged.")) + (setq rmail-mailbox-path (rtrim (pathname_ (car mbxpath) (cdr mbxpath)))) + (setq rmail-msgcount msgcount) + (setq rmail-mailbox-ptr mailbox-pointer) + 1))) + + +;;; This gets a string from the user turns it into a pathname +;;; using the mail system address to parse it if needed + +(defun rmail-get-address-pathname-from-user () + (let ((answer (trim-minibuf-response "Mailbox: " NL))) + (cond ((nullstringp answer) (display-error "No mailbox name given.")) + ((and (= 1 (index answer "{")) ; {thing} + (samepnamep (substr answer (stringlength answer)) + "}")) + (let ((result (mlsys_utils_$parse_address_text answer)) + (address nil) + (code 0) + (path "")) + (protect + (setq address (car result) + code (cadr result)) + (if (not (= code 0)) + (display-com-error + code "Getting mail address for " answer) + else + (setq path (rmail-get-address-pathname address)) + (let ((entry (rtrim (cdr path)))) + (if (not (samepnamep + ".mbx" ;catch .forum/.mls + (substr entry + (- (stringlength entry) + 3)))) + (display-error "The specified address does not identify a mailbox. " answer)))) + &always (and address + (mail_system_$free_address address))) + path)) + (t (let ((result (mlsys_utils_$parse_mailbox_text answer))) + (let ((code (third result))) + (if (not (zerop code)) + (display-com-error code answer)) + (rplacd result (second result)))))))) ;return (dir . entry) + +(defun rmail-get-default-address () + (e_mail_pl1_$get_user_default_mbx_address)) + +(defun rmail-get-address-pathname (address) + (let ((result (mail_system_$get_address_pathname address))) + (let ((dir (first result)) + (entry (second result)) + (code (fourth result))) + (cond ((not (= code 0)) + (display-com-error + code "Getting pathname of mailbox address")) + (t (cons dir entry)))))) + +;;; Get an address list from the user, parse and verify the addressees into +;;; an address-list structure to be used by the mail_system. Note that +;;; addressees must be separated by ","s as that is what it appears the +;;; mail_system wants. + +(defun rmail-get-address-list-from-user (&aux error-ptr address-ptr code) + (let ((answer (trim-minibuf-response "Forward to: "))) + (cond ((nullstringp answer) + (display-error "No addresses given.") + nil) + (t + (protect + (let ((result (e_mail_pl1_$emacs_get_address_list answer))) + (setq address-ptr (first result) + error-ptr (second result) + code (third result)) + (if (not (= code 0)) + (if (not (= code (error-table 'mlsys_et_ 'text_parse_failed))) + (display-com-error code "While parsing address list.") + else + (display-as-printout + (rmail-display-parse-errors + error-ptr answer))) + (setq address-ptr nil))) + &always (and error-ptr + (not (= error-ptr null-pointer)) + (e_mail_pl1_$free_parse_text_error_list error-ptr)) + &failure (and address-ptr + (mail_system_$free_address_list address-ptr)))))) + address-ptr) + +;;; Display the current (i.e. rmail-msgx) message. + +(defun rmail-display-current-msg () + (if (not (eq current-buffer 'Incoming/ mail)) + (display-error "Error: not in RMAIL")) + (if (> rmail-msgx rmail-msgcount) + (display-error-noabort "No next msg.")) + (setq fpathname rmail-mailbox-path) + (without-modifying + (destroy-buffer-contents) + (let ((msg (rmail-read-message rmail-msgx))) + +;;; Set the seen switch as we are now looking at it, so it really is seen + + (rmail-set-seen t) + +;;; Display the message size and the message + + (insert-string (catenate + "(" (decimal-rep rmail-msgx) + ") -- " (decimal-rep (car msg)) + " line" (if (= (car msg) 1) "" else "s"))) + (new-line) + (new-line) + (insert-string (cdr msg)) + (go-to-beginning-of-buffer)))) + +;;; This calls the mail system to actually format the message and +;;; returns (number of lines in text; a black magic string containing the +;;; entire message) + +(defun rmail-read-message (message-number) + (let ((message-ptr (rmail-get-message-ptr + rmail-mailbox-ptr message-number))) + (let ((result (e_mail_pl1_$emacs_read_message + message-ptr rmail-message-buffer screenlinelen + (if rmail-send-acknowledgement -1 else 0) + +;;; if the user has given values to various formatting option variable, +;;; then we use them, otherwise we use the documented rmail-header-format +;;; option + + (or envelope-format-var + (cond ((eq rmail-header-format 'brief-formatting-mode) 'none-formatting-mode) + (t rmail-header-format))) + (or header-format-var + rmail-header-format) + (or redistributions-list-format-var + rmail-header-format)))) + (let ((lines-in-body (first result)) ;MF + (code (third result))) ;MF + (setq rmail-seen (if (= (second result) 0) nil else t)) + (cond ((= code -1) ; e_mail_pl1_ special case + (display-com-error 0 "envelope-format (rmail-header-format) is invalid.")) + ((= code -2) + (display-com-error 0 "rmail-header-format is invalid.")) + ((= code -3) + (display-com-error 0 "redistributions-list-format (rmail-header-format) is invalid.")) + ((not (= code 0)) + (display-com-error-noabort code "Reading message " + (decimal-rep message-number))) + (t + (cons lines-in-body + (e_lap_$make-dat-ol-black-magic-string + rmail-message-buffer)))))))) + + +;;; Given a mailbox and a message number get a pointer to a mail system +;;; message structure. e_mail_pl1_ will read the message if it hasn't +;;; already done so. + +(defun rmail-get-message-ptr (mailbox-ptr message-number) + (let ((result (e_mail_pl1_$emacs_get_message_ptr + mailbox-ptr message-number))) + (let ((message-ptr (car result)) + (code (cadr result))) + (if (not (= code 0)) + (display-com-error code "While getting message " + (decimal-rep (message-number)) ".")) + message-ptr))) + +(defcom rmail-quit + &prologue rmail-check-if-in-rmail-buffer + (let ((message-to-goto (1+ rmail-msgcount))) + (if (and (rmail-check-for-new-messages) ;new messages and + (= rmail-commands-since-new-mail 0)) ;no new commands + (if (yesp "Do you still want to quit?") + (rmail-quit-1) + else + (rmail-go message-to-goto 'forward)) + else + (rmail-quit-1)))) + +(defun rmail-quit-1 () + (if rmail-message-buffer (e$release_temporary_seg rmail-message-buffer)) + (let ((code (e_mail_pl1_$emacs_mailbox_close rmail-mailbox-ptr))) + (if (not (= code 0)) + (display-com-error code "closing" rmail-mailbox-path))) + (set-buffer-self-destruct current-buffer) + (rmail-echo "") + (setq rmail-open-state nil) + (go-to-or-create-buffer rmail-buffer-to-go-back-to)) + +(defun rmail-check-if-in-rmail-buffer () ;check rmail buffer + (cond ((eq current-buffer-mode 'RMAIL) + t) + (t + (display-error "Error: not in RMAIL") + nil))) + +(defun rmail-check-if-in-rmail () + (cond ((rmail-check-if-in-rmail-buffer) ;check rmail buffer + (setq rmail-commands-since-new-mail ;increment command count + (+ rmail-commands-since-new-mail 1)) + (rmail-check-for-new-messages)))) ;check for new mail + + +(defun rmail-check-for-new-messages () + (let ((result (mail_system_$read_new_messages rmail-mailbox-ptr))) + (setq rmail-mailbox-ptr (car result)) + (let ((number-of-new-messages (cadr result)) + (code 0)) +; (code (cadddr (cdr result)))) ; this won't run compiled + (setq code (cadddr (cdr result))) ; but this appears to work + (if (and (not (= code 0)) + (not (= code + (error-table 'mlsys_et_ 'no_more_messages)))) + (display-com-error-noabort + code "Trying to determine if new messages had arrived.") + nil + else + (if (= number-of-new-messages 0) + nil + else + (setq rmail-msgcount + (+ rmail-msgcount number-of-new-messages)) + (setq rmail-commands-since-new-mail 0) ;reset count + (if (= 1 number-of-new-messages) + (minibuffer-print "One new message has arrived.") + else + (minibuffer-print (decimal-rep + number-of-new-messages) + " new messages have arrived.")) + t))))) + + +(defcom rmail-argument + &prologue rmail-check-if-in-rmail + &numeric-argument (&pass) + (rmail-echo last-input-char) + (let ((digit (- (CtoI last-input-char) (CtoI "0")))) + (if (null numarg) + (setq numarg digit) + else + (setq numarg (if (< numarg 0) (- (* numarg 10.) digit) + else (+ (* numarg 10.) digit))))) + (process-char (get-char))) + +(defcom rmail-minus + &prologue rmail-check-if-in-rmail + (rmail-echo last-input-char) + (let ((c (get-char))) + (if (or (< c (CtoI "0")) (> c (CtoI "9"))) + (setq numarg -1) + (process-char c) + else + (setq numarg (- (CtoI "0") c)) + (rmail-echo (ItoC c)) + (process-char (get-char))))) + + +(defcom rmail-go-forward () + &prologue rmail-check-if-in-rmail + &numeric-argument (&pass) + &negative-function rmail-go-backward + (rmail-echo last-input-char) + (rmail-go (+ rmail-msgx (or numarg 1)) 'forward)) + +(defcom rmail-go-backward + &prologue rmail-check-if-in-rmail + &numeric-argument (&pass) + &negative-function rmail-go-forward + (rmail-echo last-input-char) + (rmail-go (- rmail-msgx (or numarg 1)) 'backward)) + +(defcom rmail-go-last-msg + &prologue rmail-check-if-in-rmail + (rmail-check-for-new-messages) + (rmail-echo 'l) + (rmail-go rmail-msgcount 'backward)) + +(defun rmail-not-deleted-message (message-number) + (not (memq message-number rmail-deleteq))) + +(defun rmail-queue-deletion (message-index) + (if (rmail-not-deleted-message message-index) + (let ((message-ptr (rmail-get-message-ptr + rmail-mailbox-ptr message-index))) + (let ((code (mail_system_$mark_message_for_deletion + message-ptr))) + (if (not (= 0 code)) + (display-com-error code "deleting message " + (decimal-rep message-index)) + else + (setq rmail-deleteq + (cons message-index rmail-deleteq))))) + else + (display-error "Message " (decimal-rep message-index) + "has already been deleted."))) + +(defcom rmail-queue-delete-forward + &prologue rmail-check-if-in-rmail + (rmail-echo 'd) + (rmail-queue-deletion rmail-msgx) + (cond ((let ((mno (rmail-find-message-forward (1+ rmail-msgx)))) + (if mno (rmail-go mno 'forward) t else nil))) + ((let ((mno (rmail-find-message-backward (1- rmail-msgx)))) + (if mno (rmail-go mno 'backward) t else nil))) + (t (rmail-delete-desperator)))) + +(defcom rmail-queue-delete-backward + &prologue rmail-check-if-in-rmail + (rmail-echo 'D) + (rmail-queue-deletion rmail-msgx) + (cond ((let ((mno (rmail-find-message-backward (1- rmail-msgx)))) + (if mno (rmail-go mno 'backward) t else nil))) + ((let ((mno (rmail-find-message-forward (1+ rmail-msgx)))) + (if mno (rmail-go mno 'forward) t else nil))) + (t (rmail-delete-desperator)))) + +(defun rmail-delete-desperator () + (cond ((yesp "All messages deleted. Quit rmail?") + (rmail-quit)) + (t (minibuffer-print "Undeleting this message.") + (rmail-undelete)))) + +(defcom rmail-undelete + &prologue rmail-check-if-in-rmail + (rmail-echo 'u) + (if rmail-deleteq + (let ((last-deleted-message (car rmail-deleteq))) + (let ((message-ptr (rmail-get-message-ptr + rmail-mailbox-ptr last-deleted-message))) + (let ((code (mail_system_$unmark_message_for_deletion + message-ptr))) + (if (not (= code 0)) + (display-com-error code "Un-deleting message " + (decimal-rep last-deleted-message)) + else + (setq rmail-deleteq (cdr rmail-deleteq)) + (rmail-go last-deleted-message 'forward))))) + else + (display-error-noabort "No pending deletions.") + (ring-tty-bell))) + +;;; Toggle the seen switch on the current message, update the minor mode to +;;; reflect the new status. + +(defcom rmail-toggle-seen () + &prologue rmail-check-if-in-rmail + (rmail-echo 'x) + (rmail-set-seen (not rmail-seen))) + +(defun rmail-set-seen (mode) + (let ((code (mail_system_$set_message_switch + (rmail-get-message-ptr rmail-mailbox-ptr rmail-msgx) + "SEEN" (if mode -1 else 0)))) + (cond ((= code 0) + (setq rmail-seen mode) + (if rmail-seen (assert-minor-mode 'Seen) + else (negate-minor-mode 'Seen))) + (t + (display-com-error code "While setting seen switch."))))) + +(declare (special tty-no-upmotionp)) + +(defun rmail-echo (x) + (if (not tty-no-upmotionp) + (minibuffer-print-noclear x))) + +(defun rmail-go (msgno direction) + (if (> msgno rmail-msgcount)(rmail-check-for-new-messages)) + (cond ((and (> msgno rmail-msgcount)(eq direction 'forward)) + (display-error "No more messages forward.")) + ((or (< msgno 1)(> msgno rmail-msgcount)) + (display-error "Invalid message number: " (decimal-rep msgno))) + ((rmail-not-deleted-message msgno) + (setq rmail-msgx msgno) + (rmail-display-current-msg)) + ((eq direction 'forward) + (let ((fno (rmail-find-message-forward msgno))) + (if fno (rmail-go fno 'forward) + else (display-error "No more messages forward.")))) + (t (let ((fno (rmail-find-message-backward msgno))) + (if fno (rmail-go fno 'backward) + else (display-error "No more messages backward.")))))) + +(defun rmail-find-message-forward (msgno) + (do ((tentative msgno (1+ tentative)) + (checkedflag)) + ((> tentative rmail-msgcount) nil) + (if (rmail-not-deleted-message tentative) + (return tentative)) + (if (and (= tentative rmail-msgcount)(not checkedflag)) + (setq checkedflag t) + (rmail-check-for-new-messages)))) + +(defun rmail-find-message-backward (msgno) + (do ((tentative msgno (1- tentative))) + ((< tentative 1) nil) + (if (rmail-not-deleted-message tentative) + (return tentative)))) + +(defcom rmail-go-command + &prologue rmail-check-if-in-rmail + &numarg &pass + (let ((here rmail-msgx)) + (if numarg (rmail-go numarg 'forward)) + (if (not (= here rmail-msgx)) + (rmail-echo (catenate "(" (decimal-rep rmail-msgx) ")"))))) + +(defcom rmail-summarize + &prologue rmail-check-if-in-rmail + (rmail-check-for-new-messages) + (display-as-printout (rmail-create-summary-buffer))) + +(defun rmail-create-summary-buffer () + (protect + (rmail-set-up-file-output) + (rmail-get-summary-header) + (do message-number 1 (1+ message-number) + (> message-number rmail-msgcount) + (if (rmail-not-deleted-message message-number) + (rmail-summarize-one message-number))) + &always (rmail-clean-up-file-output))) + +(defun rmail-get-summary-header () + (let ((code (mlsys_utils_$print_message_summary_header + screenlinelen null-pointer))) + (if (not (= code 0)) + (go-to-buffer 'Incoming/ mail) + (rmail-clean-up-file-output) + (display-com-error code + "While getting message summary header.")))) + + +(defun rmail-summarize-one (message-number) + (let ((message-ptr (rmail-get-message-ptr + rmail-mailbox-ptr message-number)) + (current-msg-flag 0)) ;"0"b + (if (= rmail-msgx message-number) (setq current-msg-flag -1));"1"b + (let ((code (mlsys_utils_$print_message_summary + message-ptr message-number current-msg-flag + screenlinelen null-pointer))) + (if (not (= code 0)) + (rmail-clean-up-file-output) + (go-to-buffer 'Incoming/ mail) + (display-com-error code + "While getting summary for message" + (decimal-rep message-number)))))) + +; Maybe there is too much internal knowledge here, and this should +; be done some other way + +; delcare's for file-output hacking + +(declare (special pdir-temp-ename pdir-temp-pathname)) +(declare (*lexpr ncline e_pl1_$get_iocb hcs_$truncate_file hcs_$set_bc)) +(declare + (defpl1 iox_$control "" (ptr) (char (*)) (ptr) (return fixed bin (35.)))) + +(defun rmail-set-up-file-output () + (hcs_$set_bc process-dir pdir-temp-ename 0) + (ncline 'file_output pdir-temp-pathname '-ssw 'user_output + '-ssw 'error_output)) + +(defun rmail-clean-up-file-output () + (e_cline_ "revert_output -ssw user_output -ssw error_output") + (let ((fpathname nil)) + (read-in-file pdir-temp-pathname)) + (hcs_$truncate_file process-dir pdir-temp-ename 0) + (iox_$control (e_pl1_$get_iocb) "reset_more" null-pointer)) + + +;;; Reply + +(defcom rmail-reply + &prologue rmail-check-if-in-rmail + &numarg &pass + (rmail-echo 'r) + (setq rmail-original-buffer current-buffer) + (let ((original-message-text (rmail-collect-orig)) + (include-authors (if (or + rmail-reply-include-authors + numarg) + -1 else 0)) + (include-recipients (if (or + rmail-reply-include-recipients + numarg) + -1 else 0)) + (include-self (if rmail-reply-include-self -1 else 0)) + (original-message-ptr (rmail-get-message-ptr + rmail-mailbox-ptr rmail-msgx))) + (let ((result (e_mail_pl1_$emacs_create_reply_message + original-message-ptr include-authors + include-recipients include-self))) + (let ((new-message-ptr (car result)) + (code (cadr result))) + (if (not (= code 0)) + (display-com-error code "While creating reply message.")) + (find-buffer-in-window + (make_atom (catenate "Reply to message " + (decimal-rep rmail-msgx))));;; ugh, ugh, ugh + (without-saving (destroy-buffer-contents)) + (send-mail-beargumented-1 new-message-ptr "" "") + (mail-append) + (setq current-buffer-mode 'RMAIL/ reply) + (rmail-prepare-response-environment + original-message-text original-message-ptr))))) + +(defun rmail-collect-orig () + (save-excursion + (go-to-beginning-of-buffer) + (next-line) + (with-mark start-of-buffer + (go-to-end-of-buffer) + (point-mark-to-string + start-of-buffer)))) + +;;; 10/15/80 + +(defcom send-mail-from-rmail + &prologue rmail-check-if-in-rmail + (let ((msg (rmail-collect-orig))) + (execute-command 'send-mail nil nil) + (rmail-prepare-response-environment msg nil))) + +;;; We must keep track of the original message and add the reply reference +;;; ourselves because mail_system_ can't hack parsing In-Reply-To: fields +;;; (grumble, grumble) + +(defun rmail-prepare-response-environment (original-msg-text original-msg-ptr) + (register-local-var 'mail-original-message) + (register-local-var 'rmail-original-buffer) ; buffer to return to if successful + (setq mail-original-message original-msg-text) + (setq rmail-original-buffer 'Incoming/ mail) + (if original-msg-ptr ; non-nil implies we are a reply message + (register-local-var 'mail-original-message-ptr) + (setq mail-original-message-ptr original-msg-ptr)) + (set-key 'ESC-^Y 'rmail-yank-mail) + (set-key '^X^Q 'return-to-rmail)) + +(defcom return-to-rmail + (minibuffer-clear) + (find-buffer-in-window 'Incoming/ mail)) + +(defcom rmail-yank-mail + &numeric-argument (&reject) + (set-the-mark) + (insert-string mail-original-message) + (let ((numarg rmail-original-yank-indent)) + (indent-rigidly)) + (if (not (back-at NL))(new-line))) + +;;; 02/07/89 +;;; Forward the current piece of mail to a list of addresses. A numeric +;;; argument allows the user to add redistribution comments to the mail +;;; by creating a comments buffer. + +(defcom rmail-forward + &prologue rmail-check-if-in-rmail + &numarg &pass + (rmail-echo 'f) + (setq rmail-original-buffer current-buffer) + (let ((original-message-ptr + (rmail-get-message-ptr rmail-mailbox-ptr rmail-msgx)) + (address-ptr nil)) + (protect + (cond ((setq address-ptr (rmail-get-address-list-from-user)) + (if numarg + (find-buffer-in-window + (make_atom + (catenate "Forwarding comments for message " + (decimal-rep rmail-msgx)))) + (rmail-prepare-comment-environment + original-message-ptr address-ptr) + else + (display-as-printout + (rmail-display-redistrib-results + original-message-ptr nil address-ptr + mail-request-ack)) + (and address-ptr + (mail_system_$free_address_list address-ptr))))) + &failure (and address-ptr + (mail_system_$free_address_list address-ptr))))) + +;;; Prepare the current buffer as a comment buffer for sending redistribution +;;; comments + +(defun rmail-prepare-comment-environment (original-msg-ptr address-ptr) + +;;; Local variables used + + (register-local-var 'rmail-original-buffer) ; return buffer + (register-local-var 'mail-original-message-ptr); mail to forward + (register-local-var 'mail-address-ptr) ; destination addresses + (register-local-var 'mail-request-ack) ; if an ack is required + (setq rmail-original-buffer 'Incoming/ mail) + (setq mail-original-message-ptr original-msg-ptr) + (setq mail-address-ptr address-ptr) + (setq mail-request-ack rmail-request-acknowledgement) + +;;; Set up the buffer display + + (without-saving (destroy-buffer-contents)) + (setq current-buffer-mode 'RMAIL/ comments) + (if mail-request-ack (assert-minor-mode 'Ack) + else (negate-minor-mode 'Ack)) + +;;; Set up buffer characteristics + + (fill-mode) + (setq fill-column 61.) ;72.-11. for indentation + (set-key '^X^A 'mail-toggle-ack) + (set-key '^X^Q 'return-to-rmail) + (set-key '^X^S 'forward-the-mail)) + +;;; +;;; RMAIL correspondence recorder +;;; + +(declare (special known-buflist)) +(defcom rmail-logger-append + &prologue rmail-check-if-in-rmail + &numarg (&pass) + (rmail-guts-of-logger 'append)) + +(defcom rmail-logger-prepend () + &prologue rmail-check-if-in-rmail + &numarg (&pass) + (rmail-guts-of-logger 'prepend)) + +(defun rmail-guts-of-logger (whichway) + (if (not (and (memq 'Mail/ log known-buflist) (null numarg))) + (let ((new-pathname (trim-minibuf-response "RMAIL Log file: " NL))) + (if (nullstringp new-pathname) + (display-error "You must supply a pathname.")) + (open-file new-pathname 'write) ;;; phx20937/21049 + (save-excursion-buffer + (go-to-or-create-buffer 'Mail/ log) + (read-in-file new-pathname)))) + (save-excursion + (save-excursion-buffer + (let ((z (curbuf-as-string))) + (go-to-buffer 'Mail/ log) + (if (eq whichway 'append) + (go-to-end-of-buffer) + else + (go-to-beginning-of-buffer)) + (insert-char FF) + (insert-string z)) + (save-same-file)))) + + +;;; Rmail copy request --- this is the same as read_mail's save request + +(defcom rmail-copy + &prologue rmail-check-if-in-rmail + (let ((result (e_mail_pl1_$emacs_expand_svbx_pathname + (minibuf-response "Save Mailbox: " NL)))) + (let ((rmail-sv-dname (car result)) + (rmail-sv-ename (cadr result)) + (code (caddr result))) + (if (not (= code 0)) + (display-com-error + code "Expanding save mailbox pathname.") + else + (rmail-copy-1 rmail-sv-dname rmail-sv-ename 0))))) + +(defun rmail-copy-1 (rmail-sv-dname rmail-sv-ename create-flag) + (let ((code (mail_system_$save_message + (rmail-get-message-ptr rmail-mailbox-ptr rmail-msgx) + rmail-sv-dname rmail-sv-ename create-flag))) + (if (and (= code (error-table 'mlsys_et_ 'no_savebox)) + (yesp "Save mailbox doesn't exist. Create it?")) + (rmail-copy-1 rmail-sv-dname rmail-sv-ename -1) + else + (if (and (not (= code 0)) + (not (= code + (error-table 'mlsys_et_ 'savebox_created)))) + (display-com-error code "Trying to save message."))))) + + + + + + bull_copyright_notice.txt 08/30/05 1008.4r 08/30/05 1007.3 00020025 + + ----------------------------------------------------------- + + +Historical Background + +This edition of the Multics software materials and documentation is provided and donated +to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. +as a contribution to computer science knowledge. +This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, +Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull +and Bull HN Information Systems Inc. to the development of this operating system. +Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), +renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership +of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for +managing computer hardware properly and for executing programs. Many subsequent operating systems +incorporated Multics principles. +Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., +as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . + + ----------------------------------------------------------- + +Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without +fee is hereby granted,provided that the below copyright notice and historical background appear in all copies +and that both the copyright notice and historical background and this permission notice appear in supporting +documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining +to distribution of the programs without specific prior written permission. + Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. + Copyright 2006 by Bull HN Information Systems Inc. + Copyright 2006 by Bull SAS + All Rights Reserved diff --git a/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_multics_emacs_.s.archive b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_multics_emacs_.s.archive new file mode 100644 index 0000000..1238957 Binary files /dev/null and b/web.mit.edu/multics-history/source/Multics/ldd/system_library_unbundled/source/bound_multics_emacs_.s.archive differ