xref: /freebsd/contrib/libedit/common.c (revision 136d69caf03bc38de95c4df34c5a683e9ce81bfa)
1*136d69caSBaptiste Daroussin /*	$NetBSD: common.c,v 1.50 2024/06/30 16:29:42 christos 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*136d69caSBaptiste Daroussin __RCSID("$NetBSD: common.c,v 1.50 2024/06/30 16:29:42 christos 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
225*136d69caSBaptiste Daroussin 		if (el->el_line.cursor > el->el_line.buffer)
226d0ef721eSBaptiste Daroussin 			el->el_line.cursor--;
227d0ef721eSBaptiste Daroussin #endif
228d0ef721eSBaptiste Daroussin 	}
229d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
230d0ef721eSBaptiste Daroussin }
231d0ef721eSBaptiste Daroussin 
232d0ef721eSBaptiste Daroussin 
233d0ef721eSBaptiste Daroussin /* ed_move_to_beg():
234d0ef721eSBaptiste Daroussin  *	Move cursor to the beginning of line
235d0ef721eSBaptiste Daroussin  *	[^A] [^A]
236d0ef721eSBaptiste Daroussin  */
237d0ef721eSBaptiste Daroussin libedit_private el_action_t
238d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_move_to_beg(EditLine * el,wint_t c)239d0ef721eSBaptiste Daroussin ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
240d0ef721eSBaptiste Daroussin {
241d0ef721eSBaptiste Daroussin 
242d0ef721eSBaptiste Daroussin 	el->el_line.cursor = el->el_line.buffer;
243d0ef721eSBaptiste Daroussin 
244d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI) {
245d0ef721eSBaptiste Daroussin 			/* We want FIRST non space character */
246d0ef721eSBaptiste Daroussin 		while (iswspace(*el->el_line.cursor))
247d0ef721eSBaptiste Daroussin 			el->el_line.cursor++;
248d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
249d0ef721eSBaptiste Daroussin 			cv_delfini(el);
250d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
251d0ef721eSBaptiste Daroussin 		}
252d0ef721eSBaptiste Daroussin 	}
253d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
254d0ef721eSBaptiste Daroussin }
255d0ef721eSBaptiste Daroussin 
256d0ef721eSBaptiste Daroussin 
257d0ef721eSBaptiste Daroussin /* ed_transpose_chars():
258d0ef721eSBaptiste Daroussin  *	Exchange the character to the left of the cursor with the one under it
259d0ef721eSBaptiste Daroussin  *	[^T] [^T]
260d0ef721eSBaptiste Daroussin  */
261d0ef721eSBaptiste Daroussin libedit_private el_action_t
ed_transpose_chars(EditLine * el,wint_t c)262d0ef721eSBaptiste Daroussin ed_transpose_chars(EditLine *el, wint_t c)
263d0ef721eSBaptiste Daroussin {
264d0ef721eSBaptiste Daroussin 
265d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor < el->el_line.lastchar) {
266d0ef721eSBaptiste Daroussin 		if (el->el_line.lastchar <= &el->el_line.buffer[1])
267d0ef721eSBaptiste Daroussin 			return CC_ERROR;
268d0ef721eSBaptiste Daroussin 		else
269d0ef721eSBaptiste Daroussin 			el->el_line.cursor++;
270d0ef721eSBaptiste Daroussin 	}
271d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
272d0ef721eSBaptiste Daroussin 		/* must have at least two chars entered */
273d0ef721eSBaptiste Daroussin 		c = el->el_line.cursor[-2];
274d0ef721eSBaptiste Daroussin 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
275d0ef721eSBaptiste Daroussin 		el->el_line.cursor[-1] = c;
276d0ef721eSBaptiste Daroussin 		return CC_REFRESH;
277d0ef721eSBaptiste Daroussin 	} else
278d0ef721eSBaptiste Daroussin 		return CC_ERROR;
279d0ef721eSBaptiste Daroussin }
280d0ef721eSBaptiste Daroussin 
281d0ef721eSBaptiste Daroussin 
282d0ef721eSBaptiste Daroussin /* ed_next_char():
283d0ef721eSBaptiste Daroussin  *	Move to the right one character
284d0ef721eSBaptiste Daroussin  *	[^F] [^F]
285d0ef721eSBaptiste Daroussin  */
286d0ef721eSBaptiste Daroussin libedit_private el_action_t
287d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_next_char(EditLine * el,wint_t c)288d0ef721eSBaptiste Daroussin ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
289d0ef721eSBaptiste Daroussin {
290d0ef721eSBaptiste Daroussin 	wchar_t *lim = el->el_line.lastchar;
291d0ef721eSBaptiste Daroussin 
292d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor >= lim ||
293d0ef721eSBaptiste Daroussin 	    (el->el_line.cursor == lim - 1 &&
294d0ef721eSBaptiste Daroussin 	    el->el_map.type == MAP_VI &&
295d0ef721eSBaptiste Daroussin 	    el->el_chared.c_vcmd.action == NOP))
296d0ef721eSBaptiste Daroussin 		return CC_ERROR;
297d0ef721eSBaptiste Daroussin 
298d0ef721eSBaptiste Daroussin 	el->el_line.cursor += el->el_state.argument;
299d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor > lim)
300d0ef721eSBaptiste Daroussin 		el->el_line.cursor = lim;
301d0ef721eSBaptiste Daroussin 
302d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI)
303d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
304d0ef721eSBaptiste Daroussin 			cv_delfini(el);
305d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
306d0ef721eSBaptiste Daroussin 		}
307d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
308d0ef721eSBaptiste Daroussin }
309d0ef721eSBaptiste Daroussin 
310d0ef721eSBaptiste Daroussin 
311d0ef721eSBaptiste Daroussin /* ed_prev_word():
312d0ef721eSBaptiste Daroussin  *	Move to the beginning of the current word
313d0ef721eSBaptiste Daroussin  *	[M-b] [b]
314d0ef721eSBaptiste Daroussin  */
315d0ef721eSBaptiste Daroussin libedit_private el_action_t
316d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_prev_word(EditLine * el,wint_t c)317d0ef721eSBaptiste Daroussin ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
318d0ef721eSBaptiste Daroussin {
319d0ef721eSBaptiste Daroussin 
320d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor == el->el_line.buffer)
321d0ef721eSBaptiste Daroussin 		return CC_ERROR;
322d0ef721eSBaptiste Daroussin 
323d0ef721eSBaptiste Daroussin 	el->el_line.cursor = c__prev_word(el->el_line.cursor,
324d0ef721eSBaptiste Daroussin 	    el->el_line.buffer,
325d0ef721eSBaptiste Daroussin 	    el->el_state.argument,
326d0ef721eSBaptiste Daroussin 	    ce__isword);
327d0ef721eSBaptiste Daroussin 
328d0ef721eSBaptiste Daroussin 	if (el->el_map.type == MAP_VI)
329d0ef721eSBaptiste Daroussin 		if (el->el_chared.c_vcmd.action != NOP) {
330d0ef721eSBaptiste Daroussin 			cv_delfini(el);
331d0ef721eSBaptiste Daroussin 			return CC_REFRESH;
332d0ef721eSBaptiste Daroussin 		}
333d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
334d0ef721eSBaptiste Daroussin }
335d0ef721eSBaptiste Daroussin 
336d0ef721eSBaptiste Daroussin 
337d0ef721eSBaptiste Daroussin /* ed_prev_char():
338d0ef721eSBaptiste Daroussin  *	Move to the left one character
339d0ef721eSBaptiste Daroussin  *	[^B] [^B]
340d0ef721eSBaptiste Daroussin  */
341d0ef721eSBaptiste Daroussin libedit_private el_action_t
342d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_prev_char(EditLine * el,wint_t c)343d0ef721eSBaptiste Daroussin ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
344d0ef721eSBaptiste Daroussin {
345d0ef721eSBaptiste Daroussin 
346d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor > el->el_line.buffer) {
347d0ef721eSBaptiste Daroussin 		el->el_line.cursor -= el->el_state.argument;
348d0ef721eSBaptiste Daroussin 		if (el->el_line.cursor < el->el_line.buffer)
349d0ef721eSBaptiste Daroussin 			el->el_line.cursor = el->el_line.buffer;
350d0ef721eSBaptiste Daroussin 
351d0ef721eSBaptiste Daroussin 		if (el->el_map.type == MAP_VI)
352d0ef721eSBaptiste Daroussin 			if (el->el_chared.c_vcmd.action != NOP) {
353d0ef721eSBaptiste Daroussin 				cv_delfini(el);
354d0ef721eSBaptiste Daroussin 				return CC_REFRESH;
355d0ef721eSBaptiste Daroussin 			}
356d0ef721eSBaptiste Daroussin 		return CC_CURSOR;
357d0ef721eSBaptiste Daroussin 	} else
358d0ef721eSBaptiste Daroussin 		return CC_ERROR;
359d0ef721eSBaptiste Daroussin }
360d0ef721eSBaptiste Daroussin 
361d0ef721eSBaptiste Daroussin 
362d0ef721eSBaptiste Daroussin /* ed_quoted_insert():
363d0ef721eSBaptiste Daroussin  *	Add the next character typed verbatim
364d0ef721eSBaptiste Daroussin  *	[^V] [^V]
365d0ef721eSBaptiste Daroussin  */
366d0ef721eSBaptiste Daroussin libedit_private el_action_t
367d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_quoted_insert(EditLine * el,wint_t c)368d0ef721eSBaptiste Daroussin ed_quoted_insert(EditLine *el, wint_t c __attribute__((__unused__)))
369d0ef721eSBaptiste Daroussin {
370d0ef721eSBaptiste Daroussin 	int num;
371d0ef721eSBaptiste Daroussin 	wchar_t ch;
372d0ef721eSBaptiste Daroussin 
373d0ef721eSBaptiste Daroussin 	tty_quotemode(el);
374d0ef721eSBaptiste Daroussin 	num = el_wgetc(el, &ch);
375d0ef721eSBaptiste Daroussin 	tty_noquotemode(el);
376d0ef721eSBaptiste Daroussin 	if (num == 1)
377d0ef721eSBaptiste Daroussin 		return ed_insert(el, ch);
378d0ef721eSBaptiste Daroussin 	else
379d0ef721eSBaptiste Daroussin 		return ed_end_of_file(el, 0);
380d0ef721eSBaptiste Daroussin }
381d0ef721eSBaptiste Daroussin 
382d0ef721eSBaptiste Daroussin 
383d0ef721eSBaptiste Daroussin /* ed_digit():
384d0ef721eSBaptiste Daroussin  *	Adds to argument or enters a digit
385d0ef721eSBaptiste Daroussin  */
386d0ef721eSBaptiste Daroussin libedit_private el_action_t
ed_digit(EditLine * el,wint_t c)387d0ef721eSBaptiste Daroussin ed_digit(EditLine *el, wint_t c)
388d0ef721eSBaptiste Daroussin {
389d0ef721eSBaptiste Daroussin 
390d0ef721eSBaptiste Daroussin 	if (!iswdigit(c))
391d0ef721eSBaptiste Daroussin 		return CC_ERROR;
392d0ef721eSBaptiste Daroussin 
393d0ef721eSBaptiste Daroussin 	if (el->el_state.doingarg) {
394d0ef721eSBaptiste Daroussin 			/* if doing an arg, add this in... */
395d0ef721eSBaptiste Daroussin 		if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
396d0ef721eSBaptiste Daroussin 			el->el_state.argument = c - '0';
397d0ef721eSBaptiste Daroussin 		else {
398d0ef721eSBaptiste Daroussin 			if (el->el_state.argument > 1000000)
399d0ef721eSBaptiste Daroussin 				return CC_ERROR;
400d0ef721eSBaptiste Daroussin 			el->el_state.argument =
401d0ef721eSBaptiste Daroussin 			    (el->el_state.argument * 10) + (c - '0');
402d0ef721eSBaptiste Daroussin 		}
403d0ef721eSBaptiste Daroussin 		return CC_ARGHACK;
404d0ef721eSBaptiste Daroussin 	}
405d0ef721eSBaptiste Daroussin 
406d0ef721eSBaptiste Daroussin 	return ed_insert(el, c);
407d0ef721eSBaptiste Daroussin }
408d0ef721eSBaptiste Daroussin 
409d0ef721eSBaptiste Daroussin 
410d0ef721eSBaptiste Daroussin /* ed_argument_digit():
411d0ef721eSBaptiste Daroussin  *	Digit that starts argument
412d0ef721eSBaptiste Daroussin  *	For ESC-n
413d0ef721eSBaptiste Daroussin  */
414d0ef721eSBaptiste Daroussin libedit_private el_action_t
ed_argument_digit(EditLine * el,wint_t c)415d0ef721eSBaptiste Daroussin ed_argument_digit(EditLine *el, wint_t c)
416d0ef721eSBaptiste Daroussin {
417d0ef721eSBaptiste Daroussin 
418d0ef721eSBaptiste Daroussin 	if (!iswdigit(c))
419d0ef721eSBaptiste Daroussin 		return CC_ERROR;
420d0ef721eSBaptiste Daroussin 
421d0ef721eSBaptiste Daroussin 	if (el->el_state.doingarg) {
422d0ef721eSBaptiste Daroussin 		if (el->el_state.argument > 1000000)
423d0ef721eSBaptiste Daroussin 			return CC_ERROR;
424d0ef721eSBaptiste Daroussin 		el->el_state.argument = (el->el_state.argument * 10) +
425d0ef721eSBaptiste Daroussin 		    (c - '0');
426d0ef721eSBaptiste Daroussin 	} else {		/* else starting an argument */
427d0ef721eSBaptiste Daroussin 		el->el_state.argument = c - '0';
428d0ef721eSBaptiste Daroussin 		el->el_state.doingarg = 1;
429d0ef721eSBaptiste Daroussin 	}
430d0ef721eSBaptiste Daroussin 	return CC_ARGHACK;
431d0ef721eSBaptiste Daroussin }
432d0ef721eSBaptiste Daroussin 
433d0ef721eSBaptiste Daroussin 
434d0ef721eSBaptiste Daroussin /* ed_unassigned():
435d0ef721eSBaptiste Daroussin  *	Indicates unbound character
436d0ef721eSBaptiste Daroussin  *	Bound to keys that are not assigned
437d0ef721eSBaptiste Daroussin  */
438d0ef721eSBaptiste Daroussin libedit_private el_action_t
439d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_unassigned(EditLine * el,wint_t c)440d0ef721eSBaptiste Daroussin ed_unassigned(EditLine *el __attribute__((__unused__)),
441d0ef721eSBaptiste Daroussin     wint_t c __attribute__((__unused__)))
442d0ef721eSBaptiste Daroussin {
443d0ef721eSBaptiste Daroussin 
444d0ef721eSBaptiste Daroussin 	return CC_ERROR;
445d0ef721eSBaptiste Daroussin }
446d0ef721eSBaptiste Daroussin 
447d0ef721eSBaptiste Daroussin 
448d0ef721eSBaptiste Daroussin /* ed_ignore():
449d0ef721eSBaptiste Daroussin  *	Input characters that have no effect
450d0ef721eSBaptiste Daroussin  *	[^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
451d0ef721eSBaptiste Daroussin  */
452d0ef721eSBaptiste Daroussin libedit_private el_action_t
453d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_ignore(EditLine * el,wint_t c)454d0ef721eSBaptiste Daroussin ed_ignore(EditLine *el __attribute__((__unused__)),
455d0ef721eSBaptiste Daroussin 	      wint_t c __attribute__((__unused__)))
456d0ef721eSBaptiste Daroussin {
457d0ef721eSBaptiste Daroussin 
458d0ef721eSBaptiste Daroussin 	return CC_NORM;
459d0ef721eSBaptiste Daroussin }
460d0ef721eSBaptiste Daroussin 
461d0ef721eSBaptiste Daroussin 
462d0ef721eSBaptiste Daroussin /* ed_newline():
463d0ef721eSBaptiste Daroussin  *	Execute command
464d0ef721eSBaptiste Daroussin  *	[^J]
465d0ef721eSBaptiste Daroussin  */
466d0ef721eSBaptiste Daroussin libedit_private el_action_t
467d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_newline(EditLine * el,wint_t c)468d0ef721eSBaptiste Daroussin ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
469d0ef721eSBaptiste Daroussin {
470d0ef721eSBaptiste Daroussin 
471d0ef721eSBaptiste Daroussin 	re_goto_bottom(el);
472d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar++ = '\n';
473d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';
474d0ef721eSBaptiste Daroussin 	return CC_NEWLINE;
475d0ef721eSBaptiste Daroussin }
476d0ef721eSBaptiste Daroussin 
477d0ef721eSBaptiste Daroussin 
478d0ef721eSBaptiste Daroussin /* ed_delete_prev_char():
479d0ef721eSBaptiste Daroussin  *	Delete the character to the left of the cursor
480d0ef721eSBaptiste Daroussin  *	[^?]
481d0ef721eSBaptiste Daroussin  */
482d0ef721eSBaptiste Daroussin libedit_private el_action_t
483d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_delete_prev_char(EditLine * el,wint_t c)484d0ef721eSBaptiste Daroussin ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
485d0ef721eSBaptiste Daroussin {
486d0ef721eSBaptiste Daroussin 
487d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor <= el->el_line.buffer)
488d0ef721eSBaptiste Daroussin 		return CC_ERROR;
489d0ef721eSBaptiste Daroussin 
490d0ef721eSBaptiste Daroussin 	c_delbefore(el, el->el_state.argument);
491d0ef721eSBaptiste Daroussin 	el->el_line.cursor -= el->el_state.argument;
492d0ef721eSBaptiste Daroussin 	if (el->el_line.cursor < el->el_line.buffer)
493d0ef721eSBaptiste Daroussin 		el->el_line.cursor = el->el_line.buffer;
494d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
495d0ef721eSBaptiste Daroussin }
496d0ef721eSBaptiste Daroussin 
497d0ef721eSBaptiste Daroussin 
498d0ef721eSBaptiste Daroussin /* ed_clear_screen():
499d0ef721eSBaptiste Daroussin  *	Clear screen leaving current line at the top
500d0ef721eSBaptiste Daroussin  *	[^L]
501d0ef721eSBaptiste Daroussin  */
502d0ef721eSBaptiste Daroussin libedit_private el_action_t
503d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_clear_screen(EditLine * el,wint_t c)504d0ef721eSBaptiste Daroussin ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
505d0ef721eSBaptiste Daroussin {
506d0ef721eSBaptiste Daroussin 
507d0ef721eSBaptiste Daroussin 	terminal_clear_screen(el);	/* clear the whole real screen */
508d0ef721eSBaptiste Daroussin 	re_clear_display(el);	/* reset everything */
509d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
510d0ef721eSBaptiste Daroussin }
511d0ef721eSBaptiste Daroussin 
512d0ef721eSBaptiste Daroussin 
513d0ef721eSBaptiste Daroussin /* ed_redisplay():
514d0ef721eSBaptiste Daroussin  *	Redisplay everything
515d0ef721eSBaptiste Daroussin  *	^R
516d0ef721eSBaptiste Daroussin  */
517d0ef721eSBaptiste Daroussin libedit_private el_action_t
518d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_redisplay(EditLine * el,wint_t c)519d0ef721eSBaptiste Daroussin ed_redisplay(EditLine *el __attribute__((__unused__)),
520d0ef721eSBaptiste Daroussin 	     wint_t c __attribute__((__unused__)))
521d0ef721eSBaptiste Daroussin {
522d0ef721eSBaptiste Daroussin 
523d0ef721eSBaptiste Daroussin 	return CC_REDISPLAY;
524d0ef721eSBaptiste Daroussin }
525d0ef721eSBaptiste Daroussin 
526d0ef721eSBaptiste Daroussin 
527d0ef721eSBaptiste Daroussin /* ed_start_over():
528d0ef721eSBaptiste Daroussin  *	Erase current line and start from scratch
529d0ef721eSBaptiste Daroussin  *	[^G]
530d0ef721eSBaptiste Daroussin  */
531d0ef721eSBaptiste Daroussin libedit_private el_action_t
532d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_start_over(EditLine * el,wint_t c)533d0ef721eSBaptiste Daroussin ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
534d0ef721eSBaptiste Daroussin {
535d0ef721eSBaptiste Daroussin 
536d0ef721eSBaptiste Daroussin 	ch_reset(el);
537d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
538d0ef721eSBaptiste Daroussin }
539d0ef721eSBaptiste Daroussin 
540d0ef721eSBaptiste Daroussin 
541d0ef721eSBaptiste Daroussin /* ed_sequence_lead_in():
542d0ef721eSBaptiste Daroussin  *	First character in a bound sequence
543d0ef721eSBaptiste Daroussin  *	Placeholder for external keys
544d0ef721eSBaptiste Daroussin  */
545d0ef721eSBaptiste Daroussin libedit_private el_action_t
546d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_sequence_lead_in(EditLine * el,wint_t c)547d0ef721eSBaptiste Daroussin ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
548d0ef721eSBaptiste Daroussin 		    wint_t c __attribute__((__unused__)))
549d0ef721eSBaptiste Daroussin {
550d0ef721eSBaptiste Daroussin 
551d0ef721eSBaptiste Daroussin 	return CC_NORM;
552d0ef721eSBaptiste Daroussin }
553d0ef721eSBaptiste Daroussin 
554d0ef721eSBaptiste Daroussin 
555d0ef721eSBaptiste Daroussin /* ed_prev_history():
556d0ef721eSBaptiste Daroussin  *	Move to the previous history line
557d0ef721eSBaptiste Daroussin  *	[^P] [k]
558d0ef721eSBaptiste Daroussin  */
559d0ef721eSBaptiste Daroussin libedit_private el_action_t
560d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_prev_history(EditLine * el,wint_t c)561d0ef721eSBaptiste Daroussin ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
562d0ef721eSBaptiste Daroussin {
563d0ef721eSBaptiste Daroussin 	char beep = 0;
564d0ef721eSBaptiste Daroussin 	int sv_event = el->el_history.eventno;
565d0ef721eSBaptiste Daroussin 
566d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
567d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';		/* just in case */
568d0ef721eSBaptiste Daroussin 
569d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno == 0) {	/* save the current buffer
570d0ef721eSBaptiste Daroussin 						 * away */
571d0ef721eSBaptiste Daroussin 		(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
572d0ef721eSBaptiste Daroussin 		    EL_BUFSIZ);
573d0ef721eSBaptiste Daroussin 		el->el_history.last = el->el_history.buf +
574d0ef721eSBaptiste Daroussin 		    (el->el_line.lastchar - el->el_line.buffer);
575d0ef721eSBaptiste Daroussin 	}
576d0ef721eSBaptiste Daroussin 	el->el_history.eventno += el->el_state.argument;
577d0ef721eSBaptiste Daroussin 
578d0ef721eSBaptiste Daroussin 	if (hist_get(el) == CC_ERROR) {
579d0ef721eSBaptiste Daroussin 		if (el->el_map.type == MAP_VI) {
580d0ef721eSBaptiste Daroussin 			el->el_history.eventno = sv_event;
581d0ef721eSBaptiste Daroussin 		}
582d0ef721eSBaptiste Daroussin 		beep = 1;
583d0ef721eSBaptiste Daroussin 		/* el->el_history.eventno was fixed by first call */
584d0ef721eSBaptiste Daroussin 		(void) hist_get(el);
585d0ef721eSBaptiste Daroussin 	}
586d0ef721eSBaptiste Daroussin 	if (beep)
587d0ef721eSBaptiste Daroussin 		return CC_REFRESH_BEEP;
588d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
589d0ef721eSBaptiste Daroussin }
590d0ef721eSBaptiste Daroussin 
591d0ef721eSBaptiste Daroussin 
592d0ef721eSBaptiste Daroussin /* ed_next_history():
593d0ef721eSBaptiste Daroussin  *	Move to the next history line
594d0ef721eSBaptiste Daroussin  *	[^N] [j]
595d0ef721eSBaptiste Daroussin  */
596d0ef721eSBaptiste Daroussin libedit_private el_action_t
597d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_next_history(EditLine * el,wint_t c)598d0ef721eSBaptiste Daroussin ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
599d0ef721eSBaptiste Daroussin {
600d0ef721eSBaptiste Daroussin 	el_action_t beep = CC_REFRESH, rval;
601d0ef721eSBaptiste Daroussin 
602d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
603d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';	/* just in case */
604d0ef721eSBaptiste Daroussin 
605d0ef721eSBaptiste Daroussin 	el->el_history.eventno -= el->el_state.argument;
606d0ef721eSBaptiste Daroussin 
607d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno < 0) {
608d0ef721eSBaptiste Daroussin 		el->el_history.eventno = 0;
609d0ef721eSBaptiste Daroussin 		beep = CC_REFRESH_BEEP;
610d0ef721eSBaptiste Daroussin 	}
611d0ef721eSBaptiste Daroussin 	rval = hist_get(el);
612d0ef721eSBaptiste Daroussin 	if (rval == CC_REFRESH)
613d0ef721eSBaptiste Daroussin 		return beep;
614d0ef721eSBaptiste Daroussin 	return rval;
615d0ef721eSBaptiste Daroussin 
616d0ef721eSBaptiste Daroussin }
617d0ef721eSBaptiste Daroussin 
618d0ef721eSBaptiste Daroussin 
619d0ef721eSBaptiste Daroussin /* ed_search_prev_history():
620d0ef721eSBaptiste Daroussin  *	Search previous in history for a line matching the current
621d0ef721eSBaptiste Daroussin  *	next search history [M-P] [K]
622d0ef721eSBaptiste Daroussin  */
623d0ef721eSBaptiste Daroussin libedit_private el_action_t
624d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_search_prev_history(EditLine * el,wint_t c)625d0ef721eSBaptiste Daroussin ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
626d0ef721eSBaptiste Daroussin {
627d0ef721eSBaptiste Daroussin 	const wchar_t *hp;
628d0ef721eSBaptiste Daroussin 	int h;
629d0ef721eSBaptiste Daroussin 	int found = 0;
630d0ef721eSBaptiste Daroussin 
631d0ef721eSBaptiste Daroussin 	el->el_chared.c_vcmd.action = NOP;
632d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
633d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';	/* just in case */
634d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno < 0) {
635d0ef721eSBaptiste Daroussin #ifdef DEBUG_EDIT
636d0ef721eSBaptiste Daroussin 		(void) fprintf(el->el_errfile,
637d0ef721eSBaptiste Daroussin 		    "e_prev_search_hist(): eventno < 0;\n");
638d0ef721eSBaptiste Daroussin #endif
639d0ef721eSBaptiste Daroussin 		el->el_history.eventno = 0;
640d0ef721eSBaptiste Daroussin 		return CC_ERROR;
641d0ef721eSBaptiste Daroussin 	}
642d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno == 0) {
643d0ef721eSBaptiste Daroussin 		(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
644d0ef721eSBaptiste Daroussin 		    EL_BUFSIZ);
645d0ef721eSBaptiste Daroussin 		el->el_history.last = el->el_history.buf +
646d0ef721eSBaptiste Daroussin 		    (el->el_line.lastchar - el->el_line.buffer);
647d0ef721eSBaptiste Daroussin 	}
648d0ef721eSBaptiste Daroussin 	if (el->el_history.ref == NULL)
649d0ef721eSBaptiste Daroussin 		return CC_ERROR;
650d0ef721eSBaptiste Daroussin 
651d0ef721eSBaptiste Daroussin 	hp = HIST_FIRST(el);
652d0ef721eSBaptiste Daroussin 	if (hp == NULL)
653d0ef721eSBaptiste Daroussin 		return CC_ERROR;
654d0ef721eSBaptiste Daroussin 
655d0ef721eSBaptiste Daroussin 	c_setpat(el);		/* Set search pattern !! */
656d0ef721eSBaptiste Daroussin 
657d0ef721eSBaptiste Daroussin 	for (h = 1; h <= el->el_history.eventno; h++)
658d0ef721eSBaptiste Daroussin 		hp = HIST_NEXT(el);
659d0ef721eSBaptiste Daroussin 
660d0ef721eSBaptiste Daroussin 	while (hp != NULL) {
661d0ef721eSBaptiste Daroussin #ifdef SDEBUG
662f9a159daSBaptiste Daroussin 		(void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp);
663d0ef721eSBaptiste Daroussin #endif
664d0ef721eSBaptiste Daroussin 		if ((wcsncmp(hp, el->el_line.buffer, (size_t)
665d0ef721eSBaptiste Daroussin 			    (el->el_line.lastchar - el->el_line.buffer)) ||
666d0ef721eSBaptiste Daroussin 			hp[el->el_line.lastchar - el->el_line.buffer]) &&
667d0ef721eSBaptiste Daroussin 		    c_hmatch(el, hp)) {
668d0ef721eSBaptiste Daroussin 			found = 1;
669d0ef721eSBaptiste Daroussin 			break;
670d0ef721eSBaptiste Daroussin 		}
671d0ef721eSBaptiste Daroussin 		h++;
672d0ef721eSBaptiste Daroussin 		hp = HIST_NEXT(el);
673d0ef721eSBaptiste Daroussin 	}
674d0ef721eSBaptiste Daroussin 
675d0ef721eSBaptiste Daroussin 	if (!found) {
676d0ef721eSBaptiste Daroussin #ifdef SDEBUG
677d0ef721eSBaptiste Daroussin 		(void) fprintf(el->el_errfile, "not found\n");
678d0ef721eSBaptiste Daroussin #endif
679d0ef721eSBaptiste Daroussin 		return CC_ERROR;
680d0ef721eSBaptiste Daroussin 	}
681d0ef721eSBaptiste Daroussin 	el->el_history.eventno = h;
682d0ef721eSBaptiste Daroussin 
683d0ef721eSBaptiste Daroussin 	return hist_get(el);
684d0ef721eSBaptiste Daroussin }
685d0ef721eSBaptiste Daroussin 
686d0ef721eSBaptiste Daroussin 
687d0ef721eSBaptiste Daroussin /* ed_search_next_history():
688d0ef721eSBaptiste Daroussin  *	Search next in history for a line matching the current
689d0ef721eSBaptiste Daroussin  *	[M-N] [J]
690d0ef721eSBaptiste Daroussin  */
691d0ef721eSBaptiste Daroussin libedit_private el_action_t
692d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_search_next_history(EditLine * el,wint_t c)693d0ef721eSBaptiste Daroussin ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
694d0ef721eSBaptiste Daroussin {
695d0ef721eSBaptiste Daroussin 	const wchar_t *hp;
696d0ef721eSBaptiste Daroussin 	int h;
697d0ef721eSBaptiste Daroussin 	int found = 0;
698d0ef721eSBaptiste Daroussin 
699d0ef721eSBaptiste Daroussin 	el->el_chared.c_vcmd.action = NOP;
700d0ef721eSBaptiste Daroussin 	el->el_chared.c_undo.len = -1;
701d0ef721eSBaptiste Daroussin 	*el->el_line.lastchar = '\0';	/* just in case */
702d0ef721eSBaptiste Daroussin 
703d0ef721eSBaptiste Daroussin 	if (el->el_history.eventno == 0)
704d0ef721eSBaptiste Daroussin 		return CC_ERROR;
705d0ef721eSBaptiste Daroussin 
706d0ef721eSBaptiste Daroussin 	if (el->el_history.ref == NULL)
707d0ef721eSBaptiste Daroussin 		return CC_ERROR;
708d0ef721eSBaptiste Daroussin 
709d0ef721eSBaptiste Daroussin 	hp = HIST_FIRST(el);
710d0ef721eSBaptiste Daroussin 	if (hp == NULL)
711d0ef721eSBaptiste Daroussin 		return CC_ERROR;
712d0ef721eSBaptiste Daroussin 
713d0ef721eSBaptiste Daroussin 	c_setpat(el);		/* Set search pattern !! */
714d0ef721eSBaptiste Daroussin 
715d0ef721eSBaptiste Daroussin 	for (h = 1; h < el->el_history.eventno && hp; h++) {
716d0ef721eSBaptiste Daroussin #ifdef SDEBUG
717f9a159daSBaptiste Daroussin 		(void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp);
718d0ef721eSBaptiste Daroussin #endif
719d0ef721eSBaptiste Daroussin 		if ((wcsncmp(hp, el->el_line.buffer, (size_t)
720d0ef721eSBaptiste Daroussin 			    (el->el_line.lastchar - el->el_line.buffer)) ||
721d0ef721eSBaptiste Daroussin 			hp[el->el_line.lastchar - el->el_line.buffer]) &&
722d0ef721eSBaptiste Daroussin 		    c_hmatch(el, hp))
723d0ef721eSBaptiste Daroussin 			found = h;
724d0ef721eSBaptiste Daroussin 		hp = HIST_NEXT(el);
725d0ef721eSBaptiste Daroussin 	}
726d0ef721eSBaptiste Daroussin 
727d0ef721eSBaptiste Daroussin 	if (!found) {		/* is it the current history number? */
728d0ef721eSBaptiste Daroussin 		if (!c_hmatch(el, el->el_history.buf)) {
729d0ef721eSBaptiste Daroussin #ifdef SDEBUG
730d0ef721eSBaptiste Daroussin 			(void) fprintf(el->el_errfile, "not found\n");
731d0ef721eSBaptiste Daroussin #endif
732d0ef721eSBaptiste Daroussin 			return CC_ERROR;
733d0ef721eSBaptiste Daroussin 		}
734d0ef721eSBaptiste Daroussin 	}
735d0ef721eSBaptiste Daroussin 	el->el_history.eventno = found;
736d0ef721eSBaptiste Daroussin 
737d0ef721eSBaptiste Daroussin 	return hist_get(el);
738d0ef721eSBaptiste Daroussin }
739d0ef721eSBaptiste Daroussin 
740d0ef721eSBaptiste Daroussin 
741d0ef721eSBaptiste Daroussin /* ed_prev_line():
742d0ef721eSBaptiste Daroussin  *	Move up one line
743d0ef721eSBaptiste Daroussin  *	Could be [k] [^p]
744d0ef721eSBaptiste Daroussin  */
745d0ef721eSBaptiste Daroussin libedit_private el_action_t
746d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_prev_line(EditLine * el,wint_t c)747d0ef721eSBaptiste Daroussin ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
748d0ef721eSBaptiste Daroussin {
749d0ef721eSBaptiste Daroussin 	wchar_t *ptr;
750d0ef721eSBaptiste Daroussin 	int nchars = c_hpos(el);
751d0ef721eSBaptiste Daroussin 
752d0ef721eSBaptiste Daroussin 	/*
753d0ef721eSBaptiste Daroussin          * Move to the line requested
754d0ef721eSBaptiste Daroussin          */
755d0ef721eSBaptiste Daroussin 	if (*(ptr = el->el_line.cursor) == '\n')
756d0ef721eSBaptiste Daroussin 		ptr--;
757d0ef721eSBaptiste Daroussin 
758d0ef721eSBaptiste Daroussin 	for (; ptr >= el->el_line.buffer; ptr--)
759d0ef721eSBaptiste Daroussin 		if (*ptr == '\n' && --el->el_state.argument <= 0)
760d0ef721eSBaptiste Daroussin 			break;
761d0ef721eSBaptiste Daroussin 
762d0ef721eSBaptiste Daroussin 	if (el->el_state.argument > 0)
763d0ef721eSBaptiste Daroussin 		return CC_ERROR;
764d0ef721eSBaptiste Daroussin 
765d0ef721eSBaptiste Daroussin 	/*
766d0ef721eSBaptiste Daroussin          * Move to the beginning of the line
767d0ef721eSBaptiste Daroussin          */
768d0ef721eSBaptiste Daroussin 	for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
769d0ef721eSBaptiste Daroussin 		continue;
770d0ef721eSBaptiste Daroussin 
771d0ef721eSBaptiste Daroussin 	/*
772d0ef721eSBaptiste Daroussin          * Move to the character requested
773d0ef721eSBaptiste Daroussin          */
774d0ef721eSBaptiste Daroussin 	for (ptr++;
775d0ef721eSBaptiste Daroussin 	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
776d0ef721eSBaptiste Daroussin 	    ptr++)
777d0ef721eSBaptiste Daroussin 		continue;
778d0ef721eSBaptiste Daroussin 
779d0ef721eSBaptiste Daroussin 	el->el_line.cursor = ptr;
780d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
781d0ef721eSBaptiste Daroussin }
782d0ef721eSBaptiste Daroussin 
783d0ef721eSBaptiste Daroussin 
784d0ef721eSBaptiste Daroussin /* ed_next_line():
785d0ef721eSBaptiste Daroussin  *	Move down one line
786d0ef721eSBaptiste Daroussin  *	Could be [j] [^n]
787d0ef721eSBaptiste Daroussin  */
788d0ef721eSBaptiste Daroussin libedit_private el_action_t
789d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_next_line(EditLine * el,wint_t c)790d0ef721eSBaptiste Daroussin ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
791d0ef721eSBaptiste Daroussin {
792d0ef721eSBaptiste Daroussin 	wchar_t *ptr;
793d0ef721eSBaptiste Daroussin 	int nchars = c_hpos(el);
794d0ef721eSBaptiste Daroussin 
795d0ef721eSBaptiste Daroussin 	/*
796d0ef721eSBaptiste Daroussin          * Move to the line requested
797d0ef721eSBaptiste Daroussin          */
798d0ef721eSBaptiste Daroussin 	for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
799d0ef721eSBaptiste Daroussin 		if (*ptr == '\n' && --el->el_state.argument <= 0)
800d0ef721eSBaptiste Daroussin 			break;
801d0ef721eSBaptiste Daroussin 
802d0ef721eSBaptiste Daroussin 	if (el->el_state.argument > 0)
803d0ef721eSBaptiste Daroussin 		return CC_ERROR;
804d0ef721eSBaptiste Daroussin 
805d0ef721eSBaptiste Daroussin 	/*
806d0ef721eSBaptiste Daroussin          * Move to the character requested
807d0ef721eSBaptiste Daroussin          */
808d0ef721eSBaptiste Daroussin 	for (ptr++;
809d0ef721eSBaptiste Daroussin 	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
810d0ef721eSBaptiste Daroussin 	    ptr++)
811d0ef721eSBaptiste Daroussin 		continue;
812d0ef721eSBaptiste Daroussin 
813d0ef721eSBaptiste Daroussin 	el->el_line.cursor = ptr;
814d0ef721eSBaptiste Daroussin 	return CC_CURSOR;
815d0ef721eSBaptiste Daroussin }
816d0ef721eSBaptiste Daroussin 
817d0ef721eSBaptiste Daroussin 
818d0ef721eSBaptiste Daroussin /* ed_command():
819d0ef721eSBaptiste Daroussin  *	Editline extended command
820d0ef721eSBaptiste Daroussin  *	[M-X] [:]
821d0ef721eSBaptiste Daroussin  */
822d0ef721eSBaptiste Daroussin libedit_private el_action_t
823d0ef721eSBaptiste Daroussin /*ARGSUSED*/
ed_command(EditLine * el,wint_t c)824d0ef721eSBaptiste Daroussin ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
825d0ef721eSBaptiste Daroussin {
826d0ef721eSBaptiste Daroussin 	wchar_t tmpbuf[EL_BUFSIZ];
827d0ef721eSBaptiste Daroussin 	int tmplen;
828d0ef721eSBaptiste Daroussin 
829d0ef721eSBaptiste Daroussin 	tmplen = c_gets(el, tmpbuf, L"\n: ");
830d0ef721eSBaptiste Daroussin 	terminal__putc(el, '\n');
831d0ef721eSBaptiste Daroussin 
832d0ef721eSBaptiste Daroussin 	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
833d0ef721eSBaptiste Daroussin 		terminal_beep(el);
834d0ef721eSBaptiste Daroussin 
835d0ef721eSBaptiste Daroussin 	el->el_map.current = el->el_map.key;
836d0ef721eSBaptiste Daroussin 	re_clear_display(el);
837d0ef721eSBaptiste Daroussin 	return CC_REFRESH;
838d0ef721eSBaptiste Daroussin }
839