[BACK]Return to help.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/help.c, Revision 1.37

1.37    ! guenther    1: /*     $OpenBSD: help.c,v 1.36 2022/01/28 06:18:41 guenther Exp $      */
1.24      kjell       2:
                      3: /* This file is in the public domain. */
1.4       niklas      4:
1.3       millert     5: /*
1.12      mickey      6:  * Help functions for Mg 2
1.3       millert     7:  */
1.1       deraadt     8:
1.35      bcallah     9: #include <sys/queue.h>
                     10: #include <signal.h>
                     11: #include <stdio.h>
                     12: #include <string.h>
                     13:
1.1       deraadt    14: #include "def.h"
1.14      art        15: #include "funmap.h"
1.1       deraadt    16: #include "kbd.h"
                     17: #include "key.h"
                     18: #include "macro.h"
1.2       millert    19:
1.27      deraadt    20: static int     showall(struct buffer *, KEYMAP *, char *);
1.11      mickey     21: static int     findbind(KEYMAP *, PF, char *, size_t);
1.1       deraadt    22:
                     23: /*
1.2       millert    24:  * Read a key from the keyboard, and look it up in the keymap.
                     25:  * Display the name of the function currently bound to the key.
1.1       deraadt    26:  */
1.2       millert    27: int
1.22      db         28: desckey(int f, int n)
1.1       deraadt    29: {
1.3       millert    30:        KEYMAP  *curmap;
                     31:        PF       funct;
1.18      vincent    32:        int      c, m, i, num;
1.3       millert    33:        char    *pep;
1.28      kjell      34:        char     dprompt[80];
1.1       deraadt    35:
1.2       millert    36:        if (inmacro)
1.22      db         37:                return (TRUE);  /* ignore inside keyboard macro */
1.34      lum        38:
1.28      kjell      39:        num = strlcpy(dprompt, "Describe key briefly: ", sizeof(dprompt));
                     40:        if (num >= sizeof(dprompt))
                     41:                num = sizeof(dprompt) - 1;
                     42:        pep = dprompt + num;
1.2       millert    43:        key.k_count = 0;
                     44:        m = curbp->b_nmodes;
                     45:        curmap = curbp->b_modes[m]->p_map;
                     46:        for (;;) {
                     47:                for (;;) {
1.28      kjell      48:                        ewprintf("%s", dprompt);
1.2       millert    49:                        pep[-1] = ' ';
1.29      kjell      50:                        pep = getkeyname(pep, sizeof(dprompt) - (pep - dprompt),
1.11      mickey     51:                            key.k_chars[key.k_count++] = c = getkey(FALSE));
1.6       art        52:                        if ((funct = doscan(curmap, c, &curmap)) != NULL)
1.2       millert    53:                                break;
                     54:                        *pep++ = '-';
                     55:                        *pep = '\0';
                     56:                }
                     57:                if (funct != rescan)
                     58:                        break;
                     59:                if (ISUPPER(key.k_chars[key.k_count - 1])) {
                     60:                        funct = doscan(curmap,
1.6       art        61:                            TOLOWER(key.k_chars[key.k_count - 1]), &curmap);
1.5       art        62:                        if (funct == NULL) {
1.2       millert    63:                                *pep++ = '-';
                     64:                                *pep = '\0';
                     65:                                continue;
                     66:                        }
                     67:                        if (funct != rescan)
                     68:                                break;
                     69:                }
                     70: nextmode:
                     71:                if (--m < 0)
                     72:                        break;
                     73:                curmap = curbp->b_modes[m]->p_map;
                     74:                for (i = 0; i < key.k_count; i++) {
1.6       art        75:                        funct = doscan(curmap, key.k_chars[i], &curmap);
1.5       art        76:                        if (funct != NULL) {
1.2       millert    77:                                if (i == key.k_count - 1 && funct != rescan)
                     78:                                        goto found;
                     79:                                funct = rescan;
                     80:                                goto nextmode;
                     81:                        }
                     82:                }
1.1       deraadt    83:                *pep++ = '-';
                     84:                *pep = '\0';
                     85:        }
                     86: found:
1.7       art        87:        if (funct == rescan || funct == selfinsert)
1.2       millert    88:                ewprintf("%k is not bound to any function");
1.16      vincent    89:        else if ((pep = (char *)function_name(funct)) != NULL)
1.2       millert    90:                ewprintf("%k runs the command %s", pep);
                     91:        else
                     92:                ewprintf("%k is bound to an unnamed function");
1.22      db         93:        return (TRUE);
1.1       deraadt    94: }
                     95:
                     96: /*
1.2       millert    97:  * This function creates a table, listing all of the command
                     98:  * keys and their current bindings, and stores the table in the
1.36      guenther   99:  * *help* pop-up buffer.  This lets Mg produce its own wall chart.
1.1       deraadt   100:  */
1.2       millert   101: int
1.22      db        102: wallchart(int f, int n)
1.1       deraadt   103: {
1.3       millert   104:        int              m;
1.27      deraadt   105:        struct buffer           *bp;
1.1       deraadt   106:
                    107:        bp = bfind("*help*", TRUE);
1.2       millert   108:        if (bclear(bp) != TRUE)
1.3       millert   109:                /* clear it out */
1.22      db        110:                return (FALSE);
1.20      deraadt   111:        bp->b_flag |= BFREADONLY;
1.2       millert   112:        for (m = curbp->b_nmodes; m > 0; m--) {
1.8       art       113:                if ((addlinef(bp, "Local keybindings for mode %s:",
                    114:                                curbp->b_modes[m]->p_name) == FALSE) ||
                    115:                    (showall(bp, curbp->b_modes[m]->p_map, "") == FALSE) ||
1.2       millert   116:                    (addline(bp, "") == FALSE))
1.22      db        117:                        return (FALSE);
1.1       deraadt   118:        }
1.2       millert   119:        if ((addline(bp, "Global bindings:") == FALSE) ||
1.9       art       120:            (showall(bp, fundamental_map, "") == FALSE))
1.22      db        121:                return (FALSE);
1.32      kjell     122:        return (popbuftop(bp, WNONE));
1.1       deraadt   123: }
                    124:
1.2       millert   125: static int
1.27      deraadt   126: showall(struct buffer *bp, KEYMAP *map, char *prefix)
1.1       deraadt   127: {
1.22      db        128:        KEYMAP  *newmap;
1.30      kjell     129:        char     buf[80], keybuf[16];
1.22      db        130:        PF       fun;
                    131:        int      c;
1.1       deraadt   132:
1.2       millert   133:        if (addline(bp, "") == FALSE)
1.22      db        134:                return (FALSE);
1.8       art       135:
                    136:        /* XXX - 256 ? */
                    137:        for (c = 0; c < 256; c++) {
                    138:                fun = doscan(map, c, &newmap);
                    139:                if (fun == rescan || fun == selfinsert)
                    140:                        continue;
1.29      kjell     141:                getkeyname(buf, sizeof(buf), c);
1.30      kjell     142:                (void)snprintf(keybuf, sizeof(keybuf), "%s%s ", prefix, buf);
1.8       art       143:                if (fun == NULL) {
1.30      kjell     144:                        if (showall(bp, newmap, keybuf) == FALSE)
1.22      db        145:                                return (FALSE);
1.8       art       146:                } else {
1.31      kjell     147:                        if (addlinef(bp, "%-16s%s", keybuf,
1.8       art       148:                                    function_name(fun)) == FALSE)
1.22      db        149:                                return (FALSE);
1.1       deraadt   150:                }
                    151:        }
1.22      db        152:        return (TRUE);
1.1       deraadt   153: }
                    154:
1.2       millert   155: int
1.22      db        156: help_help(int f, int n)
1.1       deraadt   157: {
1.3       millert   158:        KEYMAP  *kp;
                    159:        PF       funct;
1.1       deraadt   160:
1.2       millert   161:        if ((kp = name_map("help")) == NULL)
1.22      db        162:                return (FALSE);
1.2       millert   163:        ewprintf("a b c: ");
                    164:        do {
1.6       art       165:                funct = doscan(kp, getkey(FALSE), NULL);
1.2       millert   166:        } while (funct == NULL || funct == help_help);
1.34      lum       167:
1.2       millert   168:        if (macrodef && macrocount < MAXMACRO)
                    169:                macro[macrocount - 1].m_funct = funct;
1.34      lum       170:
1.22      db        171:        return ((*funct)(f, n));
1.1       deraadt   172: }
                    173:
1.2       millert   174: int
1.22      db        175: apropos_command(int f, int n)
1.1       deraadt   176: {
1.27      deraadt   177:        struct buffer           *bp;
                    178:        struct list             *fnames, *el;
1.26      deraadt   179:        char             string[32];
1.1       deraadt   180:
1.26      deraadt   181:        if (eread("apropos: ", string, sizeof(string), EFNUL | EFNEW) == NULL)
1.22      db        182:                return (ABORT);
1.1       deraadt   183:        /* FALSE means we got a 0 character string, which is fine */
1.2       millert   184:        bp = bfind("*help*", TRUE);
                    185:        if (bclear(bp) == FALSE)
1.22      db        186:                return (FALSE);
1.8       art       187:
1.23      otto      188:        fnames = complete_function_list("");
1.8       art       189:        for (el = fnames; el != NULL; el = el->l_next) {
                    190:                char buf[32];
1.9       art       191:
1.8       art       192:                if (strstr(el->l_name, string) == NULL)
                    193:                        continue;
1.9       art       194:
1.8       art       195:                buf[0] = '\0';
1.11      mickey    196:                findbind(fundamental_map, name_function(el->l_name),
                    197:                    buf, sizeof(buf));
1.8       art       198:
                    199:                if (addlinef(bp, "%-32s%s", el->l_name,  buf) == FALSE) {
                    200:                        free_file_list(fnames);
1.22      db        201:                        return (FALSE);
1.2       millert   202:                }
1.1       deraadt   203:        }
1.8       art       204:        free_file_list(fnames);
1.32      kjell     205:        return (popbuftop(bp, WNONE));
1.1       deraadt   206: }
                    207:
1.8       art       208: static int
1.11      mickey    209: findbind(KEYMAP *map, PF fun, char *buf, size_t len)
1.1       deraadt   210: {
1.22      db        211:        KEYMAP  *newmap;
                    212:        PF       nfun;
1.30      kjell     213:        char     buf2[16], keybuf[16];
1.22      db        214:        int      c;
1.8       art       215:
                    216:        /* XXX - 256 ? */
                    217:        for (c = 0; c < 256; c++) {
                    218:                nfun = doscan(map, c, &newmap);
                    219:                if (nfun == fun) {
1.29      kjell     220:                        getkeyname(buf, len, c);
1.22      db        221:                        return (TRUE);
1.2       millert   222:                }
1.8       art       223:                if (nfun == NULL) {
1.11      mickey    224:                        if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) {
1.30      kjell     225:                                getkeyname(keybuf, sizeof(keybuf), c);
                    226:                                (void)snprintf(buf, len, "%s %s", keybuf, buf2);
1.22      db        227:                                return (TRUE);
1.2       millert   228:                        }
                    229:                }
1.1       deraadt   230:        }
1.22      db        231:        return (FALSE);
1.1       deraadt   232: }