xref: /openbsd-src/lib/libedit/emacs.c (revision 28d54ee83c6affd52032b6242140cc317714b94c)
1*28d54ee8Sschwarze /*	$OpenBSD: emacs.c,v 1.11 2016/01/30 12:22:20 schwarze Exp $	*/
2*28d54ee8Sschwarze /*	$NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 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  */
41df930be7Sderaadt #include "el.h"
42df930be7Sderaadt 
43df930be7Sderaadt /* em_delete_or_list():
44df930be7Sderaadt  *	Delete character under cursor or list completions if at end of line
45df930be7Sderaadt  *	[^D]
46df930be7Sderaadt  */
47df930be7Sderaadt protected el_action_t
48df930be7Sderaadt /*ARGSUSED*/
49aed0ee81Snicm em_delete_or_list(EditLine *el, Int c)
50df930be7Sderaadt {
51d484b7d0Sotto 
52d484b7d0Sotto 	if (el->el_line.cursor == el->el_line.lastchar) {
53d484b7d0Sotto 					/* if I'm at the end */
54d484b7d0Sotto 		if (el->el_line.cursor == el->el_line.buffer) {
55d484b7d0Sotto 					/* and the beginning */
56fd40972aSschwarze 			terminal_writec(el, c);	/* then do an EOF */
57*28d54ee8Sschwarze 			return CC_EOF;
58d484b7d0Sotto 		} else {
59d484b7d0Sotto 			/*
60d484b7d0Sotto 			 * Here we could list completions, but it is an
61d484b7d0Sotto 			 * error right now
62d484b7d0Sotto 			 */
63fd40972aSschwarze 			terminal_beep(el);
64*28d54ee8Sschwarze 			return CC_ERROR;
65df930be7Sderaadt 		}
66d484b7d0Sotto 	} else {
67aed0ee81Snicm 		if (el->el_state.doingarg)
68aed0ee81Snicm 			c_delafter(el, el->el_state.argument);
69aed0ee81Snicm 		else
70aed0ee81Snicm 			c_delafter1(el);
71df930be7Sderaadt 		if (el->el_line.cursor > el->el_line.lastchar)
72d484b7d0Sotto 			el->el_line.cursor = el->el_line.lastchar;
73d484b7d0Sotto 				/* bounds check */
74*28d54ee8Sschwarze 		return CC_REFRESH;
75df930be7Sderaadt 	}
76df930be7Sderaadt }
77df930be7Sderaadt 
78df930be7Sderaadt 
79df930be7Sderaadt /* em_delete_next_word():
80df930be7Sderaadt  *	Cut from cursor to end of current word
81df930be7Sderaadt  *	[M-d]
82df930be7Sderaadt  */
83df930be7Sderaadt protected el_action_t
84df930be7Sderaadt /*ARGSUSED*/
85aed0ee81Snicm em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
86df930be7Sderaadt {
87aed0ee81Snicm 	Char *cp, *p, *kp;
88df930be7Sderaadt 
89df930be7Sderaadt 	if (el->el_line.cursor == el->el_line.lastchar)
90*28d54ee8Sschwarze 		return CC_ERROR;
91df930be7Sderaadt 
92df930be7Sderaadt 	cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
93df930be7Sderaadt 	    el->el_state.argument, ce__isword);
94df930be7Sderaadt 
95df930be7Sderaadt 	for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
96df930be7Sderaadt 				/* save the text */
97df930be7Sderaadt 		*kp++ = *p;
98df930be7Sderaadt 	el->el_chared.c_kill.last = kp;
99df930be7Sderaadt 
100aed0ee81Snicm 	c_delafter(el, (int)(cp - el->el_line.cursor));	/* delete after dot */
101df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
102d484b7d0Sotto 		el->el_line.cursor = el->el_line.lastchar;
103d484b7d0Sotto 				/* bounds check */
104*28d54ee8Sschwarze 	return CC_REFRESH;
105df930be7Sderaadt }
106df930be7Sderaadt 
107df930be7Sderaadt 
108df930be7Sderaadt /* em_yank():
109df930be7Sderaadt  *	Paste cut buffer at cursor position
110df930be7Sderaadt  *	[^Y]
111df930be7Sderaadt  */
112df930be7Sderaadt protected el_action_t
113df930be7Sderaadt /*ARGSUSED*/
114aed0ee81Snicm em_yank(EditLine *el, Int c __attribute__((__unused__)))
115df930be7Sderaadt {
116aed0ee81Snicm 	Char *kp, *cp;
117df930be7Sderaadt 
1186e02e073Sotto 	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
119*28d54ee8Sschwarze 		return CC_NORM;
120df930be7Sderaadt 
121df930be7Sderaadt 	if (el->el_line.lastchar +
122df930be7Sderaadt 	    (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
123df930be7Sderaadt 	    el->el_line.limit)
124*28d54ee8Sschwarze 		return CC_ERROR;
125df930be7Sderaadt 
126df930be7Sderaadt 	el->el_chared.c_kill.mark = el->el_line.cursor;
127df930be7Sderaadt 	cp = el->el_line.cursor;
128df930be7Sderaadt 
129df930be7Sderaadt 	/* open the space, */
130aed0ee81Snicm 	c_insert(el,
131aed0ee81Snicm 	    (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
132df930be7Sderaadt 	/* copy the chars */
133df930be7Sderaadt 	for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
134df930be7Sderaadt 		*cp++ = *kp;
135df930be7Sderaadt 
136df930be7Sderaadt 	/* if an arg, cursor at beginning else cursor at end */
137df930be7Sderaadt 	if (el->el_state.argument == 1)
138df930be7Sderaadt 		el->el_line.cursor = cp;
139df930be7Sderaadt 
140*28d54ee8Sschwarze 	return CC_REFRESH;
141df930be7Sderaadt }
142df930be7Sderaadt 
143df930be7Sderaadt 
144df930be7Sderaadt /* em_kill_line():
145df930be7Sderaadt  *	Cut the entire line and save in cut buffer
146df930be7Sderaadt  *	[^U]
147df930be7Sderaadt  */
148df930be7Sderaadt protected el_action_t
149df930be7Sderaadt /*ARGSUSED*/
150aed0ee81Snicm em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
151df930be7Sderaadt {
152aed0ee81Snicm 	Char *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;
162*28d54ee8Sschwarze 	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
171df930be7Sderaadt /*ARGSUSED*/
172aed0ee81Snicm em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
173df930be7Sderaadt {
174aed0ee81Snicm 	Char *kp, *cp;
175df930be7Sderaadt 
176df930be7Sderaadt 	if (!el->el_chared.c_kill.mark)
177*28d54ee8Sschwarze 		return CC_ERROR;
178df930be7Sderaadt 
179df930be7Sderaadt 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
180df930be7Sderaadt 		cp = el->el_line.cursor;
181df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
182df930be7Sderaadt 		while (cp < el->el_chared.c_kill.mark)
183df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
184df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
185aed0ee81Snicm 		c_delafter(el, (int)(cp - el->el_line.cursor));
186d484b7d0Sotto 	} else {		/* mark is before cursor */
187df930be7Sderaadt 		cp = el->el_chared.c_kill.mark;
188df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
189df930be7Sderaadt 		while (cp < el->el_line.cursor)
190df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
191df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
192aed0ee81Snicm 		c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
193df930be7Sderaadt 		el->el_line.cursor = el->el_chared.c_kill.mark;
194df930be7Sderaadt 	}
195*28d54ee8Sschwarze 	return CC_REFRESH;
196df930be7Sderaadt }
197df930be7Sderaadt 
198df930be7Sderaadt 
199df930be7Sderaadt /* em_copy_region():
200df930be7Sderaadt  *	Copy area between mark and cursor to cut buffer
201df930be7Sderaadt  *	[M-W]
202df930be7Sderaadt  */
203df930be7Sderaadt protected el_action_t
204df930be7Sderaadt /*ARGSUSED*/
205aed0ee81Snicm em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
206df930be7Sderaadt {
207aed0ee81Snicm 	Char *kp, *cp;
208df930be7Sderaadt 
209d484b7d0Sotto 	if (!el->el_chared.c_kill.mark)
210*28d54ee8Sschwarze 		return CC_ERROR;
211df930be7Sderaadt 
212df930be7Sderaadt 	if (el->el_chared.c_kill.mark > el->el_line.cursor) {
213df930be7Sderaadt 		cp = el->el_line.cursor;
214df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
215df930be7Sderaadt 		while (cp < el->el_chared.c_kill.mark)
216df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
217df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
218d484b7d0Sotto 	} else {
219df930be7Sderaadt 		cp = el->el_chared.c_kill.mark;
220df930be7Sderaadt 		kp = el->el_chared.c_kill.buf;
221df930be7Sderaadt 		while (cp < el->el_line.cursor)
222df930be7Sderaadt 			*kp++ = *cp++;	/* copy it */
223df930be7Sderaadt 		el->el_chared.c_kill.last = kp;
224df930be7Sderaadt 	}
225*28d54ee8Sschwarze 	return CC_NORM;
226df930be7Sderaadt }
227df930be7Sderaadt 
228df930be7Sderaadt 
229d484b7d0Sotto /* em_gosmacs_transpose():
230df930be7Sderaadt  *	Exchange the two characters before the cursor
231df930be7Sderaadt  *	Gosling emacs transpose chars [^T]
232df930be7Sderaadt  */
233df930be7Sderaadt protected el_action_t
234aed0ee81Snicm em_gosmacs_transpose(EditLine *el, Int c)
235df930be7Sderaadt {
236df930be7Sderaadt 
237df930be7Sderaadt 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
238df930be7Sderaadt 		/* must have at least two chars entered */
239df930be7Sderaadt 		c = el->el_line.cursor[-2];
240df930be7Sderaadt 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
241df930be7Sderaadt 		el->el_line.cursor[-1] = c;
242*28d54ee8Sschwarze 		return CC_REFRESH;
243d484b7d0Sotto 	} else
244*28d54ee8Sschwarze 		return CC_ERROR;
245df930be7Sderaadt }
246df930be7Sderaadt 
247df930be7Sderaadt 
248df930be7Sderaadt /* em_next_word():
249df930be7Sderaadt  *	Move next to end of current word
250df930be7Sderaadt  *	[M-f]
251df930be7Sderaadt  */
252df930be7Sderaadt protected el_action_t
253df930be7Sderaadt /*ARGSUSED*/
254aed0ee81Snicm em_next_word(EditLine *el, Int c __attribute__((__unused__)))
255df930be7Sderaadt {
256df930be7Sderaadt 	if (el->el_line.cursor == el->el_line.lastchar)
257*28d54ee8Sschwarze 		return CC_ERROR;
258df930be7Sderaadt 
259d484b7d0Sotto 	el->el_line.cursor = c__next_word(el->el_line.cursor,
260d484b7d0Sotto 	    el->el_line.lastchar,
261df930be7Sderaadt 	    el->el_state.argument,
262df930be7Sderaadt 	    ce__isword);
263df930be7Sderaadt 
264df930be7Sderaadt 	if (el->el_map.type == MAP_VI)
265d484b7d0Sotto 		if (el->el_chared.c_vcmd.action != NOP) {
266df930be7Sderaadt 			cv_delfini(el);
267*28d54ee8Sschwarze 			return CC_REFRESH;
268d484b7d0Sotto 		}
269*28d54ee8Sschwarze 	return CC_CURSOR;
270df930be7Sderaadt }
271df930be7Sderaadt 
272df930be7Sderaadt 
273df930be7Sderaadt /* em_upper_case():
274df930be7Sderaadt  *	Uppercase the characters from cursor to end of current word
275df930be7Sderaadt  *	[M-u]
276df930be7Sderaadt  */
277df930be7Sderaadt protected el_action_t
278df930be7Sderaadt /*ARGSUSED*/
279aed0ee81Snicm em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
280df930be7Sderaadt {
281aed0ee81Snicm 	Char *cp, *ep;
282df930be7Sderaadt 
283df930be7Sderaadt 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
284df930be7Sderaadt 	    el->el_state.argument, ce__isword);
285df930be7Sderaadt 
286df930be7Sderaadt 	for (cp = el->el_line.cursor; cp < ep; cp++)
287aed0ee81Snicm 		if (Islower(*cp))
288aed0ee81Snicm 			*cp = Toupper(*cp);
289df930be7Sderaadt 
290df930be7Sderaadt 	el->el_line.cursor = ep;
291df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
292df930be7Sderaadt 		el->el_line.cursor = el->el_line.lastchar;
293*28d54ee8Sschwarze 	return CC_REFRESH;
294df930be7Sderaadt }
295df930be7Sderaadt 
296df930be7Sderaadt 
297df930be7Sderaadt /* em_capitol_case():
298df930be7Sderaadt  *	Capitalize the characters from cursor to end of current word
299df930be7Sderaadt  *	[M-c]
300df930be7Sderaadt  */
301df930be7Sderaadt protected el_action_t
302df930be7Sderaadt /*ARGSUSED*/
303aed0ee81Snicm em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
304df930be7Sderaadt {
305aed0ee81Snicm 	Char *cp, *ep;
306df930be7Sderaadt 
307df930be7Sderaadt 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
308df930be7Sderaadt 	    el->el_state.argument, ce__isword);
309df930be7Sderaadt 
310df930be7Sderaadt 	for (cp = el->el_line.cursor; cp < ep; cp++) {
311aed0ee81Snicm 		if (Isalpha(*cp)) {
312aed0ee81Snicm 			if (Islower(*cp))
313aed0ee81Snicm 				*cp = Toupper(*cp);
314df930be7Sderaadt 			cp++;
315df930be7Sderaadt 			break;
316df930be7Sderaadt 		}
317df930be7Sderaadt 	}
318df930be7Sderaadt 	for (; cp < ep; cp++)
319aed0ee81Snicm 		if (Isupper(*cp))
320aed0ee81Snicm 			*cp = Tolower(*cp);
321df930be7Sderaadt 
322df930be7Sderaadt 	el->el_line.cursor = ep;
323df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
324df930be7Sderaadt 		el->el_line.cursor = el->el_line.lastchar;
325*28d54ee8Sschwarze 	return CC_REFRESH;
326df930be7Sderaadt }
327df930be7Sderaadt 
328d484b7d0Sotto 
329df930be7Sderaadt /* em_lower_case():
330df930be7Sderaadt  *	Lowercase the characters from cursor to end of current word
331df930be7Sderaadt  *	[M-l]
332df930be7Sderaadt  */
333df930be7Sderaadt protected el_action_t
334df930be7Sderaadt /*ARGSUSED*/
335aed0ee81Snicm em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
336df930be7Sderaadt {
337aed0ee81Snicm 	Char *cp, *ep;
338df930be7Sderaadt 
339df930be7Sderaadt 	ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
340df930be7Sderaadt 	    el->el_state.argument, ce__isword);
341df930be7Sderaadt 
342df930be7Sderaadt 	for (cp = el->el_line.cursor; cp < ep; cp++)
343aed0ee81Snicm 		if (Isupper(*cp))
344aed0ee81Snicm 			*cp = Tolower(*cp);
345df930be7Sderaadt 
346df930be7Sderaadt 	el->el_line.cursor = ep;
347df930be7Sderaadt 	if (el->el_line.cursor > el->el_line.lastchar)
348df930be7Sderaadt 		el->el_line.cursor = el->el_line.lastchar;
349*28d54ee8Sschwarze 	return CC_REFRESH;
350df930be7Sderaadt }
351df930be7Sderaadt 
352df930be7Sderaadt 
353df930be7Sderaadt /* em_set_mark():
354df930be7Sderaadt  *	Set the mark at cursor
355df930be7Sderaadt  *	[^@]
356df930be7Sderaadt  */
357df930be7Sderaadt protected el_action_t
358df930be7Sderaadt /*ARGSUSED*/
359aed0ee81Snicm em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
360df930be7Sderaadt {
361d484b7d0Sotto 
362df930be7Sderaadt 	el->el_chared.c_kill.mark = el->el_line.cursor;
363*28d54ee8Sschwarze 	return CC_NORM;
364df930be7Sderaadt }
365df930be7Sderaadt 
366df930be7Sderaadt 
367df930be7Sderaadt /* em_exchange_mark():
368df930be7Sderaadt  *	Exchange the cursor and mark
369df930be7Sderaadt  *	[^X^X]
370df930be7Sderaadt  */
371df930be7Sderaadt protected el_action_t
372df930be7Sderaadt /*ARGSUSED*/
373aed0ee81Snicm em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
374df930be7Sderaadt {
375aed0ee81Snicm 	Char *cp;
376df930be7Sderaadt 
377df930be7Sderaadt 	cp = el->el_line.cursor;
378df930be7Sderaadt 	el->el_line.cursor = el->el_chared.c_kill.mark;
379df930be7Sderaadt 	el->el_chared.c_kill.mark = cp;
380*28d54ee8Sschwarze 	return CC_CURSOR;
381df930be7Sderaadt }
382df930be7Sderaadt 
383d484b7d0Sotto 
384df930be7Sderaadt /* em_universal_argument():
385df930be7Sderaadt  *	Universal argument (argument times 4)
386df930be7Sderaadt  *	[^U]
387df930be7Sderaadt  */
388df930be7Sderaadt protected el_action_t
389df930be7Sderaadt /*ARGSUSED*/
390aed0ee81Snicm em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
391df930be7Sderaadt {				/* multiply current argument by 4 */
392d484b7d0Sotto 
393df930be7Sderaadt 	if (el->el_state.argument > 1000000)
394*28d54ee8Sschwarze 		return CC_ERROR;
395df930be7Sderaadt 	el->el_state.doingarg = 1;
396df930be7Sderaadt 	el->el_state.argument *= 4;
397*28d54ee8Sschwarze 	return CC_ARGHACK;
398df930be7Sderaadt }
399df930be7Sderaadt 
400d484b7d0Sotto 
401df930be7Sderaadt /* em_meta_next():
402df930be7Sderaadt  *	Add 8th bit to next character typed
403df930be7Sderaadt  *	[<ESC>]
404df930be7Sderaadt  */
405df930be7Sderaadt protected el_action_t
406df930be7Sderaadt /*ARGSUSED*/
407aed0ee81Snicm em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
408df930be7Sderaadt {
409d484b7d0Sotto 
410df930be7Sderaadt 	el->el_state.metanext = 1;
411*28d54ee8Sschwarze 	return CC_ARGHACK;
412df930be7Sderaadt }
413df930be7Sderaadt 
414df930be7Sderaadt 
415df930be7Sderaadt /* em_toggle_overwrite():
416df930be7Sderaadt  *	Switch from insert to overwrite mode or vice versa
417df930be7Sderaadt  */
418df930be7Sderaadt protected el_action_t
419df930be7Sderaadt /*ARGSUSED*/
420aed0ee81Snicm em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
421df930be7Sderaadt {
422d484b7d0Sotto 
423d484b7d0Sotto 	el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
424d484b7d0Sotto 	    MODE_REPLACE : MODE_INSERT;
425*28d54ee8Sschwarze 	return CC_NORM;
426df930be7Sderaadt }
427df930be7Sderaadt 
428df930be7Sderaadt 
429df930be7Sderaadt /* em_copy_prev_word():
430df930be7Sderaadt  *	Copy current word to cursor
431df930be7Sderaadt  */
432df930be7Sderaadt protected el_action_t
433df930be7Sderaadt /*ARGSUSED*/
434aed0ee81Snicm em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
435df930be7Sderaadt {
436aed0ee81Snicm 	Char *cp, *oldc, *dp;
437df930be7Sderaadt 
438df930be7Sderaadt 	if (el->el_line.cursor == el->el_line.buffer)
439*28d54ee8Sschwarze 		return CC_ERROR;
440df930be7Sderaadt 
441df930be7Sderaadt 	oldc = el->el_line.cursor;
442df930be7Sderaadt 	/* does a bounds check */
443df930be7Sderaadt 	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
444df930be7Sderaadt 	    el->el_state.argument, ce__isword);
445df930be7Sderaadt 
446aed0ee81Snicm 	c_insert(el, (int)(oldc - cp));
447df930be7Sderaadt 	for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
448df930be7Sderaadt 		*dp++ = *cp;
449df930be7Sderaadt 
450df930be7Sderaadt 	el->el_line.cursor = dp;/* put cursor at end */
451df930be7Sderaadt 
452*28d54ee8Sschwarze 	return CC_REFRESH;
453df930be7Sderaadt }
454df930be7Sderaadt 
455df930be7Sderaadt 
456df930be7Sderaadt /* em_inc_search_next():
457df930be7Sderaadt  *	Emacs incremental next search
458df930be7Sderaadt  */
459df930be7Sderaadt protected el_action_t
460df930be7Sderaadt /*ARGSUSED*/
461aed0ee81Snicm em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
462df930be7Sderaadt {
463d484b7d0Sotto 
464df930be7Sderaadt 	el->el_search.patlen = 0;
465*28d54ee8Sschwarze 	return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
466df930be7Sderaadt }
467df930be7Sderaadt 
468df930be7Sderaadt 
469df930be7Sderaadt /* em_inc_search_prev():
470df930be7Sderaadt  *	Emacs incremental reverse search
471df930be7Sderaadt  */
472df930be7Sderaadt protected el_action_t
473df930be7Sderaadt /*ARGSUSED*/
474aed0ee81Snicm em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
475df930be7Sderaadt {
476d484b7d0Sotto 
477df930be7Sderaadt 	el->el_search.patlen = 0;
478*28d54ee8Sschwarze 	return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
479df930be7Sderaadt }
480aed0ee81Snicm 
481aed0ee81Snicm 
482aed0ee81Snicm /* em_delete_prev_char():
483aed0ee81Snicm  *	Delete the character to the left of the cursor
484aed0ee81Snicm  *	[^?]
485aed0ee81Snicm  */
486aed0ee81Snicm protected el_action_t
487aed0ee81Snicm /*ARGSUSED*/
488aed0ee81Snicm em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
489aed0ee81Snicm {
490aed0ee81Snicm 
491aed0ee81Snicm 	if (el->el_line.cursor <= el->el_line.buffer)
492*28d54ee8Sschwarze 		return CC_ERROR;
493aed0ee81Snicm 
494aed0ee81Snicm 	if (el->el_state.doingarg)
495aed0ee81Snicm 		c_delbefore(el, el->el_state.argument);
496aed0ee81Snicm 	else
497aed0ee81Snicm 		c_delbefore1(el);
498aed0ee81Snicm 	el->el_line.cursor -= el->el_state.argument;
499aed0ee81Snicm 	if (el->el_line.cursor < el->el_line.buffer)
500aed0ee81Snicm 		el->el_line.cursor = el->el_line.buffer;
501*28d54ee8Sschwarze 	return CC_REFRESH;
502aed0ee81Snicm }
503