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