xref: /netbsd-src/lib/libedit/emacs.c (revision 34e53048e6f83f8e7e8303aec85dae23817d82a4)
1*34e53048Schristos /*	$NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 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*34e53048Schristos __RCSID("$NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
412543e3e6Slukem #endif
426dc2f1dbScgd #endif /* not lint && not SCCSID */
436dc2f1dbScgd 
446dc2f1dbScgd /*
456dc2f1dbScgd  * emacs.c: Emacs functions
466dc2f1dbScgd  */
476dc2f1dbScgd #include "el.h"
486dc2f1dbScgd 
496dc2f1dbScgd /* em_delete_or_list():
506dc2f1dbScgd  *	Delete character under cursor or list completions if at end of line
516dc2f1dbScgd  *	[^D]
526dc2f1dbScgd  */
536dc2f1dbScgd protected el_action_t
546dc2f1dbScgd /*ARGSUSED*/
55*34e53048Schristos em_delete_or_list(EditLine *el, Int c)
566dc2f1dbScgd {
57d30d584aSlukem 
58d30d584aSlukem 	if (el->el_line.cursor == el->el_line.lastchar) {
59d30d584aSlukem 					/* if I'm at the end */
60d30d584aSlukem 		if (el->el_line.cursor == el->el_line.buffer) {
61d30d584aSlukem 					/* and the beginning */
62230c3d4eSchristos 			term_writec(el, c);	/* then do an EOF */
63d30d584aSlukem 			return (CC_EOF);
64d30d584aSlukem 		} else {
65d30d584aSlukem 			/*
66d30d584aSlukem 			 * Here we could list completions, but it is an
67d30d584aSlukem 			 * error right now
68d30d584aSlukem 			 */
69b7cc0db1Scgd 			term_beep(el);
70d30d584aSlukem 			return (CC_ERROR);
716dc2f1dbScgd 		}
72d30d584aSlukem 	} else {
736360c4b0Smycroft 		if (el->el_state.doingarg)
746360c4b0Smycroft 			c_delafter(el, el->el_state.argument);
756360c4b0Smycroft 		else
766360c4b0Smycroft 			c_delafter1(el);
776dc2f1dbScgd 		if (el->el_line.cursor > el->el_line.lastchar)
78d30d584aSlukem 			el->el_line.cursor = el->el_line.lastchar;
79d30d584aSlukem 				/* bounds check */
80d30d584aSlukem 		return (CC_REFRESH);
816dc2f1dbScgd 	}
826dc2f1dbScgd }
836dc2f1dbScgd 
846dc2f1dbScgd 
856dc2f1dbScgd /* em_delete_next_word():
866dc2f1dbScgd  *	Cut from cursor to end of current word
876dc2f1dbScgd  *	[M-d]
886dc2f1dbScgd  */
896dc2f1dbScgd protected el_action_t
906dc2f1dbScgd /*ARGSUSED*/
91*34e53048Schristos em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
926dc2f1dbScgd {
93*34e53048Schristos 	Char *cp, *p, *kp;
946dc2f1dbScgd 
956dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.lastchar)
96d30d584aSlukem 		return (CC_ERROR);
976dc2f1dbScgd 
986dc2f1dbScgd 	cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
996dc2f1dbScgd 	    el->el_state.argument, ce__isword);
1006dc2f1dbScgd 
1016dc2f1dbScgd 	for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
1026dc2f1dbScgd 				/* save the text */
1036dc2f1dbScgd 		*kp++ = *p;
1046dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
1056dc2f1dbScgd 
1065c894153Schristos 	c_delafter(el, (int)(cp - el->el_line.cursor));	/* delete after dot */
1076dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
108d30d584aSlukem 		el->el_line.cursor = el->el_line.lastchar;
109d30d584aSlukem 				/* bounds check */
110d30d584aSlukem 	return (CC_REFRESH);
1116dc2f1dbScgd }
1126dc2f1dbScgd 
1136dc2f1dbScgd 
1146dc2f1dbScgd /* em_yank():
1156dc2f1dbScgd  *	Paste cut buffer at cursor position
1166dc2f1dbScgd  *	[^Y]
1176dc2f1dbScgd  */
1186dc2f1dbScgd protected el_action_t
1196dc2f1dbScgd /*ARGSUSED*/
120*34e53048Schristos em_yank(EditLine *el, Int c __attribute__((__unused__)))
1216dc2f1dbScgd {
122*34e53048Schristos 	Char *kp, *cp;
1236dc2f1dbScgd 
12472dc1c2aSchristos 	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
12572dc1c2aSchristos 		return (CC_NORM);
1266dc2f1dbScgd 
1276dc2f1dbScgd 	if (el->el_line.lastchar +
1286dc2f1dbScgd 	    (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
1296dc2f1dbScgd 	    el->el_line.limit)
130d30d584aSlukem 		return (CC_ERROR);
1316dc2f1dbScgd 
1326dc2f1dbScgd 	el->el_chared.c_kill.mark = el->el_line.cursor;
1336dc2f1dbScgd 	cp = el->el_line.cursor;
1346dc2f1dbScgd 
1356dc2f1dbScgd 	/* open the space, */
1365c894153Schristos 	c_insert(el,
1375c894153Schristos 	    (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
1386dc2f1dbScgd 	/* copy the chars */
1396dc2f1dbScgd 	for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
1406dc2f1dbScgd 		*cp++ = *kp;
1416dc2f1dbScgd 
1426dc2f1dbScgd 	/* if an arg, cursor at beginning else cursor at end */
1436dc2f1dbScgd 	if (el->el_state.argument == 1)
1446dc2f1dbScgd 		el->el_line.cursor = cp;
1456dc2f1dbScgd 
146d30d584aSlukem 	return (CC_REFRESH);
1476dc2f1dbScgd }
1486dc2f1dbScgd 
1496dc2f1dbScgd 
1506dc2f1dbScgd /* em_kill_line():
1516dc2f1dbScgd  *	Cut the entire line and save in cut buffer
1526dc2f1dbScgd  *	[^U]
1536dc2f1dbScgd  */
1546dc2f1dbScgd protected el_action_t
1556dc2f1dbScgd /*ARGSUSED*/
156*34e53048Schristos em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
1576dc2f1dbScgd {
158*34e53048Schristos 	Char *kp, *cp;
1596dc2f1dbScgd 
1606dc2f1dbScgd 	cp = el->el_line.buffer;
1616dc2f1dbScgd 	kp = el->el_chared.c_kill.buf;
1626dc2f1dbScgd 	while (cp < el->el_line.lastchar)
1636dc2f1dbScgd 		*kp++ = *cp++;	/* copy it */
1646dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
165d30d584aSlukem 				/* zap! -- delete all of it */
166d30d584aSlukem 	el->el_line.lastchar = el->el_line.buffer;
1676dc2f1dbScgd 	el->el_line.cursor = el->el_line.buffer;
168d30d584aSlukem 	return (CC_REFRESH);
1696dc2f1dbScgd }
1706dc2f1dbScgd 
1716dc2f1dbScgd 
1726dc2f1dbScgd /* em_kill_region():
1736dc2f1dbScgd  *	Cut area between mark and cursor and save in cut buffer
1746dc2f1dbScgd  *	[^W]
1756dc2f1dbScgd  */
1766dc2f1dbScgd protected el_action_t
1776dc2f1dbScgd /*ARGSUSED*/
178*34e53048Schristos em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
1796dc2f1dbScgd {
180*34e53048Schristos 	Char *kp, *cp;
1816dc2f1dbScgd 
1826dc2f1dbScgd 	if (!el->el_chared.c_kill.mark)
183d30d584aSlukem 		return (CC_ERROR);
1846dc2f1dbScgd 
1856dc2f1dbScgd 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
1866dc2f1dbScgd 		cp = el->el_line.cursor;
1876dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
1886dc2f1dbScgd 		while (cp < el->el_chared.c_kill.mark)
1896dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
1906dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
1915c894153Schristos 		c_delafter(el, (int)(cp - el->el_line.cursor));
192d30d584aSlukem 	} else {		/* mark is before cursor */
1936dc2f1dbScgd 		cp = el->el_chared.c_kill.mark;
1946dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
1956dc2f1dbScgd 		while (cp < el->el_line.cursor)
1966dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
1976dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
1985c894153Schristos 		c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
1996dc2f1dbScgd 		el->el_line.cursor = el->el_chared.c_kill.mark;
2006dc2f1dbScgd 	}
201d30d584aSlukem 	return (CC_REFRESH);
2026dc2f1dbScgd }
2036dc2f1dbScgd 
2046dc2f1dbScgd 
2056dc2f1dbScgd /* em_copy_region():
2066dc2f1dbScgd  *	Copy area between mark and cursor to cut buffer
2076dc2f1dbScgd  *	[M-W]
2086dc2f1dbScgd  */
2096dc2f1dbScgd protected el_action_t
2106dc2f1dbScgd /*ARGSUSED*/
211*34e53048Schristos em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
2126dc2f1dbScgd {
213*34e53048Schristos 	Char *kp, *cp;
2146dc2f1dbScgd 
215a17c7fe4Schristos 	if (!el->el_chared.c_kill.mark)
216d30d584aSlukem 		return (CC_ERROR);
2176dc2f1dbScgd 
2186dc2f1dbScgd 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
2196dc2f1dbScgd 		cp = el->el_line.cursor;
2206dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
2216dc2f1dbScgd 		while (cp < el->el_chared.c_kill.mark)
2226dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
2236dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
224d30d584aSlukem 	} else {
2256dc2f1dbScgd 		cp = el->el_chared.c_kill.mark;
2266dc2f1dbScgd 		kp = el->el_chared.c_kill.buf;
2276dc2f1dbScgd 		while (cp < el->el_line.cursor)
2286dc2f1dbScgd 			*kp++ = *cp++;	/* copy it */
2296dc2f1dbScgd 		el->el_chared.c_kill.last = kp;
2306dc2f1dbScgd 	}
231d30d584aSlukem 	return (CC_NORM);
2326dc2f1dbScgd }
2336dc2f1dbScgd 
2346dc2f1dbScgd 
23570286103Sperry /* em_gosmacs_transpose():
2366dc2f1dbScgd  *	Exchange the two characters before the cursor
2376dc2f1dbScgd  *	Gosling emacs transpose chars [^T]
2386dc2f1dbScgd  */
2396dc2f1dbScgd protected el_action_t
240*34e53048Schristos em_gosmacs_transpose(EditLine *el, Int c)
2416dc2f1dbScgd {
2426dc2f1dbScgd 
2436dc2f1dbScgd 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
2446dc2f1dbScgd 		/* must have at least two chars entered */
2456dc2f1dbScgd 		c = el->el_line.cursor[-2];
2466dc2f1dbScgd 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
2476dc2f1dbScgd 		el->el_line.cursor[-1] = c;
248d30d584aSlukem 		return (CC_REFRESH);
249d30d584aSlukem 	} else
250d30d584aSlukem 		return (CC_ERROR);
2516dc2f1dbScgd }
2526dc2f1dbScgd 
2536dc2f1dbScgd 
2546dc2f1dbScgd /* em_next_word():
2556dc2f1dbScgd  *	Move next to end of current word
2566dc2f1dbScgd  *	[M-f]
2576dc2f1dbScgd  */
2586dc2f1dbScgd protected el_action_t
2596dc2f1dbScgd /*ARGSUSED*/
260*34e53048Schristos em_next_word(EditLine *el, Int c __attribute__((__unused__)))
2616dc2f1dbScgd {
2626dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.lastchar)
263d30d584aSlukem 		return (CC_ERROR);
2646dc2f1dbScgd 
265d30d584aSlukem 	el->el_line.cursor = c__next_word(el->el_line.cursor,
266d30d584aSlukem 	    el->el_line.lastchar,
2676dc2f1dbScgd 	    el->el_state.argument,
2686dc2f1dbScgd 	    ce__isword);
2696dc2f1dbScgd 
2706dc2f1dbScgd 	if (el->el_map.type == MAP_VI)
27139f224afSchristos 		if (el->el_chared.c_vcmd.action != NOP) {
2726dc2f1dbScgd 			cv_delfini(el);
273d30d584aSlukem 			return (CC_REFRESH);
274d30d584aSlukem 		}
275d30d584aSlukem 	return (CC_CURSOR);
2766dc2f1dbScgd }
2776dc2f1dbScgd 
2786dc2f1dbScgd 
2796dc2f1dbScgd /* em_upper_case():
2806dc2f1dbScgd  *	Uppercase the characters from cursor to end of current word
2816dc2f1dbScgd  *	[M-u]
2826dc2f1dbScgd  */
2836dc2f1dbScgd protected el_action_t
2846dc2f1dbScgd /*ARGSUSED*/
285*34e53048Schristos em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
2866dc2f1dbScgd {
287*34e53048Schristos 	Char *cp, *ep;
2886dc2f1dbScgd 
2896dc2f1dbScgd 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
2906dc2f1dbScgd 	    el->el_state.argument, ce__isword);
2916dc2f1dbScgd 
2926dc2f1dbScgd 	for (cp = el->el_line.cursor; cp < ep; cp++)
293*34e53048Schristos 		if (Islower(*cp))
294*34e53048Schristos 			*cp = Toupper(*cp);
2956dc2f1dbScgd 
2966dc2f1dbScgd 	el->el_line.cursor = ep;
2976dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
2986dc2f1dbScgd 		el->el_line.cursor = el->el_line.lastchar;
299d30d584aSlukem 	return (CC_REFRESH);
3006dc2f1dbScgd }
3016dc2f1dbScgd 
3026dc2f1dbScgd 
3036dc2f1dbScgd /* em_capitol_case():
3046dc2f1dbScgd  *	Capitalize the characters from cursor to end of current word
3056dc2f1dbScgd  *	[M-c]
3066dc2f1dbScgd  */
3076dc2f1dbScgd protected el_action_t
3086dc2f1dbScgd /*ARGSUSED*/
309*34e53048Schristos em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
3106dc2f1dbScgd {
311*34e53048Schristos 	Char *cp, *ep;
3126dc2f1dbScgd 
3136dc2f1dbScgd 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
3146dc2f1dbScgd 	    el->el_state.argument, ce__isword);
3156dc2f1dbScgd 
3166dc2f1dbScgd 	for (cp = el->el_line.cursor; cp < ep; cp++) {
317*34e53048Schristos 		if (Isalpha(*cp)) {
318*34e53048Schristos 			if (Islower(*cp))
319*34e53048Schristos 				*cp = Toupper(*cp);
3206dc2f1dbScgd 			cp++;
3216dc2f1dbScgd 			break;
3226dc2f1dbScgd 		}
3236dc2f1dbScgd 	}
3246dc2f1dbScgd 	for (; cp < ep; cp++)
325*34e53048Schristos 		if (Isupper(*cp))
326*34e53048Schristos 			*cp = Tolower(*cp);
3276dc2f1dbScgd 
3286dc2f1dbScgd 	el->el_line.cursor = ep;
3296dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
3306dc2f1dbScgd 		el->el_line.cursor = el->el_line.lastchar;
331d30d584aSlukem 	return (CC_REFRESH);
3326dc2f1dbScgd }
3336dc2f1dbScgd 
334d30d584aSlukem 
3356dc2f1dbScgd /* em_lower_case():
3366dc2f1dbScgd  *	Lowercase the characters from cursor to end of current word
3376dc2f1dbScgd  *	[M-l]
3386dc2f1dbScgd  */
3396dc2f1dbScgd protected el_action_t
3406dc2f1dbScgd /*ARGSUSED*/
341*34e53048Schristos em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
3426dc2f1dbScgd {
343*34e53048Schristos 	Char *cp, *ep;
3446dc2f1dbScgd 
3456dc2f1dbScgd 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
3466dc2f1dbScgd 	    el->el_state.argument, ce__isword);
3476dc2f1dbScgd 
3486dc2f1dbScgd 	for (cp = el->el_line.cursor; cp < ep; cp++)
349*34e53048Schristos 		if (Isupper(*cp))
350*34e53048Schristos 			*cp = Tolower(*cp);
3516dc2f1dbScgd 
3526dc2f1dbScgd 	el->el_line.cursor = ep;
3536dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
3546dc2f1dbScgd 		el->el_line.cursor = el->el_line.lastchar;
355d30d584aSlukem 	return (CC_REFRESH);
3566dc2f1dbScgd }
3576dc2f1dbScgd 
3586dc2f1dbScgd 
3596dc2f1dbScgd /* em_set_mark():
3606dc2f1dbScgd  *	Set the mark at cursor
3616dc2f1dbScgd  *	[^@]
3626dc2f1dbScgd  */
3636dc2f1dbScgd protected el_action_t
3646dc2f1dbScgd /*ARGSUSED*/
365*34e53048Schristos em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
3666dc2f1dbScgd {
367d30d584aSlukem 
3686dc2f1dbScgd 	el->el_chared.c_kill.mark = el->el_line.cursor;
369d30d584aSlukem 	return (CC_NORM);
3706dc2f1dbScgd }
3716dc2f1dbScgd 
3726dc2f1dbScgd 
3736dc2f1dbScgd /* em_exchange_mark():
3746dc2f1dbScgd  *	Exchange the cursor and mark
3756dc2f1dbScgd  *	[^X^X]
3766dc2f1dbScgd  */
3776dc2f1dbScgd protected el_action_t
3786dc2f1dbScgd /*ARGSUSED*/
379*34e53048Schristos em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
3806dc2f1dbScgd {
381*34e53048Schristos 	Char *cp;
3826dc2f1dbScgd 
3836dc2f1dbScgd 	cp = el->el_line.cursor;
3846dc2f1dbScgd 	el->el_line.cursor = el->el_chared.c_kill.mark;
3856dc2f1dbScgd 	el->el_chared.c_kill.mark = cp;
386d30d584aSlukem 	return (CC_CURSOR);
3876dc2f1dbScgd }
3886dc2f1dbScgd 
389d30d584aSlukem 
3906dc2f1dbScgd /* em_universal_argument():
3916dc2f1dbScgd  *	Universal argument (argument times 4)
3926dc2f1dbScgd  *	[^U]
3936dc2f1dbScgd  */
3946dc2f1dbScgd protected el_action_t
3956dc2f1dbScgd /*ARGSUSED*/
396*34e53048Schristos em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
3976dc2f1dbScgd {				/* multiply current argument by 4 */
398d30d584aSlukem 
3996dc2f1dbScgd 	if (el->el_state.argument > 1000000)
400d30d584aSlukem 		return (CC_ERROR);
4016dc2f1dbScgd 	el->el_state.doingarg = 1;
4026dc2f1dbScgd 	el->el_state.argument *= 4;
403d30d584aSlukem 	return (CC_ARGHACK);
4046dc2f1dbScgd }
4056dc2f1dbScgd 
406d30d584aSlukem 
4076dc2f1dbScgd /* em_meta_next():
4086dc2f1dbScgd  *	Add 8th bit to next character typed
4096dc2f1dbScgd  *	[<ESC>]
4106dc2f1dbScgd  */
4116dc2f1dbScgd protected el_action_t
4126dc2f1dbScgd /*ARGSUSED*/
413*34e53048Schristos em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
4146dc2f1dbScgd {
415d30d584aSlukem 
4166dc2f1dbScgd 	el->el_state.metanext = 1;
417d30d584aSlukem 	return (CC_ARGHACK);
4186dc2f1dbScgd }
4196dc2f1dbScgd 
4206dc2f1dbScgd 
4216dc2f1dbScgd /* em_toggle_overwrite():
4226dc2f1dbScgd  *	Switch from insert to overwrite mode or vice versa
4236dc2f1dbScgd  */
4246dc2f1dbScgd protected el_action_t
4256dc2f1dbScgd /*ARGSUSED*/
426*34e53048Schristos em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
4276dc2f1dbScgd {
428d30d584aSlukem 
429d30d584aSlukem 	el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
430d30d584aSlukem 	    MODE_REPLACE : MODE_INSERT;
431d30d584aSlukem 	return (CC_NORM);
4326dc2f1dbScgd }
4336dc2f1dbScgd 
4346dc2f1dbScgd 
4356dc2f1dbScgd /* em_copy_prev_word():
4366dc2f1dbScgd  *	Copy current word to cursor
4376dc2f1dbScgd  */
4386dc2f1dbScgd protected el_action_t
4396dc2f1dbScgd /*ARGSUSED*/
440*34e53048Schristos em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
4416dc2f1dbScgd {
442*34e53048Schristos 	Char *cp, *oldc, *dp;
4436dc2f1dbScgd 
4446dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.buffer)
445d30d584aSlukem 		return (CC_ERROR);
4466dc2f1dbScgd 
4476dc2f1dbScgd 	oldc = el->el_line.cursor;
4486dc2f1dbScgd 	/* does a bounds check */
4496dc2f1dbScgd 	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
4506dc2f1dbScgd 	    el->el_state.argument, ce__isword);
4516dc2f1dbScgd 
4525c894153Schristos 	c_insert(el, (int)(oldc - cp));
4536dc2f1dbScgd 	for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
4546dc2f1dbScgd 		*dp++ = *cp;
4556dc2f1dbScgd 
4566dc2f1dbScgd 	el->el_line.cursor = dp;/* put cursor at end */
4576dc2f1dbScgd 
458d30d584aSlukem 	return (CC_REFRESH);
4596dc2f1dbScgd }
4606dc2f1dbScgd 
4616dc2f1dbScgd 
4626dc2f1dbScgd /* em_inc_search_next():
4636dc2f1dbScgd  *	Emacs incremental next search
4646dc2f1dbScgd  */
4656dc2f1dbScgd protected el_action_t
4666dc2f1dbScgd /*ARGSUSED*/
467*34e53048Schristos em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
4686dc2f1dbScgd {
469d30d584aSlukem 
4706dc2f1dbScgd 	el->el_search.patlen = 0;
471d30d584aSlukem 	return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
4726dc2f1dbScgd }
4736dc2f1dbScgd 
4746dc2f1dbScgd 
4756dc2f1dbScgd /* em_inc_search_prev():
4766dc2f1dbScgd  *	Emacs incremental reverse search
4776dc2f1dbScgd  */
4786dc2f1dbScgd protected el_action_t
4796dc2f1dbScgd /*ARGSUSED*/
480*34e53048Schristos em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
4816dc2f1dbScgd {
482d30d584aSlukem 
4836dc2f1dbScgd 	el->el_search.patlen = 0;
484d30d584aSlukem 	return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
4856dc2f1dbScgd }
4866360c4b0Smycroft 
4876360c4b0Smycroft 
4886360c4b0Smycroft /* em_delete_prev_char():
4896360c4b0Smycroft  *	Delete the character to the left of the cursor
4906360c4b0Smycroft  *	[^?]
4916360c4b0Smycroft  */
4926360c4b0Smycroft protected el_action_t
4936360c4b0Smycroft /*ARGSUSED*/
494*34e53048Schristos em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
4956360c4b0Smycroft {
4966360c4b0Smycroft 
4976360c4b0Smycroft 	if (el->el_line.cursor <= el->el_line.buffer)
4986360c4b0Smycroft 		return (CC_ERROR);
4996360c4b0Smycroft 
5006360c4b0Smycroft 	if (el->el_state.doingarg)
5016360c4b0Smycroft 		c_delbefore(el, el->el_state.argument);
5026360c4b0Smycroft 	else
5036360c4b0Smycroft 		c_delbefore1(el);
5046360c4b0Smycroft 	el->el_line.cursor -= el->el_state.argument;
5056360c4b0Smycroft 	if (el->el_line.cursor < el->el_line.buffer)
5066360c4b0Smycroft 		el->el_line.cursor = el->el_line.buffer;
5076360c4b0Smycroft 	return (CC_REFRESH);
5086360c4b0Smycroft }
509