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