ex_map.c revision 19304
1251881Speter/*-
2251881Speter * Copyright (c) 1992, 1993, 1994
3251881Speter *	The Regents of the University of California.  All rights reserved.
4251881Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996
5251881Speter *	Keith Bostic.  All rights reserved.
6251881Speter *
7251881Speter * See the LICENSE file for redistribution information.
8251881Speter */
9251881Speter
10251881Speter#include "config.h"
11251881Speter
12251881Speter#ifndef lint
13251881Speterstatic const char sccsid[] = "@(#)ex_map.c	10.9 (Berkeley) 3/6/96";
14251881Speter#endif /* not lint */
15251881Speter
16251881Speter#include <sys/types.h>
17251881Speter#include <sys/queue.h>
18251881Speter
19251881Speter#include <bitstring.h>
20251881Speter#include <ctype.h>
21251881Speter#include <limits.h>
22251881Speter#include <stdio.h>
23251881Speter#include <stdlib.h>
24251881Speter#include <string.h>
25251881Speter
26251881Speter#include "../common/common.h"
27251881Speter
28251881Speter/*
29251881Speter * ex_map -- :map[!] [input] [replacement]
30251881Speter *	Map a key/string or display mapped keys.
31251881Speter *
32251881Speter * Historical note:
33251881Speter *	Historic vi maps were fairly bizarre, and likely to differ in
34251881Speter *	very subtle and strange ways from this implementation.  Two
35251881Speter *	things worth noting are that vi would often hang or drop core
36251881Speter *	if the map was strange enough (ex: map X "xy$@x^V), or, simply
37251881Speter *	not work.  One trick worth remembering is that if you put a
38251881Speter *	mark at the start of the map, e.g. map X mx"xy ...), or if you
39251881Speter *	put the map in a .exrc file, things would often work much better.
40251881Speter *	No clue why.
41251881Speter *
42251881Speter * PUBLIC: int ex_map __P((SCR *, EXCMD *));
43251881Speter */
44251881Speterint
45251881Speterex_map(sp, cmdp)
46251881Speter	SCR *sp;
47251881Speter	EXCMD *cmdp;
48251881Speter{
49251881Speter	seq_t stype;
50251881Speter	CHAR_T *input, *p;
51251881Speter
52251881Speter	stype = FL_ISSET(cmdp->iflags, E_C_FORCE) ? SEQ_INPUT : SEQ_COMMAND;
53251881Speter
54251881Speter	switch (cmdp->argc) {
55251881Speter	case 0:
56251881Speter		if (seq_dump(sp, stype, 1) == 0)
57251881Speter			msgq(sp, M_INFO, stype == SEQ_INPUT ?
58251881Speter			    "132|No input map entries" :
59251881Speter			    "133|No command map entries");
60251881Speter		return (0);
61251881Speter	case 2:
62251881Speter		input = cmdp->argv[0]->bp;
63251881Speter		break;
64251881Speter	default:
65251881Speter		abort();
66251881Speter	}
67251881Speter
68251881Speter	/*
69251881Speter	 * If the mapped string is #[0-9]* (and wasn't quoted) then store the
70251881Speter	 * function key mapping.  If the screen specific routine has been set,
71251881Speter	 * call it as well.  Note, the SEQ_FUNCMAP type is persistent across
72251881Speter	 * screen types, maybe the next screen type will get it right.
73251881Speter	 */
74251881Speter	if (input[0] == '#' && isdigit(input[1])) {
75251881Speter		for (p = input + 2; isdigit(*p); ++p);
76251881Speter		if (p[0] != '\0')
77251881Speter			goto nofunc;
78251881Speter
79251881Speter		if (seq_set(sp, NULL, 0, input, cmdp->argv[0]->len,
80251881Speter		    cmdp->argv[1]->bp, cmdp->argv[1]->len, stype,
81251881Speter		    SEQ_FUNCMAP | SEQ_USERDEF))
82251881Speter			return (1);
83251881Speter		return (sp->gp->scr_fmap == NULL ? 0 :
84251881Speter		    sp->gp->scr_fmap(sp, stype, input, cmdp->argv[0]->len,
85251881Speter		    cmdp->argv[1]->bp, cmdp->argv[1]->len));
86251881Speter	}
87251881Speter
88251881Speter	/* Some single keys may not be remapped in command mode. */
89251881Speternofunc:	if (stype == SEQ_COMMAND && input[1] == '\0')
90251881Speter		switch (KEY_VAL(sp, input[0])) {
91251881Speter		case K_COLON:
92251881Speter		case K_ESCAPE:
93251881Speter		case K_NL:
94251881Speter			msgq(sp, M_ERR,
95251881Speter			    "134|The %s character may not be remapped",
96251881Speter			    KEY_NAME(sp, input[0]));
97251881Speter			return (1);
98251881Speter		}
99251881Speter	return (seq_set(sp, NULL, 0, input, cmdp->argv[0]->len,
100251881Speter	    cmdp->argv[1]->bp, cmdp->argv[1]->len, stype, SEQ_USERDEF));
101251881Speter}
102251881Speter
103251881Speter/*
104251881Speter * ex_unmap -- (:unmap[!] key)
105251881Speter *	Unmap a key.
106251881Speter *
107251881Speter * PUBLIC: int ex_unmap __P((SCR *, EXCMD *));
108251881Speter */
109251881Speterint
110251881Speterex_unmap(sp, cmdp)
111251881Speter	SCR *sp;
112251881Speter	EXCMD *cmdp;
113251881Speter{
114251881Speter	if (seq_delete(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len,
115251881Speter	    FL_ISSET(cmdp->iflags, E_C_FORCE) ? SEQ_INPUT : SEQ_COMMAND)) {
116251881Speter		msgq_str(sp, M_INFO,
117251881Speter		    cmdp->argv[0]->bp, "135|\"%s\" isn't currently mapped");
118251881Speter		return (1);
119251881Speter	}
120251881Speter	return (0);
121251881Speter}
122251881Speter