1 /* $OpenBSD: ex_usage.c,v 1.10 2018/07/13 09:02:07 krw 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(SCR * sp,EXCMD * cmdp)35 ex_help(SCR *sp, EXCMD *cmdp)
36 {
37 (void)ex_puts(sp,
38 "To see the list of vi commands, enter \":viusage<CR>\"\n");
39 (void)ex_puts(sp,
40 "To see the list of ex commands, enter \":exusage<CR>\"\n");
41 (void)ex_puts(sp,
42 "For an ex command usage statement enter \":exusage [cmd]<CR>\"\n");
43 (void)ex_puts(sp,
44 "For a vi key usage statement enter \":viusage [key]<CR>\"\n");
45 (void)ex_puts(sp, "To exit, enter \":q!\"\n");
46 return (0);
47 }
48
49 /*
50 * ex_usage -- :exusage [cmd]
51 * Display ex usage strings.
52 *
53 * PUBLIC: int ex_usage(SCR *, EXCMD *);
54 */
55 int
ex_usage(SCR * sp,EXCMD * cmdp)56 ex_usage(SCR *sp, EXCMD *cmdp)
57 {
58 ARGS *ap;
59 EXCMDLIST const *cp;
60 int newscreen;
61
62 switch (cmdp->argc) {
63 case 1:
64 ap = cmdp->argv[0];
65 if (isupper(ap->bp[0])) {
66 newscreen = 1;
67 ap->bp[0] = tolower(ap->bp[0]);
68 } else
69 newscreen = 0;
70 for (cp = cmds; cp->name != NULL &&
71 memcmp(ap->bp, cp->name, ap->len); ++cp);
72 if (cp->name == NULL ||
73 (newscreen && !F_ISSET(cp, E_NEWSCREEN))) {
74 if (newscreen)
75 ap->bp[0] = toupper(ap->bp[0]);
76 (void)ex_printf(sp, "The %.*s command is unknown\n",
77 (int)ap->len, ap->bp);
78 } else {
79 (void)ex_printf(sp,
80 "Command: %s\n Usage: %s\n", cp->help, cp->usage);
81 /*
82 * !!!
83 * The "visual" command has two modes, one from ex,
84 * one from the vi colon line. Don't ask.
85 */
86 if (cp != &cmds[C_VISUAL_EX] &&
87 cp != &cmds[C_VISUAL_VI])
88 break;
89 if (cp == &cmds[C_VISUAL_EX])
90 cp = &cmds[C_VISUAL_VI];
91 else
92 cp = &cmds[C_VISUAL_EX];
93 (void)ex_printf(sp,
94 "Command: %s\n Usage: %s\n", cp->help, cp->usage);
95 }
96 break;
97 case 0:
98 for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp)
99 (void)ex_printf(sp, "%*s: %s\n", MAXCMDNAMELEN,
100 /* The ^D command has an unprintable name. */
101 cp == &cmds[C_SCROLL] ? "^D" : cp->name,
102 cp->help);
103 break;
104 default:
105 abort();
106 }
107 return (0);
108 }
109
110 /*
111 * ex_viusage -- :viusage [key]
112 * Display vi usage strings.
113 *
114 * PUBLIC: int ex_viusage(SCR *, EXCMD *);
115 */
116 int
ex_viusage(SCR * sp,EXCMD * cmdp)117 ex_viusage(SCR *sp, EXCMD *cmdp)
118 {
119 VIKEYS const *kp;
120 int key;
121
122 switch (cmdp->argc) {
123 case 1:
124 if (cmdp->argv[0]->len != 1) {
125 ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
126 return (1);
127 }
128 key = cmdp->argv[0]->bp[0];
129 if (key > MAXVIKEY)
130 goto nokey;
131
132 /* Special case: '[' and ']' commands. */
133 if ((key == '[' || key == ']') && cmdp->argv[0]->bp[1] != key)
134 goto nokey;
135
136 /* Special case: ~ command. */
137 if (key == '~' && O_ISSET(sp, O_TILDEOP))
138 kp = &tmotion;
139 else
140 kp = &vikeys[key];
141
142 if (kp->usage == NULL)
143 nokey: (void)ex_printf(sp,
144 "The %s key has no current meaning\n",
145 KEY_NAME(sp, key));
146 else
147 (void)ex_printf(sp,
148 " Key:%s%s\nUsage: %s\n",
149 isblank(*kp->help) ? "" : " ", kp->help, kp->usage);
150 break;
151 case 0:
152 for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) {
153 /* Special case: ~ command. */
154 if (key == '~' && O_ISSET(sp, O_TILDEOP))
155 kp = &tmotion;
156 else
157 kp = &vikeys[key];
158 if (kp->help != NULL)
159 (void)ex_printf(sp, "%s\n", kp->help);
160 }
161 break;
162 default:
163 abort();
164 }
165 return (0);
166 }
167