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
1319304Speterstatic const char sccsid[] = "@(#)ex_usage.c	10.13 (Berkeley) 5/3/96";
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 *
3419304Speter * PUBLIC: int ex_help __P((SCR *, EXCMD *));
3519304Speter */
3619304Speterint
3719304Speterex_help(sp, cmdp)
3819304Speter	SCR *sp;
3919304Speter	EXCMD *cmdp;
4019304Speter{
4119304Speter	(void)ex_puts(sp,
4219304Speter	    "To see the list of vi commands, enter \":viusage<CR>\"\n");
4319304Speter	(void)ex_puts(sp,
4419304Speter	    "To see the list of ex commands, enter \":exusage<CR>\"\n");
4519304Speter	(void)ex_puts(sp,
4619304Speter	    "For an ex command usage statement enter \":exusage [cmd]<CR>\"\n");
4719304Speter	(void)ex_puts(sp,
4819304Speter	    "For a vi key usage statement enter \":viusage [key]<CR>\"\n");
4919304Speter	(void)ex_puts(sp, "To exit, enter \":q!\"\n");
5019304Speter	return (0);
5119304Speter}
5219304Speter
5319304Speter/*
5419304Speter * ex_usage -- :exusage [cmd]
5519304Speter *	Display ex usage strings.
5619304Speter *
5719304Speter * PUBLIC: int ex_usage __P((SCR *, EXCMD *));
5819304Speter */
5919304Speterint
6019304Speterex_usage(sp, cmdp)
6119304Speter	SCR *sp;
6219304Speter	EXCMD *cmdp;
6319304Speter{
6419304Speter	ARGS *ap;
6519304Speter	EXCMDLIST const *cp;
6619304Speter	int newscreen;
6719304Speter	char *name, *p, nb[MAXCMDNAMELEN + 5];
6819304Speter
6919304Speter	switch (cmdp->argc) {
7019304Speter	case 1:
7119304Speter		ap = cmdp->argv[0];
7219304Speter		if (isupper(ap->bp[0])) {
7319304Speter			newscreen = 1;
7419304Speter			ap->bp[0] = tolower(ap->bp[0]);
7519304Speter		} else
7619304Speter			newscreen = 0;
7719304Speter		for (cp = cmds; cp->name != NULL &&
7819304Speter		    memcmp(ap->bp, cp->name, ap->len); ++cp);
7919304Speter		if (cp->name == NULL ||
8019304Speter		    newscreen && !F_ISSET(cp, E_NEWSCREEN)) {
8119304Speter			if (newscreen)
8219304Speter				ap->bp[0] = toupper(ap->bp[0]);
8319304Speter			(void)ex_printf(sp, "The %.*s command is unknown\n",
8419304Speter			    (int)ap->len, ap->bp);
8519304Speter		} else {
8619304Speter			(void)ex_printf(sp,
8719304Speter			    "Command: %s\n  Usage: %s\n", cp->help, cp->usage);
8819304Speter			/*
8919304Speter			 * !!!
9019304Speter			 * The "visual" command has two modes, one from ex,
9119304Speter			 * one from the vi colon line.  Don't ask.
9219304Speter			 */
9319304Speter			if (cp != &cmds[C_VISUAL_EX] &&
9419304Speter			    cp != &cmds[C_VISUAL_VI])
9519304Speter				break;
9619304Speter			if (cp == &cmds[C_VISUAL_EX])
9719304Speter				cp = &cmds[C_VISUAL_VI];
9819304Speter			else
9919304Speter				cp = &cmds[C_VISUAL_EX];
10019304Speter			(void)ex_printf(sp,
10119304Speter			    "Command: %s\n  Usage: %s\n", cp->help, cp->usage);
10219304Speter		}
10319304Speter		break;
10419304Speter	case 0:
10519304Speter		for (cp = cmds; cp->name != NULL && !INTERRUPTED(sp); ++cp) {
10619304Speter			/*
10719304Speter			 * The ^D command has an unprintable name.
10819304Speter			 *
10919304Speter			 * XXX
11019304Speter			 * We display both capital and lower-case versions of
11119304Speter			 * the appropriate commands -- no need to add in extra
11219304Speter			 * room, they're all short names.
11319304Speter			 */
11419304Speter			if (cp == &cmds[C_SCROLL])
11519304Speter				name = "^D";
11619304Speter			else if (F_ISSET(cp, E_NEWSCREEN)) {
11719304Speter				nb[0] = '[';
11819304Speter				nb[1] = toupper(cp->name[0]);
11919304Speter				nb[2] = cp->name[0];
12019304Speter				nb[3] = ']';
12119304Speter				for (name = cp->name + 1,
12219304Speter				    p = nb + 4; (*p++ = *name++) != '\0';);
12319304Speter				name = nb;
12419304Speter			} else
12519304Speter				name = cp->name;
12619304Speter			(void)ex_printf(sp,
12719304Speter			    "%*s: %s\n", MAXCMDNAMELEN, name, cp->help);
12819304Speter		}
12919304Speter		break;
13019304Speter	default:
13119304Speter		abort();
13219304Speter	}
13319304Speter	return (0);
13419304Speter}
13519304Speter
13619304Speter/*
13719304Speter * ex_viusage -- :viusage [key]
13819304Speter *	Display vi usage strings.
13919304Speter *
14019304Speter * PUBLIC: int ex_viusage __P((SCR *, EXCMD *));
14119304Speter */
14219304Speterint
14319304Speterex_viusage(sp, cmdp)
14419304Speter	SCR *sp;
14519304Speter	EXCMD *cmdp;
14619304Speter{
14719304Speter	GS *gp;
14819304Speter	VIKEYS const *kp;
14919304Speter	int key;
15019304Speter
15119304Speter	gp = sp->gp;
15219304Speter	switch (cmdp->argc) {
15319304Speter	case 1:
15419304Speter		if (cmdp->argv[0]->len != 1) {
15519304Speter			ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
15619304Speter			return (1);
15719304Speter		}
15819304Speter		key = cmdp->argv[0]->bp[0];
15919304Speter		if (key > MAXVIKEY)
16019304Speter			goto nokey;
16119304Speter
16219304Speter		/* Special case: '[' and ']' commands. */
16319304Speter		if ((key == '[' || key == ']') && cmdp->argv[0]->bp[1] != key)
16419304Speter			goto nokey;
16519304Speter
16619304Speter		/* Special case: ~ command. */
16719304Speter		if (key == '~' && O_ISSET(sp, O_TILDEOP))
16819304Speter			kp = &tmotion;
16919304Speter		else
17019304Speter			kp = &vikeys[key];
17119304Speter
17219304Speter		if (kp->usage == NULL)
17319304Speternokey:			(void)ex_printf(sp,
17419304Speter			    "The %s key has no current meaning\n",
17519304Speter			    KEY_NAME(sp, key));
17619304Speter		else
17719304Speter			(void)ex_printf(sp,
17819304Speter			    "  Key:%s%s\nUsage: %s\n",
17919304Speter			    isblank(*kp->help) ? "" : " ", kp->help, kp->usage);
18019304Speter		break;
18119304Speter	case 0:
18219304Speter		for (key = 0; key <= MAXVIKEY && !INTERRUPTED(sp); ++key) {
18319304Speter			/* Special case: ~ command. */
18419304Speter			if (key == '~' && O_ISSET(sp, O_TILDEOP))
18519304Speter				kp = &tmotion;
18619304Speter			else
18719304Speter				kp = &vikeys[key];
18819304Speter			if (kp->help != NULL)
18919304Speter				(void)ex_printf(sp, "%s\n", kp->help);
19019304Speter		}
19119304Speter		break;
19219304Speter	default:
19319304Speter		abort();
19419304Speter	}
19519304Speter	return (0);
19619304Speter}
197