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