119304Speter/*-
219304Speter * Copyright (c) 1992, 1993, 1994
319304Speter *	The Regents of the University of California.  All rights reserved.
419304Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996
519304Speter *	Keith Bostic.  All rights reserved.
619304Speter *
719304Speter * See the LICENSE file for redistribution information.
819304Speter */
919304Speter
1019304Speter#include "config.h"
1119304Speter
1219304Speter#ifndef lint
13254225Speterstatic const char sccsid[] = "$Id: ex_usage.c,v 10.16 2011/12/21 19:26:48 zy Exp $";
1419304Speter#endif /* not lint */
1519304Speter
1619304Speter#include <sys/types.h>
1719304Speter#include <sys/queue.h>
1819304Speter#include <sys/time.h>
1919304Speter
2019304Speter#include <bitstring.h>
2119304Speter#include <ctype.h>
2219304Speter#include <limits.h>
2319304Speter#include <stdio.h>
2419304Speter#include <stdlib.h>
2519304Speter#include <string.h>
2619304Speter
2719304Speter#include "../common/common.h"
2819304Speter#include "../vi/vi.h"
2919304Speter
3019304Speter/*
3119304Speter * ex_help -- :help
3219304Speter *	Display help message.
3319304Speter *
34281373Sbapt * PUBLIC: int ex_help(SCR *, EXCMD *);
3519304Speter */
3619304Speterint
37254225Speterex_help(SCR *sp, EXCMD *cmdp)
3819304Speter{
3919304Speter	(void)ex_puts(sp,
4019304Speter	    "To see the list of vi commands, enter \":viusage<CR>\"\n");
4119304Speter	(void)ex_puts(sp,
4219304Speter	    "To see the list of ex commands, enter \":exusage<CR>\"\n");
4319304Speter	(void)ex_puts(sp,
4419304Speter	    "For an ex command usage statement enter \":exusage [cmd]<CR>\"\n");
4519304Speter	(void)ex_puts(sp,
4619304Speter	    "For a vi key usage statement enter \":viusage [key]<CR>\"\n");
4719304Speter	(void)ex_puts(sp, "To exit, enter \":q!\"\n");
4819304Speter	return (0);
4919304Speter}
5019304Speter
5119304Speter/*
5219304Speter * ex_usage -- :exusage [cmd]
5319304Speter *	Display ex usage strings.
5419304Speter *
55281373Sbapt * PUBLIC: int ex_usage(SCR *, EXCMD *);
5619304Speter */
5719304Speterint
58254225Speterex_usage(SCR *sp, EXCMD *cmdp)
5919304Speter{
6019304Speter	ARGS *ap;
6119304Speter	EXCMDLIST const *cp;
6219304Speter	int newscreen;
63254225Speter	CHAR_T *name, *p, nb[MAXCMDNAMELEN + 5];
6419304Speter
6519304Speter	switch (cmdp->argc) {
6619304Speter	case 1:
6719304Speter		ap = cmdp->argv[0];
68254225Speter		if (ISUPPER(ap->bp[0])) {
6919304Speter			newscreen = 1;
70254225Speter			ap->bp[0] = TOLOWER(ap->bp[0]);
7119304Speter		} else
7219304Speter			newscreen = 0;
7319304Speter		for (cp = cmds; cp->name != NULL &&
74254225Speter		    MEMCMP(ap->bp, cp->name, ap->len); ++cp);
7519304Speter		if (cp->name == NULL ||
76254225Speter		    (newscreen && !F_ISSET(cp, E_NEWSCREEN))) {
7719304Speter			if (newscreen)
78254225Speter				ap->bp[0] = TOUPPER(ap->bp[0]);
79254225Speter			(void)ex_printf(sp, "The "WVS" command is unknown\n",
8019304Speter			    (int)ap->len, ap->bp);
8119304Speter		} else {
8219304Speter			(void)ex_printf(sp,
8319304Speter			    "Command: %s\n  Usage: %s\n", cp->help, cp->usage);
8419304Speter			/*
8519304Speter			 * !!!
8619304Speter			 * The "visual" command has two modes, one from ex,
8719304Speter			 * one from the vi colon line.  Don't ask.
8819304Speter			 */
8919304Speter			if (cp != &cmds[C_VISUAL_EX] &&
9019304Speter			    cp != &cmds[C_VISUAL_VI])
9119304Speter				break;
9219304Speter			if (cp == &cmds[C_VISUAL_EX])
9319304Speter				cp = &cmds[C_VISUAL_VI];
9419304Speter			else
9519304Speter				cp = &cmds[C_VISUAL_EX];
9619304Speter			(void)ex_printf(sp,
9719304Speter			    "Command: %s\n  Usage: %s\n", cp->help, cp->usage);
9819304Speter		}
9919304Speter		break;
10019304Speter	case 0:
10119304Speter		for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp) {
10219304Speter			/*
10319304Speter			 * The ^D command has an unprintable name.
10419304Speter			 *
10519304Speter			 * XXX
10619304Speter			 * We display both capital and lower-case versions of
10719304Speter			 * the appropriate commands -- no need to add in extra
10819304Speter			 * room, they're all short names.
10919304Speter			 */
11019304Speter			if (cp == &cmds[C_SCROLL])
111254225Speter				name = L("^D");
11219304Speter			else if (F_ISSET(cp, E_NEWSCREEN)) {
11319304Speter				nb[0] = '[';
114254225Speter				nb[1] = TOUPPER(cp->name[0]);
11519304Speter				nb[2] = cp->name[0];
11619304Speter				nb[3] = ']';
11719304Speter				for (name = cp->name + 1,
11819304Speter				    p = nb + 4; (*p++ = *name++) != '\0';);
11919304Speter				name = nb;
12019304Speter			} else
12119304Speter				name = cp->name;
12219304Speter			(void)ex_printf(sp,
123254225Speter			    WVS": %s\n", MAXCMDNAMELEN, name, cp->help);
12419304Speter		}
12519304Speter		break;
12619304Speter	default:
12719304Speter		abort();
12819304Speter	}
12919304Speter	return (0);
13019304Speter}
13119304Speter
13219304Speter/*
13319304Speter * ex_viusage -- :viusage [key]
13419304Speter *	Display vi usage strings.
13519304Speter *
136281373Sbapt * PUBLIC: int ex_viusage(SCR *, EXCMD *);
13719304Speter */
13819304Speterint
139254225Speterex_viusage(SCR *sp, EXCMD *cmdp)
14019304Speter{
14119304Speter	GS *gp;
14219304Speter	VIKEYS const *kp;
14319304Speter	int key;
14419304Speter
14519304Speter	gp = sp->gp;
14619304Speter	switch (cmdp->argc) {
14719304Speter	case 1:
14819304Speter		if (cmdp->argv[0]->len != 1) {
14919304Speter			ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
15019304Speter			return (1);
15119304Speter		}
15219304Speter		key = cmdp->argv[0]->bp[0];
15319304Speter		if (key > MAXVIKEY)
15419304Speter			goto nokey;
15519304Speter
15619304Speter		/* Special case: '[' and ']' commands. */
15719304Speter		if ((key == '[' || key == ']') && cmdp->argv[0]->bp[1] != key)
15819304Speter			goto nokey;
15919304Speter
16019304Speter		/* Special case: ~ command. */
16119304Speter		if (key == '~' && O_ISSET(sp, O_TILDEOP))
16219304Speter			kp = &tmotion;
16319304Speter		else
16419304Speter			kp = &vikeys[key];
16519304Speter
16619304Speter		if (kp->usage == NULL)
16719304Speternokey:			(void)ex_printf(sp,
16819304Speter			    "The %s key has no current meaning\n",
16919304Speter			    KEY_NAME(sp, key));
17019304Speter		else
17119304Speter			(void)ex_printf(sp,
17219304Speter			    "  Key:%s%s\nUsage: %s\n",
17319304Speter			    isblank(*kp->help) ? "" : " ", kp->help, kp->usage);
17419304Speter		break;
17519304Speter	case 0:
17619304Speter		for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) {
17719304Speter			/* Special case: ~ command. */
17819304Speter			if (key == '~' && O_ISSET(sp, O_TILDEOP))
17919304Speter				kp = &tmotion;
18019304Speter			else
18119304Speter				kp = &vikeys[key];
18219304Speter			if (kp->help != NULL)
18319304Speter				(void)ex_printf(sp, "%s\n", kp->help);
18419304Speter		}
18519304Speter		break;
18619304Speter	default:
18719304Speter		abort();
18819304Speter	}
18919304Speter	return (0);
19019304Speter}
191