xref: /netbsd-src/lib/libedit/emacs.c (revision e84df91e329c612f2c9ce617d30a181994d93d29)
1*e84df91eSchristos /*	$NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $	*/
22543e3e6Slukem 
36dc2f1dbScgd /*-
46dc2f1dbScgd  * Copyright (c) 1992, 1993
56dc2f1dbScgd  *	The Regents of the University of California.  All rights reserved.
66dc2f1dbScgd  *
76dc2f1dbScgd  * This code is derived from software contributed to Berkeley by
86dc2f1dbScgd  * Christos Zoulas of Cornell University.
96dc2f1dbScgd  *
106dc2f1dbScgd  * Redistribution and use in source and binary forms, with or without
116dc2f1dbScgd  * modification, are permitted provided that the following conditions
126dc2f1dbScgd  * are met:
136dc2f1dbScgd  * 1. Redistributions of source code must retain the above copyright
146dc2f1dbScgd  *    notice, this list of conditions and the following disclaimer.
156dc2f1dbScgd  * 2. Redistributions in binary form must reproduce the above copyright
166dc2f1dbScgd  *    notice, this list of conditions and the following disclaimer in the
176dc2f1dbScgd  *    documentation and/or other materials provided with the distribution.
18eb7c1594Sagc  * 3. Neither the name of the University nor the names of its contributors
196dc2f1dbScgd  *    may be used to endorse or promote products derived from this software
206dc2f1dbScgd  *    without specific prior written permission.
216dc2f1dbScgd  *
226dc2f1dbScgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
236dc2f1dbScgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
246dc2f1dbScgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
256dc2f1dbScgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
266dc2f1dbScgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
276dc2f1dbScgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
286dc2f1dbScgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
296dc2f1dbScgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
306dc2f1dbScgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
316dc2f1dbScgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
326dc2f1dbScgd  * SUCH DAMAGE.
336dc2f1dbScgd  */
346dc2f1dbScgd 
350e0ac6b7Schristos #include "config.h"
366dc2f1dbScgd #if !defined(lint) && !defined(SCCSID)
372543e3e6Slukem #if 0
386dc2f1dbScgd static char sccsid[] = "@(#)emacs.c	8.1 (Berkeley) 6/4/93";
392543e3e6Slukem #else
40*e84df91eSchristos __RCSID("$NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $");
412543e3e6Slukem #endif
426dc2f1dbScgd #endif /* not lint && not SCCSID */
436dc2f1dbScgd 
446dc2f1dbScgd /*
456dc2f1dbScgd  * emacs.c: Emacs functions
466dc2f1dbScgd  */
47*e84df91eSchristos #include <ctype.h>
48*e84df91eSchristos 
496dc2f1dbScgd #include "el.h"
50747f6811Schristos #include "emacs.h"
516dc2f1dbScgd 
526dc2f1dbScgd /* em_delete_or_list():
536dc2f1dbScgd  *	Delete character under cursor or list completions if at end of line
546dc2f1dbScgd  *	[^D]
556dc2f1dbScgd  */
566dc2f1dbScgd protected el_action_t
576dc2f1dbScgd /*ARGSUSED*/
58f54e4f97Schristos em_delete_or_list(EditLine *el, wint_t c)
596dc2f1dbScgd {
60d30d584aSlukem 
61d30d584aSlukem 	if (el->el_line.cursor == el->el_line.lastchar) {
62d30d584aSlukem 					/* if I'm at the end */
63d30d584aSlukem 		if (el->el_line.cursor == el->el_line.buffer) {
64d30d584aSlukem 					/* and the beginning */
6598c7cbebSchristos 			terminal_writec(el, c);	/* then do an EOF */
66b71bed95Schristos 			return CC_EOF;
67d30d584aSlukem 		} else {
68d30d584aSlukem 			/*
69d30d584aSlukem 			 * Here we could list completions, but it is an
70d30d584aSlukem 			 * error right now
71d30d584aSlukem 			 */
7298c7cbebSchristos 			terminal_beep(el);
73b71bed95Schristos 			return CC_ERROR;
746dc2f1dbScgd 		}
75d30d584aSlukem 	} else {
766360c4b0Smycroft 		if (el->el_state.doingarg)
776360c4b0Smycroft 			c_delafter(el, el->el_state.argument);
786360c4b0Smycroft 		else
796360c4b0Smycroft 			c_delafter1(el);
806dc2f1dbScgd 		if (el->el_line.cursor > el->el_line.lastchar)
81d30d584aSlukem 			el->el_line.cursor = el->el_line.lastchar;
82d30d584aSlukem 				/* bounds check */
83b71bed95Schristos 		return CC_REFRESH;
846dc2f1dbScgd 	}
856dc2f1dbScgd }
866dc2f1dbScgd 
876dc2f1dbScgd 
886dc2f1dbScgd /* em_delete_next_word():
896dc2f1dbScgd  *	Cut from cursor to end of current word
906dc2f1dbScgd  *	[M-d]
916dc2f1dbScgd  */
926dc2f1dbScgd protected el_action_t
936dc2f1dbScgd /*ARGSUSED*/
94f54e4f97Schristos em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
956dc2f1dbScgd {
9634e53048Schristos 	Char *cp, *p, *kp;
976dc2f1dbScgd 
986dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.lastchar)
99b71bed95Schristos 		return CC_ERROR;
1006dc2f1dbScgd 
1016dc2f1dbScgd 	cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
1026dc2f1dbScgd 	    el->el_state.argument, ce__isword);
1036dc2f1dbScgd 
1046dc2f1dbScgd 	for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
1056dc2f1dbScgd 				/* save the text */
1066dc2f1dbScgd 		*kp++ = *p;
1076dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
1086dc2f1dbScgd 
1095c894153Schristos 	c_delafter(el, (int)(cp - el->el_line.cursor));	/* delete after dot */
1106dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
111d30d584aSlukem 		el->el_line.cursor = el->el_line.lastchar;
112d30d584aSlukem 				/* bounds check */
113b71bed95Schristos 	return CC_REFRESH;
1146dc2f1dbScgd }
1156dc2f1dbScgd 
1166dc2f1dbScgd 
1176dc2f1dbScgd /* em_yank():
1186dc2f1dbScgd  *	Paste cut buffer at cursor position
1196dc2f1dbScgd  *	[^Y]
1206dc2f1dbScgd  */
1216dc2f1dbScgd protected el_action_t
1226dc2f1dbScgd /*ARGSUSED*/
123f54e4f97Schristos em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
1246dc2f1dbScgd {
12534e53048Schristos 	Char *kp, *cp;
1266dc2f1dbScgd 
12772dc1c2aSchristos 	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
128b71bed95Schristos 		return CC_NORM;
1296dc2f1dbScgd 
1306dc2f1dbScgd 	if (el->el_line.lastchar +
1316dc2f1dbScgd 	    (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
1326dc2f1dbScgd 	    el->el_line.limit)
133b71bed95Schristos 		return CC_ERROR;
1346dc2f1dbScgd 
1356dc2f1dbScgd 	el->el_chared.c_kill.mark = el->el_line.cursor;
1366dc2f1dbScgd 	cp = el->el_line.cursor;
1376dc2f1dbScgd 
1386dc2f1dbScgd 	/* open the space, */
1395c894153Schristos 	c_insert(el,
1405c894153Schristos 	    (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
1416dc2f1dbScgd 	/* copy the chars */
1426dc2f1dbScgd 	for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
1436dc2f1dbScgd 		*cp++ = *kp;
1446dc2f1dbScgd 
1456dc2f1dbScgd 	/* if an arg, cursor at beginning else cursor at end */
1466dc2f1dbScgd 	if (el->el_state.argument == 1)
1476dc2f1dbScgd 		el->el_line.cursor = cp;
1486dc2f1dbScgd 
149b71bed95Schristos 	return CC_REFRESH;
1506dc2f1dbScgd }
1516dc2f1dbScgd 
1526dc2f1dbScgd 
1536dc2f1dbScgd /* em_kill_line():
1546dc2f1dbScgd  *	Cut the entire line and save in cut buffer
1556dc2f1dbScgd  *	[^U]
1566dc2f1dbScgd  */
1576dc2f1dbScgd protected el_action_t
1586dc2f1dbScgd /*ARGSUSED*/
159f54e4f97Schristos em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
1606dc2f1dbScgd {
16134e53048Schristos 	Char *kp, *cp;
1626dc2f1dbScgd 
1636dc2f1dbScgd 	cp = el->el_line.buffer;
1646dc2f1dbScgd 	kp = el->el_chared.c_kill.buf;
1656dc2f1dbScgd 	while (cp < el->el_line.lastchar)
1666dc2f1dbScgd 		*kp++ = *cp++;	/* copy it */
1676dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
168d30d584aSlukem 				/* zap! -- delete all of it */
169d30d584aSlukem 	el->el_line.lastchar = el->el_line.buffer;
1706dc2f1dbScgd 	el->el_line.cursor = el->el_line.buffer;
171b71bed95Schristos 	return CC_REFRESH;
1726dc2f1dbScgd }
1736dc2f1dbScgd 
1746dc2f1dbScgd 
1756dc2f1dbScgd /* em_kill_region():
1766dc2f1dbScgd  *	Cut area between mark and cursor and save in cut buffer
1776dc2f1dbScgd  *	[^W]
1786dc2f1dbScgd  */
1796dc2f1dbScgd protected el_action_t
1806dc2f1dbScgd /*ARGSUSED*/
181f54e4f97Schristos em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
1826dc2f1dbScgd {
18334e53048Schristos 	Char *kp, *cp;
1846dc2f1dbScgd 
1856dc2f1dbScgd 	if (!el->el_chared.c_kill.mark)
186b71bed95Schristos 		return CC_ERROR;
1876dc2f1dbScgd 
1886dc2f1dbScgd 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
1896dc2f1dbScgd 		cp = el->el_line.cursor;
1906dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
1916dc2f1dbScgd 		while (cp < el->el_chared.c_kill.mark)
1926dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
1936dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
1945c894153Schristos 		c_delafter(el, (int)(cp - el->el_line.cursor));
195d30d584aSlukem 	} else {		/* mark is before cursor */
1966dc2f1dbScgd 		cp = el->el_chared.c_kill.mark;
1976dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
1986dc2f1dbScgd 		while (cp < el->el_line.cursor)
1996dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
2006dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
2015c894153Schristos 		c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
2026dc2f1dbScgd 		el->el_line.cursor = el->el_chared.c_kill.mark;
2036dc2f1dbScgd 	}
204b71bed95Schristos 	return CC_REFRESH;
2056dc2f1dbScgd }
2066dc2f1dbScgd 
2076dc2f1dbScgd 
2086dc2f1dbScgd /* em_copy_region():
2096dc2f1dbScgd  *	Copy area between mark and cursor to cut buffer
2106dc2f1dbScgd  *	[M-W]
2116dc2f1dbScgd  */
2126dc2f1dbScgd protected el_action_t
2136dc2f1dbScgd /*ARGSUSED*/
214f54e4f97Schristos em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
2156dc2f1dbScgd {
21634e53048Schristos 	Char *kp, *cp;
2176dc2f1dbScgd 
218a17c7fe4Schristos 	if (!el->el_chared.c_kill.mark)
219b71bed95Schristos 		return CC_ERROR;
2206dc2f1dbScgd 
2216dc2f1dbScgd 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
2226dc2f1dbScgd 		cp = el->el_line.cursor;
2236dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
2246dc2f1dbScgd 		while (cp < el->el_chared.c_kill.mark)
2256dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
2266dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
227d30d584aSlukem 	} else {
2286dc2f1dbScgd 		cp = el->el_chared.c_kill.mark;
2296dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
2306dc2f1dbScgd 		while (cp < el->el_line.cursor)
2316dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
2326dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
2336dc2f1dbScgd 	}
234b71bed95Schristos 	return CC_NORM;
2356dc2f1dbScgd }
2366dc2f1dbScgd 
2376dc2f1dbScgd 
23870286103Sperry /* em_gosmacs_transpose():
2396dc2f1dbScgd  *	Exchange the two characters before the cursor
2406dc2f1dbScgd  *	Gosling emacs transpose chars [^T]
2416dc2f1dbScgd  */
2426dc2f1dbScgd protected el_action_t
243f54e4f97Schristos em_gosmacs_transpose(EditLine *el, wint_t c)
2446dc2f1dbScgd {
2456dc2f1dbScgd 
2466dc2f1dbScgd 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
2476dc2f1dbScgd 		/* must have at least two chars entered */
2486dc2f1dbScgd 		c = el->el_line.cursor[-2];
2496dc2f1dbScgd 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
2506af8d673Schristos 		el->el_line.cursor[-1] = (Char)c;
251b71bed95Schristos 		return CC_REFRESH;
252d30d584aSlukem 	} else
253b71bed95Schristos 		return CC_ERROR;
2546dc2f1dbScgd }
2556dc2f1dbScgd 
2566dc2f1dbScgd 
2576dc2f1dbScgd /* em_next_word():
2586dc2f1dbScgd  *	Move next to end of current word
2596dc2f1dbScgd  *	[M-f]
2606dc2f1dbScgd  */
2616dc2f1dbScgd protected el_action_t
2626dc2f1dbScgd /*ARGSUSED*/
263f54e4f97Schristos em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
2646dc2f1dbScgd {
2656dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.lastchar)
266b71bed95Schristos 		return CC_ERROR;
2676dc2f1dbScgd 
268d30d584aSlukem 	el->el_line.cursor = c__next_word(el->el_line.cursor,
269d30d584aSlukem 	    el->el_line.lastchar,
2706dc2f1dbScgd 	    el->el_state.argument,
2716dc2f1dbScgd 	    ce__isword);
2726dc2f1dbScgd 
2736dc2f1dbScgd 	if (el->el_map.type == MAP_VI)
27439f224afSchristos 		if (el->el_chared.c_vcmd.action != NOP) {
2756dc2f1dbScgd 			cv_delfini(el);
276b71bed95Schristos 			return CC_REFRESH;
277d30d584aSlukem 		}
278b71bed95Schristos 	return CC_CURSOR;
2796dc2f1dbScgd }
2806dc2f1dbScgd 
2816dc2f1dbScgd 
2826dc2f1dbScgd /* em_upper_case():
2836dc2f1dbScgd  *	Uppercase the characters from cursor to end of current word
2846dc2f1dbScgd  *	[M-u]
2856dc2f1dbScgd  */
2866dc2f1dbScgd protected el_action_t
2876dc2f1dbScgd /*ARGSUSED*/
288f54e4f97Schristos em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
2896dc2f1dbScgd {
29034e53048Schristos 	Char *cp, *ep;
2916dc2f1dbScgd 
2926dc2f1dbScgd 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
2936dc2f1dbScgd 	    el->el_state.argument, ce__isword);
2946dc2f1dbScgd 
2956dc2f1dbScgd 	for (cp = el->el_line.cursor; cp < ep; cp++)
29634e53048Schristos 		if (Islower(*cp))
29734e53048Schristos 			*cp = Toupper(*cp);
2986dc2f1dbScgd 
2996dc2f1dbScgd 	el->el_line.cursor = ep;
3006dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
3016dc2f1dbScgd 		el->el_line.cursor = el->el_line.lastchar;
302b71bed95Schristos 	return CC_REFRESH;
3036dc2f1dbScgd }
3046dc2f1dbScgd 
3056dc2f1dbScgd 
3066dc2f1dbScgd /* em_capitol_case():
3076dc2f1dbScgd  *	Capitalize the characters from cursor to end of current word
3086dc2f1dbScgd  *	[M-c]
3096dc2f1dbScgd  */
3106dc2f1dbScgd protected el_action_t
3116dc2f1dbScgd /*ARGSUSED*/
312f54e4f97Schristos em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
3136dc2f1dbScgd {
31434e53048Schristos 	Char *cp, *ep;
3156dc2f1dbScgd 
3166dc2f1dbScgd 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
3176dc2f1dbScgd 	    el->el_state.argument, ce__isword);
3186dc2f1dbScgd 
3196dc2f1dbScgd 	for (cp = el->el_line.cursor; cp < ep; cp++) {
32034e53048Schristos 		if (Isalpha(*cp)) {
32134e53048Schristos 			if (Islower(*cp))
32234e53048Schristos 				*cp = Toupper(*cp);
3236dc2f1dbScgd 			cp++;
3246dc2f1dbScgd 			break;
3256dc2f1dbScgd 		}
3266dc2f1dbScgd 	}
3276dc2f1dbScgd 	for (; cp < ep; cp++)
32834e53048Schristos 		if (Isupper(*cp))
32934e53048Schristos 			*cp = Tolower(*cp);
3306dc2f1dbScgd 
3316dc2f1dbScgd 	el->el_line.cursor = ep;
3326dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
3336dc2f1dbScgd 		el->el_line.cursor = el->el_line.lastchar;
334b71bed95Schristos 	return CC_REFRESH;
3356dc2f1dbScgd }
3366dc2f1dbScgd 
337d30d584aSlukem 
3386dc2f1dbScgd /* em_lower_case():
3396dc2f1dbScgd  *	Lowercase the characters from cursor to end of current word
3406dc2f1dbScgd  *	[M-l]
3416dc2f1dbScgd  */
3426dc2f1dbScgd protected el_action_t
3436dc2f1dbScgd /*ARGSUSED*/
344f54e4f97Schristos em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
3456dc2f1dbScgd {
34634e53048Schristos 	Char *cp, *ep;
3476dc2f1dbScgd 
3486dc2f1dbScgd 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
3496dc2f1dbScgd 	    el->el_state.argument, ce__isword);
3506dc2f1dbScgd 
3516dc2f1dbScgd 	for (cp = el->el_line.cursor; cp < ep; cp++)
35234e53048Schristos 		if (Isupper(*cp))
35334e53048Schristos 			*cp = Tolower(*cp);
3546dc2f1dbScgd 
3556dc2f1dbScgd 	el->el_line.cursor = ep;
3566dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
3576dc2f1dbScgd 		el->el_line.cursor = el->el_line.lastchar;
358b71bed95Schristos 	return CC_REFRESH;
3596dc2f1dbScgd }
3606dc2f1dbScgd 
3616dc2f1dbScgd 
3626dc2f1dbScgd /* em_set_mark():
3636dc2f1dbScgd  *	Set the mark at cursor
3646dc2f1dbScgd  *	[^@]
3656dc2f1dbScgd  */
3666dc2f1dbScgd protected el_action_t
3676dc2f1dbScgd /*ARGSUSED*/
368f54e4f97Schristos em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
3696dc2f1dbScgd {
370d30d584aSlukem 
3716dc2f1dbScgd 	el->el_chared.c_kill.mark = el->el_line.cursor;
372b71bed95Schristos 	return CC_NORM;
3736dc2f1dbScgd }
3746dc2f1dbScgd 
3756dc2f1dbScgd 
3766dc2f1dbScgd /* em_exchange_mark():
3776dc2f1dbScgd  *	Exchange the cursor and mark
3786dc2f1dbScgd  *	[^X^X]
3796dc2f1dbScgd  */
3806dc2f1dbScgd protected el_action_t
3816dc2f1dbScgd /*ARGSUSED*/
382f54e4f97Schristos em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
3836dc2f1dbScgd {
38434e53048Schristos 	Char *cp;
3856dc2f1dbScgd 
3866dc2f1dbScgd 	cp = el->el_line.cursor;
3876dc2f1dbScgd 	el->el_line.cursor = el->el_chared.c_kill.mark;
3886dc2f1dbScgd 	el->el_chared.c_kill.mark = cp;
389b71bed95Schristos 	return CC_CURSOR;
3906dc2f1dbScgd }
3916dc2f1dbScgd 
392d30d584aSlukem 
3936dc2f1dbScgd /* em_universal_argument():
3946dc2f1dbScgd  *	Universal argument (argument times 4)
3956dc2f1dbScgd  *	[^U]
3966dc2f1dbScgd  */
3976dc2f1dbScgd protected el_action_t
3986dc2f1dbScgd /*ARGSUSED*/
399f54e4f97Schristos em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
4006dc2f1dbScgd {				/* multiply current argument by 4 */
401d30d584aSlukem 
4026dc2f1dbScgd 	if (el->el_state.argument > 1000000)
403b71bed95Schristos 		return CC_ERROR;
4046dc2f1dbScgd 	el->el_state.doingarg = 1;
4056dc2f1dbScgd 	el->el_state.argument *= 4;
406b71bed95Schristos 	return CC_ARGHACK;
4076dc2f1dbScgd }
4086dc2f1dbScgd 
409d30d584aSlukem 
4106dc2f1dbScgd /* em_meta_next():
4116dc2f1dbScgd  *	Add 8th bit to next character typed
4126dc2f1dbScgd  *	[<ESC>]
4136dc2f1dbScgd  */
4146dc2f1dbScgd protected el_action_t
4156dc2f1dbScgd /*ARGSUSED*/
416f54e4f97Schristos em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
4176dc2f1dbScgd {
418d30d584aSlukem 
4196dc2f1dbScgd 	el->el_state.metanext = 1;
420b71bed95Schristos 	return CC_ARGHACK;
4216dc2f1dbScgd }
4226dc2f1dbScgd 
4236dc2f1dbScgd 
4246dc2f1dbScgd /* em_toggle_overwrite():
4256dc2f1dbScgd  *	Switch from insert to overwrite mode or vice versa
4266dc2f1dbScgd  */
4276dc2f1dbScgd protected el_action_t
4286dc2f1dbScgd /*ARGSUSED*/
429f54e4f97Schristos em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
4306dc2f1dbScgd {
431d30d584aSlukem 
432d30d584aSlukem 	el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
433d30d584aSlukem 	    MODE_REPLACE : MODE_INSERT;
434b71bed95Schristos 	return CC_NORM;
4356dc2f1dbScgd }
4366dc2f1dbScgd 
4376dc2f1dbScgd 
4386dc2f1dbScgd /* em_copy_prev_word():
4396dc2f1dbScgd  *	Copy current word to cursor
4406dc2f1dbScgd  */
4416dc2f1dbScgd protected el_action_t
4426dc2f1dbScgd /*ARGSUSED*/
443f54e4f97Schristos em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
4446dc2f1dbScgd {
44534e53048Schristos 	Char *cp, *oldc, *dp;
4466dc2f1dbScgd 
4476dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.buffer)
448b71bed95Schristos 		return CC_ERROR;
4496dc2f1dbScgd 
4506dc2f1dbScgd 	oldc = el->el_line.cursor;
4516dc2f1dbScgd 	/* does a bounds check */
4526dc2f1dbScgd 	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
4536dc2f1dbScgd 	    el->el_state.argument, ce__isword);
4546dc2f1dbScgd 
4555c894153Schristos 	c_insert(el, (int)(oldc - cp));
4566dc2f1dbScgd 	for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
4576dc2f1dbScgd 		*dp++ = *cp;
4586dc2f1dbScgd 
4596dc2f1dbScgd 	el->el_line.cursor = dp;/* put cursor at end */
4606dc2f1dbScgd 
461b71bed95Schristos 	return CC_REFRESH;
4626dc2f1dbScgd }
4636dc2f1dbScgd 
4646dc2f1dbScgd 
4656dc2f1dbScgd /* em_inc_search_next():
4666dc2f1dbScgd  *	Emacs incremental next search
4676dc2f1dbScgd  */
4686dc2f1dbScgd protected el_action_t
4696dc2f1dbScgd /*ARGSUSED*/
470f54e4f97Schristos em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
4716dc2f1dbScgd {
472d30d584aSlukem 
4736dc2f1dbScgd 	el->el_search.patlen = 0;
474b71bed95Schristos 	return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
4756dc2f1dbScgd }
4766dc2f1dbScgd 
4776dc2f1dbScgd 
4786dc2f1dbScgd /* em_inc_search_prev():
4796dc2f1dbScgd  *	Emacs incremental reverse search
4806dc2f1dbScgd  */
4816dc2f1dbScgd protected el_action_t
4826dc2f1dbScgd /*ARGSUSED*/
483f54e4f97Schristos em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
4846dc2f1dbScgd {
485d30d584aSlukem 
4866dc2f1dbScgd 	el->el_search.patlen = 0;
487b71bed95Schristos 	return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
4886dc2f1dbScgd }
4896360c4b0Smycroft 
4906360c4b0Smycroft 
4916360c4b0Smycroft /* em_delete_prev_char():
4926360c4b0Smycroft  *	Delete the character to the left of the cursor
4936360c4b0Smycroft  *	[^?]
4946360c4b0Smycroft  */
4956360c4b0Smycroft protected el_action_t
4966360c4b0Smycroft /*ARGSUSED*/
497f54e4f97Schristos em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
4986360c4b0Smycroft {
4996360c4b0Smycroft 
5006360c4b0Smycroft 	if (el->el_line.cursor <= el->el_line.buffer)
501b71bed95Schristos 		return CC_ERROR;
5026360c4b0Smycroft 
5036360c4b0Smycroft 	if (el->el_state.doingarg)
5046360c4b0Smycroft 		c_delbefore(el, el->el_state.argument);
5056360c4b0Smycroft 	else
5066360c4b0Smycroft 		c_delbefore1(el);
5076360c4b0Smycroft 	el->el_line.cursor -= el->el_state.argument;
5086360c4b0Smycroft 	if (el->el_line.cursor < el->el_line.buffer)
5096360c4b0Smycroft 		el->el_line.cursor = el->el_line.buffer;
510b71bed95Schristos 	return CC_REFRESH;
5116360c4b0Smycroft }
512