xref: /minix/external/bsd/nvi/dist/ex/ex_usage.c (revision 0a6a1f1d)
1 /*	$NetBSD: ex_usage.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
2 /*-
3  * Copyright (c) 1992, 1993, 1994
4  *	The Regents of the University of California.  All rights reserved.
5  * Copyright (c) 1992, 1993, 1994, 1995, 1996
6  *	Keith Bostic.  All rights reserved.
7  *
8  * See the LICENSE file for redistribution information.
9  */
10 
11 #include "config.h"
12 
13 #include <sys/cdefs.h>
14 #if 0
15 #ifndef lint
16 static const char sccsid[] = "Id: ex_usage.c,v 10.15 2001/06/25 15:19:21 skimo Exp  (Berkeley) Date: 2001/06/25 15:19:21 ";
17 #endif /* not lint */
18 #else
19 __RCSID("$NetBSD: ex_usage.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
20 #endif
21 
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/time.h>
25 
26 #include <bitstring.h>
27 #include <ctype.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "../common/common.h"
34 #include "../vi/vi.h"
35 
36 /*
37  * ex_help -- :help
38  *	Display help message.
39  *
40  * PUBLIC: int ex_help __P((SCR *, EXCMD *));
41  */
42 int
ex_help(SCR * sp,EXCMD * cmdp)43 ex_help(SCR *sp, EXCMD *cmdp)
44 {
45 	(void)ex_puts(sp,
46 	    "To see the list of vi commands, enter \":viusage<CR>\"\n");
47 	(void)ex_puts(sp,
48 	    "To see the list of ex commands, enter \":exusage<CR>\"\n");
49 	(void)ex_puts(sp,
50 	    "For an ex command usage statement enter \":exusage [cmd]<CR>\"\n");
51 	(void)ex_puts(sp,
52 	    "For a vi key usage statement enter \":viusage [key]<CR>\"\n");
53 	(void)ex_puts(sp, "To exit, enter \":q!\"\n");
54 	return (0);
55 }
56 
57 /*
58  * ex_usage -- :exusage [cmd]
59  *	Display ex usage strings.
60  *
61  * PUBLIC: int ex_usage __P((SCR *, EXCMD *));
62  */
63 int
ex_usage(SCR * sp,EXCMD * cmdp)64 ex_usage(SCR *sp, EXCMD *cmdp)
65 {
66 	ARGS *ap;
67 	EXCMDLIST const *cp;
68 	int newscreen;
69 	CHAR_T *p, nb[MAXCMDNAMELEN + 5];
70 	const CHAR_T *name;
71 
72 	switch (cmdp->argc) {
73 	case 1:
74 		ap = cmdp->argv[0];
75 		if (ISUPPER((UCHAR_T)ap->bp[0])) {
76 			newscreen = 1;
77 			ap->bp[0] = TOLOWER((UCHAR_T)ap->bp[0]);
78 		} else
79 			newscreen = 0;
80 		for (cp = cmds; cp->name != NULL &&
81 		    memcmp(ap->bp, cp->name, ap->len); ++cp);
82 		if (cp->name == NULL ||
83 		    (newscreen && !F_ISSET(cp, E_NEWSCREEN))) {
84 			const char *nstr;
85 			size_t nlen;
86 
87 			if (newscreen)
88 				ap->bp[0] = TOUPPER((UCHAR_T)ap->bp[0]);
89 
90 			INT2CHAR(sp, ap->bp, ap->len + 1, nstr, nlen);
91 			(void)ex_printf(sp, "The %.*s command is unknown\n",
92 			    (int)ap->len, nstr);
93 		} else {
94 			(void)ex_printf(sp,
95 			    "Command: %s\n  Usage: %s\n", cp->help, cp->usage);
96 			/*
97 			 * !!!
98 			 * The "visual" command has two modes, one from ex,
99 			 * one from the vi colon line.  Don't ask.
100 			 */
101 			if (cp != &cmds[C_VISUAL_EX] &&
102 			    cp != &cmds[C_VISUAL_VI])
103 				break;
104 			if (cp == &cmds[C_VISUAL_EX])
105 				cp = &cmds[C_VISUAL_VI];
106 			else
107 				cp = &cmds[C_VISUAL_EX];
108 			(void)ex_printf(sp,
109 			    "Command: %s\n  Usage: %s\n", cp->help, cp->usage);
110 		}
111 		break;
112 	case 0:
113 		for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp) {
114 			/*
115 			 * The ^D command has an unprintable name.
116 			 *
117 			 * XXX
118 			 * We display both capital and lower-case versions of
119 			 * the appropriate commands -- no need to add in extra
120 			 * room, they're all short names.
121 			 */
122 			if (cp == &cmds[C_SCROLL])
123 				name = L("^D");
124 			else if (F_ISSET(cp, E_NEWSCREEN)) {
125 				nb[0] = L('[');
126 				nb[1] = TOUPPER((UCHAR_T)cp->name[0]);
127 				nb[2] = cp->name[0];
128 				nb[3] = L(']');
129 				for (name = cp->name + 1,
130 				    p = nb + 4; (*p++ = *name++) != '\0';);
131 				name = nb;
132 			} else
133 				name = cp->name;
134 			(void)ex_printf(sp,
135 			    WVS": %s\n", MAXCMDNAMELEN, name, cp->help);
136 		}
137 		break;
138 	default:
139 		abort();
140 	}
141 	return (0);
142 }
143 
144 /*
145  * ex_viusage -- :viusage [key]
146  *	Display vi usage strings.
147  *
148  * PUBLIC: int ex_viusage __P((SCR *, EXCMD *));
149  */
150 int
ex_viusage(SCR * sp,EXCMD * cmdp)151 ex_viusage(SCR *sp, EXCMD *cmdp)
152 {
153 	VIKEYS const *kp;
154 	int key;
155 
156 	switch (cmdp->argc) {
157 	case 1:
158 		if (cmdp->argv[0]->len != 1) {
159 			ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
160 			return (1);
161 		}
162 		key = cmdp->argv[0]->bp[0];
163 		if (key > MAXVIKEY)
164 			goto nokey;
165 
166 		/* Special case: '[' and ']' commands. */
167 		if ((key == '[' || key == ']') && cmdp->argv[0]->bp[1] != key)
168 			goto nokey;
169 
170 		/* Special case: ~ command. */
171 		if (key == '~' && O_ISSET(sp, O_TILDEOP))
172 			kp = &tmotion;
173 		else
174 			kp = &vikeys[key];
175 
176 		if (kp->usage == NULL)
177 nokey:			(void)ex_printf(sp,
178 			    "The %s key has no current meaning\n",
179 			    KEY_NAME(sp, key));
180 		else
181 			(void)ex_printf(sp,
182 			    "  Key:%s%s\nUsage: %s\n",
183 			    isblank((unsigned char)*kp->help) ? "" : " ", kp->help, kp->usage);
184 		break;
185 	case 0:
186 		for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) {
187 			/* Special case: ~ command. */
188 			if (key == '~' && O_ISSET(sp, O_TILDEOP))
189 				kp = &tmotion;
190 			else
191 				kp = &vikeys[key];
192 			if (kp->help != NULL)
193 				(void)ex_printf(sp, "%s\n", kp->help);
194 		}
195 		break;
196 	default:
197 		abort();
198 	}
199 	return (0);
200 }
201