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