GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mg/help.c Lines: 0 104 0.0 %
Date: 2016-12-06 Branches: 0 86 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: help.c,v 1.35 2015/03/19 21:22:15 bcallah Exp $	*/
2
3
/* This file is in the public domain. */
4
5
/*
6
 * Help functions for Mg 2
7
 */
8
9
#include <sys/queue.h>
10
#include <signal.h>
11
#include <stdio.h>
12
#include <string.h>
13
14
#include "def.h"
15
#include "funmap.h"
16
#include "kbd.h"
17
#include "key.h"
18
#include "macro.h"
19
20
static int	showall(struct buffer *, KEYMAP *, char *);
21
static int	findbind(KEYMAP *, PF, char *, size_t);
22
23
/*
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.
26
 */
27
/* ARGSUSED */
28
int
29
desckey(int f, int n)
30
{
31
	KEYMAP	*curmap;
32
	PF	 funct;
33
	int	 c, m, i, num;
34
	char	*pep;
35
	char	 dprompt[80];
36
37
	if (inmacro)
38
		return (TRUE);	/* ignore inside keyboard macro */
39
40
	num = strlcpy(dprompt, "Describe key briefly: ", sizeof(dprompt));
41
	if (num >= sizeof(dprompt))
42
		num = sizeof(dprompt) - 1;
43
	pep = dprompt + num;
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", dprompt);
50
			pep[-1] = ' ';
51
			pep = getkeyname(pep, sizeof(dprompt) - (pep - dprompt),
52
			    key.k_chars[key.k_count++] = c = getkey(FALSE));
53
			if ((funct = doscan(curmap, c, &curmap)) != NULL)
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,
62
			    TOLOWER(key.k_chars[key.k_count - 1]), &curmap);
63
			if (funct == NULL) {
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++) {
76
			funct = doscan(curmap, key.k_chars[i], &curmap);
77
			if (funct != NULL) {
78
				if (i == key.k_count - 1 && funct != rescan)
79
					goto found;
80
				funct = rescan;
81
				goto nextmode;
82
			}
83
		}
84
		*pep++ = '-';
85
		*pep = '\0';
86
	}
87
found:
88
	if (funct == rescan || funct == selfinsert)
89
		ewprintf("%k is not bound to any function");
90
	else if ((pep = (char *)function_name(funct)) != NULL)
91
		ewprintf("%k runs the command %s", pep);
92
	else
93
		ewprintf("%k is bound to an unnamed function");
94
	return (TRUE);
95
}
96
97
/*
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.
101
 */
102
/* ARGSUSED */
103
int
104
wallchart(int f, int n)
105
{
106
	int		 m;
107
	struct buffer		*bp;
108
109
	bp = bfind("*help*", TRUE);
110
	if (bclear(bp) != TRUE)
111
		/* clear it out */
112
		return (FALSE);
113
	bp->b_flag |= BFREADONLY;
114
	for (m = curbp->b_nmodes; m > 0; m--) {
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) ||
118
		    (addline(bp, "") == FALSE))
119
			return (FALSE);
120
	}
121
	if ((addline(bp, "Global bindings:") == FALSE) ||
122
	    (showall(bp, fundamental_map, "") == FALSE))
123
		return (FALSE);
124
	return (popbuftop(bp, WNONE));
125
}
126
127
static int
128
showall(struct buffer *bp, KEYMAP *map, char *prefix)
129
{
130
	KEYMAP	*newmap;
131
	char	 buf[80], keybuf[16];
132
	PF	 fun;
133
	int	 c;
134
135
	if (addline(bp, "") == FALSE)
136
		return (FALSE);
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;
143
		getkeyname(buf, sizeof(buf), c);
144
		(void)snprintf(keybuf, sizeof(keybuf), "%s%s ", prefix, buf);
145
		if (fun == NULL) {
146
			if (showall(bp, newmap, keybuf) == FALSE)
147
				return (FALSE);
148
		} else {
149
			if (addlinef(bp, "%-16s%s", keybuf,
150
				    function_name(fun)) == FALSE)
151
				return (FALSE);
152
		}
153
	}
154
	return (TRUE);
155
}
156
157
int
158
help_help(int f, int n)
159
{
160
	KEYMAP	*kp;
161
	PF	 funct;
162
163
	if ((kp = name_map("help")) == NULL)
164
		return (FALSE);
165
	ewprintf("a b c: ");
166
	do {
167
		funct = doscan(kp, getkey(FALSE), NULL);
168
	} while (funct == NULL || funct == help_help);
169
170
	if (macrodef && macrocount < MAXMACRO)
171
		macro[macrocount - 1].m_funct = funct;
172
173
	return ((*funct)(f, n));
174
}
175
176
/* ARGSUSED */
177
int
178
apropos_command(int f, int n)
179
{
180
	struct buffer		*bp;
181
	struct list		*fnames, *el;
182
	char		 string[32];
183
184
	if (eread("apropos: ", string, sizeof(string), EFNUL | EFNEW) == NULL)
185
		return (ABORT);
186
	/* FALSE means we got a 0 character string, which is fine */
187
	bp = bfind("*help*", TRUE);
188
	if (bclear(bp) == FALSE)
189
		return (FALSE);
190
191
	fnames = complete_function_list("");
192
	for (el = fnames; el != NULL; el = el->l_next) {
193
		char buf[32];
194
195
		if (strstr(el->l_name, string) == NULL)
196
			continue;
197
198
		buf[0] = '\0';
199
		findbind(fundamental_map, name_function(el->l_name),
200
		    buf, sizeof(buf));
201
202
		if (addlinef(bp, "%-32s%s", el->l_name,  buf) == FALSE) {
203
			free_file_list(fnames);
204
			return (FALSE);
205
		}
206
	}
207
	free_file_list(fnames);
208
	return (popbuftop(bp, WNONE));
209
}
210
211
static int
212
findbind(KEYMAP *map, PF fun, char *buf, size_t len)
213
{
214
	KEYMAP	*newmap;
215
	PF	 nfun;
216
	char	 buf2[16], keybuf[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) {
223
			getkeyname(buf, len, c);
224
			return (TRUE);
225
		}
226
		if (nfun == NULL) {
227
			if (findbind(newmap, fun, buf2, sizeof(buf2)) == TRUE) {
228
				getkeyname(keybuf, sizeof(keybuf), c);
229
				(void)snprintf(buf, len, "%s %s", keybuf, buf2);
230
				return (TRUE);
231
			}
232
		}
233
	}
234
	return (FALSE);
235
}