1 /* $OpenBSD: ex_usage.c,v 1.10 2018/07/13 09:02:07 krw 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 62 switch (cmdp->argc) { 63 case 1: 64 ap = cmdp->argv[0]; 65 if (isupper(ap->bp[0])) { 66 newscreen = 1; 67 ap->bp[0] = tolower(ap->bp[0]); 68 } else 69 newscreen = 0; 70 for (cp = cmds; cp->name != NULL && 71 memcmp(ap->bp, cp->name, ap->len); ++cp); 72 if (cp->name == NULL || 73 (newscreen && !F_ISSET(cp, E_NEWSCREEN))) { 74 if (newscreen) 75 ap->bp[0] = toupper(ap->bp[0]); 76 (void)ex_printf(sp, "The %.*s command is unknown\n", 77 (int)ap->len, ap->bp); 78 } else { 79 (void)ex_printf(sp, 80 "Command: %s\n Usage: %s\n", cp->help, cp->usage); 81 /* 82 * !!! 83 * The "visual" command has two modes, one from ex, 84 * one from the vi colon line. Don't ask. 85 */ 86 if (cp != &cmds[C_VISUAL_EX] && 87 cp != &cmds[C_VISUAL_VI]) 88 break; 89 if (cp == &cmds[C_VISUAL_EX]) 90 cp = &cmds[C_VISUAL_VI]; 91 else 92 cp = &cmds[C_VISUAL_EX]; 93 (void)ex_printf(sp, 94 "Command: %s\n Usage: %s\n", cp->help, cp->usage); 95 } 96 break; 97 case 0: 98 for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp) 99 (void)ex_printf(sp, "%*s: %s\n", MAXCMDNAMELEN, 100 /* The ^D command has an unprintable name. */ 101 cp == &cmds[C_SCROLL] ? "^D" : cp->name, 102 cp->help); 103 break; 104 default: 105 abort(); 106 } 107 return (0); 108 } 109 110 /* 111 * ex_viusage -- :viusage [key] 112 * Display vi usage strings. 113 * 114 * PUBLIC: int ex_viusage(SCR *, EXCMD *); 115 */ 116 int 117 ex_viusage(SCR *sp, EXCMD *cmdp) 118 { 119 VIKEYS const *kp; 120 int key; 121 122 switch (cmdp->argc) { 123 case 1: 124 if (cmdp->argv[0]->len != 1) { 125 ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE); 126 return (1); 127 } 128 key = cmdp->argv[0]->bp[0]; 129 if (key > MAXVIKEY) 130 goto nokey; 131 132 /* Special case: '[' and ']' commands. */ 133 if ((key == '[' || key == ']') && cmdp->argv[0]->bp[1] != key) 134 goto nokey; 135 136 /* Special case: ~ command. */ 137 if (key == '~' && O_ISSET(sp, O_TILDEOP)) 138 kp = &tmotion; 139 else 140 kp = &vikeys[key]; 141 142 if (kp->usage == NULL) 143 nokey: (void)ex_printf(sp, 144 "The %s key has no current meaning\n", 145 KEY_NAME(sp, key)); 146 else 147 (void)ex_printf(sp, 148 " Key:%s%s\nUsage: %s\n", 149 isblank(*kp->help) ? "" : " ", kp->help, kp->usage); 150 break; 151 case 0: 152 for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) { 153 /* Special case: ~ command. */ 154 if (key == '~' && O_ISSET(sp, O_TILDEOP)) 155 kp = &tmotion; 156 else 157 kp = &vikeys[key]; 158 if (kp->help != NULL) 159 (void)ex_printf(sp, "%s\n", kp->help); 160 } 161 break; 162 default: 163 abort(); 164 } 165 return (0); 166 } 167