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