Annotation of src/usr.bin/mg/help.c, Revision 1.28
1.28 ! kjell 1: /* $OpenBSD: help.c,v 1.27 2005/11/18 20:56:53 deraadt Exp $ */
1.24 kjell 2:
3: /* This file is in the public domain. */
1.4 niklas 4:
1.3 millert 5: /*
1.12 mickey 6: * Help functions for Mg 2
1.3 millert 7: */
1.1 deraadt 8:
9: #include "def.h"
1.14 art 10: #include "funmap.h"
1.1 deraadt 11:
12: #ifndef NO_HELP
13: #include "kbd.h"
14: #include "key.h"
15: #ifndef NO_MACRO
16: #include "macro.h"
1.3 millert 17: #endif /* !NO_MACRO */
1.2 millert 18:
1.27 deraadt 19: static int showall(struct buffer *, KEYMAP *, char *);
1.11 mickey 20: static int findbind(KEYMAP *, PF, char *, size_t);
1.1 deraadt 21:
22: /*
1.2 millert 23: * Read a key from the keyboard, and look it up in the keymap.
24: * Display the name of the function currently bound to the key.
1.1 deraadt 25: */
1.2 millert 26: /* ARGSUSED */
27: int
1.22 db 28: desckey(int f, int n)
1.1 deraadt 29: {
1.3 millert 30: KEYMAP *curmap;
31: PF funct;
1.18 vincent 32: int c, m, i, num;
1.3 millert 33: char *pep;
1.28 ! kjell 34: char dprompt[80];
1.1 deraadt 35:
36: #ifndef NO_MACRO
1.2 millert 37: if (inmacro)
1.22 db 38: return (TRUE); /* ignore inside keyboard macro */
1.3 millert 39: #endif /* !NO_MACRO */
1.28 ! kjell 40: num = strlcpy(dprompt, "Describe key briefly: ", sizeof(dprompt));
! 41: if (num >= sizeof(dprompt))
! 42: num = sizeof(dprompt) - 1;
! 43: pep = dprompt + num;
1.2 millert 44: key.k_count = 0;
45: m = curbp->b_nmodes;
46: curmap = curbp->b_modes[m]->p_map;
47: for (;;) {
48: for (;;) {
1.28 ! kjell 49: ewprintf("%s", dprompt);
1.2 millert 50: pep[-1] = ' ';
1.28 ! kjell 51: pep = keyname(pep, sizeof(dprompt) - (pep - dprompt),
1.11 mickey 52: key.k_chars[key.k_count++] = c = getkey(FALSE));
1.6 art 53: if ((funct = doscan(curmap, c, &curmap)) != NULL)
1.2 millert 54: break;
55: *pep++ = '-';
56: *pep = '\0';
57: }
58: if (funct != rescan)
59: break;
60: if (ISUPPER(key.k_chars[key.k_count - 1])) {
61: funct = doscan(curmap,
1.6 art 62: TOLOWER(key.k_chars[key.k_count - 1]), &curmap);
1.5 art 63: if (funct == NULL) {
1.2 millert 64: *pep++ = '-';
65: *pep = '\0';
66: continue;
67: }
68: if (funct != rescan)
69: break;
70: }
71: nextmode:
72: if (--m < 0)
73: break;
74: curmap = curbp->b_modes[m]->p_map;
75: for (i = 0; i < key.k_count; i++) {
1.6 art 76: funct = doscan(curmap, key.k_chars[i], &curmap);
1.5 art 77: if (funct != NULL) {
1.2 millert 78: if (i == key.k_count - 1 && funct != rescan)
79: goto found;
80: funct = rescan;
81: goto nextmode;
82: }
83: }
1.1 deraadt 84: *pep++ = '-';
85: *pep = '\0';
86: }
87: found:
1.7 art 88: if (funct == rescan || funct == selfinsert)
1.2 millert 89: ewprintf("%k is not bound to any function");
1.16 vincent 90: else if ((pep = (char *)function_name(funct)) != NULL)
1.2 millert 91: ewprintf("%k runs the command %s", pep);
92: else
93: ewprintf("%k is bound to an unnamed function");
1.22 db 94: return (TRUE);
1.1 deraadt 95: }
96:
97: /*
1.2 millert 98: * This function creates a table, listing all of the command
99: * keys and their current bindings, and stores the table in the
100: * *help* pop-up buffer. This lets Mg produce it's own wall chart.
1.1 deraadt 101: */
1.2 millert 102: /* ARGSUSED */
103: int
1.22 db 104: wallchart(int f, int n)
1.1 deraadt 105: {
1.3 millert 106: int m;
1.27 deraadt 107: struct buffer *bp;
1.1 deraadt 108:
109: bp = bfind("*help*", TRUE);
1.2 millert 110: if (bclear(bp) != TRUE)
1.3 millert 111: /* clear it out */
1.22 db 112: return (FALSE);
1.20 deraadt 113: bp->b_flag |= BFREADONLY;
1.2 millert 114: for (m = curbp->b_nmodes; m > 0; m--) {
1.8 art 115: if ((addlinef(bp, "Local keybindings for mode %s:",
116: curbp->b_modes[m]->p_name) == FALSE) ||
117: (showall(bp, curbp->b_modes[m]->p_map, "") == FALSE) ||
1.2 millert 118: (addline(bp, "") == FALSE))
1.22 db 119: return (FALSE);
1.1 deraadt 120: }
1.2 millert 121: if ((addline(bp, "Global bindings:") == FALSE) ||
1.9 art 122: (showall(bp, fundamental_map, "") == FALSE))
1.22 db 123: return (FALSE);
124: return (popbuftop(bp));
1.1 deraadt 125: }
126:
1.2 millert 127: static int
1.27 deraadt 128: showall(struct buffer *bp, KEYMAP *map, char *prefix)
1.1 deraadt 129: {
1.22 db 130: KEYMAP *newmap;
131: char buf[80], key[16];
132: PF fun;
133: int c;
1.1 deraadt 134:
1.2 millert 135: if (addline(bp, "") == FALSE)
1.22 db 136: return (FALSE);
1.8 art 137:
138: /* XXX - 256 ? */
139: for (c = 0; c < 256; c++) {
140: fun = doscan(map, c, &newmap);
141: if (fun == rescan || fun == selfinsert)
142: continue;
1.13 art 143: keyname(buf, sizeof(buf), c);
1.22 db 144: (void)snprintf(key, sizeof(key), "%s%s ", prefix, buf);
1.8 art 145: if (fun == NULL) {
146: if (showall(bp, newmap, key) == FALSE)
1.22 db 147: return (FALSE);
1.8 art 148: } else {
149: if (addlinef(bp, "%-16s%s", key,
150: function_name(fun)) == FALSE)
1.22 db 151: return (FALSE);
1.1 deraadt 152: }
153: }
1.22 db 154: return (TRUE);
1.1 deraadt 155: }
156:
1.2 millert 157: int
1.22 db 158: help_help(int f, int n)
1.1 deraadt 159: {
1.3 millert 160: KEYMAP *kp;
161: PF funct;
1.1 deraadt 162:
1.2 millert 163: if ((kp = name_map("help")) == NULL)
1.22 db 164: return (FALSE);
1.2 millert 165: ewprintf("a b c: ");
166: do {
1.6 art 167: funct = doscan(kp, getkey(FALSE), NULL);
1.2 millert 168: } while (funct == NULL || funct == help_help);
1.1 deraadt 169: #ifndef NO_MACRO
1.2 millert 170: if (macrodef && macrocount < MAXMACRO)
171: macro[macrocount - 1].m_funct = funct;
1.3 millert 172: #endif /* !NO_MACRO */
1.22 db 173: return ((*funct)(f, n));
1.1 deraadt 174: }
175:
1.2 millert 176: /* ARGSUSED */
177: int
1.22 db 178: apropos_command(int f, int n)
1.1 deraadt 179: {
1.27 deraadt 180: struct buffer *bp;
181: struct list *fnames, *el;
1.26 deraadt 182: char string[32];
1.1 deraadt 183:
1.26 deraadt 184: if (eread("apropos: ", string, sizeof(string), EFNUL | EFNEW) == NULL)
1.22 db 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)
1.22 db 189: return (FALSE);
1.8 art 190:
1.23 otto 191: fnames = complete_function_list("");
1.8 art 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);
1.22 db 204: return (FALSE);
1.2 millert 205: }
1.1 deraadt 206: }
1.8 art 207: free_file_list(fnames);
1.22 db 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.22 db 214: KEYMAP *newmap;
215: PF nfun;
216: char buf2[16], key[16];
217: int c;
1.8 art 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.22 db 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.19 vincent 229: (void)snprintf(buf, len, "%s %s", key, buf2);
1.22 db 230: return (TRUE);
1.2 millert 231: }
232: }
1.1 deraadt 233: }
1.22 db 234: return (FALSE);
1.1 deraadt 235: }
1.3 millert 236: #endif /* !NO_HELP */