xref: /netbsd-src/lib/libedit/emacs.c (revision 6dc2f1db52b49c75bccc82d628849b87198380ef)
1*6dc2f1dbScgd /*-
2*6dc2f1dbScgd  * Copyright (c) 1992, 1993
3*6dc2f1dbScgd  *	The Regents of the University of California.  All rights reserved.
4*6dc2f1dbScgd  *
5*6dc2f1dbScgd  * This code is derived from software contributed to Berkeley by
6*6dc2f1dbScgd  * Christos Zoulas of Cornell University.
7*6dc2f1dbScgd  *
8*6dc2f1dbScgd  * Redistribution and use in source and binary forms, with or without
9*6dc2f1dbScgd  * modification, are permitted provided that the following conditions
10*6dc2f1dbScgd  * are met:
11*6dc2f1dbScgd  * 1. Redistributions of source code must retain the above copyright
12*6dc2f1dbScgd  *    notice, this list of conditions and the following disclaimer.
13*6dc2f1dbScgd  * 2. Redistributions in binary form must reproduce the above copyright
14*6dc2f1dbScgd  *    notice, this list of conditions and the following disclaimer in the
15*6dc2f1dbScgd  *    documentation and/or other materials provided with the distribution.
16*6dc2f1dbScgd  * 3. All advertising materials mentioning features or use of this software
17*6dc2f1dbScgd  *    must display the following acknowledgement:
18*6dc2f1dbScgd  *	This product includes software developed by the University of
19*6dc2f1dbScgd  *	California, Berkeley and its contributors.
20*6dc2f1dbScgd  * 4. Neither the name of the University nor the names of its contributors
21*6dc2f1dbScgd  *    may be used to endorse or promote products derived from this software
22*6dc2f1dbScgd  *    without specific prior written permission.
23*6dc2f1dbScgd  *
24*6dc2f1dbScgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25*6dc2f1dbScgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*6dc2f1dbScgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*6dc2f1dbScgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28*6dc2f1dbScgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*6dc2f1dbScgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*6dc2f1dbScgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*6dc2f1dbScgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*6dc2f1dbScgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*6dc2f1dbScgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*6dc2f1dbScgd  * SUCH DAMAGE.
35*6dc2f1dbScgd  */
36*6dc2f1dbScgd 
37*6dc2f1dbScgd #if !defined(lint) && !defined(SCCSID)
38*6dc2f1dbScgd static char sccsid[] = "@(#)emacs.c	8.1 (Berkeley) 6/4/93";
39*6dc2f1dbScgd #endif /* not lint && not SCCSID */
40*6dc2f1dbScgd 
41*6dc2f1dbScgd /*
42*6dc2f1dbScgd  * emacs.c: Emacs functions
43*6dc2f1dbScgd  */
44*6dc2f1dbScgd #include "sys.h"
45*6dc2f1dbScgd #include "el.h"
46*6dc2f1dbScgd 
47*6dc2f1dbScgd /* em_delete_or_list():
48*6dc2f1dbScgd  *	Delete character under cursor or list completions if at end of line
49*6dc2f1dbScgd  *	[^D]
50*6dc2f1dbScgd  */
51*6dc2f1dbScgd protected el_action_t
52*6dc2f1dbScgd /*ARGSUSED*/
53*6dc2f1dbScgd em_delete_or_list(el, c)
54*6dc2f1dbScgd     EditLine *el;
55*6dc2f1dbScgd     int c;
56*6dc2f1dbScgd {
57*6dc2f1dbScgd     if (el->el_line.cursor == el->el_line.lastchar) {	/* if I'm at the end */
58*6dc2f1dbScgd #ifdef notyet
59*6dc2f1dbScgd 	if (el->el_line.cursor == el->el_line.buffer) {	/* and the beginning */
60*6dc2f1dbScgd #endif
61*6dc2f1dbScgd 	    term_overwrite(el, STReof, 4);/* then do a EOF */
62*6dc2f1dbScgd 	    term__flush();
63*6dc2f1dbScgd 	    return CC_EOF;
64*6dc2f1dbScgd #ifdef notyet
65*6dc2f1dbScgd 	}
66*6dc2f1dbScgd 	else {
67*6dc2f1dbScgd 	    re_goto_bottom(el);
68*6dc2f1dbScgd 	    *el->el_line.lastchar = '\0';		/* just in case */
69*6dc2f1dbScgd 	    return CC_LIST_CHOICES;
70*6dc2f1dbScgd 	}
71*6dc2f1dbScgd #endif
72*6dc2f1dbScgd     }
73*6dc2f1dbScgd     else {
74*6dc2f1dbScgd 	c_delafter(el, el->el_state.argument);	/* delete after dot */
75*6dc2f1dbScgd 	if (el->el_line.cursor > el->el_line.lastchar)
76*6dc2f1dbScgd 	    el->el_line.cursor = el->el_line.lastchar;	/* bounds check */
77*6dc2f1dbScgd 	return CC_REFRESH;
78*6dc2f1dbScgd     }
79*6dc2f1dbScgd }
80*6dc2f1dbScgd 
81*6dc2f1dbScgd 
82*6dc2f1dbScgd /* em_delete_next_word():
83*6dc2f1dbScgd  *	Cut from cursor to end of current word
84*6dc2f1dbScgd  *	[M-d]
85*6dc2f1dbScgd  */
86*6dc2f1dbScgd protected el_action_t
87*6dc2f1dbScgd /*ARGSUSED*/
88*6dc2f1dbScgd em_delete_next_word(el, c)
89*6dc2f1dbScgd     EditLine *el;
90*6dc2f1dbScgd     int c;
91*6dc2f1dbScgd {
92*6dc2f1dbScgd     char *cp, *p, *kp;
93*6dc2f1dbScgd 
94*6dc2f1dbScgd     if (el->el_line.cursor == el->el_line.lastchar)
95*6dc2f1dbScgd 	return CC_ERROR;
96*6dc2f1dbScgd 
97*6dc2f1dbScgd     cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
98*6dc2f1dbScgd 		      el->el_state.argument, ce__isword);
99*6dc2f1dbScgd 
100*6dc2f1dbScgd     for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
101*6dc2f1dbScgd 	/* save the text */
102*6dc2f1dbScgd 	*kp++ = *p;
103*6dc2f1dbScgd     el->el_chared.c_kill.last = kp;
104*6dc2f1dbScgd 
105*6dc2f1dbScgd     c_delafter(el, cp - el->el_line.cursor);		/* delete after dot */
106*6dc2f1dbScgd     if (el->el_line.cursor > el->el_line.lastchar)
107*6dc2f1dbScgd 	el->el_line.cursor = el->el_line.lastchar;	/* bounds check */
108*6dc2f1dbScgd     return CC_REFRESH;
109*6dc2f1dbScgd }
110*6dc2f1dbScgd 
111*6dc2f1dbScgd 
112*6dc2f1dbScgd /* em_yank():
113*6dc2f1dbScgd  *	Paste cut buffer at cursor position
114*6dc2f1dbScgd  *	[^Y]
115*6dc2f1dbScgd  */
116*6dc2f1dbScgd protected el_action_t
117*6dc2f1dbScgd /*ARGSUSED*/
118*6dc2f1dbScgd em_yank(el, c)
119*6dc2f1dbScgd     EditLine *el;
120*6dc2f1dbScgd     int c;
121*6dc2f1dbScgd {
122*6dc2f1dbScgd     char *kp, *cp;
123*6dc2f1dbScgd 
124*6dc2f1dbScgd     if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
125*6dc2f1dbScgd 	return CC_ERROR;
126*6dc2f1dbScgd 
127*6dc2f1dbScgd     if (el->el_line.lastchar +
128*6dc2f1dbScgd 	(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
129*6dc2f1dbScgd 	el->el_line.limit)
130*6dc2f1dbScgd 	return CC_ERROR;
131*6dc2f1dbScgd 
132*6dc2f1dbScgd     el->el_chared.c_kill.mark = el->el_line.cursor;
133*6dc2f1dbScgd     cp = el->el_line.cursor;
134*6dc2f1dbScgd 
135*6dc2f1dbScgd     /* open the space, */
136*6dc2f1dbScgd     c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
137*6dc2f1dbScgd     /* copy the chars */
138*6dc2f1dbScgd     for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
139*6dc2f1dbScgd 	*cp++ = *kp;
140*6dc2f1dbScgd 
141*6dc2f1dbScgd     /* if an arg, cursor at beginning else cursor at end */
142*6dc2f1dbScgd     if (el->el_state.argument == 1)
143*6dc2f1dbScgd 	el->el_line.cursor = cp;
144*6dc2f1dbScgd 
145*6dc2f1dbScgd     return CC_REFRESH;
146*6dc2f1dbScgd }
147*6dc2f1dbScgd 
148*6dc2f1dbScgd 
149*6dc2f1dbScgd /* em_kill_line():
150*6dc2f1dbScgd  *	Cut the entire line and save in cut buffer
151*6dc2f1dbScgd  *	[^U]
152*6dc2f1dbScgd  */
153*6dc2f1dbScgd protected el_action_t
154*6dc2f1dbScgd /*ARGSUSED*/
155*6dc2f1dbScgd em_kill_line(el, c)
156*6dc2f1dbScgd     EditLine *el;
157*6dc2f1dbScgd     int c;
158*6dc2f1dbScgd {
159*6dc2f1dbScgd     char *kp, *cp;
160*6dc2f1dbScgd 
161*6dc2f1dbScgd     cp = el->el_line.buffer;
162*6dc2f1dbScgd     kp = el->el_chared.c_kill.buf;
163*6dc2f1dbScgd     while (cp < el->el_line.lastchar)
164*6dc2f1dbScgd 	*kp++ = *cp++;		/* copy it */
165*6dc2f1dbScgd     el->el_chared.c_kill.last = kp;
166*6dc2f1dbScgd     el->el_line.lastchar = el->el_line.buffer;	/* zap! -- delete all of it */
167*6dc2f1dbScgd     el->el_line.cursor = el->el_line.buffer;
168*6dc2f1dbScgd     return CC_REFRESH;
169*6dc2f1dbScgd }
170*6dc2f1dbScgd 
171*6dc2f1dbScgd 
172*6dc2f1dbScgd /* em_kill_region():
173*6dc2f1dbScgd  *	Cut area between mark and cursor and save in cut buffer
174*6dc2f1dbScgd  *	[^W]
175*6dc2f1dbScgd  */
176*6dc2f1dbScgd protected el_action_t
177*6dc2f1dbScgd /*ARGSUSED*/
178*6dc2f1dbScgd em_kill_region(el, c)
179*6dc2f1dbScgd     EditLine *el;
180*6dc2f1dbScgd     int c;
181*6dc2f1dbScgd {
182*6dc2f1dbScgd     char *kp, *cp;
183*6dc2f1dbScgd 
184*6dc2f1dbScgd     if (!el->el_chared.c_kill.mark)
185*6dc2f1dbScgd 	return CC_ERROR;
186*6dc2f1dbScgd 
187*6dc2f1dbScgd     if (el->el_chared.c_kill.mark > el->el_line.cursor) {
188*6dc2f1dbScgd 	cp = el->el_line.cursor;
189*6dc2f1dbScgd 	kp = el->el_chared.c_kill.buf;
190*6dc2f1dbScgd 	while (cp < el->el_chared.c_kill.mark)
191*6dc2f1dbScgd 	    *kp++ = *cp++;	/* copy it */
192*6dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
193*6dc2f1dbScgd 	c_delafter(el, cp - el->el_line.cursor);
194*6dc2f1dbScgd     }
195*6dc2f1dbScgd     else {			/* mark is before cursor */
196*6dc2f1dbScgd 	cp = el->el_chared.c_kill.mark;
197*6dc2f1dbScgd 	kp = el->el_chared.c_kill.buf;
198*6dc2f1dbScgd 	while (cp < el->el_line.cursor)
199*6dc2f1dbScgd 	    *kp++ = *cp++;	/* copy it */
200*6dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
201*6dc2f1dbScgd 	c_delbefore(el, cp - el->el_chared.c_kill.mark);
202*6dc2f1dbScgd 	el->el_line.cursor = el->el_chared.c_kill.mark;
203*6dc2f1dbScgd     }
204*6dc2f1dbScgd     return CC_REFRESH;
205*6dc2f1dbScgd }
206*6dc2f1dbScgd 
207*6dc2f1dbScgd 
208*6dc2f1dbScgd /* em_copy_region():
209*6dc2f1dbScgd  *	Copy area between mark and cursor to cut buffer
210*6dc2f1dbScgd  *	[M-W]
211*6dc2f1dbScgd  */
212*6dc2f1dbScgd protected el_action_t
213*6dc2f1dbScgd /*ARGSUSED*/
214*6dc2f1dbScgd em_copy_region(el, c)
215*6dc2f1dbScgd     EditLine *el;
216*6dc2f1dbScgd     int c;
217*6dc2f1dbScgd {
218*6dc2f1dbScgd     char *kp, *cp;
219*6dc2f1dbScgd 
220*6dc2f1dbScgd     if (el->el_chared.c_kill.mark)
221*6dc2f1dbScgd 	return CC_ERROR;
222*6dc2f1dbScgd 
223*6dc2f1dbScgd     if (el->el_chared.c_kill.mark > el->el_line.cursor) {
224*6dc2f1dbScgd 	cp = el->el_line.cursor;
225*6dc2f1dbScgd 	kp = el->el_chared.c_kill.buf;
226*6dc2f1dbScgd 	while (cp < el->el_chared.c_kill.mark)
227*6dc2f1dbScgd 	    *kp++ = *cp++;	/* copy it */
228*6dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
229*6dc2f1dbScgd     }
230*6dc2f1dbScgd     else {
231*6dc2f1dbScgd 	cp = el->el_chared.c_kill.mark;
232*6dc2f1dbScgd 	kp = el->el_chared.c_kill.buf;
233*6dc2f1dbScgd 	while (cp < el->el_line.cursor)
234*6dc2f1dbScgd 	    *kp++ = *cp++;	/* copy it */
235*6dc2f1dbScgd 	el->el_chared.c_kill.last = kp;
236*6dc2f1dbScgd     }
237*6dc2f1dbScgd     return CC_NORM;
238*6dc2f1dbScgd }
239*6dc2f1dbScgd 
240*6dc2f1dbScgd 
241*6dc2f1dbScgd /* em_gosmacs_traspose():
242*6dc2f1dbScgd  *	Exchange the two characters before the cursor
243*6dc2f1dbScgd  *	Gosling emacs transpose chars [^T]
244*6dc2f1dbScgd  */
245*6dc2f1dbScgd protected el_action_t
246*6dc2f1dbScgd em_gosmacs_traspose(el, c)
247*6dc2f1dbScgd     EditLine *el;
248*6dc2f1dbScgd     int c;
249*6dc2f1dbScgd {
250*6dc2f1dbScgd 
251*6dc2f1dbScgd     if (el->el_line.cursor > &el->el_line.buffer[1]) {
252*6dc2f1dbScgd    	/* must have at least two chars entered */
253*6dc2f1dbScgd 	c = el->el_line.cursor[-2];
254*6dc2f1dbScgd 	el->el_line.cursor[-2] = el->el_line.cursor[-1];
255*6dc2f1dbScgd 	el->el_line.cursor[-1] = c;
256*6dc2f1dbScgd 	return CC_REFRESH;
257*6dc2f1dbScgd     }
258*6dc2f1dbScgd     else
259*6dc2f1dbScgd 	return CC_ERROR;
260*6dc2f1dbScgd }
261*6dc2f1dbScgd 
262*6dc2f1dbScgd 
263*6dc2f1dbScgd /* em_next_word():
264*6dc2f1dbScgd  *	Move next to end of current word
265*6dc2f1dbScgd  *	[M-f]
266*6dc2f1dbScgd  */
267*6dc2f1dbScgd protected el_action_t
268*6dc2f1dbScgd /*ARGSUSED*/
269*6dc2f1dbScgd em_next_word(el, c)
270*6dc2f1dbScgd     EditLine *el;
271*6dc2f1dbScgd     int c;
272*6dc2f1dbScgd {
273*6dc2f1dbScgd     if (el->el_line.cursor == el->el_line.lastchar)
274*6dc2f1dbScgd 	return CC_ERROR;
275*6dc2f1dbScgd 
276*6dc2f1dbScgd     el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar,
277*6dc2f1dbScgd 				      el->el_state.argument,
278*6dc2f1dbScgd 				      ce__isword);
279*6dc2f1dbScgd 
280*6dc2f1dbScgd     if (el->el_map.type == MAP_VI)
281*6dc2f1dbScgd 	if (el->el_chared.c_vcmd.action & DELETE) {
282*6dc2f1dbScgd 	    cv_delfini(el);
283*6dc2f1dbScgd 	    return CC_REFRESH;
284*6dc2f1dbScgd 	}
285*6dc2f1dbScgd 
286*6dc2f1dbScgd     return CC_CURSOR;
287*6dc2f1dbScgd }
288*6dc2f1dbScgd 
289*6dc2f1dbScgd /* em_upper_case():
290*6dc2f1dbScgd  *	Uppercase the characters from cursor to end of current word
291*6dc2f1dbScgd  *	[M-u]
292*6dc2f1dbScgd  */
293*6dc2f1dbScgd protected el_action_t
294*6dc2f1dbScgd /*ARGSUSED*/
295*6dc2f1dbScgd em_upper_case(el, c)
296*6dc2f1dbScgd     EditLine *el;
297*6dc2f1dbScgd     int c;
298*6dc2f1dbScgd {
299*6dc2f1dbScgd     char   *cp, *ep;
300*6dc2f1dbScgd 
301*6dc2f1dbScgd     ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
302*6dc2f1dbScgd 		      el->el_state.argument, ce__isword);
303*6dc2f1dbScgd 
304*6dc2f1dbScgd     for (cp = el->el_line.cursor; cp < ep; cp++)
305*6dc2f1dbScgd 	if (islower(*cp))
306*6dc2f1dbScgd 	    *cp = toupper(*cp);
307*6dc2f1dbScgd 
308*6dc2f1dbScgd     el->el_line.cursor = ep;
309*6dc2f1dbScgd     if (el->el_line.cursor > el->el_line.lastchar)
310*6dc2f1dbScgd 	el->el_line.cursor = el->el_line.lastchar;
311*6dc2f1dbScgd     return CC_REFRESH;
312*6dc2f1dbScgd }
313*6dc2f1dbScgd 
314*6dc2f1dbScgd 
315*6dc2f1dbScgd /* em_capitol_case():
316*6dc2f1dbScgd  *	Capitalize the characters from cursor to end of current word
317*6dc2f1dbScgd  *	[M-c]
318*6dc2f1dbScgd  */
319*6dc2f1dbScgd protected el_action_t
320*6dc2f1dbScgd /*ARGSUSED*/
321*6dc2f1dbScgd em_capitol_case(el, c)
322*6dc2f1dbScgd     EditLine *el;
323*6dc2f1dbScgd     int c;
324*6dc2f1dbScgd {
325*6dc2f1dbScgd     char   *cp, *ep;
326*6dc2f1dbScgd 
327*6dc2f1dbScgd     ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
328*6dc2f1dbScgd 		      el->el_state.argument, ce__isword);
329*6dc2f1dbScgd 
330*6dc2f1dbScgd     for (cp = el->el_line.cursor; cp < ep; cp++) {
331*6dc2f1dbScgd 	if (isalpha(*cp)) {
332*6dc2f1dbScgd 	    if (islower(*cp))
333*6dc2f1dbScgd 		*cp = toupper(*cp);
334*6dc2f1dbScgd 	    cp++;
335*6dc2f1dbScgd 	    break;
336*6dc2f1dbScgd 	}
337*6dc2f1dbScgd     }
338*6dc2f1dbScgd     for (; cp < ep; cp++)
339*6dc2f1dbScgd 	if (isupper(*cp))
340*6dc2f1dbScgd 	    *cp = tolower(*cp);
341*6dc2f1dbScgd 
342*6dc2f1dbScgd     el->el_line.cursor = ep;
343*6dc2f1dbScgd     if (el->el_line.cursor > el->el_line.lastchar)
344*6dc2f1dbScgd 	el->el_line.cursor = el->el_line.lastchar;
345*6dc2f1dbScgd     return CC_REFRESH;
346*6dc2f1dbScgd }
347*6dc2f1dbScgd 
348*6dc2f1dbScgd /* em_lower_case():
349*6dc2f1dbScgd  *	Lowercase the characters from cursor to end of current word
350*6dc2f1dbScgd  *	[M-l]
351*6dc2f1dbScgd  */
352*6dc2f1dbScgd protected el_action_t
353*6dc2f1dbScgd /*ARGSUSED*/
354*6dc2f1dbScgd em_lower_case(el, c)
355*6dc2f1dbScgd     EditLine *el;
356*6dc2f1dbScgd     int c;
357*6dc2f1dbScgd {
358*6dc2f1dbScgd     char   *cp, *ep;
359*6dc2f1dbScgd 
360*6dc2f1dbScgd     ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
361*6dc2f1dbScgd 		      el->el_state.argument, ce__isword);
362*6dc2f1dbScgd 
363*6dc2f1dbScgd     for (cp = el->el_line.cursor; cp < ep; cp++)
364*6dc2f1dbScgd 	if (isupper(*cp))
365*6dc2f1dbScgd 	    *cp = tolower(*cp);
366*6dc2f1dbScgd 
367*6dc2f1dbScgd     el->el_line.cursor = ep;
368*6dc2f1dbScgd     if (el->el_line.cursor > el->el_line.lastchar)
369*6dc2f1dbScgd 	el->el_line.cursor = el->el_line.lastchar;
370*6dc2f1dbScgd     return CC_REFRESH;
371*6dc2f1dbScgd }
372*6dc2f1dbScgd 
373*6dc2f1dbScgd 
374*6dc2f1dbScgd /* em_set_mark():
375*6dc2f1dbScgd  *	Set the mark at cursor
376*6dc2f1dbScgd  *	[^@]
377*6dc2f1dbScgd  */
378*6dc2f1dbScgd protected el_action_t
379*6dc2f1dbScgd /*ARGSUSED*/
380*6dc2f1dbScgd em_set_mark(el, c)
381*6dc2f1dbScgd     EditLine *el;
382*6dc2f1dbScgd     int c;
383*6dc2f1dbScgd {
384*6dc2f1dbScgd     el->el_chared.c_kill.mark = el->el_line.cursor;
385*6dc2f1dbScgd     return CC_NORM;
386*6dc2f1dbScgd }
387*6dc2f1dbScgd 
388*6dc2f1dbScgd 
389*6dc2f1dbScgd /* em_exchange_mark():
390*6dc2f1dbScgd  *	Exchange the cursor and mark
391*6dc2f1dbScgd  *	[^X^X]
392*6dc2f1dbScgd  */
393*6dc2f1dbScgd protected el_action_t
394*6dc2f1dbScgd /*ARGSUSED*/
395*6dc2f1dbScgd em_exchange_mark(el, c)
396*6dc2f1dbScgd     EditLine *el;
397*6dc2f1dbScgd     int c;
398*6dc2f1dbScgd {
399*6dc2f1dbScgd     register char *cp;
400*6dc2f1dbScgd 
401*6dc2f1dbScgd     cp = el->el_line.cursor;
402*6dc2f1dbScgd     el->el_line.cursor = el->el_chared.c_kill.mark;
403*6dc2f1dbScgd     el->el_chared.c_kill.mark = cp;
404*6dc2f1dbScgd     return CC_CURSOR;
405*6dc2f1dbScgd }
406*6dc2f1dbScgd 
407*6dc2f1dbScgd /* em_universal_argument():
408*6dc2f1dbScgd  *	Universal argument (argument times 4)
409*6dc2f1dbScgd  *	[^U]
410*6dc2f1dbScgd  */
411*6dc2f1dbScgd protected el_action_t
412*6dc2f1dbScgd /*ARGSUSED*/
413*6dc2f1dbScgd em_universal_argument(el, c)
414*6dc2f1dbScgd     EditLine *el;
415*6dc2f1dbScgd     int c;
416*6dc2f1dbScgd {				/* multiply current argument by 4 */
417*6dc2f1dbScgd     if (el->el_state.argument > 1000000)
418*6dc2f1dbScgd 	return CC_ERROR;
419*6dc2f1dbScgd     el->el_state.doingarg = 1;
420*6dc2f1dbScgd     el->el_state.argument *= 4;
421*6dc2f1dbScgd     return CC_ARGHACK;
422*6dc2f1dbScgd }
423*6dc2f1dbScgd 
424*6dc2f1dbScgd /* em_meta_next():
425*6dc2f1dbScgd  *	Add 8th bit to next character typed
426*6dc2f1dbScgd  *	[<ESC>]
427*6dc2f1dbScgd  */
428*6dc2f1dbScgd protected el_action_t
429*6dc2f1dbScgd /*ARGSUSED*/
430*6dc2f1dbScgd em_meta_next(el, c)
431*6dc2f1dbScgd     EditLine *el;
432*6dc2f1dbScgd     int c;
433*6dc2f1dbScgd {
434*6dc2f1dbScgd     el->el_state.metanext = 1;
435*6dc2f1dbScgd     return CC_ARGHACK;
436*6dc2f1dbScgd }
437*6dc2f1dbScgd 
438*6dc2f1dbScgd 
439*6dc2f1dbScgd /* em_toggle_overwrite():
440*6dc2f1dbScgd  *	Switch from insert to overwrite mode or vice versa
441*6dc2f1dbScgd  */
442*6dc2f1dbScgd protected el_action_t
443*6dc2f1dbScgd /*ARGSUSED*/
444*6dc2f1dbScgd em_toggle_overwrite(el, c)
445*6dc2f1dbScgd     EditLine *el;
446*6dc2f1dbScgd     int c;
447*6dc2f1dbScgd {
448*6dc2f1dbScgd     el->el_state.inputmode =
449*6dc2f1dbScgd 	(el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT;
450*6dc2f1dbScgd     return CC_NORM;
451*6dc2f1dbScgd }
452*6dc2f1dbScgd 
453*6dc2f1dbScgd 
454*6dc2f1dbScgd /* em_copy_prev_word():
455*6dc2f1dbScgd  *	Copy current word to cursor
456*6dc2f1dbScgd  */
457*6dc2f1dbScgd protected el_action_t
458*6dc2f1dbScgd /*ARGSUSED*/
459*6dc2f1dbScgd em_copy_prev_word(el, c)
460*6dc2f1dbScgd     EditLine *el;
461*6dc2f1dbScgd     int c;
462*6dc2f1dbScgd {
463*6dc2f1dbScgd     char *cp, *oldc, *dp;
464*6dc2f1dbScgd 
465*6dc2f1dbScgd     if (el->el_line.cursor == el->el_line.buffer)
466*6dc2f1dbScgd 	return CC_ERROR;
467*6dc2f1dbScgd 
468*6dc2f1dbScgd     oldc = el->el_line.cursor;
469*6dc2f1dbScgd     /* does a bounds check */
470*6dc2f1dbScgd     cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
471*6dc2f1dbScgd 		      el->el_state.argument, ce__isword);
472*6dc2f1dbScgd 
473*6dc2f1dbScgd     c_insert(el, oldc - cp);
474*6dc2f1dbScgd     for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
475*6dc2f1dbScgd 	*dp++ = *cp;
476*6dc2f1dbScgd 
477*6dc2f1dbScgd     el->el_line.cursor = dp;		/* put cursor at end */
478*6dc2f1dbScgd 
479*6dc2f1dbScgd     return CC_REFRESH;
480*6dc2f1dbScgd }
481*6dc2f1dbScgd 
482*6dc2f1dbScgd 
483*6dc2f1dbScgd /* em_inc_search_next():
484*6dc2f1dbScgd  *	Emacs incremental next search
485*6dc2f1dbScgd  */
486*6dc2f1dbScgd protected el_action_t
487*6dc2f1dbScgd /*ARGSUSED*/
488*6dc2f1dbScgd em_inc_search_next(el, c)
489*6dc2f1dbScgd     EditLine *el;
490*6dc2f1dbScgd     int c;
491*6dc2f1dbScgd {
492*6dc2f1dbScgd     el->el_search.patlen = 0;
493*6dc2f1dbScgd     return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
494*6dc2f1dbScgd }
495*6dc2f1dbScgd 
496*6dc2f1dbScgd 
497*6dc2f1dbScgd /* em_inc_search_prev():
498*6dc2f1dbScgd  *	Emacs incremental reverse search
499*6dc2f1dbScgd  */
500*6dc2f1dbScgd protected el_action_t
501*6dc2f1dbScgd /*ARGSUSED*/
502*6dc2f1dbScgd em_inc_search_prev(el, c)
503*6dc2f1dbScgd     EditLine *el;
504*6dc2f1dbScgd     int c;
505*6dc2f1dbScgd {
506*6dc2f1dbScgd     el->el_search.patlen = 0;
507*6dc2f1dbScgd     return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
508*6dc2f1dbScgd }
509