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 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 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 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