xref: /freebsd/contrib/libedit/common.c (revision d0ef721ed3dc99bddc1e48605a6921ec60322efc)
1*d0ef721eSBaptiste Daroussin /*	$NetBSD: common.c,v 1.48 2018/02/26 17:36:14 christos Exp $	*/
2*d0ef721eSBaptiste Daroussin 
3*d0ef721eSBaptiste Daroussin /*-
4*d0ef721eSBaptiste Daroussin  * Copyright (c) 1992, 1993
5*d0ef721eSBaptiste Daroussin  *	The Regents of the University of California.  All rights reserved.
6*d0ef721eSBaptiste Daroussin  *
7*d0ef721eSBaptiste Daroussin  * This code is derived from software contributed to Berkeley by
8*d0ef721eSBaptiste Daroussin  * Christos Zoulas of Cornell University.
9*d0ef721eSBaptiste Daroussin  *
10*d0ef721eSBaptiste Daroussin  * Redistribution and use in source and binary forms, with or without
11*d0ef721eSBaptiste Daroussin  * modification, are permitted provided that the following conditions
12*d0ef721eSBaptiste Daroussin  * are met:
13*d0ef721eSBaptiste Daroussin  * 1. Redistributions of source code must retain the above copyright
14*d0ef721eSBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer.
15*d0ef721eSBaptiste Daroussin  * 2. Redistributions in binary form must reproduce the above copyright
16*d0ef721eSBaptiste Daroussin  *    notice, this list of conditions and the following disclaimer in the
17*d0ef721eSBaptiste Daroussin  *    documentation and/or other materials provided with the distribution.
18*d0ef721eSBaptiste Daroussin  * 3. Neither the name of the University nor the names of its contributors
19*d0ef721eSBaptiste Daroussin  *    may be used to endorse or promote products derived from this software
20*d0ef721eSBaptiste Daroussin  *    without specific prior written permission.
21*d0ef721eSBaptiste Daroussin  *
22*d0ef721eSBaptiste Daroussin  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*d0ef721eSBaptiste Daroussin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*d0ef721eSBaptiste Daroussin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*d0ef721eSBaptiste Daroussin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*d0ef721eSBaptiste Daroussin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*d0ef721eSBaptiste Daroussin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*d0ef721eSBaptiste Daroussin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*d0ef721eSBaptiste Daroussin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*d0ef721eSBaptiste Daroussin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*d0ef721eSBaptiste Daroussin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*d0ef721eSBaptiste Daroussin  * SUCH DAMAGE.
33*d0ef721eSBaptiste Daroussin  */
34*d0ef721eSBaptiste Daroussin 
35*d0ef721eSBaptiste Daroussin #include "config.h"
36*d0ef721eSBaptiste Daroussin #if !defined(lint) && !defined(SCCSID)
37*d0ef721eSBaptiste Daroussin #if 0
38*d0ef721eSBaptiste Daroussin static char sccsid[] = "@(#)common.c	8.1 (Berkeley) 6/4/93";
39*d0ef721eSBaptiste Daroussin #else
40*d0ef721eSBaptiste Daroussin __RCSID("$NetBSD: common.c,v 1.48 2018/02/26 17:36:14 christos Exp $");
41*d0ef721eSBaptiste Daroussin #endif
42*d0ef721eSBaptiste Daroussin #endif /* not lint && not SCCSID */
43*d0ef721eSBaptiste Daroussin 
44*d0ef721eSBaptiste Daroussin /*
45*d0ef721eSBaptiste Daroussin  * common.c: Common Editor functions
46*d0ef721eSBaptiste Daroussin  */
47*d0ef721eSBaptiste Daroussin #include <ctype.h>
48*d0ef721eSBaptiste Daroussin #include <string.h>
49*d0ef721eSBaptiste Daroussin 
50*d0ef721eSBaptiste Daroussin #include "el.h"
51*d0ef721eSBaptiste Daroussin #include "common.h"
52*d0ef721eSBaptiste Daroussin #include "fcns.h"
53*d0ef721eSBaptiste Daroussin #include "parse.h"
54*d0ef721eSBaptiste Daroussin #include "vi.h"
55*d0ef721eSBaptiste Daroussin 
56*d0ef721eSBaptiste Daroussin /* ed_end_of_file():
57*d0ef721eSBaptiste Daroussin  *	Indicate end of file
58*d0ef721eSBaptiste Daroussin  *	[^D]
59*d0ef721eSBaptiste Daroussin  */
60*d0ef721eSBaptiste Daroussin libedit_private el_action_t
61*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
62*d0ef721eSBaptiste Daroussin ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
63*d0ef721eSBaptiste Daroussin {
64*d0ef721eSBaptiste Daroussin 
65*d0ef721eSBaptiste Daroussin 	re_goto_bottom(el);
66*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';
67*d0ef721eSBaptiste Daroussin 	return CC_EOF;
68*d0ef721eSBaptiste Daroussin }
69*d0ef721eSBaptiste Daroussin 
70*d0ef721eSBaptiste Daroussin 
71*d0ef721eSBaptiste Daroussin /* ed_insert():
72*d0ef721eSBaptiste Daroussin  *	Add character to the line
73*d0ef721eSBaptiste Daroussin  *	Insert a character [bound to all insert keys]
74*d0ef721eSBaptiste Daroussin  */
75*d0ef721eSBaptiste Daroussin libedit_private el_action_t
76*d0ef721eSBaptiste Daroussin ed_insert(EditLine *el, wint_t c)
77*d0ef721eSBaptiste Daroussin {
78*d0ef721eSBaptiste Daroussin 	int count = el->el_state.argument;
79*d0ef721eSBaptiste Daroussin 
80*d0ef721eSBaptiste Daroussin 	if (c == '\0')
81*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
82*d0ef721eSBaptiste Daroussin 
83*d0ef721eSBaptiste Daroussin 	if (el->el_line.lastchar + el->el_state.argument >=
84*d0ef721eSBaptiste Daroussin 	    el->el_line.limit) {
85*d0ef721eSBaptiste Daroussin 		/* end of buffer space, try to allocate more */
86*d0ef721eSBaptiste Daroussin 		if (!ch_enlargebufs(el, (size_t) count))
87*d0ef721eSBaptiste Daroussin 			return CC_ERROR;	/* error allocating more */
88*d0ef721eSBaptiste Daroussin 	}
89*d0ef721eSBaptiste Daroussin 
90*d0ef721eSBaptiste Daroussin 	if (count == 1) {
91*d0ef721eSBaptiste Daroussin 		if (el->el_state.inputmode == MODE_INSERT
92*d0ef721eSBaptiste Daroussin 		    || el->el_line.cursor >= el->el_line.lastchar)
93*d0ef721eSBaptiste Daroussin 			c_insert(el, 1);
94*d0ef721eSBaptiste Daroussin 
95*d0ef721eSBaptiste Daroussin 		*el->el_line.cursor++ = c;
96*d0ef721eSBaptiste Daroussin 		re_fastaddc(el);		/* fast refresh for one char. */
97*d0ef721eSBaptiste Daroussin 	} else {
98*d0ef721eSBaptiste Daroussin 		if (el->el_state.inputmode != MODE_REPLACE_1)
99*d0ef721eSBaptiste Daroussin 			c_insert(el, el->el_state.argument);
100*d0ef721eSBaptiste Daroussin 
101*d0ef721eSBaptiste Daroussin 		while (count-- && el->el_line.cursor < el->el_line.lastchar)
102*d0ef721eSBaptiste Daroussin 			*el->el_line.cursor++ = c;
103*d0ef721eSBaptiste Daroussin 		re_refresh(el);
104*d0ef721eSBaptiste Daroussin 	}
105*d0ef721eSBaptiste Daroussin 
106*d0ef721eSBaptiste Daroussin 	if (el->el_state.inputmode == MODE_REPLACE_1)
107*d0ef721eSBaptiste Daroussin 		return vi_command_mode(el, 0);
108*d0ef721eSBaptiste Daroussin 
109*d0ef721eSBaptiste Daroussin 	return CC_NORM;
110*d0ef721eSBaptiste Daroussin }
111*d0ef721eSBaptiste Daroussin 
112*d0ef721eSBaptiste Daroussin 
113*d0ef721eSBaptiste Daroussin /* ed_delete_prev_word():
114*d0ef721eSBaptiste Daroussin  *	Delete from beginning of current word to cursor
115*d0ef721eSBaptiste Daroussin  *	[M-^?] [^W]
116*d0ef721eSBaptiste Daroussin  */
117*d0ef721eSBaptiste Daroussin libedit_private el_action_t
118*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
119*d0ef721eSBaptiste Daroussin ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
120*d0ef721eSBaptiste Daroussin {
121*d0ef721eSBaptiste Daroussin 	wchar_t *cp, *p, *kp;
122*d0ef721eSBaptiste Daroussin 
123*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor == el->el_line.buffer)
124*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
125*d0ef721eSBaptiste Daroussin 
126*d0ef721eSBaptiste Daroussin 	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
127*d0ef721eSBaptiste Daroussin 	    el->el_state.argument, ce__isword);
128*d0ef721eSBaptiste Daroussin 
129*d0ef721eSBaptiste Daroussin 	for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
130*d0ef721eSBaptiste Daroussin 		*kp++ = *p;
131*d0ef721eSBaptiste Daroussin 	el->el_chared.c_kill.last = kp;
132*d0ef721eSBaptiste Daroussin 
133*d0ef721eSBaptiste Daroussin 	c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
134*d0ef721eSBaptiste Daroussin 	el->el_line.cursor = cp;
135*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor < el->el_line.buffer)
136*d0ef721eSBaptiste Daroussin 		el->el_line.cursor = el->el_line.buffer; /* bounds check */
137*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
138*d0ef721eSBaptiste Daroussin }
139*d0ef721eSBaptiste Daroussin 
140*d0ef721eSBaptiste Daroussin 
141*d0ef721eSBaptiste Daroussin /* ed_delete_next_char():
142*d0ef721eSBaptiste Daroussin  *	Delete character under cursor
143*d0ef721eSBaptiste Daroussin  *	[^D] [x]
144*d0ef721eSBaptiste Daroussin  */
145*d0ef721eSBaptiste Daroussin libedit_private el_action_t
146*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
147*d0ef721eSBaptiste Daroussin ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
148*d0ef721eSBaptiste Daroussin {
149*d0ef721eSBaptiste Daroussin #ifdef DEBUG_EDIT
150*d0ef721eSBaptiste Daroussin #define	EL	el->el_line
151*d0ef721eSBaptiste Daroussin 	(void) fprintf(el->el_errfile,
152*d0ef721eSBaptiste Daroussin 	    "\nD(b: %p(%ls)  c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
153*d0ef721eSBaptiste Daroussin 	    EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
154*d0ef721eSBaptiste Daroussin 	    EL.lastchar, EL.limit, EL.limit);
155*d0ef721eSBaptiste Daroussin #endif
156*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor == el->el_line.lastchar) {
157*d0ef721eSBaptiste Daroussin 			/* if I'm at the end */
158*d0ef721eSBaptiste Daroussin 		if (el->el_map.type == MAP_VI) {
159*d0ef721eSBaptiste Daroussin 			if (el->el_line.cursor == el->el_line.buffer) {
160*d0ef721eSBaptiste Daroussin 				/* if I'm also at the beginning */
161*d0ef721eSBaptiste Daroussin #ifdef KSHVI
162*d0ef721eSBaptiste Daroussin 				return CC_ERROR;
163*d0ef721eSBaptiste Daroussin #else
164*d0ef721eSBaptiste Daroussin 				/* then do an EOF */
165*d0ef721eSBaptiste Daroussin 				terminal_writec(el, c);
166*d0ef721eSBaptiste Daroussin 				return CC_EOF;
167*d0ef721eSBaptiste Daroussin #endif
168*d0ef721eSBaptiste Daroussin 			} else {
169*d0ef721eSBaptiste Daroussin #ifdef KSHVI
170*d0ef721eSBaptiste Daroussin 				el->el_line.cursor--;
171*d0ef721eSBaptiste Daroussin #else
172*d0ef721eSBaptiste Daroussin 				return CC_ERROR;
173*d0ef721eSBaptiste Daroussin #endif
174*d0ef721eSBaptiste Daroussin 			}
175*d0ef721eSBaptiste Daroussin 		} else
176*d0ef721eSBaptiste Daroussin 				return CC_ERROR;
177*d0ef721eSBaptiste Daroussin 	}
178*d0ef721eSBaptiste Daroussin 	c_delafter(el, el->el_state.argument);	/* delete after dot */
179*d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI &&
180*d0ef721eSBaptiste Daroussin 	    el->el_line.cursor >= el->el_line.lastchar &&
181*d0ef721eSBaptiste Daroussin 	    el->el_line.cursor > el->el_line.buffer)
182*d0ef721eSBaptiste Daroussin 			/* bounds check */
183*d0ef721eSBaptiste Daroussin 		el->el_line.cursor = el->el_line.lastchar - 1;
184*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
185*d0ef721eSBaptiste Daroussin }
186*d0ef721eSBaptiste Daroussin 
187*d0ef721eSBaptiste Daroussin 
188*d0ef721eSBaptiste Daroussin /* ed_kill_line():
189*d0ef721eSBaptiste Daroussin  *	Cut to the end of line
190*d0ef721eSBaptiste Daroussin  *	[^K] [^K]
191*d0ef721eSBaptiste Daroussin  */
192*d0ef721eSBaptiste Daroussin libedit_private el_action_t
193*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
194*d0ef721eSBaptiste Daroussin ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
195*d0ef721eSBaptiste Daroussin {
196*d0ef721eSBaptiste Daroussin 	wchar_t *kp, *cp;
197*d0ef721eSBaptiste Daroussin 
198*d0ef721eSBaptiste Daroussin 	cp = el->el_line.cursor;
199*d0ef721eSBaptiste Daroussin 	kp = el->el_chared.c_kill.buf;
200*d0ef721eSBaptiste Daroussin 	while (cp < el->el_line.lastchar)
201*d0ef721eSBaptiste Daroussin 		*kp++ = *cp++;	/* copy it */
202*d0ef721eSBaptiste Daroussin 	el->el_chared.c_kill.last = kp;
203*d0ef721eSBaptiste Daroussin 			/* zap! -- delete to end */
204*d0ef721eSBaptiste Daroussin 	el->el_line.lastchar = el->el_line.cursor;
205*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
206*d0ef721eSBaptiste Daroussin }
207*d0ef721eSBaptiste Daroussin 
208*d0ef721eSBaptiste Daroussin 
209*d0ef721eSBaptiste Daroussin /* ed_move_to_end():
210*d0ef721eSBaptiste Daroussin  *	Move cursor to the end of line
211*d0ef721eSBaptiste Daroussin  *	[^E] [^E]
212*d0ef721eSBaptiste Daroussin  */
213*d0ef721eSBaptiste Daroussin libedit_private el_action_t
214*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
215*d0ef721eSBaptiste Daroussin ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
216*d0ef721eSBaptiste Daroussin {
217*d0ef721eSBaptiste Daroussin 
218*d0ef721eSBaptiste Daroussin 	el->el_line.cursor = el->el_line.lastchar;
219*d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI) {
220*d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
221*d0ef721eSBaptiste Daroussin 			cv_delfini(el);
222*d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
223*d0ef721eSBaptiste Daroussin 		}
224*d0ef721eSBaptiste Daroussin #ifdef VI_MOVE
225*d0ef721eSBaptiste Daroussin 		el->el_line.cursor--;
226*d0ef721eSBaptiste Daroussin #endif
227*d0ef721eSBaptiste Daroussin 	}
228*d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
229*d0ef721eSBaptiste Daroussin }
230*d0ef721eSBaptiste Daroussin 
231*d0ef721eSBaptiste Daroussin 
232*d0ef721eSBaptiste Daroussin /* ed_move_to_beg():
233*d0ef721eSBaptiste Daroussin  *	Move cursor to the beginning of line
234*d0ef721eSBaptiste Daroussin  *	[^A] [^A]
235*d0ef721eSBaptiste Daroussin  */
236*d0ef721eSBaptiste Daroussin libedit_private el_action_t
237*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
238*d0ef721eSBaptiste Daroussin ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
239*d0ef721eSBaptiste Daroussin {
240*d0ef721eSBaptiste Daroussin 
241*d0ef721eSBaptiste Daroussin 	el->el_line.cursor = el->el_line.buffer;
242*d0ef721eSBaptiste Daroussin 
243*d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI) {
244*d0ef721eSBaptiste Daroussin 			/* We want FIRST non space character */
245*d0ef721eSBaptiste Daroussin 		while (iswspace(*el->el_line.cursor))
246*d0ef721eSBaptiste Daroussin 			el->el_line.cursor++;
247*d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
248*d0ef721eSBaptiste Daroussin 			cv_delfini(el);
249*d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
250*d0ef721eSBaptiste Daroussin 		}
251*d0ef721eSBaptiste Daroussin 	}
252*d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
253*d0ef721eSBaptiste Daroussin }
254*d0ef721eSBaptiste Daroussin 
255*d0ef721eSBaptiste Daroussin 
256*d0ef721eSBaptiste Daroussin /* ed_transpose_chars():
257*d0ef721eSBaptiste Daroussin  *	Exchange the character to the left of the cursor with the one under it
258*d0ef721eSBaptiste Daroussin  *	[^T] [^T]
259*d0ef721eSBaptiste Daroussin  */
260*d0ef721eSBaptiste Daroussin libedit_private el_action_t
261*d0ef721eSBaptiste Daroussin ed_transpose_chars(EditLine *el, wint_t c)
262*d0ef721eSBaptiste Daroussin {
263*d0ef721eSBaptiste Daroussin 
264*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor < el->el_line.lastchar) {
265*d0ef721eSBaptiste Daroussin 		if (el->el_line.lastchar <= &el->el_line.buffer[1])
266*d0ef721eSBaptiste Daroussin 			return CC_ERROR;
267*d0ef721eSBaptiste Daroussin 		else
268*d0ef721eSBaptiste Daroussin 			el->el_line.cursor++;
269*d0ef721eSBaptiste Daroussin 	}
270*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
271*d0ef721eSBaptiste Daroussin 		/* must have at least two chars entered */
272*d0ef721eSBaptiste Daroussin 		c = el->el_line.cursor[-2];
273*d0ef721eSBaptiste Daroussin 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
274*d0ef721eSBaptiste Daroussin 		el->el_line.cursor[-1] = c;
275*d0ef721eSBaptiste Daroussin 		return CC_REFRESH;
276*d0ef721eSBaptiste Daroussin 	} else
277*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
278*d0ef721eSBaptiste Daroussin }
279*d0ef721eSBaptiste Daroussin 
280*d0ef721eSBaptiste Daroussin 
281*d0ef721eSBaptiste Daroussin /* ed_next_char():
282*d0ef721eSBaptiste Daroussin  *	Move to the right one character
283*d0ef721eSBaptiste Daroussin  *	[^F] [^F]
284*d0ef721eSBaptiste Daroussin  */
285*d0ef721eSBaptiste Daroussin libedit_private el_action_t
286*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
287*d0ef721eSBaptiste Daroussin ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
288*d0ef721eSBaptiste Daroussin {
289*d0ef721eSBaptiste Daroussin 	wchar_t *lim = el->el_line.lastchar;
290*d0ef721eSBaptiste Daroussin 
291*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor >= lim ||
292*d0ef721eSBaptiste Daroussin 	    (el->el_line.cursor == lim - 1 &&
293*d0ef721eSBaptiste Daroussin 	    el->el_map.type == MAP_VI &&
294*d0ef721eSBaptiste Daroussin 	    el->el_chared.c_vcmd.action == NOP))
295*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
296*d0ef721eSBaptiste Daroussin 
297*d0ef721eSBaptiste Daroussin 	el->el_line.cursor += el->el_state.argument;
298*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor > lim)
299*d0ef721eSBaptiste Daroussin 		el->el_line.cursor = lim;
300*d0ef721eSBaptiste Daroussin 
301*d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI)
302*d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
303*d0ef721eSBaptiste Daroussin 			cv_delfini(el);
304*d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
305*d0ef721eSBaptiste Daroussin 		}
306*d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
307*d0ef721eSBaptiste Daroussin }
308*d0ef721eSBaptiste Daroussin 
309*d0ef721eSBaptiste Daroussin 
310*d0ef721eSBaptiste Daroussin /* ed_prev_word():
311*d0ef721eSBaptiste Daroussin  *	Move to the beginning of the current word
312*d0ef721eSBaptiste Daroussin  *	[M-b] [b]
313*d0ef721eSBaptiste Daroussin  */
314*d0ef721eSBaptiste Daroussin libedit_private el_action_t
315*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
316*d0ef721eSBaptiste Daroussin ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
317*d0ef721eSBaptiste Daroussin {
318*d0ef721eSBaptiste Daroussin 
319*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor == el->el_line.buffer)
320*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
321*d0ef721eSBaptiste Daroussin 
322*d0ef721eSBaptiste Daroussin 	el->el_line.cursor = c__prev_word(el->el_line.cursor,
323*d0ef721eSBaptiste Daroussin 	    el->el_line.buffer,
324*d0ef721eSBaptiste Daroussin 	    el->el_state.argument,
325*d0ef721eSBaptiste Daroussin 	    ce__isword);
326*d0ef721eSBaptiste Daroussin 
327*d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI)
328*d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
329*d0ef721eSBaptiste Daroussin 			cv_delfini(el);
330*d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
331*d0ef721eSBaptiste Daroussin 		}
332*d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
333*d0ef721eSBaptiste Daroussin }
334*d0ef721eSBaptiste Daroussin 
335*d0ef721eSBaptiste Daroussin 
336*d0ef721eSBaptiste Daroussin /* ed_prev_char():
337*d0ef721eSBaptiste Daroussin  *	Move to the left one character
338*d0ef721eSBaptiste Daroussin  *	[^B] [^B]
339*d0ef721eSBaptiste Daroussin  */
340*d0ef721eSBaptiste Daroussin libedit_private el_action_t
341*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
342*d0ef721eSBaptiste Daroussin ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
343*d0ef721eSBaptiste Daroussin {
344*d0ef721eSBaptiste Daroussin 
345*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor > el->el_line.buffer) {
346*d0ef721eSBaptiste Daroussin 		el->el_line.cursor -= el->el_state.argument;
347*d0ef721eSBaptiste Daroussin 		if (el->el_line.cursor < el->el_line.buffer)
348*d0ef721eSBaptiste Daroussin 			el->el_line.cursor = el->el_line.buffer;
349*d0ef721eSBaptiste Daroussin 
350*d0ef721eSBaptiste Daroussin 		if (el->el_map.type == MAP_VI)
351*d0ef721eSBaptiste Daroussin 			if (el->el_chared.c_vcmd.action != NOP) {
352*d0ef721eSBaptiste Daroussin 				cv_delfini(el);
353*d0ef721eSBaptiste Daroussin 				return CC_REFRESH;
354*d0ef721eSBaptiste Daroussin 			}
355*d0ef721eSBaptiste Daroussin 		return CC_CURSOR;
356*d0ef721eSBaptiste Daroussin 	} else
357*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
358*d0ef721eSBaptiste Daroussin }
359*d0ef721eSBaptiste Daroussin 
360*d0ef721eSBaptiste Daroussin 
361*d0ef721eSBaptiste Daroussin /* ed_quoted_insert():
362*d0ef721eSBaptiste Daroussin  *	Add the next character typed verbatim
363*d0ef721eSBaptiste Daroussin  *	[^V] [^V]
364*d0ef721eSBaptiste Daroussin  */
365*d0ef721eSBaptiste Daroussin libedit_private el_action_t
366*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
367*d0ef721eSBaptiste Daroussin ed_quoted_insert(EditLine *el, wint_t c __attribute__((__unused__)))
368*d0ef721eSBaptiste Daroussin {
369*d0ef721eSBaptiste Daroussin 	int num;
370*d0ef721eSBaptiste Daroussin 	wchar_t ch;
371*d0ef721eSBaptiste Daroussin 
372*d0ef721eSBaptiste Daroussin 	tty_quotemode(el);
373*d0ef721eSBaptiste Daroussin 	num = el_wgetc(el, &ch);
374*d0ef721eSBaptiste Daroussin 	tty_noquotemode(el);
375*d0ef721eSBaptiste Daroussin 	if (num == 1)
376*d0ef721eSBaptiste Daroussin 		return ed_insert(el, ch);
377*d0ef721eSBaptiste Daroussin 	else
378*d0ef721eSBaptiste Daroussin 		return ed_end_of_file(el, 0);
379*d0ef721eSBaptiste Daroussin }
380*d0ef721eSBaptiste Daroussin 
381*d0ef721eSBaptiste Daroussin 
382*d0ef721eSBaptiste Daroussin /* ed_digit():
383*d0ef721eSBaptiste Daroussin  *	Adds to argument or enters a digit
384*d0ef721eSBaptiste Daroussin  */
385*d0ef721eSBaptiste Daroussin libedit_private el_action_t
386*d0ef721eSBaptiste Daroussin ed_digit(EditLine *el, wint_t c)
387*d0ef721eSBaptiste Daroussin {
388*d0ef721eSBaptiste Daroussin 
389*d0ef721eSBaptiste Daroussin 	if (!iswdigit(c))
390*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
391*d0ef721eSBaptiste Daroussin 
392*d0ef721eSBaptiste Daroussin 	if (el->el_state.doingarg) {
393*d0ef721eSBaptiste Daroussin 			/* if doing an arg, add this in... */
394*d0ef721eSBaptiste Daroussin 		if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
395*d0ef721eSBaptiste Daroussin 			el->el_state.argument = c - '0';
396*d0ef721eSBaptiste Daroussin 		else {
397*d0ef721eSBaptiste Daroussin 			if (el->el_state.argument > 1000000)
398*d0ef721eSBaptiste Daroussin 				return CC_ERROR;
399*d0ef721eSBaptiste Daroussin 			el->el_state.argument =
400*d0ef721eSBaptiste Daroussin 			    (el->el_state.argument * 10) + (c - '0');
401*d0ef721eSBaptiste Daroussin 		}
402*d0ef721eSBaptiste Daroussin 		return CC_ARGHACK;
403*d0ef721eSBaptiste Daroussin 	}
404*d0ef721eSBaptiste Daroussin 
405*d0ef721eSBaptiste Daroussin 	return ed_insert(el, c);
406*d0ef721eSBaptiste Daroussin }
407*d0ef721eSBaptiste Daroussin 
408*d0ef721eSBaptiste Daroussin 
409*d0ef721eSBaptiste Daroussin /* ed_argument_digit():
410*d0ef721eSBaptiste Daroussin  *	Digit that starts argument
411*d0ef721eSBaptiste Daroussin  *	For ESC-n
412*d0ef721eSBaptiste Daroussin  */
413*d0ef721eSBaptiste Daroussin libedit_private el_action_t
414*d0ef721eSBaptiste Daroussin ed_argument_digit(EditLine *el, wint_t c)
415*d0ef721eSBaptiste Daroussin {
416*d0ef721eSBaptiste Daroussin 
417*d0ef721eSBaptiste Daroussin 	if (!iswdigit(c))
418*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
419*d0ef721eSBaptiste Daroussin 
420*d0ef721eSBaptiste Daroussin 	if (el->el_state.doingarg) {
421*d0ef721eSBaptiste Daroussin 		if (el->el_state.argument > 1000000)
422*d0ef721eSBaptiste Daroussin 			return CC_ERROR;
423*d0ef721eSBaptiste Daroussin 		el->el_state.argument = (el->el_state.argument * 10) +
424*d0ef721eSBaptiste Daroussin 		    (c - '0');
425*d0ef721eSBaptiste Daroussin 	} else {		/* else starting an argument */
426*d0ef721eSBaptiste Daroussin 		el->el_state.argument = c - '0';
427*d0ef721eSBaptiste Daroussin 		el->el_state.doingarg = 1;
428*d0ef721eSBaptiste Daroussin 	}
429*d0ef721eSBaptiste Daroussin 	return CC_ARGHACK;
430*d0ef721eSBaptiste Daroussin }
431*d0ef721eSBaptiste Daroussin 
432*d0ef721eSBaptiste Daroussin 
433*d0ef721eSBaptiste Daroussin /* ed_unassigned():
434*d0ef721eSBaptiste Daroussin  *	Indicates unbound character
435*d0ef721eSBaptiste Daroussin  *	Bound to keys that are not assigned
436*d0ef721eSBaptiste Daroussin  */
437*d0ef721eSBaptiste Daroussin libedit_private el_action_t
438*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
439*d0ef721eSBaptiste Daroussin ed_unassigned(EditLine *el __attribute__((__unused__)),
440*d0ef721eSBaptiste Daroussin     wint_t c __attribute__((__unused__)))
441*d0ef721eSBaptiste Daroussin {
442*d0ef721eSBaptiste Daroussin 
443*d0ef721eSBaptiste Daroussin 	return CC_ERROR;
444*d0ef721eSBaptiste Daroussin }
445*d0ef721eSBaptiste Daroussin 
446*d0ef721eSBaptiste Daroussin 
447*d0ef721eSBaptiste Daroussin /* ed_ignore():
448*d0ef721eSBaptiste Daroussin  *	Input characters that have no effect
449*d0ef721eSBaptiste Daroussin  *	[^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
450*d0ef721eSBaptiste Daroussin  */
451*d0ef721eSBaptiste Daroussin libedit_private el_action_t
452*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
453*d0ef721eSBaptiste Daroussin ed_ignore(EditLine *el __attribute__((__unused__)),
454*d0ef721eSBaptiste Daroussin 	      wint_t c __attribute__((__unused__)))
455*d0ef721eSBaptiste Daroussin {
456*d0ef721eSBaptiste Daroussin 
457*d0ef721eSBaptiste Daroussin 	return CC_NORM;
458*d0ef721eSBaptiste Daroussin }
459*d0ef721eSBaptiste Daroussin 
460*d0ef721eSBaptiste Daroussin 
461*d0ef721eSBaptiste Daroussin /* ed_newline():
462*d0ef721eSBaptiste Daroussin  *	Execute command
463*d0ef721eSBaptiste Daroussin  *	[^J]
464*d0ef721eSBaptiste Daroussin  */
465*d0ef721eSBaptiste Daroussin libedit_private el_action_t
466*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
467*d0ef721eSBaptiste Daroussin ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
468*d0ef721eSBaptiste Daroussin {
469*d0ef721eSBaptiste Daroussin 
470*d0ef721eSBaptiste Daroussin 	re_goto_bottom(el);
471*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar++ = '\n';
472*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';
473*d0ef721eSBaptiste Daroussin 	return CC_NEWLINE;
474*d0ef721eSBaptiste Daroussin }
475*d0ef721eSBaptiste Daroussin 
476*d0ef721eSBaptiste Daroussin 
477*d0ef721eSBaptiste Daroussin /* ed_delete_prev_char():
478*d0ef721eSBaptiste Daroussin  *	Delete the character to the left of the cursor
479*d0ef721eSBaptiste Daroussin  *	[^?]
480*d0ef721eSBaptiste Daroussin  */
481*d0ef721eSBaptiste Daroussin libedit_private el_action_t
482*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
483*d0ef721eSBaptiste Daroussin ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
484*d0ef721eSBaptiste Daroussin {
485*d0ef721eSBaptiste Daroussin 
486*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor <= el->el_line.buffer)
487*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
488*d0ef721eSBaptiste Daroussin 
489*d0ef721eSBaptiste Daroussin 	c_delbefore(el, el->el_state.argument);
490*d0ef721eSBaptiste Daroussin 	el->el_line.cursor -= el->el_state.argument;
491*d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor < el->el_line.buffer)
492*d0ef721eSBaptiste Daroussin 		el->el_line.cursor = el->el_line.buffer;
493*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
494*d0ef721eSBaptiste Daroussin }
495*d0ef721eSBaptiste Daroussin 
496*d0ef721eSBaptiste Daroussin 
497*d0ef721eSBaptiste Daroussin /* ed_clear_screen():
498*d0ef721eSBaptiste Daroussin  *	Clear screen leaving current line at the top
499*d0ef721eSBaptiste Daroussin  *	[^L]
500*d0ef721eSBaptiste Daroussin  */
501*d0ef721eSBaptiste Daroussin libedit_private el_action_t
502*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
503*d0ef721eSBaptiste Daroussin ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
504*d0ef721eSBaptiste Daroussin {
505*d0ef721eSBaptiste Daroussin 
506*d0ef721eSBaptiste Daroussin 	terminal_clear_screen(el);	/* clear the whole real screen */
507*d0ef721eSBaptiste Daroussin 	re_clear_display(el);	/* reset everything */
508*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
509*d0ef721eSBaptiste Daroussin }
510*d0ef721eSBaptiste Daroussin 
511*d0ef721eSBaptiste Daroussin 
512*d0ef721eSBaptiste Daroussin /* ed_redisplay():
513*d0ef721eSBaptiste Daroussin  *	Redisplay everything
514*d0ef721eSBaptiste Daroussin  *	^R
515*d0ef721eSBaptiste Daroussin  */
516*d0ef721eSBaptiste Daroussin libedit_private el_action_t
517*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
518*d0ef721eSBaptiste Daroussin ed_redisplay(EditLine *el __attribute__((__unused__)),
519*d0ef721eSBaptiste Daroussin 	     wint_t c __attribute__((__unused__)))
520*d0ef721eSBaptiste Daroussin {
521*d0ef721eSBaptiste Daroussin 
522*d0ef721eSBaptiste Daroussin 	return CC_REDISPLAY;
523*d0ef721eSBaptiste Daroussin }
524*d0ef721eSBaptiste Daroussin 
525*d0ef721eSBaptiste Daroussin 
526*d0ef721eSBaptiste Daroussin /* ed_start_over():
527*d0ef721eSBaptiste Daroussin  *	Erase current line and start from scratch
528*d0ef721eSBaptiste Daroussin  *	[^G]
529*d0ef721eSBaptiste Daroussin  */
530*d0ef721eSBaptiste Daroussin libedit_private el_action_t
531*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
532*d0ef721eSBaptiste Daroussin ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
533*d0ef721eSBaptiste Daroussin {
534*d0ef721eSBaptiste Daroussin 
535*d0ef721eSBaptiste Daroussin 	ch_reset(el);
536*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
537*d0ef721eSBaptiste Daroussin }
538*d0ef721eSBaptiste Daroussin 
539*d0ef721eSBaptiste Daroussin 
540*d0ef721eSBaptiste Daroussin /* ed_sequence_lead_in():
541*d0ef721eSBaptiste Daroussin  *	First character in a bound sequence
542*d0ef721eSBaptiste Daroussin  *	Placeholder for external keys
543*d0ef721eSBaptiste Daroussin  */
544*d0ef721eSBaptiste Daroussin libedit_private el_action_t
545*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
546*d0ef721eSBaptiste Daroussin ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
547*d0ef721eSBaptiste Daroussin 		    wint_t c __attribute__((__unused__)))
548*d0ef721eSBaptiste Daroussin {
549*d0ef721eSBaptiste Daroussin 
550*d0ef721eSBaptiste Daroussin 	return CC_NORM;
551*d0ef721eSBaptiste Daroussin }
552*d0ef721eSBaptiste Daroussin 
553*d0ef721eSBaptiste Daroussin 
554*d0ef721eSBaptiste Daroussin /* ed_prev_history():
555*d0ef721eSBaptiste Daroussin  *	Move to the previous history line
556*d0ef721eSBaptiste Daroussin  *	[^P] [k]
557*d0ef721eSBaptiste Daroussin  */
558*d0ef721eSBaptiste Daroussin libedit_private el_action_t
559*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
560*d0ef721eSBaptiste Daroussin ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
561*d0ef721eSBaptiste Daroussin {
562*d0ef721eSBaptiste Daroussin 	char beep = 0;
563*d0ef721eSBaptiste Daroussin 	int sv_event = el->el_history.eventno;
564*d0ef721eSBaptiste Daroussin 
565*d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
566*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';		/* just in case */
567*d0ef721eSBaptiste Daroussin 
568*d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno == 0) {	/* save the current buffer
569*d0ef721eSBaptiste Daroussin 						 * away */
570*d0ef721eSBaptiste Daroussin 		(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
571*d0ef721eSBaptiste Daroussin 		    EL_BUFSIZ);
572*d0ef721eSBaptiste Daroussin 		el->el_history.last = el->el_history.buf +
573*d0ef721eSBaptiste Daroussin 		    (el->el_line.lastchar - el->el_line.buffer);
574*d0ef721eSBaptiste Daroussin 	}
575*d0ef721eSBaptiste Daroussin 	el->el_history.eventno += el->el_state.argument;
576*d0ef721eSBaptiste Daroussin 
577*d0ef721eSBaptiste Daroussin 	if (hist_get(el) == CC_ERROR) {
578*d0ef721eSBaptiste Daroussin 		if (el->el_map.type == MAP_VI) {
579*d0ef721eSBaptiste Daroussin 			el->el_history.eventno = sv_event;
580*d0ef721eSBaptiste Daroussin 		}
581*d0ef721eSBaptiste Daroussin 		beep = 1;
582*d0ef721eSBaptiste Daroussin 		/* el->el_history.eventno was fixed by first call */
583*d0ef721eSBaptiste Daroussin 		(void) hist_get(el);
584*d0ef721eSBaptiste Daroussin 	}
585*d0ef721eSBaptiste Daroussin 	if (beep)
586*d0ef721eSBaptiste Daroussin 		return CC_REFRESH_BEEP;
587*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
588*d0ef721eSBaptiste Daroussin }
589*d0ef721eSBaptiste Daroussin 
590*d0ef721eSBaptiste Daroussin 
591*d0ef721eSBaptiste Daroussin /* ed_next_history():
592*d0ef721eSBaptiste Daroussin  *	Move to the next history line
593*d0ef721eSBaptiste Daroussin  *	[^N] [j]
594*d0ef721eSBaptiste Daroussin  */
595*d0ef721eSBaptiste Daroussin libedit_private el_action_t
596*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
597*d0ef721eSBaptiste Daroussin ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
598*d0ef721eSBaptiste Daroussin {
599*d0ef721eSBaptiste Daroussin 	el_action_t beep = CC_REFRESH, rval;
600*d0ef721eSBaptiste Daroussin 
601*d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
602*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';	/* just in case */
603*d0ef721eSBaptiste Daroussin 
604*d0ef721eSBaptiste Daroussin 	el->el_history.eventno -= el->el_state.argument;
605*d0ef721eSBaptiste Daroussin 
606*d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno < 0) {
607*d0ef721eSBaptiste Daroussin 		el->el_history.eventno = 0;
608*d0ef721eSBaptiste Daroussin 		beep = CC_REFRESH_BEEP;
609*d0ef721eSBaptiste Daroussin 	}
610*d0ef721eSBaptiste Daroussin 	rval = hist_get(el);
611*d0ef721eSBaptiste Daroussin 	if (rval == CC_REFRESH)
612*d0ef721eSBaptiste Daroussin 		return beep;
613*d0ef721eSBaptiste Daroussin 	return rval;
614*d0ef721eSBaptiste Daroussin 
615*d0ef721eSBaptiste Daroussin }
616*d0ef721eSBaptiste Daroussin 
617*d0ef721eSBaptiste Daroussin 
618*d0ef721eSBaptiste Daroussin /* ed_search_prev_history():
619*d0ef721eSBaptiste Daroussin  *	Search previous in history for a line matching the current
620*d0ef721eSBaptiste Daroussin  *	next search history [M-P] [K]
621*d0ef721eSBaptiste Daroussin  */
622*d0ef721eSBaptiste Daroussin libedit_private el_action_t
623*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
624*d0ef721eSBaptiste Daroussin ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
625*d0ef721eSBaptiste Daroussin {
626*d0ef721eSBaptiste Daroussin 	const wchar_t *hp;
627*d0ef721eSBaptiste Daroussin 	int h;
628*d0ef721eSBaptiste Daroussin 	int found = 0;
629*d0ef721eSBaptiste Daroussin 
630*d0ef721eSBaptiste Daroussin 	el->el_chared.c_vcmd.action = NOP;
631*d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
632*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';	/* just in case */
633*d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno < 0) {
634*d0ef721eSBaptiste Daroussin #ifdef DEBUG_EDIT
635*d0ef721eSBaptiste Daroussin 		(void) fprintf(el->el_errfile,
636*d0ef721eSBaptiste Daroussin 		    "e_prev_search_hist(): eventno < 0;\n");
637*d0ef721eSBaptiste Daroussin #endif
638*d0ef721eSBaptiste Daroussin 		el->el_history.eventno = 0;
639*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
640*d0ef721eSBaptiste Daroussin 	}
641*d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno == 0) {
642*d0ef721eSBaptiste Daroussin 		(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
643*d0ef721eSBaptiste Daroussin 		    EL_BUFSIZ);
644*d0ef721eSBaptiste Daroussin 		el->el_history.last = el->el_history.buf +
645*d0ef721eSBaptiste Daroussin 		    (el->el_line.lastchar - el->el_line.buffer);
646*d0ef721eSBaptiste Daroussin 	}
647*d0ef721eSBaptiste Daroussin 	if (el->el_history.ref == NULL)
648*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
649*d0ef721eSBaptiste Daroussin 
650*d0ef721eSBaptiste Daroussin 	hp = HIST_FIRST(el);
651*d0ef721eSBaptiste Daroussin 	if (hp == NULL)
652*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
653*d0ef721eSBaptiste Daroussin 
654*d0ef721eSBaptiste Daroussin 	c_setpat(el);		/* Set search pattern !! */
655*d0ef721eSBaptiste Daroussin 
656*d0ef721eSBaptiste Daroussin 	for (h = 1; h <= el->el_history.eventno; h++)
657*d0ef721eSBaptiste Daroussin 		hp = HIST_NEXT(el);
658*d0ef721eSBaptiste Daroussin 
659*d0ef721eSBaptiste Daroussin 	while (hp != NULL) {
660*d0ef721eSBaptiste Daroussin #ifdef SDEBUG
661*d0ef721eSBaptiste Daroussin 		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
662*d0ef721eSBaptiste Daroussin #endif
663*d0ef721eSBaptiste Daroussin 		if ((wcsncmp(hp, el->el_line.buffer, (size_t)
664*d0ef721eSBaptiste Daroussin 			    (el->el_line.lastchar - el->el_line.buffer)) ||
665*d0ef721eSBaptiste Daroussin 			hp[el->el_line.lastchar - el->el_line.buffer]) &&
666*d0ef721eSBaptiste Daroussin 		    c_hmatch(el, hp)) {
667*d0ef721eSBaptiste Daroussin 			found = 1;
668*d0ef721eSBaptiste Daroussin 			break;
669*d0ef721eSBaptiste Daroussin 		}
670*d0ef721eSBaptiste Daroussin 		h++;
671*d0ef721eSBaptiste Daroussin 		hp = HIST_NEXT(el);
672*d0ef721eSBaptiste Daroussin 	}
673*d0ef721eSBaptiste Daroussin 
674*d0ef721eSBaptiste Daroussin 	if (!found) {
675*d0ef721eSBaptiste Daroussin #ifdef SDEBUG
676*d0ef721eSBaptiste Daroussin 		(void) fprintf(el->el_errfile, "not found\n");
677*d0ef721eSBaptiste Daroussin #endif
678*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
679*d0ef721eSBaptiste Daroussin 	}
680*d0ef721eSBaptiste Daroussin 	el->el_history.eventno = h;
681*d0ef721eSBaptiste Daroussin 
682*d0ef721eSBaptiste Daroussin 	return hist_get(el);
683*d0ef721eSBaptiste Daroussin }
684*d0ef721eSBaptiste Daroussin 
685*d0ef721eSBaptiste Daroussin 
686*d0ef721eSBaptiste Daroussin /* ed_search_next_history():
687*d0ef721eSBaptiste Daroussin  *	Search next in history for a line matching the current
688*d0ef721eSBaptiste Daroussin  *	[M-N] [J]
689*d0ef721eSBaptiste Daroussin  */
690*d0ef721eSBaptiste Daroussin libedit_private el_action_t
691*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
692*d0ef721eSBaptiste Daroussin ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
693*d0ef721eSBaptiste Daroussin {
694*d0ef721eSBaptiste Daroussin 	const wchar_t *hp;
695*d0ef721eSBaptiste Daroussin 	int h;
696*d0ef721eSBaptiste Daroussin 	int found = 0;
697*d0ef721eSBaptiste Daroussin 
698*d0ef721eSBaptiste Daroussin 	el->el_chared.c_vcmd.action = NOP;
699*d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
700*d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';	/* just in case */
701*d0ef721eSBaptiste Daroussin 
702*d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno == 0)
703*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
704*d0ef721eSBaptiste Daroussin 
705*d0ef721eSBaptiste Daroussin 	if (el->el_history.ref == NULL)
706*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
707*d0ef721eSBaptiste Daroussin 
708*d0ef721eSBaptiste Daroussin 	hp = HIST_FIRST(el);
709*d0ef721eSBaptiste Daroussin 	if (hp == NULL)
710*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
711*d0ef721eSBaptiste Daroussin 
712*d0ef721eSBaptiste Daroussin 	c_setpat(el);		/* Set search pattern !! */
713*d0ef721eSBaptiste Daroussin 
714*d0ef721eSBaptiste Daroussin 	for (h = 1; h < el->el_history.eventno && hp; h++) {
715*d0ef721eSBaptiste Daroussin #ifdef SDEBUG
716*d0ef721eSBaptiste Daroussin 		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
717*d0ef721eSBaptiste Daroussin #endif
718*d0ef721eSBaptiste Daroussin 		if ((wcsncmp(hp, el->el_line.buffer, (size_t)
719*d0ef721eSBaptiste Daroussin 			    (el->el_line.lastchar - el->el_line.buffer)) ||
720*d0ef721eSBaptiste Daroussin 			hp[el->el_line.lastchar - el->el_line.buffer]) &&
721*d0ef721eSBaptiste Daroussin 		    c_hmatch(el, hp))
722*d0ef721eSBaptiste Daroussin 			found = h;
723*d0ef721eSBaptiste Daroussin 		hp = HIST_NEXT(el);
724*d0ef721eSBaptiste Daroussin 	}
725*d0ef721eSBaptiste Daroussin 
726*d0ef721eSBaptiste Daroussin 	if (!found) {		/* is it the current history number? */
727*d0ef721eSBaptiste Daroussin 		if (!c_hmatch(el, el->el_history.buf)) {
728*d0ef721eSBaptiste Daroussin #ifdef SDEBUG
729*d0ef721eSBaptiste Daroussin 			(void) fprintf(el->el_errfile, "not found\n");
730*d0ef721eSBaptiste Daroussin #endif
731*d0ef721eSBaptiste Daroussin 			return CC_ERROR;
732*d0ef721eSBaptiste Daroussin 		}
733*d0ef721eSBaptiste Daroussin 	}
734*d0ef721eSBaptiste Daroussin 	el->el_history.eventno = found;
735*d0ef721eSBaptiste Daroussin 
736*d0ef721eSBaptiste Daroussin 	return hist_get(el);
737*d0ef721eSBaptiste Daroussin }
738*d0ef721eSBaptiste Daroussin 
739*d0ef721eSBaptiste Daroussin 
740*d0ef721eSBaptiste Daroussin /* ed_prev_line():
741*d0ef721eSBaptiste Daroussin  *	Move up one line
742*d0ef721eSBaptiste Daroussin  *	Could be [k] [^p]
743*d0ef721eSBaptiste Daroussin  */
744*d0ef721eSBaptiste Daroussin libedit_private el_action_t
745*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
746*d0ef721eSBaptiste Daroussin ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
747*d0ef721eSBaptiste Daroussin {
748*d0ef721eSBaptiste Daroussin 	wchar_t *ptr;
749*d0ef721eSBaptiste Daroussin 	int nchars = c_hpos(el);
750*d0ef721eSBaptiste Daroussin 
751*d0ef721eSBaptiste Daroussin 	/*
752*d0ef721eSBaptiste Daroussin          * Move to the line requested
753*d0ef721eSBaptiste Daroussin          */
754*d0ef721eSBaptiste Daroussin 	if (*(ptr = el->el_line.cursor) == '\n')
755*d0ef721eSBaptiste Daroussin 		ptr--;
756*d0ef721eSBaptiste Daroussin 
757*d0ef721eSBaptiste Daroussin 	for (; ptr >= el->el_line.buffer; ptr--)
758*d0ef721eSBaptiste Daroussin 		if (*ptr == '\n' && --el->el_state.argument <= 0)
759*d0ef721eSBaptiste Daroussin 			break;
760*d0ef721eSBaptiste Daroussin 
761*d0ef721eSBaptiste Daroussin 	if (el->el_state.argument > 0)
762*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
763*d0ef721eSBaptiste Daroussin 
764*d0ef721eSBaptiste Daroussin 	/*
765*d0ef721eSBaptiste Daroussin          * Move to the beginning of the line
766*d0ef721eSBaptiste Daroussin          */
767*d0ef721eSBaptiste Daroussin 	for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
768*d0ef721eSBaptiste Daroussin 		continue;
769*d0ef721eSBaptiste Daroussin 
770*d0ef721eSBaptiste Daroussin 	/*
771*d0ef721eSBaptiste Daroussin          * Move to the character requested
772*d0ef721eSBaptiste Daroussin          */
773*d0ef721eSBaptiste Daroussin 	for (ptr++;
774*d0ef721eSBaptiste Daroussin 	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
775*d0ef721eSBaptiste Daroussin 	    ptr++)
776*d0ef721eSBaptiste Daroussin 		continue;
777*d0ef721eSBaptiste Daroussin 
778*d0ef721eSBaptiste Daroussin 	el->el_line.cursor = ptr;
779*d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
780*d0ef721eSBaptiste Daroussin }
781*d0ef721eSBaptiste Daroussin 
782*d0ef721eSBaptiste Daroussin 
783*d0ef721eSBaptiste Daroussin /* ed_next_line():
784*d0ef721eSBaptiste Daroussin  *	Move down one line
785*d0ef721eSBaptiste Daroussin  *	Could be [j] [^n]
786*d0ef721eSBaptiste Daroussin  */
787*d0ef721eSBaptiste Daroussin libedit_private el_action_t
788*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
789*d0ef721eSBaptiste Daroussin ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
790*d0ef721eSBaptiste Daroussin {
791*d0ef721eSBaptiste Daroussin 	wchar_t *ptr;
792*d0ef721eSBaptiste Daroussin 	int nchars = c_hpos(el);
793*d0ef721eSBaptiste Daroussin 
794*d0ef721eSBaptiste Daroussin 	/*
795*d0ef721eSBaptiste Daroussin          * Move to the line requested
796*d0ef721eSBaptiste Daroussin          */
797*d0ef721eSBaptiste Daroussin 	for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
798*d0ef721eSBaptiste Daroussin 		if (*ptr == '\n' && --el->el_state.argument <= 0)
799*d0ef721eSBaptiste Daroussin 			break;
800*d0ef721eSBaptiste Daroussin 
801*d0ef721eSBaptiste Daroussin 	if (el->el_state.argument > 0)
802*d0ef721eSBaptiste Daroussin 		return CC_ERROR;
803*d0ef721eSBaptiste Daroussin 
804*d0ef721eSBaptiste Daroussin 	/*
805*d0ef721eSBaptiste Daroussin          * Move to the character requested
806*d0ef721eSBaptiste Daroussin          */
807*d0ef721eSBaptiste Daroussin 	for (ptr++;
808*d0ef721eSBaptiste Daroussin 	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
809*d0ef721eSBaptiste Daroussin 	    ptr++)
810*d0ef721eSBaptiste Daroussin 		continue;
811*d0ef721eSBaptiste Daroussin 
812*d0ef721eSBaptiste Daroussin 	el->el_line.cursor = ptr;
813*d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
814*d0ef721eSBaptiste Daroussin }
815*d0ef721eSBaptiste Daroussin 
816*d0ef721eSBaptiste Daroussin 
817*d0ef721eSBaptiste Daroussin /* ed_command():
818*d0ef721eSBaptiste Daroussin  *	Editline extended command
819*d0ef721eSBaptiste Daroussin  *	[M-X] [:]
820*d0ef721eSBaptiste Daroussin  */
821*d0ef721eSBaptiste Daroussin libedit_private el_action_t
822*d0ef721eSBaptiste Daroussin /*ARGSUSED*/
823*d0ef721eSBaptiste Daroussin ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
824*d0ef721eSBaptiste Daroussin {
825*d0ef721eSBaptiste Daroussin 	wchar_t tmpbuf[EL_BUFSIZ];
826*d0ef721eSBaptiste Daroussin 	int tmplen;
827*d0ef721eSBaptiste Daroussin 
828*d0ef721eSBaptiste Daroussin 	tmplen = c_gets(el, tmpbuf, L"\n: ");
829*d0ef721eSBaptiste Daroussin 	terminal__putc(el, '\n');
830*d0ef721eSBaptiste Daroussin 
831*d0ef721eSBaptiste Daroussin 	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
832*d0ef721eSBaptiste Daroussin 		terminal_beep(el);
833*d0ef721eSBaptiste Daroussin 
834*d0ef721eSBaptiste Daroussin 	el->el_map.current = el->el_map.key;
835*d0ef721eSBaptiste Daroussin 	re_clear_display(el);
836*d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
837*d0ef721eSBaptiste Daroussin }
838