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