home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: MicroEMACS
- * Symbol table stuff for GNU emacs compatability
- * Version: 29
- * Last edit: 19-Apr-86
- * By: {sun, amdahl, cbosgd}!rtech!gonzo!daveb
- *
- * Symbol tables, and keymap setup.
- * The terminal specific parts of building the
- * keymap has been moved to a better place.
- *
- * This version matches the standard GNU Emacs 17.49 bindings.
- * With this file, MicroEMACS is a proper subset of GNU.
- *
- * If a GNU feature was misnamed, it was moved.
- * If a GNU feature was "nearly" right, it was noted for later work.
- * If a MicroEMACS feature was incompatible, it was dropped.
- *
- * Compatibility NOW for the future!
- */
- #include "def.h"
-
- #define DIRLIST 0 /* Disarmed! */
-
- # define DEL 0x7f
- # define ESC 0x1b
-
- /* # define DAVEB *//* Dave Brower specials, not GNU compatibility */
-
- /*
- * Defined by "main.c".
- */
- extern int ctrlg(); /* Abort out of things */
- extern int quit(); /* Rude Quit */
- extern int ctlxlp(); /* Begin macro */
- extern int ctlxrp(); /* End macro */
- extern int ctlxe(); /* Execute macro */
- extern int showversion(); /* Show version numbers, etc. */
-
- /*
- * defined by "gnucmds.c"
- */
- extern int savebuffs(); /* GNU style save-some-buffers */
- extern int savequit(); /* GNU save-buffers-kill-emacs */
- extern int suspend(); /* GNU style suspend */
- extern int notmodified(); /* GNU make buffer undirty */
- extern int scrollother(); /* GNU scroll other window */
-
- /*
- * Defined by "search.c".
- */
- extern int forwsearch(); /* Search forward */
- extern int backsearch(); /* Search backwards */
- extern int searchagain(); /* Repeat last search command */
- extern int forwisearch(); /* Incremental search forward */
- extern int backisearch(); /* Incremental search backwards */
- extern int queryrepl(); /* Query replace */
-
- /*
- * Defined by "basic.c".
- */
- extern int gotobol(); /* Move to start of line */
- extern int backchar(); /* Move backward by characters */
- extern int gotoeol(); /* Move to end of line */
- extern int forwchar(); /* Move forward by characters */
- extern int gotobob(); /* Move to start of buffer */
- extern int gotoeob(); /* Move to end of buffer */
- extern int forwline(); /* Move forward by lines */
- extern int backline(); /* Move backward by lines */
- extern int forwpage(); /* Move forward by pages */
- extern int backpage(); /* Move backward by pages */
- extern int setmark(); /* Set mark */
- extern int swapmark(); /* Swap "." and mark */
- extern int gotoline(); /* Go to a specified line. */
-
- /*
- * Defined by "buffer.c".
- */
- extern int listbuffers(); /* Display list of buffers */
- extern int usebuffer(); /* Switch a window to a buffer */
- extern int killbuffer(); /* Make a buffer go away. */
-
- #if DIRLIST
- /*
- * Defined by "dirlist.c".
- */
- extern int dirlist(); /* Directory list. */
- #endif
-
- /*
- * Defined by "file.c".
- */
- extern int fileread(); /* Get a file, read only */
- extern int filevisit(); /* Get a file, read write */
- extern int filewrite(); /* Write a file */
- extern int filesave(); /* Save current file */
- extern int filename(); /* Adjust file name */
-
- /*
- * Defined by "random.c".
- */
- extern int selfinsert(); /* Insert character */
- extern int showcpos(); /* Show the cursor position */
- extern int twiddle(); /* Twiddle characters */
- extern int quote(); /* Insert literal */
- extern int openline(); /* Open up a blank line */
- extern int newline(); /* Insert CR-LF */
- extern int deblank(); /* Delete blank lines */
- extern int indent(); /* Insert CR-LF, then indent */
- extern int forwdel(); /* Forward delete */
- extern int backdel(); /* Backward delete */
- extern int killline(); /* Kill forward */
- extern int yank(); /* Yank back from killbuffer. */
-
- /*
- * Defined by "region.c".
- */
- extern int killregion(); /* Kill region. */
- extern int copyregion(); /* Copy region to kill buffer. */
- extern int lowerregion(); /* Lower case region. */
- extern int upperregion(); /* Upper case region. */
-
- /*
- * Defined by "spawn.c".
- */
- extern int spawncli(); /* Run CLI in a subjob. */
-
- /*
- * Defined by "window.c".
- */
- extern int reposition(); /* Reposition window */
- extern int refresh(); /* Refresh the screen */
- extern int nextwind(); /* Move to the next window */
- extern int prevwind(); /* Move to the previous window */
- extern int mvdnwind(); /* Move window down */
- extern int mvupwind(); /* Move window up */
- extern int onlywind(); /* Make current window only one */
- extern int splitwind(); /* Split current window */
- extern int enlargewind(); /* Enlarge display window. */
- extern int shrinkwind(); /* Shrink window. */
-
- /*
- * Defined by "word.c".
- */
- extern int backword(); /* Backup by words */
- extern int forwword(); /* Advance by words */
- extern int upperword(); /* Upper case word. */
- extern int lowerword(); /* Lower case word. */
- extern int capword(); /* Initial capitalize word. */
- extern int delfword(); /* Delete forward word. */
- extern int delbword(); /* Delete backward word. */
-
- /*
- * Defined by "extend.c".
- */
- extern int extend(); /* Extended commands. */
- extern int help(); /* Help key. */
- extern int bindtokey(); /* Modify key bindings. */
- extern int wallchart(); /* Make wall chart. */
-
- typedef struct {
- short k_key; /* Key to bind. */
- int (*k_funcp)(); /* Function. */
- char *k_name; /* Function name string. */
- } KEY;
-
- /*
- * Default key binding table. This contains
- * the function names, the symbol table name, and (possibly)
- * a key binding for the builtin functions. There are no
- * bindings for C-U or C-X. These are done with special
- * code, but should be done normally.
- */
-
- /* GNU standard bindings that are missing are commented out with the
- * following notations:
- *
- * /*B Braindamaged in current implementation.
- * /*D Design restructuring is needed.
- * /*E Easy, a few hours.
- * /*H Hard, (days) but possible if desirable.
- * /*I Impossible (weeks), much too hard to do right.
- * /*M Moderate difficulty, a day or so.
- * /*T On the to do list.
- * /*U Undecided.
- * /*X Means unnecessary to do.
- * /*W Current version is wrong.
- *
- * Well, braindamaged is a bit too strong, but doing all the argument
- * processing in the main loop, and not having meta- ancd ctrl-x
- * be bindable commands seems kinda funny to me (daveb).
- */
-
- KEY key[] = {
- KCTRL|'@', setmark, "set-mark-command",
- KCTRL|'A', gotobol, "beginning-of-line",
- KCTRL|'B', backchar, "backward-char",
- /*DHX KCTRL|'C', ???, "mode-specific-command-prefix", */
- KCTRL|'D', forwdel, "delete-char",
- KCTRL|'E', gotoeol, "end-of-line",
- KCTRL|'F', forwchar, "forward-char",
- KCTRL|'G', ctrlg, "keyboard-quit",
- KCTRL|'H', help, "help-command",
- /*DHX KCTRL|'I', ???, "indent-for-tab-command", */
- KCTRL|'J', indent, "newline-and-indent",
- KCTRL|'K', killline, "kill-line",
- KCTRL|'L', refresh, "recenter",
- /*W actually doesn't recenter... */
-
- KCTRL|'M', newline, "newline",
- KCTRL|'N', forwline, "next-line",
- KCTRL|'O', openline, "open-line",
- KCTRL|'P', backline, "previous-line",
- KCTRL|'Q', quote, "quoted-insert",
- KCTRL|'R', backisearch, "isearch-backward",
- KCTRL|'S', forwisearch, "isearch-forward",
- KCTRL|'T', twiddle, "transpose-characters",
- /*BMT KCTRL|'U', ???, "universal-argument," */
- KCTRL|'V', forwpage, "scroll-up",
- KCTRL|'W', killregion, "kill-region",
- /*BMT KCTRL|'X', ???, "Control-X-prefix", */
- KCTRL|'Y', yank, "yank",
- /*WET doesn't set point! */
-
- KCTRL|'Z', suspend, "suspend-emacs",
-
- /*BMT KMETA, ???, "ESC-prefix", */
- /*DX KCTRL|']', ???, "abort-recursive-edit", */
- /*DIX KCTRL|'_', ???, "undo", */
-
- DEL, backdel, "delete-backward-char",
-
- /*DIX KCTLX|KCTRL|'A',???, "add-mode-abbrev", */
- KCTLX|KCTRL|'B',listbuffers, "list-buffers",
- KCTLX|KCTRL|'C',savequit, "save-buffers-kill-emacs",
-
- #if DIRLIST
- KCTLX|KCTRL|'D',dirlist, "list-directory",
- #endif
-
- /*DIX KCTLX|KCTRL|'E',???, "eval-last-sexp", */
- KCTLX|KCTRL|'F',filevisit, "find-file",
- /*DIX KCTLX|KCTRL|'H',???, "inverse-add-mode=abbrev", */
- /*MT KCTLX|KCTRL|'I',???, "indent-rigidly", */
- KCTLX|KCTRL|'L',lowerregion, "downcase-region",
- /*ET KCTLX|KCTRL|'N', ???, "set-goal-column" */
- KCTLX|KCTRL|'O',deblank, "delete-blank-lines",
- /*MU KCTLX|KCTRL|'P',???, "mark-page" */
- KCTLX|KCTRL|'R',fileread, "file-file-read-only",
- /*WU incorrect behaviour... */
- KCTLX|KCTRL|'S',filesave, "file-buffer",
-
- /*EU KCTLX|KCTRL|'T',???, "transpose-lines", */
- KCTLX|KCTRL|'U',upperregion, "upcase-region",
- /*EU KCTLX|KCTRL|'V',findalternate, "find-alternate-file", */
- KCTLX|KCTRL|'W',filewrite, "write-file",
- KCTLX|KCTRL|'X',swapmark, "exchange-point-and-mark",
- KCTLX|KCTRL|'Z',spawncli, "suspend-emacs",
-
- /*MT KCTLX|ESC ???, "repeat-complex-command", */
- /*U KCTLX|'$' ???, "set-selective-display", */
- KCTLX|'(', ctlxlp, "start-kbd-macro",
- KCTLX|')', ctlxrp, "end-kbd-macro",
- /*DIX KCTLX|'+', ???, "add-global-abbrev", */
- /*DIX KCTLX|'-', ???, "inverse-add-global-abbrev", */
- /*MX KCTLX|'.', ???, "set-fill-prefix", */
- /*HX KCTLX|'/', ???, "point-to-register", */
- /*MT KCTLX|'0', ???, "delete-window", */
- KCTLX|'1', onlywind, "delete-other-windows",
- KCTLX|'2', splitwind, "split-window-vertically",
- /*MX KCTLX|'4', ???, "ctl-x-4-prefix", */
- /*DHX KCTLX|'5', ???, "split-window-horizontally", */
- /*EX KCTLX|';', ???, "set-comment-column", */
- /*HU KCTLX|'<', ???, "scroll-left", */
- KCTLX|'=', showcpos, "what-cursor-position",
- /*HU KCTLX|'>', ???, "scroll-right", */
- /*MU KCTLX|'[', ???, "backward-page", */
- /*MU KCTLX|']', ???, "forward-page", */
- KCTLX|'^', enlargewind, "enlarge-window",
- /*HX KCTLX|'`', ???, "next-error", */
- /*MU KCTLX|'A', ???, "append-to-buffer", */
- KCTLX|'B', usebuffer, "switch-to-buffer",
- /*MX KCTLX|'D', ???, "dired", */
- KCTLX|'E', ctlxe, "call-last-kbd-macro",
- /*EU KCTLX|'F', ctlxe, "set-fill-column", */
- /*HX KCTLX|'G', ???, "insert-register", */
- /*EU KCTLX|'H', ???, "mark-whole-buffer", */
- /*MU KCTLX|'I', ???, "insert-file", */
- /*HX KCTLX|'J', ???, "register-to-point", */
- KCTLX|'K', killbuffer, "kill-buffer",
- /*MU KCTLX|'L', ???, "count-lines-page", */
- /*HU KCTLX|'N', ???, "narrow-to-region", */
- KCTLX|'O', nextwind, "other-window",
- /*HU KCTLX|'P', ???, "narrow-to-page", */
- /*MX KCTLX|'Q', ???, "kbd-macro-qry", */
- /*HX KCTLX|'R', ???, "copy-rectangle-to-register", */
- KCTLX|'S', savebuffs, "save-some-buffers",
- /*HX KCTLX|'U', ???, "advertised-undo", */
- /*HX KCTLX|'W', ???, "widen", */
- /*HX KCTLX|'{', ???, "shrink-window-horizontally", */
- /*HX KCTLX|'}', ???, "enlarge-window-horizontally", */
- /*MT KCTLX|DEL, ???, "backward-kill-sentence," */
-
- /*MU KMETA|KCTRL|'@',???, "mark-sexp", */
- /*MU KMETA|KCTRL|'A',???, "beginning-of-defun", */
- /*MU KMETA|KCTRL|'B',???, "backwards-sexp", */
- /*MX KMETA|KCTRL|'C',???, "exit-recursive-edit", */
- /*MU KMETA|KCTRL|'D',???, "down-list", */
- /*MU KMETA|KCTRL|'E',???, "end-of-defun", */
- /*MU KMETA|KCTRL|'F',???, "forward-sexp", */
- /*MU KMETA|KCTRL|'H',???, "mark-defun", */
- /*MU KMETA|KCTRL|'J',???, "indent-new-comment-line", */
- /*MU KMETA|KCTRL|'K',???, "kill-sexp", */
- /*MU KMETA|KCTRL|'N',???, "foward-list", */
- /*EU KMETA|KCTRL|'O',???, "split-line", */
- /*MU KMETA|KCTRL|'P',???, "backward-list", */
- /*HX KMETA|KCTRL|'S',???, "isearch-forward-regexp", */
- /*MU KMETA|KCTRL|'T',???, "transpose-sexps", */
- /*MU KMETA|KCTRL|'U',???, "backward-up-list", */
- KMETA|KCTRL|'V',scrollother, "scroll-other-window",
- /*ET KMETA|KCTRL|'W',???, "append-next-kill", */
-
- /*IX KMETA|ESC, ??? "eval-expression", */
- /*IX KMETA|CTRL|'\', ??? "indent-region", */
- /*MU KMETA|' ', ??? "just-one-space", */
- /*HT KMETA|'!', ???, "shell-command", */
- /*HU KMETA|'$', ???, "spell-word", */
- KMETA|'%', queryrepl, "query-replace",
- /*IX KMETA|'\'', ???, "abbrev-prefix-mark", */
- /*TU KMETA|'(', ???, "insert-parenthesis", */
- /*HU KMETA|')', ???, "move-past-close-and-reindent", */
- /*HX KMETA|',', ???, "tags-loop-continue", */
- /*DT KMETA|'-', ???, "negative-argument", */
- KMETA|'>', gotoeob, "end-of-buffer",
- /*MU KMETA|'=', ???, "count-lines-region", */
- KMETA|'<', gotobob, "beginning-of-buffer",
- /*TT KMETA|'@', ???, "mark-word", */
- /*MU KMETA|'[', ???, "backward-paragraph", */
- /*TT KMETA|'\\', ???, "delete-horizontal-space", */
- /*MU KMETA|']', ???, "forward-paragraph", */
- /*TT KMETA|'^', ???, "delete-indentation", */
- /*MU KMETA|'A', ???, "backward-sentence", */
- KMETA|'B', backword, "backward-word",
- KMETA|'C', capword, "capitalize-word",
- KMETA|'D', delfword, "kill-word",
- /*MU KMETA|'E', ???, "forward-sentence", */
- KMETA|'F', forwword, "forward-word",
- /*HT KMETA|'G', ???, "fill-region", */
- /*MU KMETA|'H', ???, "mark-paragraph", */
- /*DMX KMETA|'I', ???, "tab-to-tab-stop", */
- /*MU KMETA|'J', ???, "indent-new-comment-line", */
- KMETA|'L', lowerword, "downcase-word",
- /*EU KMETA|'M', ???, "back-to-indentation", */
- /*HT KMETA|'Q', ???, "fill-paragraph", */
- KMETA|'R', reposition, "move-to-window-line",
- /*ET KMETA|'T', ???, "transpose-words", */
- KMETA|'U', upperword, "upcase-word",
- KMETA|'V', backpage, "scroll-down",
- KMETA|'W', copyregion, "copy-region-as-kill",
- KMETA|'X', extend, "execute-extended-command",
- /*HDX KMETA|'Y', ???, "yank-pop", */
- /*MU KMETA|'Z', ???, "zap-to-char", */
- /*HT KMETA|'|', ???, "shell-command-on-region", */
- KMETA|'~', notmodified, "not-modified",
- KMETA|DEL, delbword, "backward-kill-word",
-
- /*
- ** These are unbound functions, callable by name.
- ** They are GNU compatible (to various degrees).
- */
-
-
- /* -1, ???, "append-next-kill", */
- /* -1, ???, "apropos", */
- -1, wallchart, "describe-bindings",
- /*MT -1, ???, "digit-argument", */
- -1, showversion, "emacs-version",
- -1, bindtokey, "global-set-key",
- -1, gotoline, "goto-line",
- -1, quit, "kill-emacs",
- -1, backsearch, "search-backward",
- -1, forwsearch, "search-forward",
- -1, selfinsert, "self-insert-command",
- -1, filename, "set-visited-file-name",
-
- /* These are duplicate names for GNU compatible functions,
- ** or incompatible commands I've left lying around for now.
- ** The old command names get used as args to keydup() in the
- ** various tty/xxx/ttykbd.c modules for function keys.
- */
-
- -1, backchar, "back-char",
- -1, backline, "back-line",
- -1, backpage, "back-page",
- -1, prevwind, "back-window",
- -1, mvdnwind, "down-window",
- -1, enlargewind, "enlarge-window",
- -1, ctlxe, "execute-macro",
- -1, forwchar, "forw-char",
- -1, forwline, "forw-line",
- -1, forwpage, "forw-page",
- -1, nextwind, "forw-window",
- -1, help, "help",
- -1, selfinsert, "ins-self",
- -1, killregion, "kill-region",
- -1, searchagain, "search-again",
- -1, setmark, "set-mark",
- -1, shrinkwind, "shrink-window",
- -1, mvupwind, "up-window",
- /*MT incorrect behaviour */
-
- };
-
- #define NKEY (sizeof(key) / sizeof(key[0]))
-
- /*
- * Symbol table lookup.
- * Return a pointer to the SYMBOL node, or NULL if
- * the symbol is not found.
- */
- SYMBOL *
- symlookup(cp)
- register char *cp;
- {
- register SYMBOL *sp;
-
- sp = symbol[symhash(cp)];
- while (sp != NULL) {
- if (strcmp(cp, sp->s_name) == 0)
- return (sp);
- sp = sp->s_symp;
- }
- return (NULL);
- }
-
- /*
- * Take a string, and compute the symbol table
- * bucket number. This is done by adding all of the characters
- * together, and taking the sum mod NSHASH. The string probably
- * should not contain any GR characters; if it does the "*cp"
- * may get a nagative number on some machines, and the "%"
- * will return a negative number!
- */
- symhash(cp)
- register char *cp;
- {
- register int c;
- register int n;
-
- n = 0;
- while ((c = *cp++) != 0)
- n += c;
- return (n % NSHASH);
- }
-
- /*
- * Build initial keymap. The funny keys
- * (commands, odd control characters) are mapped using
- * a big table and calls to "keyadd". The printing characters
- * are done with some do-it-yourself handwaving. The terminal
- * specific keymap initialization code is called at the
- * very end to finish up. All errors are fatal.
- */
- keymapinit()
- {
- register SYMBOL *sp;
- register KEY *kp;
- register int i;
- register int hash;
-
- for (i=0; i<NKEYS; ++i)
- binding[i] = NULL;
- for (kp = &key[0]; kp < &key[NKEY]; ++kp)
- keyadd(kp->k_key, kp->k_funcp, kp->k_name);
-
- /* Multiple bindings of standard commands */
-
- #ifdef DAVEB
- keydup(KCTRL|'Z', "scroll-down");
- #endif
- keydup(KCTLX|KCTRL|'G', "keyboard-quit");
- keydup(KMETA|KCTRL|'G', "keyboard-quit");
- keydup(KMETA|' ', "set-mark-command");
-
- /*
- * Self insert should be in hash table already, bound to -1.
- * Bind all printing chars without an explicit binding already.
- */
- if ((sp=symlookup("self-insert-command")) == NULL)
- abort();
- binding[ KCTRL|'I' ] = sp;
- for ( i = ' ' ; i < DEL ; ++i ) {
- if (binding[i] != NULL)
- continue;
- binding[i] = sp;
- ++sp->s_nkey;
- }
-
- ttykeymapinit();
- }
-
- /*
- * Create a new builtin function "name"
- * with function "funcp". If the "new" is a real
- * key, bind it as a side effect. All errors
- * are fatal.
- */
- keyadd(new, funcp, name)
- int (*funcp)();
- char *name;
- {
- register SYMBOL *sp;
- register int hash;
-
- if ((sp=(SYMBOL *)malloc(sizeof(SYMBOL))) == NULL)
- abort();
- hash = symhash(name);
- sp->s_symp = symbol[hash];
- symbol[hash] = sp;
- sp->s_nkey = 0;
- sp->s_name = name;
- sp->s_funcp = funcp;
- if (new >= 0) { /* Bind this key. */
- if (binding[new] != NULL)
- abort();
- binding[new] = sp;
- ++sp->s_nkey;
- }
- }
-
- /*
- * Bind key "new" to the existing routine "name".
- * If the routine doesn't exist, just give a warning.
- * It's no error to rebind a key.
- */
- keydup(new, name)
- register int new;
- char *name;
- {
- register SYMBOL *sp;
-
- if ( (sp=symlookup(name))==NULL )
- return;
-
- if( new >= 0 )
- binding[new] = sp;
-
- ++sp->s_nkey;
- }
-