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