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