1 /*- 2 * Copyright (c) 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1992, 1993, 1994, 1995, 1996 5 * Keith Bostic. All rights reserved. 6 * 7 * See the LICENSE file for redistribution information. 8 */ 9 10 #include "config.h" 11 12 #include <sys/types.h> 13 #include <sys/queue.h> 14 #include <sys/time.h> 15 16 #include <bitstring.h> 17 #include <ctype.h> 18 #include <limits.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 #include "../common/common.h" 24 #include "../vi/vi.h" 25 26 /* 27 * ex_help -- :help 28 * Display help message. 29 * 30 * PUBLIC: int ex_help(SCR *, EXCMD *); 31 */ 32 int 33 ex_help(SCR *sp, EXCMD *cmdp) 34 { 35 (void)ex_puts(sp, 36 "To see the list of vi commands, enter \":viusage<CR>\"\n"); 37 (void)ex_puts(sp, 38 "To see the list of ex commands, enter \":exusage<CR>\"\n"); 39 (void)ex_puts(sp, 40 "For an ex command usage statement enter \":exusage [cmd]<CR>\"\n"); 41 (void)ex_puts(sp, 42 "For a vi key usage statement enter \":viusage [key]<CR>\"\n"); 43 (void)ex_puts(sp, "To exit, enter \":q!\"\n"); 44 return (0); 45 } 46 47 /* 48 * ex_usage -- :exusage [cmd] 49 * Display ex usage strings. 50 * 51 * PUBLIC: int ex_usage(SCR *, EXCMD *); 52 */ 53 int 54 ex_usage(SCR *sp, EXCMD *cmdp) 55 { 56 ARGS *ap; 57 EXCMDLIST const *cp; 58 int newscreen; 59 CHAR_T *name, *p, nb[MAXCMDNAMELEN + 5]; 60 61 switch (cmdp->argc) { 62 case 1: 63 ap = cmdp->argv[0]; 64 if (ISUPPER(ap->bp[0])) { 65 newscreen = 1; 66 ap->bp[0] = TOLOWER(ap->bp[0]); 67 } else 68 newscreen = 0; 69 for (cp = cmds; cp->name != NULL && 70 MEMCMP(ap->bp, cp->name, ap->len); ++cp); 71 if (cp->name == NULL || 72 (newscreen && !F_ISSET(cp, E_NEWSCREEN))) { 73 if (newscreen) 74 ap->bp[0] = TOUPPER(ap->bp[0]); 75 (void)ex_printf(sp, "The "WVS" command is unknown\n", 76 (int)ap->len, ap->bp); 77 } else { 78 (void)ex_printf(sp, 79 "Command: %s\n Usage: %s\n", cp->help, cp->usage); 80 /* 81 * !!! 82 * The "visual" command has two modes, one from ex, 83 * one from the vi colon line. Don't ask. 84 */ 85 if (cp != &cmds[C_VISUAL_EX] && 86 cp != &cmds[C_VISUAL_VI]) 87 break; 88 if (cp == &cmds[C_VISUAL_EX]) 89 cp = &cmds[C_VISUAL_VI]; 90 else 91 cp = &cmds[C_VISUAL_EX]; 92 (void)ex_printf(sp, 93 "Command: %s\n Usage: %s\n", cp->help, cp->usage); 94 } 95 break; 96 case 0: 97 for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp) { 98 /* 99 * The ^D command has an unprintable name. 100 * 101 * XXX 102 * We display both capital and lower-case versions of 103 * the appropriate commands -- no need to add in extra 104 * room, they're all short names. 105 */ 106 if (cp == &cmds[C_SCROLL]) 107 name = L("^D"); 108 else if (F_ISSET(cp, E_NEWSCREEN)) { 109 nb[0] = '['; 110 nb[1] = TOUPPER(cp->name[0]); 111 nb[2] = cp->name[0]; 112 nb[3] = ']'; 113 for (name = cp->name + 1, 114 p = nb + 4; (*p++ = *name++) != '\0';); 115 name = nb; 116 } else 117 name = cp->name; 118 (void)ex_printf(sp, 119 WVS": %s\n", MAXCMDNAMELEN, name, cp->help); 120 } 121 break; 122 default: 123 abort(); 124 } 125 return (0); 126 } 127 128 /* 129 * ex_viusage -- :viusage [key] 130 * Display vi usage strings. 131 * 132 * PUBLIC: int ex_viusage(SCR *, EXCMD *); 133 */ 134 int 135 ex_viusage(SCR *sp, EXCMD *cmdp) 136 { 137 GS *gp; 138 VIKEYS const *kp; 139 int key; 140 141 gp = sp->gp; 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((u_char)*kp->help) ? "" : " ", 170 kp->help, kp->usage); 171 break; 172 case 0: 173 for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) { 174 /* Special case: ~ command. */ 175 if (key == '~' && O_ISSET(sp, O_TILDEOP)) 176 kp = &tmotion; 177 else 178 kp = &vikeys[key]; 179 if (kp->help != NULL) 180 (void)ex_printf(sp, "%s\n", kp->help); 181 } 182 break; 183 default: 184 abort(); 185 } 186 return (0); 187 } 188