home *** CD-ROM | disk | FTP | other *** search
- /*
- * Extended (M-X) commands.
- */
- #include "def.h"
-
- extern char MSG_not_now[];
- extern char MSG_func[];
- extern char MSG_unk_func[];
- extern char MSG_cmd_t_ex[];
- extern char MSG_unk_ext[];
- extern char MSG_d_b[];
- extern char MSG_unbd[];
- extern char MSG_bnd_to[];
- extern char MSG_ins_self[];
- extern char MSG_bnd_file[];
- extern char MSG_bld_wall[];
- extern char MSG_wall_head[];
- extern char MSG_beavrc[];
- extern char MSG_null[];
-
- #include "lintfunc.dec"
- #ifdef CUSTOMIZE
-
- char *flook();
-
- static char *bindnm =
- {0
- }; /* file name for customized key bindings */
- #endif
-
- /*
- * This function modifies the keyboard
- * binding table, by adjusting the entries in the
- * big "bindings" array. Most of the grief deals with the
- * prompting for additional arguments. This code does not
- * work right if there is a keyboard macro floating around.
- * Should be fixed.
- */
- bool bindtokey ()
- {
-
- register int s;
- register char *cp;
- register SYMBOL * sp;
- register int c;
- char xname[NXNAME];
- #ifdef CUSTOMIZE
- char xname2[NXNAME];
- FILE * bindf;
- #endif
-
- if (kbdmip != NULL || kbdmop != NULL)
- {
- writ_echo (MSG_not_now);
- return (FALSE);
- }
-
- if ((s = eread (MSG_func, xname, NXNAME, EFAUTO, NULL)) != TRUE)
- return (s);
- if ((sp = symlookup (xname)) == NULL)
- {
- writ_echo (MSG_unk_func);
- return (FALSE);
- }
-
- #ifdef CUSTOMIZE
- strcpy (xname2, xname);
- #endif
- eputc (' ');
- eputc ('K');
- eputc ('e');
- eputc ('y');
- eputc (':');
- eputc (' ');
- ttflush ();
- c = getkey (); /* Read key. */
- keyname (xname, c); /* Display keyname. */
- eputs (xname);
- ttflush ();
- if (binding[c] != NULL) /* Unbind old, and */
- --binding[c] -> s_nkey;
- binding[c] = sp; /* rebind new. */
- ++sp -> s_nkey;
- sp -> s_modify |= SBOUND; /* flag as altered key binding */
-
- return (TRUE);
- }
-
-
- /*
- * Extended command. Call the message line
- * routine to read in the command name and apply autocompletion
- * to it. When it comes back, look the name up in the symbol table
- * and run the command if it is found and has the right type.
- * Print an error if there is anything wrong.
- */
- char extend (f, n, k)
- {
-
- register SYMBOL * sp;
- register char s;
- char xname[NXNAME];
-
- if ((s = eread (MSG_cmd_t_ex, xname, NXNAME, EFNEW | EFAUTO, NULL)) != TRUE)
- return (s);
- if ((sp = symlookup (xname)) != NULL)
- return ((*sp -> s_funcp) (f, n, KRANDOM));
- writ_echo (MSG_unk_ext);
- return (ABORT);
- }
-
-
- /*
- * Read a key from the keyboard, and look it
- * up in the binding table. Display the name of the function
- * currently bound to the key. Say that the key is not bound
- * if it is indeed not bound, or if the type is not a
- * "builtin". This is a bit of overkill, because this is the
- * only kind of function there is.
- */
- bool help ()
- {
- register SYMBOL * sp;
- register int c;
- char b[20];
- char buf[80];
-
- writ_echo (MSG_d_b);
-
- c = getkey ();
- keyname (b, c);
- if ((sp = binding[c]) == NULL)
- {
- sprintf (buf, MSG_unbd, b);
- writ_echo (buf);
- }
- else
- {
- sprintf (buf, MSG_bnd_to, b, sp -> s_name);
- writ_echo (buf);
- }
- return (TRUE);
- }
-
- /*
- * Sort the lines in the buffer.
- */
- void sort_buf (b_ptr, cnt)
- BUFFER *b_ptr;
- int cnt;
- {
- LINE *lp1, *lp2;
- bool no_swap;
- int loop1, loop2;
-
- for (loop1 = cnt; loop1 > 0; loop1--)
- {
- no_swap = TRUE;
- lp1 = b_ptr -> b_linep -> l_fp; /* point to first line */
- lp2 = lp1 -> l_fp; /* point to next line */
- for (loop2 = 0; loop2 <= loop1; loop2++)
- {
- /* compare strings and swap if necessary */
- if (0 < strcmp (&lp1 -> l_text[HFUNCCOL], &lp2 -> l_text[HFUNCCOL]))
- {
- lp1 -> l_bp -> l_fp = lp2; /* get pointer to first string */
- lp2 -> l_fp -> l_bp = lp1; /* make it point to second string */
-
- lp1 -> l_fp = lp2 -> l_fp;
- lp2 -> l_bp = lp1 -> l_bp;
-
- lp1 -> l_bp = lp2;
- lp2 -> l_fp = lp1;
-
- lp2 -> l_file_offset = lp1 -> l_file_offset;
- lp1 -> l_file_offset = lp2 -> l_file_offset + lp2 -> l_used;
-
- no_swap = FALSE;
- }
- else
- {
- /* if no swap then advance both pointers */
- lp1 = lp2;
- }
- lp2 = lp1 -> l_fp;
- }
- /* quick exit if sort is finished sooner than expected */
- if (no_swap)
- {
- return;
- }
- }
- }
-
- /*
- * This function creates a table, listing all
- * of the command keys and their current bindings, and stores
- * the table in the standard pop-op buffer (the one used by the
- * directory list command, the buffer list command, etc.). This
- * lets the editor produce it's own wall chart. The bindings to
- * "ins-self" are only displayed if there is an argument.
- */
- char wallchart (f, n, k)
- {
-
- register char s;
- register int key, i, j;
- register SYMBOL * sp;
- register char *cp1;
- register char *cp2;
- char buf[64];
- WINDOW *wp;
-
- if ((s = bclear (blistp)) != TRUE)/* Clear it out. */
- return (s);
- i = 0;
- (void) strcpy (blistp -> b_fname, MSG_null);
- blistp -> b_flag = BFVIEW;
- writ_echo (MSG_bld_wall);
- sprintf (buf, MSG_wall_head);
- if (addline (buf) == FALSE)
- return;
- for (key = 0; key < NKEYS; ++key)
- {
- /* For all keys. */
- sp = binding[key];
- if (sp != NULL &&
- (f != FALSE || strcmp (sp -> s_name, MSG_ins_self) != 0))
- {
- cp1 = &buf[0];
- while (cp1 < &buf[HFUNCCOL])/* Goto column 3. */
- *cp1++ = ' ';
- if ((sp -> s_modify & SBOUND) == 0) /* comment out default binding */
- buf[0] = '#';
- cp2 = sp -> s_name; /* Add function name. */
- while (*cp1++ = *cp2++)
- ;
- cp1--;
- while (cp1 < &buf[HKEY])/* Goto column 32. */
- *cp1++ = ' ';
- keyname (&buf[HKEY], key);
- cp1 = &buf[strlen(buf)];
- while (cp1 < &buf[HKEYCODE])/* Goto column 50. */
- *cp1++ = ' ';
- sprintf (&buf[HKEYCODE], "%4X", key);
- if (addline (buf) == FALSE)
- break; /* lets go with what we have */
- i++;
- }
- }
-
- /* list unbound functions lest they get lost */
- for (j = 0; j < NSHASH; j++)
- {
- sp = symbol[j];
- while (sp != NULL)
- {
- if (sp -> s_nkey == 0)
- {
- cp1 = &buf[0];
- while (cp1 < &buf[HFUNCCOL])/* Goto column 3. */
- *cp1++ = ' ';
- buf[0] = '#';
- cp2 = sp -> s_name; /* Add function name. */
- while (*cp1++ = *cp2++)
- ;
- cp1--;
- while (cp1 < &buf[HENDCOL])
- *cp1++ = ' ';
- *cp1 = 0;
- i++;
- if (addline (buf) == FALSE)
- break; /* lets go with what we have */
- }
- sp = sp -> s_symp;
- }
- }
- sort_buf (blistp, i); /* sort buffer lines */
- popblist ();
- writ_echo (MSG_null);
- /* make new window the current window */
- wp = wheadp;
- while (wp != NULL)
- {
- if (wp -> w_bufp == blistp)
- {
- curwp = wp;
- curbp = wp -> w_bufp;
- return (TRUE);
- }
- wp = wp -> w_wndp;
- }
- return (TRUE);
- }
-
- /* check for BEAVFIL and read it in if found
- * - also, set local file variable for bindtokey for saving new defs
- * (this is some what of a hack as it only handles 'bindtokey' changes at
- * this time - also local file io !!!)
- */
- void check_extend (sfname)
-
- char *sfname; /* name of startup file (null if default) */
-
- {
- char *fname; /* resulting file name to execute */
- char rc_name[40]; /* fixed up name of rc file */
- char *term;
- char *getenv();
- register SYMBOL * sp;
- char funcname[NXNAME + 1];
- char keybind[NXNAME + 1];
- int keyval;
- FILE * bindf;
-
- /* look up the startup file */
- if ((sfname != NULL) && (*sfname != 0))
- fname = flook(sfname, TRUE);
- else
- {
- #ifdef UNIX
- /* hidden file under unix */
- strcpy (&rc_name[0], ".");
- strcpy (&rc_name[1], MSG_beavrc);
-
- if ((term = getenv("TERM")) != 0)
- {
- strcpy (&rc_name[strlen(rc_name)], ".");
- strcpy (&rc_name[strlen(rc_name)], term);
- }
- fname = flook(rc_name, TRUE);
- /* if fixed up name is not there then check original */
- if (fname == NULL)
- {
- /* hidden file under unix */
- strcpy (&rc_name[0], ".");
- strcpy (&rc_name[1], MSG_beavrc);
- fname = flook(rc_name, TRUE);
- }
- #else
- strcpy (rc_name, MSG_beavrc);
- fname = flook(rc_name, TRUE);
- #endif
- }
- /* if it isn't around, don't sweat it */
- if (fname == NULL)
- return;
-
- if (bindf = fopen(fname, "r"))
- {
- char buffr[80];
- char *buffp;
-
- buffp = buffr;
- while (fread (buffp++, sizeof(char), 1, bindf) == 1)
- {
- /* scanf is unhappy with commas */
- if (buffp[-1] == ',')
- buffp[-1] = '-';
-
- /* did we get a whole line */
- if (buffp[-1] == '\n')
- {
- *buffp = 0; /* terminate line */
- buffp = buffr;
- sscanf (buffr, "%s %s %x", funcname, keybind, &keyval);
- if ((buffr[0] == '#') || (keyval == 0))
- continue;
- if (sp = symlookup (funcname))
- {
- if (binding[keyval] != NULL)/* Unbind old, and */
- --binding[keyval] -> s_nkey;
- binding[keyval] = sp;/* rebind new. */
- ++sp -> s_nkey;
- sp -> s_modify |= SBOUND; /* flag as altered key binding */
- }
- }
- }
- fclose (bindf);
- }
- }
-
- /* Look up the existance of a file along the normal or PATH
- environment variable. Look first in the HOME directory if
- asked and possible
- */
-
- char *flook(fname, hflag)
-
- char *fname; /* base file name to search for */
- int hflag; /* Look in the HOME environment variable first? */
-
- {
- register char *home; /* path to home directory */
- register char *path; /* environmental PATH variable */
- register char *sp; /* pointer into path spec */
- register int i; /* index */
- static char fspec[128]; /* full path spec to search */
- char *getenv();
- FILE * bindf;
-
- if (hflag) {
- home = getenv("HOME");
- if (home != NULL) {
- /* build home dir file spec */
- strcpy(fspec, home);
- if (fspec[strlen(fspec) - 1] != '/')
- strcat(fspec, "/");
- strcat(fspec, fname);
-
- /* and try it out */
- if (bindf = fopen(fspec, "r"))
- {
- fclose(bindf);
- return(fspec);
- }
- }
- }
-
- /* always try the current directory first */
- if (bindf = fopen(fname, "r"))
- {
- fclose(bindf);
- return(fname);
- }
-
- /* get the PATH variable */
- path = getenv("PATH");
- if (path != NULL)
- while (*path) {
-
- /* build next possible file spec */
- sp = fspec;
- while (*path && (*path != PATHCHR))
- *sp++ = *path++;
-
- /* add a terminating dir separator if we need it */
- if (sp[-1] != SEPCHAR)
- *sp++ = SEPCHAR;
-
- *sp = 0;
- strcat(fspec, fname);
-
- /* and try it out */
- if (bindf = fopen(fspec, "r"))
- {
- fclose(bindf);
- return(fspec);
- }
-
- if (*path == PATHCHR)
- ++path;
- }
-
- return(NULL); /* no such luck */
- }
-
-
- /* interactive method for loading binding file
- * (uses above routine, obviously)
- */
- char load_extend ()
- {
-
- #ifdef CUSTOMIZE
- register char s;
- char fname[NFILEN];
-
- if ((s = ereply (MSG_bnd_file, fname, NFILEN, NULL)) != TRUE)
- return (s);
- check_extend (fname);
- writ_echo (okmsg);
- #endif
- return (TRUE);
- }
-
- int find_keyval (name)
- char *name;
- {
- SYMBOL * sp;
- int key;
-
- for (key = 0; key < NKEYS; ++key)
- {
- /* For all keys. */
- sp = binding[key];
- if (sp != NULL && (strcmp (sp -> s_name, name) == 0))
- return (key);
- }
- return (0);
- }
-