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