home *** CD-ROM | disk | FTP | other *** search
- /* Help functions for MicroGnuEmacs 3 */
-
- #include "no_help.h"
-
- #ifndef NO_HELP
-
- #include "def.h"
- #include "buffer.h"
- #include "window.h"
- #include "kbd.h"
- #include "key.h"
- #include "no_macro.h"
-
- #ifndef NO_MACRO
- #include "macro.h"
- #endif
-
- #ifdef ANSI
- #include <string.h>
- #endif
-
- static int showall
- PROTO((char *ind, struct keymap * map));
-
- extern int rescan();
- static VOID bindfound
- PROTO((VOID));
- static VOID findbind
- PROTO((struct function *, char *, struct keymap *));
-
- /*
- * MAXKEYLEN is the offset into the line after key names in
- * describe-bindings. Default is 32; if you have keynames longer than 32
- * chars, set it to something longer than the longest of them (a multiple of
- * 8 is suggested).
- */
- #ifndef MAXKEYLEN
- #define MAXKEYLEN 32
- #endif
-
- /*
- * Read a key from the keyboard, and look it up in the keymap. Display the
- * name of the function currently bound to the key.
- */
- /* ARGSUSED */
- desckey(f, n)
- {
- register struct keymap *curmap;
- register struct function *funct;
- register char *pep;
- char prompt[80];
- int c;
- int m;
- int i;
-
- (VOID) strcpy(prompt, "Describe key briefly: ");
- pep = prompt + strlen(prompt);
- key.k_count = 0;
- m = curbp->b_nmodes;
- curmap = curbp->b_modes[m]->p_map;
- for (;;) {
- for (;;) {
- ewprintf("%s", prompt);
- pep[-1] = ' ';
- pep = keyname(pep, key.k_chars[key.k_count++] = c = getkey(DISSCR));
- if ((funct = doscan(curmap, c))->f_type != F_PREFIX)
- break;
- *pep++ = '-';
- *pep = '\0';
- curmap = (struct keymap *) funct->f_pref;
- }
- if (funct->f_funcp != rescan
- #ifndef NO_MACRO
- || funct->f_type == F_MACRO
- #endif
- )
- break;
- if (ISUPPER(key.k_chars[key.k_count - 1])) {
- funct = doscan(curmap, TOLOWER(key.k_chars[key.k_count - 1]));
- if (funct->f_type == F_PREFIX) {
- *pep++ = '-';
- *pep = '\0';
- curmap = (struct keymap *) funct->f_pref;
- continue;
- }
- if (funct->f_funcp != rescan
- #ifndef NO_MACRO
- || funct->f_type == F_MACRO
- #endif
- )
- break;
- }
- nextmode:
- if (--m < 0)
- break;
- curmap = curbp->b_modes[m]->p_map;
- for (i = 0; i < key.k_count; i++) {
- funct = doscan(curmap, key.k_chars[i]);
- if (funct->f_type != F_PREFIX) {
- if (i == key.k_count - 1
- && (funct->f_funcp != rescan
- #ifndef NO_MACRO
- || funct->f_type == F_MACRO
- #endif
- ))
- goto found;
- funct = NULL;
- goto nextmode;
- }
- curmap = (struct keymap *) funct->f_pref;
- }
- *pep++ = '-';
- *pep = '\0';
- }
- found:
- #ifndef NO_MACRO
- if (funct->f_type == F_MACRO)
- ewprintf("%k runs the macro %s",
- ((struct macro *) funct->f_macro)->m_name);
- else
- #endif
- if (funct->f_funcp == rescan || funct == NULL)
- ewprintf("%k is not bound to any function");
- else if ((pep = function_name(funct->f_funcp)) != NULL)
- ewprintf("%k runs the command %s", pep);
- else
- ewprintf("%k is bound to an unnamed function");
- epresf = TRUE;
- return TRUE;
- }
-
- /*
- * This function creates a table, listing all of the command keys and their
- * current bindings, and stores the table in the *help* pop-up buffer. This
- * lets MicroGnuEMACS produce it's own wall chart.
- */
- static struct buffer *bp;
- static char buf[80]; /* used by showall and findbind */
-
- /* ARGSUSED */
- wallchart(f, n)
- {
- int m;
- static char locbind[80] = "Local keybindings for mode ";
-
- if ((bp = bfind("*help*", TRUE)) == NULL)
- return FALSE;
- bp->b_flag &= ~BFCHG; /* don't ask, just */
- if (bclear(bp) != TRUE)
- return FALSE; /* clear it out. */
- for (m = curbp->b_nmodes; m > 0; m--) {
- (VOID) strcat(locbind, curbp->b_modes[m]->p_name);
- (VOID) strcat(locbind, ":");
- if ((addline(bp, locbind) == FALSE) ||
- (showall(buf, curbp->b_modes[m]->p_map) == FALSE) ||
- (addline(bp, "") == FALSE))
- return FALSE;
- }
- if ((addline(bp, "Global bindings:") == FALSE) ||
- (showall(buf, map_table[0].p_map) == FALSE))
- return FALSE;
- return popbuftop(bp);
- }
-
- static int
- showall(ind, map)
- char *ind;
- struct keymap *map;
- {
- register struct map_element *ele;
- register int i;
- struct function *functp;
- char *cp;
- char *cp2;
- int last;
-
- if (addline(bp, "") == FALSE)
- return FALSE;
- last = -1;
- for (ele = &map->map_element[0];
- ele < &map->map_element[map->map_num];
- ele++) {
- /*
- * Currently, map_default _must_ be a CFUNCT. May change
- * later
- */
- if (map->map_default->f_funcp != rescan && ++last < ele->k_base) {
- cp = keyname(ind, last);
- if (last < ele->k_base - 1) {
- (VOID) strcpy(cp, " .. ");
- cp = keyname(cp + 4, ele->k_base - 1);
- }
- do {
- *cp++ = ' ';
- } while (cp < &buf[MAXKEYLEN]);
- (VOID) strcpy(cp, function_name(map->map_default->f_funcp));
- if (addline(bp, buf) == FALSE)
- return FALSE;
- }
- last = ele->k_num;
- for (i = ele->k_base; i <= last; i++) {
- functp = &(ele->k_entry[i - ele->k_base]);
- cp2 = NULL;
- if (functp->f_type == F_PREFIX)
- cp2 = map_name((struct keymap *) functp->f_pref);
- #ifndef NO_MACRO
- else if (functp->f_type == F_MACRO)
- cp2 = ((struct macro *) functp->f_macro)->m_name;
- #endif
- else if (functp->f_funcp != rescan)
- cp2 = function_name(functp->f_funcp);
- if (cp2 != NULL) {
- cp = keyname(ind, i);
- do {
- *cp++ = ' ';
- } while (cp < &buf[MAXKEYLEN]);
- *cp = '\0';
- (VOID) strcpy(cp, cp2);
- if (addline(bp, buf) == FALSE)
- return FALSE;
- }
- }
- }
-
- for (ele = &map->map_element[0];
- ele < &map->map_element[map->map_num];
- ele++) {
- for (i = ele->k_base; i <= ele->k_num; i++) {
- if (ele->k_entry[i - ele->k_base].f_type == F_PREFIX) {
- cp = keyname(ind, i);
- *cp++ = ' ';
- if (showall(cp, (struct keymap *) ele->k_entry[i - ele->k_base].f_pref) == FALSE)
- return FALSE;
- }
- }
- }
- return TRUE;
- }
-
- help_help(f, n)
- int f, n;
- {
- struct keymap *kp;
- struct function *funct;
-
- if ((kp = name_map("help")) == NULL)
- return FALSE;
- ewprintf("a b c: ");
- epresf = ERASE;
- do {
- funct = doscan(kp, getkey(DISSCR));
- } while (funct->f_type != F_CFUNCT || funct->f_funcp == help_help);
- return (*funct->f_funcp) (f, n);
- }
-
- static char buf2[128];
- static char *buf2p;
-
- /* ARGSUSED */
- apropos_command(f, n)
- int f, n;
- {
- register char *cp1;
- register int slen;
- #ifndef NO_MACRO
- extern struct macro kbdmacro;
- register struct macro *mac;
- #endif
- char string[NMACN];
- struct functnames *fnp;
- struct function tmp;
- struct buffer *bp;
-
- if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
- return ABORT;
- /* FALSE means we got a 0 character string, which is fine */
- if ((bp = bfind("*help*", TRUE)) == NULL)
- return FALSE;
- bp->b_flag &= ~BFCHG;
- if (bclear(bp) == FALSE)
- return FALSE;
- tmp.f_type = F_CFUNCT;
- slen = strlen(string);
- for (fnp = &functnames[0]; fnp < &functnames[nfunct]; fnp++) {
- for (cp1 = fnp->n_name; *cp1; cp1++)
- if (strncmp(cp1, string, slen) == 0) {
- (VOID) strcpy(buf2, fnp->n_name);
- buf2p = &buf2[strlen(buf2)];
- tmp.f_funcp = fnp->n_funct;
- findbind(&tmp, buf, map_table[0].p_map);
- if (addline(bp, buf2) == FALSE)
- return FALSE;
- break;
- }
- }
- #ifndef NO_MACRO
- tmp.f_type = F_MACRO;
- for (mac = kbdmacro.m_macp; mac; mac = mac->m_macp) {
- for (cp1 = mac->m_name; *cp1; cp1++) {
- if (strncmp(cp1, string, slen) == 0) {
- (VOID) strcpy(buf2, mac->m_name);
- buf2p = &buf2[strlen(buf2)];
- tmp.f_macro = (int (*) ()) mac;
- findbind(&tmp, buf, map_table[0].p_map);
- if (addline(bp, buf2) == FALSE)
- return FALSE;
- break;
- }
- }
- }
- #endif
- return popbuftop(bp);
- }
-
- static VOID
- findbind(funct, ind, map)
- struct function *funct;
- char *ind;
- struct keymap *map;
- {
- register struct map_element *ele;
- register int i;
- char *cp;
- int last;
-
- last = -1;
- for (ele = &map->map_element[0];
- ele < &map->map_element[map->map_num];
- ele++) {
- /*
- * Cheating - we test equality on the union by testing one of
- * the elements. They are all pointers, but have different
- * types. If someone with a processor that cares about this
- * objects, we'll have to spell it out longhand. Bleah.
- */
- if (map->map_default->f_type == funct->f_type
- && map->map_default->f_funcp == funct->f_funcp && ++last < ele->k_base) {
- cp = keyname(ind, last);
- if (last < ele->k_base - 1) {
- (VOID) strcpy(cp, " .. ");
- (VOID) keyname(cp + 4, ele->k_base - 1);
- }
- bindfound();
- }
- last = ele->k_num;
- for (i = ele->k_base; i <= last; i++) {
- if (ele->k_entry[i - ele->k_base].f_type == funct->f_type
- && funct->f_funcp == ele->k_entry[i - ele->k_base].f_funcp) {
- (VOID) keyname(ind, i);
- bindfound();
- }
- }
- }
- for (ele = &map->map_element[0];
- ele < &map->map_element[map->map_num];
- ele++) {
- for (i = ele->k_base; i <= ele->k_num; i++) {
- if (ele->k_entry[i - ele->k_base].f_type == F_PREFIX) {
- cp = keyname(ind, i);
- *cp++ = ' ';
- findbind(funct, cp, (struct keymap *) ele->k_entry[i - ele->k_base].f_pref);
- }
- }
- }
- }
-
- static VOID
- bindfound()
- {
-
- if (buf2p < &buf2[32]) {
- do {
- *buf2p++ = ' ';
- } while (buf2p < &buf2[32]);
- } else {
- *buf2p++ = ',';
- *buf2p++ = ' ';
- }
- (VOID) strcpy(buf2p, buf);
- buf2p += strlen(buf);
- }
- #else
- #include "nullfile.h"
- #endif
-