[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.30

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