Annotation of src/usr.bin/mg/help.c, Revision 1.23
1.23 ! otto 1: /* $OpenBSD: help.c,v 1.22 2005/04/03 02:09:28 db Exp $ */
1.4 niklas 2:
1.3 millert 3: /*
1.12 mickey 4: * Help functions for Mg 2
1.3 millert 5: */
1.1 deraadt 6:
7: #include "def.h"
1.14 art 8: #include "funmap.h"
1.1 deraadt 9:
10: #ifndef NO_HELP
11: #include "kbd.h"
12: #include "key.h"
13: #ifndef NO_MACRO
14: #include "macro.h"
1.3 millert 15: #endif /* !NO_MACRO */
1.2 millert 16:
1.8 art 17: static int showall(BUFFER *, KEYMAP *, char *);
1.11 mickey 18: static int findbind(KEYMAP *, PF, char *, size_t);
1.1 deraadt 19:
20: /*
1.2 millert 21: * Read a key from the keyboard, and look it up in the keymap.
22: * Display the name of the function currently bound to the key.
1.1 deraadt 23: */
1.2 millert 24: /* ARGSUSED */
25: int
1.22 db 26: desckey(int f, int n)
1.1 deraadt 27: {
1.3 millert 28: KEYMAP *curmap;
29: PF funct;
1.18 vincent 30: int c, m, i, num;
1.3 millert 31: char *pep;
32: char prompt[80];
1.1 deraadt 33:
34: #ifndef NO_MACRO
1.2 millert 35: if (inmacro)
1.22 db 36: return (TRUE); /* ignore inside keyboard macro */
1.3 millert 37: #endif /* !NO_MACRO */
1.18 vincent 38: num = strlcpy(prompt, "Describe key briefly: ", sizeof(prompt));
1.22 db 39: if (num >= sizeof(prompt))
40: num = sizeof(prompt) - 1;
1.18 vincent 41: pep = prompt + num;
1.2 millert 42: key.k_count = 0;
43: m = curbp->b_nmodes;
44: curmap = curbp->b_modes[m]->p_map;
45: for (;;) {
46: for (;;) {
47: ewprintf("%s", prompt);
48: pep[-1] = ' ';
1.11 mickey 49: pep = keyname(pep, sizeof(prompt) - (pep - prompt),
50: key.k_chars[key.k_count++] = c = getkey(FALSE));
1.6 art 51: if ((funct = doscan(curmap, c, &curmap)) != NULL)
1.2 millert 52: break;
53: *pep++ = '-';
54: *pep = '\0';
55: }
56: if (funct != rescan)
57: break;
58: if (ISUPPER(key.k_chars[key.k_count - 1])) {
59: funct = doscan(curmap,
1.6 art 60: TOLOWER(key.k_chars[key.k_count - 1]), &curmap);
1.5 art 61: if (funct == NULL) {
1.2 millert 62: *pep++ = '-';
63: *pep = '\0';
64: continue;
65: }
66: if (funct != rescan)
67: break;
68: }
69: nextmode:
70: if (--m < 0)
71: break;
72: curmap = curbp->b_modes[m]->p_map;
73: for (i = 0; i < key.k_count; i++) {
1.6 art 74: funct = doscan(curmap, key.k_chars[i], &curmap);
1.5 art 75: if (funct != NULL) {
1.2 millert 76: if (i == key.k_count - 1 && funct != rescan)
77: goto found;
78: funct = rescan;
79: goto nextmode;
80: }
81: }
1.1 deraadt 82: *pep++ = '-';
83: *pep = '\0';
84: }
85: found:
1.7 art 86: if (funct == rescan || funct == selfinsert)
1.2 millert 87: ewprintf("%k is not bound to any function");
1.16 vincent 88: else if ((pep = (char *)function_name(funct)) != NULL)
1.2 millert 89: ewprintf("%k runs the command %s", pep);
90: else
91: ewprintf("%k is bound to an unnamed function");
1.22 db 92: return (TRUE);
1.1 deraadt 93: }
94:
95: /*
1.2 millert 96: * This function creates a table, listing all of the command
97: * keys and their current bindings, and stores the table in the
98: * *help* pop-up buffer. This lets Mg produce it's own wall chart.
1.1 deraadt 99: */
1.2 millert 100: /* ARGSUSED */
101: int
1.22 db 102: wallchart(int f, int n)
1.1 deraadt 103: {
1.3 millert 104: int m;
1.8 art 105: 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);
122: return (popbuftop(bp));
1.1 deraadt 123: }
124:
1.2 millert 125: static int
1.8 art 126: showall(BUFFER *bp, KEYMAP *map, char *prefix)
1.1 deraadt 127: {
1.22 db 128: KEYMAP *newmap;
129: char buf[80], key[16];
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.13 art 141: keyname(buf, sizeof(buf), c);
1.22 db 142: (void)snprintf(key, sizeof(key), "%s%s ", prefix, buf);
1.8 art 143: if (fun == NULL) {
144: if (showall(bp, newmap, key) == FALSE)
1.22 db 145: return (FALSE);
1.8 art 146: } else {
147: if (addlinef(bp, "%-16s%s", key,
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.1 deraadt 167: #ifndef NO_MACRO
1.2 millert 168: if (macrodef && macrocount < MAXMACRO)
169: macro[macrocount - 1].m_funct = funct;
1.3 millert 170: #endif /* !NO_MACRO */
1.22 db 171: return ((*funct)(f, n));
1.1 deraadt 172: }
173:
1.2 millert 174: /* ARGSUSED */
175: int
1.22 db 176: apropos_command(int f, int n)
1.1 deraadt 177: {
1.3 millert 178: BUFFER *bp;
1.8 art 179: LIST *fnames, *el;
1.21 vincent 180: char string[32], *bufp;
1.1 deraadt 181:
1.21 vincent 182: if ((bufp = eread("apropos: ", string, sizeof(string), EFNEW)) == NULL)
1.22 db 183: return (ABORT);
1.1 deraadt 184: /* FALSE means we got a 0 character string, which is fine */
1.2 millert 185: bp = bfind("*help*", TRUE);
186: if (bclear(bp) == FALSE)
1.22 db 187: return (FALSE);
1.8 art 188:
1.23 ! otto 189: fnames = complete_function_list("");
1.8 art 190: for (el = fnames; el != NULL; el = el->l_next) {
191: char buf[32];
1.9 art 192:
1.8 art 193: if (strstr(el->l_name, string) == NULL)
194: continue;
1.9 art 195:
1.8 art 196: buf[0] = '\0';
1.11 mickey 197: findbind(fundamental_map, name_function(el->l_name),
198: buf, sizeof(buf));
1.8 art 199:
200: if (addlinef(bp, "%-32s%s", el->l_name, buf) == FALSE) {
201: free_file_list(fnames);
1.22 db 202: return (FALSE);
1.2 millert 203: }
1.1 deraadt 204: }
1.8 art 205: free_file_list(fnames);
1.22 db 206: return (popbuftop(bp));
1.1 deraadt 207: }
208:
1.8 art 209: static int
1.11 mickey 210: findbind(KEYMAP *map, PF fun, char *buf, size_t len)
1.1 deraadt 211: {
1.22 db 212: KEYMAP *newmap;
213: PF nfun;
214: char buf2[16], key[16];
215: int c;
1.8 art 216:
217: /* XXX - 256 ? */
218: for (c = 0; c < 256; c++) {
219: nfun = doscan(map, c, &newmap);
220: if (nfun == fun) {
1.13 art 221: keyname(buf, len, c);
1.22 db 222: return (TRUE);
1.2 millert 223: }
1.8 art 224: if (nfun == NULL) {
1.11 mickey 225: if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) {
1.13 art 226: keyname(key, sizeof(key), c);
1.19 vincent 227: (void)snprintf(buf, len, "%s %s", key, buf2);
1.22 db 228: return (TRUE);
1.2 millert 229: }
230: }
1.1 deraadt 231: }
1.22 db 232: return (FALSE);
1.1 deraadt 233: }
1.3 millert 234: #endif /* !NO_HELP */