xref: /openbsd-src/lib/libedit/emacs.c (revision 5b133f3f277e80f096764111e64f3a1284acb179)
1*5b133f3fSguenther /*	$OpenBSD: emacs.c,v 1.18 2023/03/08 04:43:05 guenther Exp $	*/
213e01c7aSschwarze /*	$NetBSD: emacs.c,v 1.35 2016/04/18 17:01:19 christos Exp $	*/
3babb851aSmillert 
4df930be7Sderaadt /*-
5df930be7Sderaadt  * Copyright (c) 1992, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * This code is derived from software contributed to Berkeley by
9df930be7Sderaadt  * Christos Zoulas of Cornell University.
10df930be7Sderaadt  *
11df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
12df930be7Sderaadt  * modification, are permitted provided that the following conditions
13df930be7Sderaadt  * are met:
14df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
15df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
16df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
17df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
18df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
196580fee3Smillert  * 3. Neither the name of the University nor the names of its contributors
20df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
21df930be7Sderaadt  *    without specific prior written permission.
22df930be7Sderaadt  *
23df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33df930be7Sderaadt  * SUCH DAMAGE.
34df930be7Sderaadt  */
35df930be7Sderaadt 
36d484b7d0Sotto #include "config.h"
37df930be7Sderaadt 
38df930be7Sderaadt /*
39df930be7Sderaadt  * emacs.c: Emacs functions
40df930be7Sderaadt  */
417ccfa089Sschwarze #include <ctype.h>
427ccfa089Sschwarze 
43df930be7Sderaadt #include "el.h"
445564fb94Sschwarze #include "emacs.h"
4513e01c7aSschwarze #include "fcns.h"
46df930be7Sderaadt 
47df930be7Sderaadt /* em_delete_or_list():
48df930be7Sderaadt  *	Delete character under cursor or list completions if at end of line
49df930be7Sderaadt  *	[^D]
50df930be7Sderaadt  */
51df930be7Sderaadt protected el_action_t
em_delete_or_list(EditLine * el,wint_t c)52b2589f0bSschwarze em_delete_or_list(EditLine *el, wint_t c)
53df930be7Sderaadt {
54d484b7d0Sotto 
55d484b7d0Sotto 	if (el->el_line.cursor == el->el_line.lastchar) {
56d484b7d0Sotto 					/* if I'm at the end */
57d484b7d0Sotto 		if (el->el_line.cursor == el->el_line.buffer) {
58d484b7d0Sotto 					/* and the beginning */
59fd40972aSschwarze 			terminal_writec(el, c);	/* then do an EOF */
6028d54ee8Sschwarze 			return CC_EOF;
61d484b7d0Sotto 		} else {
62d484b7d0Sotto 			/*
63d484b7d0Sotto 			 * Here we could list completions, but it is an
64d484b7d0Sotto 			 * error right now
65d484b7d0Sotto 			 */
66fd40972aSschwarze 			terminal_beep(el);
6728d54ee8Sschwarze 			return CC_ERROR;
68df930be7Sderaadt 		}
69d484b7d0Sotto 	} else {
70aed0ee81Snicm 		if (el->el_state.doingarg)
71aed0ee81Snicm 			c_delafter(el, el->el_state.argument);
72aed0ee81Snicm 		else
73aed0ee81Snicm 			c_delafter1(el);
74df930be7Sderaadt 		if (el->el_line.cursor > el->el_line.lastchar)
75d484b7d0Sotto 			el->el_line.cursor = el->el_line.lastchar;
76d484b7d0Sotto 				/* bounds check */
7728d54ee8Sschwarze 		return CC_REFRESH;
78df930be7Sderaadt 	}
79df930be7Sderaadt }
80df930be7Sderaadt 
81df930be7Sderaadt 
82df930be7Sderaadt /* em_delete_next_word():
83df930be7Sderaadt  *	Cut from cursor to end of current word
84df930be7Sderaadt  *	[M-d]
85df930be7Sderaadt  */
86df930be7Sderaadt protected el_action_t
em_delete_next_word(EditLine * el,wint_t c)87b2589f0bSschwarze em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
88df930be7Sderaadt {
89e3191321Sschwarze 	wchar_t *cp, *p, *kp;
90df930be7Sderaadt 
91df930be7Sderaadt 	if (el->el_line.cursor == el->el_line.lastchar)
9228d54ee8Sschwarze 		return CC_ERROR;
93df930be7Sderaadt 
94df930be7Sderaadt 	cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
95df930be7Sderaadt 	    el->el_state.argument, ce__isword);
96df930be7Sderaadt 
97df930be7Sderaadt 	for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
98df930be7Sderaadt 				/* save the text */
99df930be7Sderaadt 		*kp++ = *p;
100df930be7Sderaadt 	el->el_chared.c_kill.last = kp;
101df930be7Sderaadt 
102aed0ee81Snicm 	c_delafter(el, (int)(cp - el->el_line.cursor));	/* delete after dot */
103df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
104d484b7d0Sotto 		el->el_line.cursor = el->el_line.lastchar;
105d484b7d0Sotto 				/* bounds check */
10628d54ee8Sschwarze 	return CC_REFRESH;
107df930be7Sderaadt }
108df930be7Sderaadt 
109df930be7Sderaadt 
110df930be7Sderaadt /* em_yank():
111df930be7Sderaadt  *	Paste cut buffer at cursor position
112df930be7Sderaadt  *	[^Y]
113df930be7Sderaadt  */
114df930be7Sderaadt protected el_action_t
em_yank(EditLine * el,wint_t c)115b2589f0bSschwarze em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
116df930be7Sderaadt {
117e3191321Sschwarze 	wchar_t *kp, *cp;
118df930be7Sderaadt 
1196e02e073Sotto 	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
12028d54ee8Sschwarze 		return CC_NORM;
121df930be7Sderaadt 
122df930be7Sderaadt 	if (el->el_line.lastchar +
123df930be7Sderaadt 	    (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
124df930be7Sderaadt 	    el->el_line.limit)
12528d54ee8Sschwarze 		return CC_ERROR;
126df930be7Sderaadt 
127df930be7Sderaadt 	el->el_chared.c_kill.mark = el->el_line.cursor;
128df930be7Sderaadt 	cp = el->el_line.cursor;
129df930be7Sderaadt 
130df930be7Sderaadt 	/* open the space, */
131aed0ee81Snicm 	c_insert(el,
132aed0ee81Snicm 	    (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
133df930be7Sderaadt 	/* copy the chars */
134df930be7Sderaadt 	for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
135df930be7Sderaadt 		*cp++ = *kp;
136df930be7Sderaadt 
137df930be7Sderaadt 	/* if an arg, cursor at beginning else cursor at end */
138df930be7Sderaadt 	if (el->el_state.argument == 1)
139df930be7Sderaadt 		el->el_line.cursor = cp;
140df930be7Sderaadt 
14128d54ee8Sschwarze 	return CC_REFRESH;
142df930be7Sderaadt }
143df930be7Sderaadt 
144df930be7Sderaadt 
145df930be7Sderaadt /* em_kill_line():
146df930be7Sderaadt  *	Cut the entire line and save in cut buffer
147df930be7Sderaadt  *	[^U]
148df930be7Sderaadt  */
149df930be7Sderaadt protected el_action_t
em_kill_line(EditLine * el,wint_t c)150b2589f0bSschwarze em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
151df930be7Sderaadt {
152e3191321Sschwarze 	wchar_t *kp, *cp;
153df930be7Sderaadt 
154df930be7Sderaadt 	cp = el->el_line.buffer;
155df930be7Sderaadt 	kp = el->el_chared.c_kill.buf;
156df930be7Sderaadt 	while (cp < el->el_line.lastchar)
157df930be7Sderaadt 		*kp++ = *cp++;	/* copy it */
158df930be7Sderaadt 	el->el_chared.c_kill.last = kp;
159d484b7d0Sotto 				/* zap! -- delete all of it */
160d484b7d0Sotto 	el->el_line.lastchar = el->el_line.buffer;
161df930be7Sderaadt 	el->el_line.cursor = el->el_line.buffer;
16228d54ee8Sschwarze 	return CC_REFRESH;
163df930be7Sderaadt }
164df930be7Sderaadt 
165df930be7Sderaadt 
166df930be7Sderaadt /* em_kill_region():
167df930be7Sderaadt  *	Cut area between mark and cursor and save in cut buffer
168df930be7Sderaadt  *	[^W]
169df930be7Sderaadt  */
170df930be7Sderaadt protected el_action_t
em_kill_region(EditLine * el,wint_t c)171b2589f0bSschwarze em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
172df930be7Sderaadt {
173e3191321Sschwarze 	wchar_t *kp, *cp;
174df930be7Sderaadt 
175df930be7Sderaadt 	if (!el->el_chared.c_kill.mark)
17628d54ee8Sschwarze 		return CC_ERROR;
177df930be7Sderaadt 
178df930be7Sderaadt 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
179df930be7Sderaadt 		cp = el->el_line.cursor;
180df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
181df930be7Sderaadt 		while (cp < el->el_chared.c_kill.mark)
182df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
183df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
184aed0ee81Snicm 		c_delafter(el, (int)(cp - el->el_line.cursor));
185d484b7d0Sotto 	} else {		/* mark is before cursor */
186df930be7Sderaadt 		cp = el->el_chared.c_kill.mark;
187df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
188df930be7Sderaadt 		while (cp < el->el_line.cursor)
189df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
190df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
191aed0ee81Snicm 		c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
192df930be7Sderaadt 		el->el_line.cursor = el->el_chared.c_kill.mark;
193df930be7Sderaadt 	}
19428d54ee8Sschwarze 	return CC_REFRESH;
195df930be7Sderaadt }
196df930be7Sderaadt 
197df930be7Sderaadt 
198df930be7Sderaadt /* em_copy_region():
199df930be7Sderaadt  *	Copy area between mark and cursor to cut buffer
200df930be7Sderaadt  *	[M-W]
201df930be7Sderaadt  */
202df930be7Sderaadt protected el_action_t
em_copy_region(EditLine * el,wint_t c)203b2589f0bSschwarze em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
204df930be7Sderaadt {
205e3191321Sschwarze 	wchar_t *kp, *cp;
206df930be7Sderaadt 
207d484b7d0Sotto 	if (!el->el_chared.c_kill.mark)
20828d54ee8Sschwarze 		return CC_ERROR;
209df930be7Sderaadt 
210df930be7Sderaadt 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
211df930be7Sderaadt 		cp = el->el_line.cursor;
212df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
213df930be7Sderaadt 		while (cp < el->el_chared.c_kill.mark)
214df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
215df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
216d484b7d0Sotto 	} else {
217df930be7Sderaadt 		cp = el->el_chared.c_kill.mark;
218df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
219df930be7Sderaadt 		while (cp < el->el_line.cursor)
220df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
221df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
222df930be7Sderaadt 	}
22328d54ee8Sschwarze 	return CC_NORM;
224df930be7Sderaadt }
225df930be7Sderaadt 
226df930be7Sderaadt 
227d484b7d0Sotto /* em_gosmacs_transpose():
228df930be7Sderaadt  *	Exchange the two characters before the cursor
229df930be7Sderaadt  *	Gosling emacs transpose chars [^T]
230df930be7Sderaadt  */
231df930be7Sderaadt protected el_action_t
em_gosmacs_transpose(EditLine * el,wint_t c)232b2589f0bSschwarze em_gosmacs_transpose(EditLine *el, wint_t c)
233df930be7Sderaadt {
234df930be7Sderaadt 
235df930be7Sderaadt 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
236df930be7Sderaadt 		/* must have at least two chars entered */
237df930be7Sderaadt 		c = el->el_line.cursor[-2];
238df930be7Sderaadt 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
239df930be7Sderaadt 		el->el_line.cursor[-1] = c;
24028d54ee8Sschwarze 		return CC_REFRESH;
241d484b7d0Sotto 	} else
24228d54ee8Sschwarze 		return CC_ERROR;
243df930be7Sderaadt }
244df930be7Sderaadt 
245df930be7Sderaadt 
246df930be7Sderaadt /* em_next_word():
247df930be7Sderaadt  *	Move next to end of current word
248df930be7Sderaadt  *	[M-f]
249df930be7Sderaadt  */
250df930be7Sderaadt protected el_action_t
em_next_word(EditLine * el,wint_t c)251b2589f0bSschwarze em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
252df930be7Sderaadt {
253df930be7Sderaadt 	if (el->el_line.cursor == el->el_line.lastchar)
25428d54ee8Sschwarze 		return CC_ERROR;
255df930be7Sderaadt 
256d484b7d0Sotto 	el->el_line.cursor = c__next_word(el->el_line.cursor,
257d484b7d0Sotto 	    el->el_line.lastchar,
258df930be7Sderaadt 	    el->el_state.argument,
259df930be7Sderaadt 	    ce__isword);
260df930be7Sderaadt 
261df930be7Sderaadt 	if (el->el_map.type == MAP_VI)
262d484b7d0Sotto 		if (el->el_chared.c_vcmd.action != NOP) {
263df930be7Sderaadt 			cv_delfini(el);
26428d54ee8Sschwarze 			return CC_REFRESH;
265d484b7d0Sotto 		}
26628d54ee8Sschwarze 	return CC_CURSOR;
267df930be7Sderaadt }
268df930be7Sderaadt 
269df930be7Sderaadt 
270df930be7Sderaadt /* em_upper_case():
271df930be7Sderaadt  *	Uppercase the characters from cursor to end of current word
272df930be7Sderaadt  *	[M-u]
273df930be7Sderaadt  */
274df930be7Sderaadt protected el_action_t
em_upper_case(EditLine * el,wint_t c)275b2589f0bSschwarze em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
276df930be7Sderaadt {
277e3191321Sschwarze 	wchar_t *cp, *ep;
278df930be7Sderaadt 
279df930be7Sderaadt 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
280df930be7Sderaadt 	    el->el_state.argument, ce__isword);
281df930be7Sderaadt 
282df930be7Sderaadt 	for (cp = el->el_line.cursor; cp < ep; cp++)
283565aa7e8Sschwarze 		if (iswlower(*cp))
284565aa7e8Sschwarze 			*cp = towupper(*cp);
285df930be7Sderaadt 
286df930be7Sderaadt 	el->el_line.cursor = ep;
287df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
288df930be7Sderaadt 		el->el_line.cursor = el->el_line.lastchar;
28928d54ee8Sschwarze 	return CC_REFRESH;
290df930be7Sderaadt }
291df930be7Sderaadt 
292df930be7Sderaadt 
293df930be7Sderaadt /* em_capitol_case():
294df930be7Sderaadt  *	Capitalize the characters from cursor to end of current word
295df930be7Sderaadt  *	[M-c]
296df930be7Sderaadt  */
297df930be7Sderaadt protected el_action_t
em_capitol_case(EditLine * el,wint_t c)298b2589f0bSschwarze em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
299df930be7Sderaadt {
300e3191321Sschwarze 	wchar_t *cp, *ep;
301df930be7Sderaadt 
302df930be7Sderaadt 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
303df930be7Sderaadt 	    el->el_state.argument, ce__isword);
304df930be7Sderaadt 
305df930be7Sderaadt 	for (cp = el->el_line.cursor; cp < ep; cp++) {
306565aa7e8Sschwarze 		if (iswalpha(*cp)) {
307565aa7e8Sschwarze 			if (iswlower(*cp))
308565aa7e8Sschwarze 				*cp = towupper(*cp);
309df930be7Sderaadt 			cp++;
310df930be7Sderaadt 			break;
311df930be7Sderaadt 		}
312df930be7Sderaadt 	}
313df930be7Sderaadt 	for (; cp < ep; cp++)
314565aa7e8Sschwarze 		if (iswupper(*cp))
315565aa7e8Sschwarze 			*cp = towlower(*cp);
316df930be7Sderaadt 
317df930be7Sderaadt 	el->el_line.cursor = ep;
318df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
319df930be7Sderaadt 		el->el_line.cursor = el->el_line.lastchar;
32028d54ee8Sschwarze 	return CC_REFRESH;
321df930be7Sderaadt }
322df930be7Sderaadt 
323d484b7d0Sotto 
324df930be7Sderaadt /* em_lower_case():
325df930be7Sderaadt  *	Lowercase the characters from cursor to end of current word
326df930be7Sderaadt  *	[M-l]
327df930be7Sderaadt  */
328df930be7Sderaadt protected el_action_t
em_lower_case(EditLine * el,wint_t c)329b2589f0bSschwarze em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
330df930be7Sderaadt {
331e3191321Sschwarze 	wchar_t *cp, *ep;
332df930be7Sderaadt 
333df930be7Sderaadt 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
334df930be7Sderaadt 	    el->el_state.argument, ce__isword);
335df930be7Sderaadt 
336df930be7Sderaadt 	for (cp = el->el_line.cursor; cp < ep; cp++)
337565aa7e8Sschwarze 		if (iswupper(*cp))
338565aa7e8Sschwarze 			*cp = towlower(*cp);
339df930be7Sderaadt 
340df930be7Sderaadt 	el->el_line.cursor = ep;
341df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
342df930be7Sderaadt 		el->el_line.cursor = el->el_line.lastchar;
34328d54ee8Sschwarze 	return CC_REFRESH;
344df930be7Sderaadt }
345df930be7Sderaadt 
346df930be7Sderaadt 
347df930be7Sderaadt /* em_set_mark():
348df930be7Sderaadt  *	Set the mark at cursor
349df930be7Sderaadt  *	[^@]
350df930be7Sderaadt  */
351df930be7Sderaadt protected el_action_t
em_set_mark(EditLine * el,wint_t c)352b2589f0bSschwarze em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
353df930be7Sderaadt {
354d484b7d0Sotto 
355df930be7Sderaadt 	el->el_chared.c_kill.mark = el->el_line.cursor;
35628d54ee8Sschwarze 	return CC_NORM;
357df930be7Sderaadt }
358df930be7Sderaadt 
359df930be7Sderaadt 
360df930be7Sderaadt /* em_exchange_mark():
361df930be7Sderaadt  *	Exchange the cursor and mark
362df930be7Sderaadt  *	[^X^X]
363df930be7Sderaadt  */
364df930be7Sderaadt protected el_action_t
em_exchange_mark(EditLine * el,wint_t c)365b2589f0bSschwarze em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
366df930be7Sderaadt {
367e3191321Sschwarze 	wchar_t *cp;
368df930be7Sderaadt 
369df930be7Sderaadt 	cp = el->el_line.cursor;
370df930be7Sderaadt 	el->el_line.cursor = el->el_chared.c_kill.mark;
371df930be7Sderaadt 	el->el_chared.c_kill.mark = cp;
37228d54ee8Sschwarze 	return CC_CURSOR;
373df930be7Sderaadt }
374df930be7Sderaadt 
375d484b7d0Sotto 
376df930be7Sderaadt /* em_universal_argument():
377df930be7Sderaadt  *	Universal argument (argument times 4)
378df930be7Sderaadt  *	[^U]
379df930be7Sderaadt  */
380df930be7Sderaadt protected el_action_t
em_universal_argument(EditLine * el,wint_t c)381b2589f0bSschwarze em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
382df930be7Sderaadt {				/* multiply current argument by 4 */
383d484b7d0Sotto 
384df930be7Sderaadt 	if (el->el_state.argument > 1000000)
38528d54ee8Sschwarze 		return CC_ERROR;
386df930be7Sderaadt 	el->el_state.doingarg = 1;
387df930be7Sderaadt 	el->el_state.argument *= 4;
38828d54ee8Sschwarze 	return CC_ARGHACK;
389df930be7Sderaadt }
390df930be7Sderaadt 
391d484b7d0Sotto 
392df930be7Sderaadt /* em_meta_next():
393df930be7Sderaadt  *	Add 8th bit to next character typed
394df930be7Sderaadt  *	[<ESC>]
395df930be7Sderaadt  */
396df930be7Sderaadt protected el_action_t
em_meta_next(EditLine * el,wint_t c)397b2589f0bSschwarze em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
398df930be7Sderaadt {
399d484b7d0Sotto 
400df930be7Sderaadt 	el->el_state.metanext = 1;
40128d54ee8Sschwarze 	return CC_ARGHACK;
402df930be7Sderaadt }
403df930be7Sderaadt 
404df930be7Sderaadt 
405df930be7Sderaadt /* em_toggle_overwrite():
406df930be7Sderaadt  *	Switch from insert to overwrite mode or vice versa
407df930be7Sderaadt  */
408df930be7Sderaadt protected el_action_t
em_toggle_overwrite(EditLine * el,wint_t c)409b2589f0bSschwarze em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
410df930be7Sderaadt {
411d484b7d0Sotto 
412d484b7d0Sotto 	el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
413d484b7d0Sotto 	    MODE_REPLACE : MODE_INSERT;
41428d54ee8Sschwarze 	return CC_NORM;
415df930be7Sderaadt }
416df930be7Sderaadt 
417df930be7Sderaadt 
418df930be7Sderaadt /* em_copy_prev_word():
419df930be7Sderaadt  *	Copy current word to cursor
420df930be7Sderaadt  */
421df930be7Sderaadt protected el_action_t
em_copy_prev_word(EditLine * el,wint_t c)422b2589f0bSschwarze em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
423df930be7Sderaadt {
424e3191321Sschwarze 	wchar_t *cp, *oldc, *dp;
425df930be7Sderaadt 
426df930be7Sderaadt 	if (el->el_line.cursor == el->el_line.buffer)
42728d54ee8Sschwarze 		return CC_ERROR;
428df930be7Sderaadt 
429df930be7Sderaadt 	oldc = el->el_line.cursor;
430df930be7Sderaadt 	/* does a bounds check */
431df930be7Sderaadt 	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
432df930be7Sderaadt 	    el->el_state.argument, ce__isword);
433df930be7Sderaadt 
434aed0ee81Snicm 	c_insert(el, (int)(oldc - cp));
435df930be7Sderaadt 	for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
436df930be7Sderaadt 		*dp++ = *cp;
437df930be7Sderaadt 
438df930be7Sderaadt 	el->el_line.cursor = dp;/* put cursor at end */
439df930be7Sderaadt 
44028d54ee8Sschwarze 	return CC_REFRESH;
441df930be7Sderaadt }
442df930be7Sderaadt 
443df930be7Sderaadt 
444df930be7Sderaadt /* em_inc_search_next():
445df930be7Sderaadt  *	Emacs incremental next search
446df930be7Sderaadt  */
447df930be7Sderaadt protected el_action_t
em_inc_search_next(EditLine * el,wint_t c)448b2589f0bSschwarze em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
449df930be7Sderaadt {
450d484b7d0Sotto 
451df930be7Sderaadt 	el->el_search.patlen = 0;
45228d54ee8Sschwarze 	return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
453df930be7Sderaadt }
454df930be7Sderaadt 
455df930be7Sderaadt 
456df930be7Sderaadt /* em_inc_search_prev():
457df930be7Sderaadt  *	Emacs incremental reverse search
458df930be7Sderaadt  */
459df930be7Sderaadt protected el_action_t
em_inc_search_prev(EditLine * el,wint_t c)460b2589f0bSschwarze em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
461df930be7Sderaadt {
462d484b7d0Sotto 
463df930be7Sderaadt 	el->el_search.patlen = 0;
46428d54ee8Sschwarze 	return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
465df930be7Sderaadt }
466aed0ee81Snicm 
467aed0ee81Snicm 
468aed0ee81Snicm /* em_delete_prev_char():
469aed0ee81Snicm  *	Delete the character to the left of the cursor
470aed0ee81Snicm  *	[^?]
471aed0ee81Snicm  */
472aed0ee81Snicm protected el_action_t
em_delete_prev_char(EditLine * el,wint_t c)473b2589f0bSschwarze em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
474aed0ee81Snicm {
475aed0ee81Snicm 
476aed0ee81Snicm 	if (el->el_line.cursor <= el->el_line.buffer)
47728d54ee8Sschwarze 		return CC_ERROR;
478aed0ee81Snicm 
479aed0ee81Snicm 	if (el->el_state.doingarg)
480aed0ee81Snicm 		c_delbefore(el, el->el_state.argument);
481aed0ee81Snicm 	else
482aed0ee81Snicm 		c_delbefore1(el);
483aed0ee81Snicm 	el->el_line.cursor -= el->el_state.argument;
484aed0ee81Snicm 	if (el->el_line.cursor < el->el_line.buffer)
485aed0ee81Snicm 		el->el_line.cursor = el->el_line.buffer;
48628d54ee8Sschwarze 	return CC_REFRESH;
487aed0ee81Snicm }
488