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 */