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

1.4     ! niklas      1: /*     $OpenBSD$       */
        !             2:
1.3       millert     3: /*
                      4:  * Help functions for Mg 2
                      5:  */
1.1       deraadt     6:
                      7: #include "def.h"
                      8:
                      9: #ifndef NO_HELP
                     10: #include "kbd.h"
                     11: #include "key.h"
                     12: #ifndef NO_MACRO
                     13: #include "macro.h"
1.3       millert    14: #endif /* !NO_MACRO */
1.2       millert    15:
1.3       millert    16: static int     showall         __P((char *ind, KEYMAP *map));
                     17: static VOID    findbind        __P((PF, char *, KEYMAP *));
                     18: static VOID    bindfound       __P((void));
                     19:
                     20: static BUFFER  *bp;
                     21: static char     buf[80];       /* used by showall and findbind */
                     22: static char     buf2[128];
                     23: static char    *buf2p;
1.1       deraadt    24:
                     25: /*
1.2       millert    26:  * Read a key from the keyboard, and look it up in the keymap.
                     27:  * Display the name of the function currently bound to the key.
1.1       deraadt    28:  */
1.2       millert    29: /* ARGSUSED */
                     30: int
1.1       deraadt    31: desckey(f, n)
1.3       millert    32:        int f, n;
1.1       deraadt    33: {
1.3       millert    34:        KEYMAP  *curmap;
                     35:        PF       funct;
                     36:        int      c, m, i;
                     37:        char    *pep;
                     38:        char     prompt[80];
1.1       deraadt    39:
                     40: #ifndef NO_MACRO
1.2       millert    41:        if (inmacro)
                     42:                return TRUE;    /* ignore inside keyboard macro */
1.3       millert    43: #endif /* !NO_MACRO */
                     44:        (VOID)strcpy(prompt, "Describe key briefly: ");
1.2       millert    45:        pep = prompt + strlen(prompt);
                     46:        key.k_count = 0;
                     47:        m = curbp->b_nmodes;
                     48:        curmap = curbp->b_modes[m]->p_map;
                     49:        for (;;) {
                     50:                for (;;) {
                     51:                        ewprintf("%s", prompt);
                     52:                        pep[-1] = ' ';
                     53:                        pep = keyname(pep, key.k_chars[key.k_count++] =
                     54:                            c = getkey(FALSE));
                     55:                        if ((funct = doscan(curmap, c)) != prefix)
                     56:                                break;
                     57:                        *pep++ = '-';
                     58:                        *pep = '\0';
                     59:                        curmap = ele->k_prefmap;
                     60:                }
                     61:                if (funct != rescan)
                     62:                        break;
                     63:                if (ISUPPER(key.k_chars[key.k_count - 1])) {
                     64:                        funct = doscan(curmap,
                     65:                            TOLOWER(key.k_chars[key.k_count - 1]));
                     66:                        if (funct == prefix) {
                     67:                                *pep++ = '-';
                     68:                                *pep = '\0';
                     69:                                curmap = ele->k_prefmap;
                     70:                                continue;
                     71:                        }
                     72:                        if (funct != rescan)
                     73:                                break;
                     74:                }
                     75: nextmode:
                     76:                if (--m < 0)
                     77:                        break;
                     78:                curmap = curbp->b_modes[m]->p_map;
                     79:                for (i = 0; i < key.k_count; i++) {
                     80:                        funct = doscan(curmap, key.k_chars[i]);
                     81:                        if (funct != prefix) {
                     82:                                if (i == key.k_count - 1 && funct != rescan)
                     83:                                        goto found;
                     84:                                funct = rescan;
                     85:                                goto nextmode;
                     86:                        }
                     87:                        curmap = ele->k_prefmap;
                     88:                }
1.1       deraadt    89:                *pep++ = '-';
                     90:                *pep = '\0';
                     91:        }
                     92: found:
1.2       millert    93:        if (funct == rescan)
                     94:                ewprintf("%k is not bound to any function");
                     95:        else if ((pep = function_name(funct)) != NULL)
                     96:                ewprintf("%k runs the command %s", pep);
                     97:        else
                     98:                ewprintf("%k is bound to an unnamed function");
                     99:        return TRUE;
1.1       deraadt   100: }
                    101:
                    102: /*
1.2       millert   103:  * This function creates a table, listing all of the command
                    104:  * keys and their current bindings, and stores the table in the
                    105:  * *help* pop-up buffer.  This lets Mg produce it's own wall chart.
1.1       deraadt   106:  */
1.2       millert   107: /* ARGSUSED */
                    108: int
1.1       deraadt   109: wallchart(f, n)
1.3       millert   110:        int f, n;
1.1       deraadt   111: {
1.3       millert   112:        int              m;
                    113:        static char      locbind[80] = "Local keybindings for mode ";
1.1       deraadt   114:
                    115:        bp = bfind("*help*", TRUE);
1.2       millert   116:        if (bclear(bp) != TRUE)
1.3       millert   117:                /* clear it out */
                    118:                return FALSE;
1.2       millert   119:        for (m = curbp->b_nmodes; m > 0; m--) {
1.3       millert   120:                (VOID)strcpy(&locbind[27], curbp->b_modes[m]->p_name);
                    121:                (VOID)strcat(&locbind[27], ":");
1.2       millert   122:                if ((addline(bp, locbind) == FALSE) ||
                    123:                    (showall(buf, curbp->b_modes[m]->p_map) == FALSE) ||
                    124:                    (addline(bp, "") == FALSE))
                    125:                        return FALSE;
1.1       deraadt   126:        }
1.2       millert   127:        if ((addline(bp, "Global bindings:") == FALSE) ||
                    128:            (showall(buf, map_table[0].p_map) == FALSE))
                    129:                return FALSE;
1.1       deraadt   130:        return popbuftop(bp);
                    131: }
                    132:
1.2       millert   133: static int
                    134: showall(ind, map)
1.3       millert   135:        char   *ind;
                    136:        KEYMAP *map;
1.1       deraadt   137: {
1.3       millert   138:        MAP_ELEMENT     *ele;
                    139:        PF               functp;
                    140:        int              i, last;
                    141:        char            *cp, *cp2;
1.1       deraadt   142:
1.2       millert   143:        if (addline(bp, "") == FALSE)
                    144:                return FALSE;
1.1       deraadt   145:        last = -1;
1.3       millert   146:        for (ele = &map->map_element[0];
                    147:            ele < &map->map_element[map->map_num]; ele++) {
1.2       millert   148:                if (map->map_default != rescan && ++last < ele->k_base) {
                    149:                        cp = keyname(ind, last);
                    150:                        if (last < ele->k_base - 1) {
1.3       millert   151:                                (VOID)strcpy(cp, " .. ");
1.2       millert   152:                                cp = keyname(cp + 4, ele->k_base - 1);
                    153:                        }
                    154:                        do {
                    155:                                *cp++ = ' ';
                    156:                        } while (cp < &buf[16]);
1.3       millert   157:                        (VOID)strcpy(cp, function_name(map->map_default));
1.2       millert   158:                        if (addline(bp, buf) == FALSE)
                    159:                                return FALSE;
1.1       deraadt   160:                }
1.2       millert   161:                last = ele->k_num;
                    162:                for (i = ele->k_base; i <= last; i++) {
                    163:                        functp = ele->k_funcp[i - ele->k_base];
                    164:                        if (functp != rescan) {
                    165:                                if (functp != prefix)
                    166:                                        cp2 = function_name(functp);
                    167:                                else
                    168:                                        cp2 = map_name(ele->k_prefmap);
                    169:                                if (cp2 != NULL) {
                    170:                                        cp = keyname(ind, i);
                    171:                                        do {
                    172:                                                *cp++ = ' ';
                    173:                                        } while (cp < &buf[16]);
1.3       millert   174:                                        (VOID)strcpy(cp, cp2);
1.2       millert   175:                                        if (addline(bp, buf) == FALSE)
                    176:                                                return FALSE;
                    177:                                }
                    178:                        }
1.1       deraadt   179:                }
                    180:        }
1.3       millert   181:        for (ele = &map->map_element[0];
                    182:            ele < &map->map_element[map->map_num]; ele++) {
1.2       millert   183:                if (ele->k_prefmap != NULL) {
                    184:                        for (i = ele->k_base;
                    185:                            ele->k_funcp[i - ele->k_base] != prefix; i++) {
1.3       millert   186:                                if (i >= ele->k_num)
                    187:                                        /* damaged map */
1.2       millert   188:                                        return FALSE;
                    189:                        }
                    190:                        cp = keyname(ind, i);
                    191:                        *cp++ = ' ';
                    192:                        if (showall(cp, ele->k_prefmap) == FALSE)
                    193:                                return FALSE;
1.1       deraadt   194:                }
                    195:        }
                    196:        return TRUE;
                    197: }
                    198:
1.2       millert   199: int
1.1       deraadt   200: help_help(f, n)
1.3       millert   201:        int f, n;
1.1       deraadt   202: {
1.3       millert   203:        KEYMAP  *kp;
                    204:        PF       funct;
1.1       deraadt   205:
1.2       millert   206:        if ((kp = name_map("help")) == NULL)
                    207:                return FALSE;
                    208:        ewprintf("a b c: ");
                    209:        do {
                    210:                funct = doscan(kp, getkey(FALSE));
                    211:        } while (funct == NULL || funct == help_help);
1.1       deraadt   212: #ifndef NO_MACRO
1.2       millert   213:        if (macrodef && macrocount < MAXMACRO)
                    214:                macro[macrocount - 1].m_funct = funct;
1.3       millert   215: #endif /* !NO_MACRO */
                    216:        return (*funct)(f, n);
1.1       deraadt   217: }
                    218:
1.2       millert   219: /* ARGSUSED */
                    220: int
1.1       deraadt   221: apropos_command(f, n)
1.3       millert   222:        int f, n;
1.1       deraadt   223: {
1.3       millert   224:        BUFFER          *bp;
                    225:        FUNCTNAMES      *fnp;
                    226:        char            *cp1, *cp2;
                    227:        char             string[32];
1.1       deraadt   228:
1.2       millert   229:        if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
                    230:                return ABORT;
1.1       deraadt   231:        /* FALSE means we got a 0 character string, which is fine */
1.2       millert   232:        bp = bfind("*help*", TRUE);
                    233:        if (bclear(bp) == FALSE)
                    234:                return FALSE;
                    235:        for (fnp = &functnames[0]; fnp < &functnames[nfunct]; fnp++) {
                    236:                for (cp1 = fnp->n_name; *cp1; cp1++) {
                    237:                        cp2 = string;
                    238:                        while (*cp2 && *cp1 == *cp2)
                    239:                                cp1++, cp2++;
                    240:                        if (!*cp2) {
1.3       millert   241:                                (VOID)strcpy(buf2, fnp->n_name);
1.2       millert   242:                                buf2p = &buf2[strlen(buf2)];
                    243:                                findbind(fnp->n_funct, buf, map_table[0].p_map);
                    244:                                if (addline(bp, buf2) == FALSE)
                    245:                                        return FALSE;
                    246:                                break;
                    247:                        } else
                    248:                                cp1 -= cp2 - string;
                    249:                }
1.1       deraadt   250:        }
1.2       millert   251:        return popbuftop(bp);
1.1       deraadt   252: }
                    253:
1.2       millert   254: static VOID
                    255: findbind(funct, ind, map)
1.3       millert   256:        KEYMAP *map;
                    257:        PF      funct;
                    258:        char   *ind;
1.1       deraadt   259: {
1.3       millert   260:        MAP_ELEMENT     *ele;
                    261:        int              i, last;
                    262:        char            *cp;
1.2       millert   263:
                    264:        last = -1;
1.3       millert   265:        for (ele = &map->map_element[0];
                    266:            ele < &map->map_element[map->map_num]; ele++) {
1.2       millert   267:                if (map->map_default == funct && ++last < ele->k_base) {
                    268:                        cp = keyname(ind, last);
                    269:                        if (last < ele->k_base - 1) {
1.3       millert   270:                                (VOID)strcpy(cp, " .. ");
                    271:                                (VOID)keyname(cp + 4, ele->k_base - 1);
1.2       millert   272:                        }
                    273:                        bindfound();
                    274:                }
                    275:                last = ele->k_num;
                    276:                for (i = ele->k_base; i <= last; i++) {
                    277:                        if (funct == ele->k_funcp[i - ele->k_base]) {
                    278:                                if (funct == prefix) {
                    279:                                        cp = map_name(ele->k_prefmap);
                    280:                                        if (!cp ||
                    281:                                            strncmp(cp, buf2, strlen(cp)) != 0)
                    282:                                                continue;
                    283:                                }
1.3       millert   284:                                (VOID)keyname(ind, i);
1.2       millert   285:                                bindfound();
                    286:                        }
                    287:                }
1.1       deraadt   288:        }
1.3       millert   289:        for (ele = &map->map_element[0];
                    290:            ele < &map->map_element[map->map_num]; ele++) {
1.2       millert   291:                if (ele->k_prefmap != NULL) {
                    292:                        for (i = ele->k_base;
                    293:                            ele->k_funcp[i - ele->k_base] != prefix; i++) {
                    294:                                if (i >= ele->k_num)
1.3       millert   295:                                        /* damaged */
                    296:                                        return;
1.2       millert   297:                        }
                    298:                        cp = keyname(ind, i);
                    299:                        *cp++ = ' ';
                    300:                        findbind(funct, cp, ele->k_prefmap);
1.1       deraadt   301:                }
                    302:        }
                    303: }
                    304:
1.2       millert   305: static VOID
                    306: bindfound()
                    307: {
                    308:        if (buf2p < &buf2[32]) {
                    309:                do {
                    310:                        *buf2p++ = ' ';
                    311:                } while (buf2p < &buf2[32]);
                    312:        } else {
                    313:                *buf2p++ = ',';
                    314:                *buf2p++ = ' ';
                    315:        }
1.3       millert   316:        (VOID)strcpy(buf2p, buf);
1.2       millert   317:        buf2p += strlen(buf);
1.1       deraadt   318: }
1.3       millert   319: #endif /* !NO_HELP */