Annotation of src/usr.bin/mg/help.c, Revision 1.17
1.17 ! vincent 1: /* $OpenBSD: help.c,v 1.16 2002/03/11 13:02:56 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;
31: int c, m, i;
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.11 mickey 39: pep = prompt + strlcpy(prompt, "Describe key briefly: ", sizeof(prompt));
1.2 millert 40: key.k_count = 0;
41: m = curbp->b_nmodes;
42: curmap = curbp->b_modes[m]->p_map;
43: for (;;) {
44: for (;;) {
45: ewprintf("%s", prompt);
46: pep[-1] = ' ';
1.11 mickey 47: pep = keyname(pep, sizeof(prompt) - (pep - prompt),
48: key.k_chars[key.k_count++] = c = getkey(FALSE));
1.6 art 49: if ((funct = doscan(curmap, c, &curmap)) != NULL)
1.2 millert 50: break;
51: *pep++ = '-';
52: *pep = '\0';
53: }
54: if (funct != rescan)
55: break;
56: if (ISUPPER(key.k_chars[key.k_count - 1])) {
57: funct = doscan(curmap,
1.6 art 58: TOLOWER(key.k_chars[key.k_count - 1]), &curmap);
1.5 art 59: if (funct == NULL) {
1.2 millert 60: *pep++ = '-';
61: *pep = '\0';
62: continue;
63: }
64: if (funct != rescan)
65: break;
66: }
67: nextmode:
68: if (--m < 0)
69: break;
70: curmap = curbp->b_modes[m]->p_map;
71: for (i = 0; i < key.k_count; i++) {
1.6 art 72: funct = doscan(curmap, key.k_chars[i], &curmap);
1.5 art 73: if (funct != NULL) {
1.2 millert 74: if (i == key.k_count - 1 && funct != rescan)
75: goto found;
76: funct = rescan;
77: goto nextmode;
78: }
79: }
1.1 deraadt 80: *pep++ = '-';
81: *pep = '\0';
82: }
83: found:
1.7 art 84: if (funct == rescan || funct == selfinsert)
1.2 millert 85: ewprintf("%k is not bound to any function");
1.16 vincent 86: else if ((pep = (char *)function_name(funct)) != NULL)
1.2 millert 87: ewprintf("%k runs the command %s", pep);
88: else
89: ewprintf("%k is bound to an unnamed function");
90: return TRUE;
1.1 deraadt 91: }
92:
93: /*
1.2 millert 94: * This function creates a table, listing all of the command
95: * keys and their current bindings, and stores the table in the
96: * *help* pop-up buffer. This lets Mg produce it's own wall chart.
1.1 deraadt 97: */
1.2 millert 98: /* ARGSUSED */
99: int
1.1 deraadt 100: wallchart(f, n)
1.3 millert 101: int f, n;
1.1 deraadt 102: {
1.3 millert 103: int m;
1.8 art 104: BUFFER *bp;
1.1 deraadt 105:
106: bp = bfind("*help*", TRUE);
1.2 millert 107: if (bclear(bp) != TRUE)
1.3 millert 108: /* clear it out */
109: return FALSE;
1.17 ! vincent 110: bp->b_flag |= BFREADONLY;
1.2 millert 111: for (m = curbp->b_nmodes; m > 0; m--) {
1.8 art 112: if ((addlinef(bp, "Local keybindings for mode %s:",
113: curbp->b_modes[m]->p_name) == FALSE) ||
114: (showall(bp, curbp->b_modes[m]->p_map, "") == FALSE) ||
1.2 millert 115: (addline(bp, "") == FALSE))
116: return FALSE;
1.1 deraadt 117: }
1.2 millert 118: if ((addline(bp, "Global bindings:") == FALSE) ||
1.9 art 119: (showall(bp, fundamental_map, "") == FALSE))
1.2 millert 120: return FALSE;
1.1 deraadt 121: return popbuftop(bp);
122: }
123:
1.2 millert 124: static int
1.8 art 125: showall(BUFFER *bp, KEYMAP *map, char *prefix)
1.1 deraadt 126: {
1.8 art 127: KEYMAP *newmap;
128: char buf[80], key[16];
129: PF fun;
130: int c;
1.1 deraadt 131:
1.2 millert 132: if (addline(bp, "") == FALSE)
133: return FALSE;
1.8 art 134:
135: /* XXX - 256 ? */
136: for (c = 0; c < 256; c++) {
137: fun = doscan(map, c, &newmap);
138: if (fun == rescan || fun == selfinsert)
139: continue;
1.13 art 140: keyname(buf, sizeof(buf), c);
1.15 deraadt 141: snprintf(key, sizeof key, "%s%s ", prefix, buf);
1.8 art 142: if (fun == NULL) {
143: if (showall(bp, newmap, key) == FALSE)
1.2 millert 144: return FALSE;
1.8 art 145: } else {
146: if (addlinef(bp, "%-16s%s", key,
147: function_name(fun)) == FALSE)
1.2 millert 148: return FALSE;
1.1 deraadt 149: }
150: }
1.8 art 151:
1.1 deraadt 152: return TRUE;
153: }
154:
1.2 millert 155: int
1.1 deraadt 156: help_help(f, n)
1.3 millert 157: int f, n;
1.1 deraadt 158: {
1.3 millert 159: KEYMAP *kp;
160: PF funct;
1.1 deraadt 161:
1.2 millert 162: if ((kp = name_map("help")) == NULL)
163: return FALSE;
164: ewprintf("a b c: ");
165: do {
1.6 art 166: funct = doscan(kp, getkey(FALSE), NULL);
1.2 millert 167: } while (funct == NULL || funct == help_help);
1.1 deraadt 168: #ifndef NO_MACRO
1.2 millert 169: if (macrodef && macrocount < MAXMACRO)
170: macro[macrocount - 1].m_funct = funct;
1.3 millert 171: #endif /* !NO_MACRO */
172: return (*funct)(f, n);
1.1 deraadt 173: }
174:
1.2 millert 175: /* ARGSUSED */
176: int
1.1 deraadt 177: apropos_command(f, n)
1.3 millert 178: int f, n;
1.1 deraadt 179: {
1.3 millert 180: BUFFER *bp;
1.8 art 181: LIST *fnames, *el;
1.3 millert 182: char string[32];
1.1 deraadt 183:
1.2 millert 184: if (eread("apropos: ", string, sizeof(string), EFNEW) == ABORT)
185: return ABORT;
1.1 deraadt 186: /* FALSE means we got a 0 character string, which is fine */
1.2 millert 187: bp = bfind("*help*", TRUE);
188: if (bclear(bp) == FALSE)
189: return FALSE;
1.8 art 190:
191: fnames = complete_function_list("", NULL);
192: for (el = fnames; el != NULL; el = el->l_next) {
193: char buf[32];
1.9 art 194:
1.8 art 195: if (strstr(el->l_name, string) == NULL)
196: continue;
1.9 art 197:
1.8 art 198: buf[0] = '\0';
1.11 mickey 199: findbind(fundamental_map, name_function(el->l_name),
200: buf, sizeof(buf));
1.8 art 201:
202: if (addlinef(bp, "%-32s%s", el->l_name, buf) == FALSE) {
203: free_file_list(fnames);
204: return FALSE;
1.2 millert 205: }
1.1 deraadt 206: }
1.8 art 207: free_file_list(fnames);
1.2 millert 208: return popbuftop(bp);
1.1 deraadt 209: }
210:
1.8 art 211: static int
1.11 mickey 212: findbind(KEYMAP *map, PF fun, char *buf, size_t len)
1.1 deraadt 213: {
1.8 art 214: KEYMAP *newmap;
215: PF nfun;
216: char buf2[16], key[16];
217: int c;
218:
219: /* XXX - 256 ? */
220: for (c = 0; c < 256; c++) {
221: nfun = doscan(map, c, &newmap);
222: if (nfun == fun) {
1.13 art 223: keyname(buf, len, c);
1.8 art 224: return TRUE;
1.2 millert 225: }
1.8 art 226: if (nfun == NULL) {
1.11 mickey 227: if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) {
1.13 art 228: keyname(key, sizeof(key), c);
1.11 mickey 229: snprintf(buf, len, "%s %s", key, buf2);
1.8 art 230: return TRUE;
1.2 millert 231: }
232: }
1.1 deraadt 233: }
234:
1.12 mickey 235: return FALSE;
1.1 deraadt 236: }
1.3 millert 237: #endif /* !NO_HELP */