1 /* $OpenBSD: ex_usage.c,v 1.8 2014/11/12 04:28:41 bentley 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(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 56 ex_usage(SCR *sp, EXCMD *cmdp) 57 { 58 ARGS *ap; 59 EXCMDLIST const *cp; 60 int newscreen; 61 char *name, *p, nb[MAXCMDNAMELEN + 5]; 62 63 switch (cmdp->argc) { 64 case 1: 65 ap = cmdp->argv[0]; 66 if (isupper(ap->bp[0])) { 67 newscreen = 1; 68 ap->bp[0] = tolower(ap->bp[0]); 69 } else 70 newscreen = 0; 71 for (cp = cmds; cp->name != NULL && 72 memcmp(ap->bp, cp->name, ap->len); ++cp); 73 if (cp->name == NULL || 74 (newscreen && !F_ISSET(cp, E_NEWSCREEN))) { 75 if (newscreen) 76 ap->bp[0] = toupper(ap->bp[0]); 77 (void)ex_printf(sp, "The %.*s command is unknown\n", 78 (int)ap->len, ap->bp); 79 } else { 80 (void)ex_printf(sp, 81 "Command: %s\n Usage: %s\n", cp->help, cp->usage); 82 /* 83 * !!! 84 * The "visual" command has two modes, one from ex, 85 * one from the vi colon line. Don't ask. 86 */ 87 if (cp != &cmds[C_VISUAL_EX] && 88 cp != &cmds[C_VISUAL_VI]) 89 break; 90 if (cp == &cmds[C_VISUAL_EX]) 91 cp = &cmds[C_VISUAL_VI]; 92 else 93 cp = &cmds[C_VISUAL_EX]; 94 (void)ex_printf(sp, 95 "Command: %s\n Usage: %s\n", cp->help, cp->usage); 96 } 97 break; 98 case 0: 99 for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp) { 100 /* 101 * The ^D command has an unprintable name. 102 * 103 * XXX 104 * We display both capital and lower-case versions of 105 * the appropriate commands -- no need to add in extra 106 * room, they're all short names. 107 */ 108 if (cp == &cmds[C_SCROLL]) 109 name = "^D"; 110 else if (F_ISSET(cp, E_NEWSCREEN)) { 111 nb[0] = '['; 112 nb[1] = toupper(cp->name[0]); 113 nb[2] = cp->name[0]; 114 nb[3] = ']'; 115 for (name = cp->name + 1, 116 p = nb + 4; (*p++ = *name++) != '\0';); 117 name = nb; 118 } else 119 name = cp->name; 120 (void)ex_printf(sp, 121 "%*s: %s\n", MAXCMDNAMELEN, name, cp->help); 122 } 123 break; 124 default: 125 abort(); 126 } 127 return (0); 128 } 129 130 /* 131 * ex_viusage -- :viusage [key] 132 * Display vi usage strings. 133 * 134 * PUBLIC: int ex_viusage(SCR *, EXCMD *); 135 */ 136 int 137 ex_viusage(SCR *sp, EXCMD *cmdp) 138 { 139 VIKEYS const *kp; 140 int key; 141 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(*kp->help) ? "" : " ", kp->help, kp->usage); 170 break; 171 case 0: 172 for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) { 173 /* Special case: ~ command. */ 174 if (key == '~' && O_ISSET(sp, O_TILDEOP)) 175 kp = &tmotion; 176 else 177 kp = &vikeys[key]; 178 if (kp->help != NULL) 179 (void)ex_printf(sp, "%s\n", kp->help); 180 } 181 break; 182 default: 183 abort(); 184 } 185 return (0); 186 } 187