/* * Name: MicroEMACS * Symbol table stuff. * Version: 29 * Last edit: 07-jun-86 * By: ajs@uk.ac.edinburgh.ecsvax * * Symbol tables, and keymap setup. * The terminal specific parts of building the * keymap has been moved to a better place. */ #include "def.h" #define DIRLIST 0 /* Disarmed! */ /* * Defined by "main.c". */ extern int ctrlg(); /* Abort out of things */ extern int quit(); /* Quit */ extern int ctlxlp(); /* Begin macro */ extern int ctlxrp(); /* End macro */ extern int ctlxe(); /* Execute macro */ extern int jeffexit(); /* Jeff Lomicka style exit. */ extern int showversion(); /* Show version numbers, etc. */ /* * 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 "display.c". */ extern int readmsg(); /* Read next line of message. */ /* * 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. */ KEY key[] = { KCTRL|'@', setmark, "set-mark", KCTRL|'A', gotobol, "goto-bol", KCTRL|'B', backchar, "back-char", KCTRL|'C', spawncli, "spawn-cli", KCTRL|'D', forwdel, "forw-del-char", KCTRL|'E', gotoeol, "goto-eol", KCTRL|'F', forwchar, "forw-char", KCTRL|'G', ctrlg, "abort", KCTRL|'H', backdel, "back-del-char", KCTRL|'I', selfinsert, "ins-self", KCTRL|'J', indent, "ins-nl-and-indent", KCTRL|'K', killline, "kill-line", KCTRL|'L', refresh, "refresh", KCTRL|'M', newline, "ins-nl", KCTRL|'N', forwline, "forw-line", KCTRL|'O', openline, "ins-nl-and-backup", KCTRL|'P', backline, "back-line", KCTRL|'Q', quote, "quote", KCTRL|'R', queryrepl, "query-replace", KCTRL|'S', forwisearch, "forw-i-search", KCTRL|'T', twiddle, "twiddle", KCTRL|'V', forwpage, "forw-page", KCTRL|'W', killregion, "kill-region", KCTRL|'Y', yank, "yank", KCTRL|'Z', filesave, "file-save", KCTLX|KCTRL|'B',listbuffers, "display-buffers", KCTLX|KCTRL|'C',quit, "quit", #if DIRLIST KCTLX|KCTRL|'D',dirlist, "display-directory", #endif KCTLX|KCTRL|'F',filename, "set-file-name", KCTLX|KCTRL|'L',lowerregion, "lower-region", KCTLX|KCTRL|'N',mvdnwind, "down-window", KCTLX|KCTRL|'O',deblank, "del-blank-lines", KCTLX|KCTRL|'P',mvupwind, "up-window", KCTLX|KCTRL|'R',fileread, "file-read", KCTLX|KCTRL|'S',filesave, "file-save", KCTLX|KCTRL|'U',upperregion, "upper-region", KCTLX|KCTRL|'V',filevisit, "file-visit", KCTLX|KCTRL|'W',filewrite, "file-write", KCTLX|KCTRL|'X',swapmark, "swap-dot-and-mark", KCTLX|KCTRL|'Z',shrinkwind, "shrink-window", KCTLX|'=', showcpos, "display-position", KCTLX|'(', ctlxlp, "start-macro", KCTLX|')', ctlxrp, "end-macro", KCTLX|'1', onlywind, "only-window", KCTLX|'2', splitwind, "split-window", KCTLX|'B', usebuffer, "use-buffer", KCTLX|'E', ctlxe, "execute-macro", KCTLX|'G', gotoline, "goto-line", KCTLX|'K', killbuffer, "kill-buffer", KCTLX|'N', nextwind, "forw-window", KCTLX|'P', prevwind, "back-window", KCTLX|'Z', enlargewind, "enlarge-window", KMETA|KCTRL|'H',delbword, "back-del-word", KMETA|KCTRL|'R',readmsg, "display-message", KMETA|KCTRL|'V',showversion, "display-version", KMETA|'!', reposition, "reposition-window", KMETA|'>', gotoeob, "goto-eob", KMETA|'<', gotobob, "goto-bob", KMETA|'%', queryrepl, "query-replace", KMETA|'B', backword, "back-word", KMETA|'C', capword, "cap-word", KMETA|'D', delfword, "forw-del-word", KMETA|'F', forwword, "forw-word", KMETA|'L', lowerword, "lower-word", KMETA|'R', backsearch, "back-search", KMETA|'S', forwsearch, "forw-search", KMETA|'U', upperword, "upper-word", KMETA|'V', backpage, "back-page", KMETA|'W', copyregion, "copy-region", KMETA|'X', extend, "extended-command", -1, searchagain, "search-again", -1, help, "help", -1, wallchart, "display-bindings", -1, bindtokey, "bind-to-key" }; #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; ik_key, kp->k_funcp, kp->k_name); keydup(KCTLX|KCTRL|'G', "abort"); keydup(KMETA|KCTRL|'G', "abort"); keydup(0x7F, "back-del-char"); keydup(KCTLX|'S', "forw-i-search"); keydup(KMETA|'.', "set-mark"); keydup(KMETA|'Q', "quote"); keydup(KMETA|0x7F, "back-del-word"); keydup(KMETA|'A', "search-again"); /* * Should be bound by "tab" already. */ if ((sp=symlookup("ins-self")) == NULL) abort(); for (i=0x20; i<0x7F; ++i) { if (binding[i] != NULL) abort(); 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 name cannot be found, * or the key is already bound, abort. */ keydup(new, name) register int new; char *name; { register SYMBOL *sp; if (binding[new]!=NULL || (sp=symlookup(name))==NULL) abort(); binding[new] = sp; ++sp->s_nkey; }