Annotation of src/usr.bin/mg/help.c, Revision 1.20
1.20 ! deraadt 1: /* $OpenBSD: help.c,v 1.19 2002/07/01 14:33:44 vincent 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.1 deraadt 26: desckey(f, n)
1.3 millert 27: int f, n;
1.1 deraadt 28: {
1.3 millert 29: KEYMAP *curmap;
30: PF funct;
1.18 vincent 31: int c, m, i, num;
1.3 millert 32: char *pep;
33: char prompt[80];
1.1 deraadt 34:
35: #ifndef NO_MACRO
1.2 millert 36: if (inmacro)
37: return TRUE; /* ignore inside keyboard macro */
1.3 millert 38: #endif /* !NO_MACRO */
1.18 vincent 39: num = strlcpy(prompt, "Describe key briefly: ", sizeof(prompt));
40: if (num >= sizeof prompt)
41: num = sizeof prompt - 1;
42: pep = prompt + 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 (;;) {
48: ewprintf("%s", prompt);
49: pep[-1] = ' ';
1.11 mickey 50: pep = keyname(pep, sizeof(prompt) - (pep - prompt),
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");
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
99: * *help* pop-up buffer. This lets Mg produce it's own wall chart.
1.1 deraadt 100: */
1.2 millert 101: /* ARGSUSED */
102: int
1.1 deraadt 103: wallchart(f, n)
1.3 millert 104: int f, n;
1.1 deraadt 105: {
1.3 millert 106: int m;
1.8 art 107: 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 */
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))
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.2 millert 123: return FALSE;
1.1 deraadt 124: return popbuftop(bp);
125: }
126:
1.2 millert 127: static int
1.8 art 128: showall(BUFFER *bp, KEYMAP *map, char *prefix)
1.1 deraadt 129: {
1.8 art 130: KEYMAP *newmap;
131: char buf[80], key[16];
132: PF fun;
133: int c;
1.1 deraadt 134:
1.2 millert 135: if (addline(bp, "") == FALSE)
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.13 art 143: keyname(buf, sizeof(buf), c);
1.19 vincent 144: (void)snprintf(key, sizeof key, "%s%s ", prefix, buf);
1.8 art 145: if (fun == NULL) {
146: if (showall(bp, newmap, key) == FALSE)
1.2 millert 147: return FALSE;
1.8 art 148: } else {
149: if (addlinef(bp, "%-16s%s", key,
150: function_name(fun)) == FALSE)
1.2 millert 151: return FALSE;
1.1 deraadt 152: }
153: }
1.8 art 154:
1.1 deraadt 155: return TRUE;
156: }
157:
1.2 millert 158: int
1.1 deraadt 159: help_help(f, n)
1.3 millert 160: int f, n;
1.1 deraadt 161: {
1.3 millert 162: KEYMAP *kp;
163: PF funct;
1.1 deraadt 164:
1.2 millert 165: if ((kp = name_map("help")) == NULL)
166: return FALSE;
167: ewprintf("a b c: ");
168: do {
1.6 art 169: funct = doscan(kp, getkey(FALSE), NULL);
1.2 millert 170: } while (funct == NULL || funct == help_help);
1.1 deraadt 171: #ifndef NO_MACRO
1.2 millert 172: if (macrodef && macrocount < MAXMACRO)
173: macro[macrocount - 1].m_funct = funct;
1.3 millert 174: #endif /* !NO_MACRO */
175: return (*funct)(f, n);
1.1 deraadt 176: }
177:
1.2 millert 178: /* ARGSUSED */
179: int
1.1 deraadt 180: apropos_command(f, n)
1.3 millert 181: int f, n;
1.1 deraadt 182: {
1.3 millert 183: BUFFER *bp;
1.8 art 184: LIST *fnames, *el;
1.3 millert 185: char string[32];
1.1 deraadt 186:
1.2 millert 187: if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
188: return ABORT;
1.1 deraadt 189: /* FALSE means we got a 0 character string, which is fine */
1.2 millert 190: bp = bfind("*help*", TRUE);
191: if (bclear(bp) == FALSE)
192: return FALSE;
1.8 art 193:
194: fnames = complete_function_list("", NULL);
195: for (el = fnames; el != NULL; el = el->l_next) {
196: char buf[32];
1.9 art 197:
1.8 art 198: if (strstr(el->l_name, string) == NULL)
199: continue;
1.9 art 200:
1.8 art 201: buf[0] = '\0';
1.11 mickey 202: findbind(fundamental_map, name_function(el->l_name),
203: buf, sizeof(buf));
1.8 art 204:
205: if (addlinef(bp, "%-32s%s", el->l_name, buf) == FALSE) {
206: free_file_list(fnames);
207: return FALSE;
1.2 millert 208: }
1.1 deraadt 209: }
1.8 art 210: free_file_list(fnames);
1.2 millert 211: return popbuftop(bp);
1.1 deraadt 212: }
213:
1.8 art 214: static int
1.11 mickey 215: findbind(KEYMAP *map, PF fun, char *buf, size_t len)
1.1 deraadt 216: {
1.8 art 217: KEYMAP *newmap;
218: PF nfun;
219: char buf2[16], key[16];
220: int c;
221:
222: /* XXX - 256 ? */
223: for (c = 0; c < 256; c++) {
224: nfun = doscan(map, c, &newmap);
225: if (nfun == fun) {
1.13 art 226: keyname(buf, len, c);
1.8 art 227: return TRUE;
1.2 millert 228: }
1.8 art 229: if (nfun == NULL) {
1.11 mickey 230: if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) {
1.13 art 231: keyname(key, sizeof(key), c);
1.19 vincent 232: (void)snprintf(buf, len, "%s %s", key, buf2);
1.8 art 233: return TRUE;
1.2 millert 234: }
235: }
1.1 deraadt 236: }
237:
1.12 mickey 238: return FALSE;
1.1 deraadt 239: }
1.3 millert 240: #endif /* !NO_HELP */