home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d352 / mg.lha / MG / src.LZH / mg / help.c < prev    next >
C/C++ Source or Header  |  1990-05-23  |  9KB  |  385 lines

  1. /* Help functions for MicroGnuEmacs 3 */
  2.  
  3. #include "no_help.h"
  4.  
  5. #ifndef NO_HELP
  6.  
  7. #include "def.h"
  8. #include "buffer.h"
  9. #include "window.h"
  10. #include "kbd.h"
  11. #include "key.h"
  12. #include "no_macro.h"
  13.  
  14. #ifndef    NO_MACRO
  15. #include "macro.h"
  16. #endif
  17.  
  18. #ifdef ANSI
  19. #include <string.h>
  20. #endif
  21.  
  22. static int showall 
  23. PROTO((char *ind, struct keymap * map));
  24.  
  25. extern int      rescan();
  26. static VOID bindfound 
  27. PROTO((VOID));
  28. static VOID findbind 
  29. PROTO((struct function *, char *, struct keymap *));
  30.  
  31. /*
  32.  * MAXKEYLEN is the offset into the line after key names in
  33.  * describe-bindings. Default is 32; if you have keynames longer than 32
  34.  * chars, set it to something longer than the longest of them (a multiple of
  35.  * 8 is suggested). 
  36.  */
  37. #ifndef    MAXKEYLEN
  38. #define    MAXKEYLEN    32
  39. #endif
  40.  
  41. /*
  42.  * Read a key from the keyboard, and look it up in the keymap.  Display the
  43.  * name of the function currently bound to the key. 
  44.  */
  45. /* ARGSUSED */
  46. desckey(f, n)
  47. {
  48.     register struct keymap *curmap;
  49.     register struct function *funct;
  50.     register char  *pep;
  51.     char            prompt[80];
  52.     int             c;
  53.     int             m;
  54.     int             i;
  55.  
  56.     (VOID) strcpy(prompt, "Describe key briefly: ");
  57.     pep = prompt + strlen(prompt);
  58.     key.k_count = 0;
  59.     m = curbp->b_nmodes;
  60.     curmap = curbp->b_modes[m]->p_map;
  61.     for (;;) {
  62.         for (;;) {
  63.             ewprintf("%s", prompt);
  64.             pep[-1] = ' ';
  65.             pep = keyname(pep, key.k_chars[key.k_count++] = c = getkey(DISSCR));
  66.             if ((funct = doscan(curmap, c))->f_type != F_PREFIX)
  67.                 break;
  68.             *pep++ = '-';
  69.             *pep = '\0';
  70.             curmap = (struct keymap *) funct->f_pref;
  71.         }
  72.         if (funct->f_funcp != rescan
  73. #ifndef    NO_MACRO
  74.             || funct->f_type == F_MACRO
  75. #endif
  76.             )
  77.             break;
  78.         if (ISUPPER(key.k_chars[key.k_count - 1])) {
  79.             funct = doscan(curmap, TOLOWER(key.k_chars[key.k_count - 1]));
  80.             if (funct->f_type == F_PREFIX) {
  81.                 *pep++ = '-';
  82.                 *pep = '\0';
  83.                 curmap = (struct keymap *) funct->f_pref;
  84.                 continue;
  85.             }
  86.             if (funct->f_funcp != rescan
  87. #ifndef    NO_MACRO
  88.                 || funct->f_type == F_MACRO
  89. #endif
  90.                 )
  91.                 break;
  92.         }
  93. nextmode:
  94.         if (--m < 0)
  95.             break;
  96.         curmap = curbp->b_modes[m]->p_map;
  97.         for (i = 0; i < key.k_count; i++) {
  98.             funct = doscan(curmap, key.k_chars[i]);
  99.             if (funct->f_type != F_PREFIX) {
  100.                 if (i == key.k_count - 1
  101.                     && (funct->f_funcp != rescan
  102. #ifndef    NO_MACRO
  103.                     || funct->f_type == F_MACRO
  104. #endif
  105.                     ))
  106.                     goto found;
  107.                 funct = NULL;
  108.                 goto nextmode;
  109.             }
  110.             curmap = (struct keymap *) funct->f_pref;
  111.         }
  112.         *pep++ = '-';
  113.         *pep = '\0';
  114.     }
  115. found:
  116. #ifndef NO_MACRO
  117.     if (funct->f_type == F_MACRO)
  118.         ewprintf("%k runs the macro %s",
  119.              ((struct macro *) funct->f_macro)->m_name);
  120.     else
  121. #endif
  122.     if (funct->f_funcp == rescan || funct == NULL)
  123.         ewprintf("%k is not bound to any function");
  124.     else if ((pep = function_name(funct->f_funcp)) != NULL)
  125.         ewprintf("%k runs the command %s", pep);
  126.     else
  127.         ewprintf("%k is bound to an unnamed function");
  128.     epresf = TRUE;
  129.     return TRUE;
  130. }
  131.  
  132. /*
  133.  * This function creates a table, listing all of the command keys and their
  134.  * current bindings, and stores the table in the *help* pop-up buffer.  This
  135.  * lets MicroGnuEMACS produce it's own wall chart. 
  136.  */
  137. static struct buffer *bp;
  138. static char     buf[80];    /* used by showall and findbind */
  139.  
  140. /* ARGSUSED */
  141. wallchart(f, n)
  142. {
  143.     int             m;
  144.     static char     locbind[80] = "Local keybindings for mode ";
  145.  
  146.     if ((bp = bfind("*help*", TRUE)) == NULL)
  147.         return FALSE;
  148.     bp->b_flag &= ~BFCHG;    /* don't ask, just     */
  149.     if (bclear(bp) != TRUE)
  150.         return FALSE;    /* clear it out.     */
  151.     for (m = curbp->b_nmodes; m > 0; m--) {
  152.         (VOID) strcat(locbind, curbp->b_modes[m]->p_name);
  153.         (VOID) strcat(locbind, ":");
  154.         if ((addline(bp, locbind) == FALSE) ||
  155.             (showall(buf, curbp->b_modes[m]->p_map) == FALSE) ||
  156.             (addline(bp, "") == FALSE))
  157.             return FALSE;
  158.     }
  159.     if ((addline(bp, "Global bindings:") == FALSE) ||
  160.         (showall(buf, map_table[0].p_map) == FALSE))
  161.         return FALSE;
  162.     return popbuftop(bp);
  163. }
  164.  
  165. static int
  166. showall(ind, map)
  167.     char           *ind;
  168.     struct keymap  *map;
  169. {
  170.     register struct map_element *ele;
  171.     register int    i;
  172.     struct function *functp;
  173.     char           *cp;
  174.     char           *cp2;
  175.     int             last;
  176.  
  177.     if (addline(bp, "") == FALSE)
  178.         return FALSE;
  179.     last = -1;
  180.     for (ele = &map->map_element[0];
  181.          ele < &map->map_element[map->map_num];
  182.          ele++) {
  183.         /*
  184.          * Currently, map_default _must_ be a CFUNCT. May change
  185.          * later 
  186.          */
  187.         if (map->map_default->f_funcp != rescan && ++last < ele->k_base) {
  188.             cp = keyname(ind, last);
  189.             if (last < ele->k_base - 1) {
  190.                 (VOID) strcpy(cp, " .. ");
  191.                 cp = keyname(cp + 4, ele->k_base - 1);
  192.             }
  193.             do {
  194.                 *cp++ = ' ';
  195.             } while (cp < &buf[MAXKEYLEN]);
  196.             (VOID) strcpy(cp, function_name(map->map_default->f_funcp));
  197.             if (addline(bp, buf) == FALSE)
  198.                 return FALSE;
  199.         }
  200.         last = ele->k_num;
  201.         for (i = ele->k_base; i <= last; i++) {
  202.             functp = &(ele->k_entry[i - ele->k_base]);
  203.             cp2 = NULL;
  204.             if (functp->f_type == F_PREFIX)
  205.                 cp2 = map_name((struct keymap *) functp->f_pref);
  206. #ifndef    NO_MACRO
  207.             else if (functp->f_type == F_MACRO)
  208.                 cp2 = ((struct macro *) functp->f_macro)->m_name;
  209. #endif
  210.             else if (functp->f_funcp != rescan)
  211.                 cp2 = function_name(functp->f_funcp);
  212.             if (cp2 != NULL) {
  213.                 cp = keyname(ind, i);
  214.                 do {
  215.                     *cp++ = ' ';
  216.                 } while (cp < &buf[MAXKEYLEN]);
  217.                 *cp = '\0';
  218.                 (VOID) strcpy(cp, cp2);
  219.                 if (addline(bp, buf) == FALSE)
  220.                     return FALSE;
  221.             }
  222.         }
  223.     }
  224.  
  225.     for (ele = &map->map_element[0];
  226.          ele < &map->map_element[map->map_num];
  227.          ele++) {
  228.         for (i = ele->k_base; i <= ele->k_num; i++) {
  229.             if (ele->k_entry[i - ele->k_base].f_type == F_PREFIX) {
  230.                 cp = keyname(ind, i);
  231.                 *cp++ = ' ';
  232.                 if (showall(cp, (struct keymap *) ele->k_entry[i - ele->k_base].f_pref) == FALSE)
  233.                     return FALSE;
  234.             }
  235.         }
  236.     }
  237.     return TRUE;
  238. }
  239.  
  240. help_help(f, n)
  241.     int             f, n;
  242. {
  243.     struct keymap  *kp;
  244.     struct function *funct;
  245.  
  246.     if ((kp = name_map("help")) == NULL)
  247.         return FALSE;
  248.     ewprintf("a b c: ");
  249.     epresf = ERASE;
  250.     do {
  251.         funct = doscan(kp, getkey(DISSCR));
  252.     } while (funct->f_type != F_CFUNCT || funct->f_funcp == help_help);
  253.     return (*funct->f_funcp) (f, n);
  254. }
  255.  
  256. static char     buf2[128];
  257. static char    *buf2p;
  258.  
  259. /* ARGSUSED */
  260. apropos_command(f, n)
  261.     int             f, n;
  262. {
  263.     register char  *cp1;
  264.     register int    slen;
  265. #ifndef    NO_MACRO
  266.     extern struct macro kbdmacro;
  267.     register struct macro *mac;
  268. #endif
  269.     char            string[NMACN];
  270.     struct functnames *fnp;
  271.     struct function tmp;
  272.     struct buffer  *bp;
  273.  
  274.     if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
  275.         return ABORT;
  276.     /* FALSE means we got a 0 character string, which is fine */
  277.     if ((bp = bfind("*help*", TRUE)) == NULL)
  278.         return FALSE;
  279.     bp->b_flag &= ~BFCHG;
  280.     if (bclear(bp) == FALSE)
  281.         return FALSE;
  282.     tmp.f_type = F_CFUNCT;
  283.     slen = strlen(string);
  284.     for (fnp = &functnames[0]; fnp < &functnames[nfunct]; fnp++) {
  285.         for (cp1 = fnp->n_name; *cp1; cp1++)
  286.             if (strncmp(cp1, string, slen) == 0) {
  287.                 (VOID) strcpy(buf2, fnp->n_name);
  288.                 buf2p = &buf2[strlen(buf2)];
  289.                 tmp.f_funcp = fnp->n_funct;
  290.                 findbind(&tmp, buf, map_table[0].p_map);
  291.                 if (addline(bp, buf2) == FALSE)
  292.                     return FALSE;
  293.                 break;
  294.             }
  295.     }
  296. #ifndef    NO_MACRO
  297.     tmp.f_type = F_MACRO;
  298.     for (mac = kbdmacro.m_macp; mac; mac = mac->m_macp) {
  299.         for (cp1 = mac->m_name; *cp1; cp1++) {
  300.             if (strncmp(cp1, string, slen) == 0) {
  301.                 (VOID) strcpy(buf2, mac->m_name);
  302.                 buf2p = &buf2[strlen(buf2)];
  303.                 tmp.f_macro = (int (*) ()) mac;
  304.                 findbind(&tmp, buf, map_table[0].p_map);
  305.                 if (addline(bp, buf2) == FALSE)
  306.                     return FALSE;
  307.                 break;
  308.             }
  309.         }
  310.     }
  311. #endif
  312.     return popbuftop(bp);
  313. }
  314.  
  315. static          VOID
  316. findbind(funct, ind, map)
  317.     struct function *funct;
  318.     char           *ind;
  319.     struct keymap  *map;
  320. {
  321.     register struct map_element *ele;
  322.     register int    i;
  323.     char           *cp;
  324.     int             last;
  325.  
  326.     last = -1;
  327.     for (ele = &map->map_element[0];
  328.          ele < &map->map_element[map->map_num];
  329.          ele++) {
  330.         /*
  331.          * Cheating - we test equality on the union by testing one of
  332.          * the elements. They are all pointers, but have different
  333.          * types. If someone with a processor that cares about this
  334.          * objects, we'll have to spell it out longhand. Bleah. 
  335.          */
  336.         if (map->map_default->f_type == funct->f_type
  337.             && map->map_default->f_funcp == funct->f_funcp && ++last < ele->k_base) {
  338.             cp = keyname(ind, last);
  339.             if (last < ele->k_base - 1) {
  340.                 (VOID) strcpy(cp, " .. ");
  341.                 (VOID) keyname(cp + 4, ele->k_base - 1);
  342.             }
  343.             bindfound();
  344.         }
  345.         last = ele->k_num;
  346.         for (i = ele->k_base; i <= last; i++) {
  347.             if (ele->k_entry[i - ele->k_base].f_type == funct->f_type
  348.                 && funct->f_funcp == ele->k_entry[i - ele->k_base].f_funcp) {
  349.                 (VOID) keyname(ind, i);
  350.                 bindfound();
  351.             }
  352.         }
  353.     }
  354.     for (ele = &map->map_element[0];
  355.          ele < &map->map_element[map->map_num];
  356.          ele++) {
  357.         for (i = ele->k_base; i <= ele->k_num; i++) {
  358.             if (ele->k_entry[i - ele->k_base].f_type == F_PREFIX) {
  359.                 cp = keyname(ind, i);
  360.                 *cp++ = ' ';
  361.                 findbind(funct, cp, (struct keymap *) ele->k_entry[i - ele->k_base].f_pref);
  362.             }
  363.         }
  364.     }
  365. }
  366.  
  367. static          VOID
  368. bindfound()
  369. {
  370.  
  371.     if (buf2p < &buf2[32]) {
  372.         do {
  373.             *buf2p++ = ' ';
  374.         } while (buf2p < &buf2[32]);
  375.     } else {
  376.         *buf2p++ = ',';
  377.         *buf2p++ = ' ';
  378.     }
  379.     (VOID) strcpy(buf2p, buf);
  380.     buf2p += strlen(buf);
  381. }
  382. #else
  383. #include "nullfile.h"
  384. #endif
  385.