xref: /dflybsd-src/contrib/libedit/src/common.c (revision 698e9e6cd5f042847de67460caaa3fde98cdfe99)
1*cdf8408cSAntonio Huete Jimenez /*	$NetBSD: common.c,v 1.49 2020/03/30 06:54:37 ryo Exp $	*/
232fe07f8SJohn Marino 
332fe07f8SJohn Marino /*-
432fe07f8SJohn Marino  * Copyright (c) 1992, 1993
532fe07f8SJohn Marino  *	The Regents of the University of California.  All rights reserved.
632fe07f8SJohn Marino  *
732fe07f8SJohn Marino  * This code is derived from software contributed to Berkeley by
832fe07f8SJohn Marino  * Christos Zoulas of Cornell University.
932fe07f8SJohn Marino  *
1032fe07f8SJohn Marino  * Redistribution and use in source and binary forms, with or without
1132fe07f8SJohn Marino  * modification, are permitted provided that the following conditions
1232fe07f8SJohn Marino  * are met:
1332fe07f8SJohn Marino  * 1. Redistributions of source code must retain the above copyright
1432fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1532fe07f8SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1632fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1732fe07f8SJohn Marino  *    documentation and/or other materials provided with the distribution.
1832fe07f8SJohn Marino  * 3. Neither the name of the University nor the names of its contributors
1932fe07f8SJohn Marino  *    may be used to endorse or promote products derived from this software
2032fe07f8SJohn Marino  *    without specific prior written permission.
2132fe07f8SJohn Marino  *
2232fe07f8SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2332fe07f8SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2432fe07f8SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2532fe07f8SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2632fe07f8SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2732fe07f8SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832fe07f8SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2932fe07f8SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3032fe07f8SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3132fe07f8SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3232fe07f8SJohn Marino  * SUCH DAMAGE.
3332fe07f8SJohn Marino  */
3432fe07f8SJohn Marino 
3532fe07f8SJohn Marino #include "config.h"
3632fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID)
3732fe07f8SJohn Marino #if 0
3832fe07f8SJohn Marino static char sccsid[] = "@(#)common.c	8.1 (Berkeley) 6/4/93";
3932fe07f8SJohn Marino #else
40*cdf8408cSAntonio Huete Jimenez __RCSID("$NetBSD: common.c,v 1.49 2020/03/30 06:54:37 ryo Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino 
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino  * common.c: Common Editor functions
4632fe07f8SJohn Marino  */
4712db70c8Szrj #include <ctype.h>
4812db70c8Szrj #include <string.h>
4912db70c8Szrj 
5032fe07f8SJohn Marino #include "el.h"
5112db70c8Szrj #include "common.h"
5212db70c8Szrj #include "fcns.h"
5312db70c8Szrj #include "parse.h"
5412db70c8Szrj #include "vi.h"
5532fe07f8SJohn Marino 
5632fe07f8SJohn Marino /* ed_end_of_file():
5732fe07f8SJohn Marino  *	Indicate end of file
5832fe07f8SJohn Marino  *	[^D]
5932fe07f8SJohn Marino  */
6012db70c8Szrj libedit_private el_action_t
6132fe07f8SJohn Marino /*ARGSUSED*/
ed_end_of_file(EditLine * el,wint_t c)6212db70c8Szrj ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
6332fe07f8SJohn Marino {
6432fe07f8SJohn Marino 
6532fe07f8SJohn Marino 	re_goto_bottom(el);
6632fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';
6732fe07f8SJohn Marino 	return CC_EOF;
6832fe07f8SJohn Marino }
6932fe07f8SJohn Marino 
7032fe07f8SJohn Marino 
7132fe07f8SJohn Marino /* ed_insert():
7232fe07f8SJohn Marino  *	Add character to the line
7332fe07f8SJohn Marino  *	Insert a character [bound to all insert keys]
7432fe07f8SJohn Marino  */
7512db70c8Szrj libedit_private el_action_t
ed_insert(EditLine * el,wint_t c)7612db70c8Szrj ed_insert(EditLine *el, wint_t c)
7732fe07f8SJohn Marino {
7832fe07f8SJohn Marino 	int count = el->el_state.argument;
7932fe07f8SJohn Marino 
8032fe07f8SJohn Marino 	if (c == '\0')
8132fe07f8SJohn Marino 		return CC_ERROR;
8232fe07f8SJohn Marino 
8332fe07f8SJohn Marino 	if (el->el_line.lastchar + el->el_state.argument >=
8432fe07f8SJohn Marino 	    el->el_line.limit) {
8532fe07f8SJohn Marino 		/* end of buffer space, try to allocate more */
8632fe07f8SJohn Marino 		if (!ch_enlargebufs(el, (size_t) count))
8732fe07f8SJohn Marino 			return CC_ERROR;	/* error allocating more */
8832fe07f8SJohn Marino 	}
8932fe07f8SJohn Marino 
9032fe07f8SJohn Marino 	if (count == 1) {
9132fe07f8SJohn Marino 		if (el->el_state.inputmode == MODE_INSERT
9232fe07f8SJohn Marino 		    || el->el_line.cursor >= el->el_line.lastchar)
9332fe07f8SJohn Marino 			c_insert(el, 1);
9432fe07f8SJohn Marino 
9532fe07f8SJohn Marino 		*el->el_line.cursor++ = c;
9632fe07f8SJohn Marino 		re_fastaddc(el);		/* fast refresh for one char. */
9732fe07f8SJohn Marino 	} else {
9832fe07f8SJohn Marino 		if (el->el_state.inputmode != MODE_REPLACE_1)
9932fe07f8SJohn Marino 			c_insert(el, el->el_state.argument);
10032fe07f8SJohn Marino 
10132fe07f8SJohn Marino 		while (count-- && el->el_line.cursor < el->el_line.lastchar)
10232fe07f8SJohn Marino 			*el->el_line.cursor++ = c;
10332fe07f8SJohn Marino 		re_refresh(el);
10432fe07f8SJohn Marino 	}
10532fe07f8SJohn Marino 
10632fe07f8SJohn Marino 	if (el->el_state.inputmode == MODE_REPLACE_1)
10732fe07f8SJohn Marino 		return vi_command_mode(el, 0);
10832fe07f8SJohn Marino 
10932fe07f8SJohn Marino 	return CC_NORM;
11032fe07f8SJohn Marino }
11132fe07f8SJohn Marino 
11232fe07f8SJohn Marino 
11332fe07f8SJohn Marino /* ed_delete_prev_word():
11432fe07f8SJohn Marino  *	Delete from beginning of current word to cursor
11532fe07f8SJohn Marino  *	[M-^?] [^W]
11632fe07f8SJohn Marino  */
11712db70c8Szrj libedit_private el_action_t
11832fe07f8SJohn Marino /*ARGSUSED*/
ed_delete_prev_word(EditLine * el,wint_t c)11912db70c8Szrj ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
12032fe07f8SJohn Marino {
12112db70c8Szrj 	wchar_t *cp, *p, *kp;
12232fe07f8SJohn Marino 
12332fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.buffer)
12432fe07f8SJohn Marino 		return CC_ERROR;
12532fe07f8SJohn Marino 
12632fe07f8SJohn Marino 	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
12732fe07f8SJohn Marino 	    el->el_state.argument, ce__isword);
12832fe07f8SJohn Marino 
12932fe07f8SJohn Marino 	for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
13032fe07f8SJohn Marino 		*kp++ = *p;
13132fe07f8SJohn Marino 	el->el_chared.c_kill.last = kp;
13232fe07f8SJohn Marino 
13332fe07f8SJohn Marino 	c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
13432fe07f8SJohn Marino 	el->el_line.cursor = cp;
13532fe07f8SJohn Marino 	if (el->el_line.cursor < el->el_line.buffer)
13632fe07f8SJohn Marino 		el->el_line.cursor = el->el_line.buffer; /* bounds check */
13732fe07f8SJohn Marino 	return CC_REFRESH;
13832fe07f8SJohn Marino }
13932fe07f8SJohn Marino 
14032fe07f8SJohn Marino 
14132fe07f8SJohn Marino /* ed_delete_next_char():
14232fe07f8SJohn Marino  *	Delete character under cursor
14332fe07f8SJohn Marino  *	[^D] [x]
14432fe07f8SJohn Marino  */
14512db70c8Szrj libedit_private el_action_t
14632fe07f8SJohn Marino /*ARGSUSED*/
ed_delete_next_char(EditLine * el,wint_t c)14712db70c8Szrj ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
14832fe07f8SJohn Marino {
14932fe07f8SJohn Marino #ifdef DEBUG_EDIT
15032fe07f8SJohn Marino #define	EL	el->el_line
15112db70c8Szrj 	(void) fprintf(el->el_errfile,
15212db70c8Szrj 	    "\nD(b: %p(%ls)  c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
15332fe07f8SJohn Marino 	    EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
15432fe07f8SJohn Marino 	    EL.lastchar, EL.limit, EL.limit);
15532fe07f8SJohn Marino #endif
15632fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.lastchar) {
15732fe07f8SJohn Marino 			/* if I'm at the end */
15832fe07f8SJohn Marino 		if (el->el_map.type == MAP_VI) {
15932fe07f8SJohn Marino 			if (el->el_line.cursor == el->el_line.buffer) {
16032fe07f8SJohn Marino 				/* if I'm also at the beginning */
16132fe07f8SJohn Marino #ifdef KSHVI
16232fe07f8SJohn Marino 				return CC_ERROR;
16332fe07f8SJohn Marino #else
16432fe07f8SJohn Marino 				/* then do an EOF */
16532fe07f8SJohn Marino 				terminal_writec(el, c);
16632fe07f8SJohn Marino 				return CC_EOF;
16732fe07f8SJohn Marino #endif
16832fe07f8SJohn Marino 			} else {
16932fe07f8SJohn Marino #ifdef KSHVI
17032fe07f8SJohn Marino 				el->el_line.cursor--;
17132fe07f8SJohn Marino #else
17232fe07f8SJohn Marino 				return CC_ERROR;
17332fe07f8SJohn Marino #endif
17432fe07f8SJohn Marino 			}
175c8e4d2bfSJohn Marino 		} else
17632fe07f8SJohn Marino 				return CC_ERROR;
17732fe07f8SJohn Marino 	}
17832fe07f8SJohn Marino 	c_delafter(el, el->el_state.argument);	/* delete after dot */
179c8e4d2bfSJohn Marino 	if (el->el_map.type == MAP_VI &&
180c8e4d2bfSJohn Marino 	    el->el_line.cursor >= el->el_line.lastchar &&
18132fe07f8SJohn Marino 	    el->el_line.cursor > el->el_line.buffer)
18232fe07f8SJohn Marino 			/* bounds check */
18332fe07f8SJohn Marino 		el->el_line.cursor = el->el_line.lastchar - 1;
18432fe07f8SJohn Marino 	return CC_REFRESH;
18532fe07f8SJohn Marino }
18632fe07f8SJohn Marino 
18732fe07f8SJohn Marino 
18832fe07f8SJohn Marino /* ed_kill_line():
18932fe07f8SJohn Marino  *	Cut to the end of line
19032fe07f8SJohn Marino  *	[^K] [^K]
19132fe07f8SJohn Marino  */
19212db70c8Szrj libedit_private el_action_t
19332fe07f8SJohn Marino /*ARGSUSED*/
ed_kill_line(EditLine * el,wint_t c)19412db70c8Szrj ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
19532fe07f8SJohn Marino {
19612db70c8Szrj 	wchar_t *kp, *cp;
19732fe07f8SJohn Marino 
19832fe07f8SJohn Marino 	cp = el->el_line.cursor;
19932fe07f8SJohn Marino 	kp = el->el_chared.c_kill.buf;
20032fe07f8SJohn Marino 	while (cp < el->el_line.lastchar)
20132fe07f8SJohn Marino 		*kp++ = *cp++;	/* copy it */
20232fe07f8SJohn Marino 	el->el_chared.c_kill.last = kp;
20332fe07f8SJohn Marino 			/* zap! -- delete to end */
20432fe07f8SJohn Marino 	el->el_line.lastchar = el->el_line.cursor;
20532fe07f8SJohn Marino 	return CC_REFRESH;
20632fe07f8SJohn Marino }
20732fe07f8SJohn Marino 
20832fe07f8SJohn Marino 
20932fe07f8SJohn Marino /* ed_move_to_end():
21032fe07f8SJohn Marino  *	Move cursor to the end of line
21132fe07f8SJohn Marino  *	[^E] [^E]
21232fe07f8SJohn Marino  */
21312db70c8Szrj libedit_private el_action_t
21432fe07f8SJohn Marino /*ARGSUSED*/
ed_move_to_end(EditLine * el,wint_t c)21512db70c8Szrj ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
21632fe07f8SJohn Marino {
21732fe07f8SJohn Marino 
21832fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.lastchar;
21932fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI) {
22032fe07f8SJohn Marino 		if (el->el_chared.c_vcmd.action != NOP) {
22132fe07f8SJohn Marino 			cv_delfini(el);
22232fe07f8SJohn Marino 			return CC_REFRESH;
22332fe07f8SJohn Marino 		}
22432fe07f8SJohn Marino #ifdef VI_MOVE
22532fe07f8SJohn Marino 		el->el_line.cursor--;
22632fe07f8SJohn Marino #endif
22732fe07f8SJohn Marino 	}
22832fe07f8SJohn Marino 	return CC_CURSOR;
22932fe07f8SJohn Marino }
23032fe07f8SJohn Marino 
23132fe07f8SJohn Marino 
23232fe07f8SJohn Marino /* ed_move_to_beg():
23332fe07f8SJohn Marino  *	Move cursor to the beginning of line
23432fe07f8SJohn Marino  *	[^A] [^A]
23532fe07f8SJohn Marino  */
23612db70c8Szrj libedit_private el_action_t
23732fe07f8SJohn Marino /*ARGSUSED*/
ed_move_to_beg(EditLine * el,wint_t c)23812db70c8Szrj ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
23932fe07f8SJohn Marino {
24032fe07f8SJohn Marino 
24132fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.buffer;
24232fe07f8SJohn Marino 
24332fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI) {
24432fe07f8SJohn Marino 			/* We want FIRST non space character */
24512db70c8Szrj 		while (iswspace(*el->el_line.cursor))
24632fe07f8SJohn Marino 			el->el_line.cursor++;
24732fe07f8SJohn Marino 		if (el->el_chared.c_vcmd.action != NOP) {
24832fe07f8SJohn Marino 			cv_delfini(el);
24932fe07f8SJohn Marino 			return CC_REFRESH;
25032fe07f8SJohn Marino 		}
25132fe07f8SJohn Marino 	}
25232fe07f8SJohn Marino 	return CC_CURSOR;
25332fe07f8SJohn Marino }
25432fe07f8SJohn Marino 
25532fe07f8SJohn Marino 
25632fe07f8SJohn Marino /* ed_transpose_chars():
25732fe07f8SJohn Marino  *	Exchange the character to the left of the cursor with the one under it
25832fe07f8SJohn Marino  *	[^T] [^T]
25932fe07f8SJohn Marino  */
26012db70c8Szrj libedit_private el_action_t
ed_transpose_chars(EditLine * el,wint_t c)26112db70c8Szrj ed_transpose_chars(EditLine *el, wint_t c)
26232fe07f8SJohn Marino {
26332fe07f8SJohn Marino 
26432fe07f8SJohn Marino 	if (el->el_line.cursor < el->el_line.lastchar) {
26532fe07f8SJohn Marino 		if (el->el_line.lastchar <= &el->el_line.buffer[1])
26632fe07f8SJohn Marino 			return CC_ERROR;
26732fe07f8SJohn Marino 		else
26832fe07f8SJohn Marino 			el->el_line.cursor++;
26932fe07f8SJohn Marino 	}
27032fe07f8SJohn Marino 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
27132fe07f8SJohn Marino 		/* must have at least two chars entered */
27232fe07f8SJohn Marino 		c = el->el_line.cursor[-2];
27332fe07f8SJohn Marino 		el->el_line.cursor[-2] = el->el_line.cursor[-1];
27432fe07f8SJohn Marino 		el->el_line.cursor[-1] = c;
27532fe07f8SJohn Marino 		return CC_REFRESH;
27632fe07f8SJohn Marino 	} else
27732fe07f8SJohn Marino 		return CC_ERROR;
27832fe07f8SJohn Marino }
27932fe07f8SJohn Marino 
28032fe07f8SJohn Marino 
28132fe07f8SJohn Marino /* ed_next_char():
28232fe07f8SJohn Marino  *	Move to the right one character
28332fe07f8SJohn Marino  *	[^F] [^F]
28432fe07f8SJohn Marino  */
28512db70c8Szrj libedit_private el_action_t
28632fe07f8SJohn Marino /*ARGSUSED*/
ed_next_char(EditLine * el,wint_t c)28712db70c8Szrj ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
28832fe07f8SJohn Marino {
28912db70c8Szrj 	wchar_t *lim = el->el_line.lastchar;
29032fe07f8SJohn Marino 
29132fe07f8SJohn Marino 	if (el->el_line.cursor >= lim ||
29232fe07f8SJohn Marino 	    (el->el_line.cursor == lim - 1 &&
29332fe07f8SJohn Marino 	    el->el_map.type == MAP_VI &&
29432fe07f8SJohn Marino 	    el->el_chared.c_vcmd.action == NOP))
29532fe07f8SJohn Marino 		return CC_ERROR;
29632fe07f8SJohn Marino 
29732fe07f8SJohn Marino 	el->el_line.cursor += el->el_state.argument;
29832fe07f8SJohn Marino 	if (el->el_line.cursor > lim)
29932fe07f8SJohn Marino 		el->el_line.cursor = lim;
30032fe07f8SJohn Marino 
30132fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI)
30232fe07f8SJohn Marino 		if (el->el_chared.c_vcmd.action != NOP) {
30332fe07f8SJohn Marino 			cv_delfini(el);
30432fe07f8SJohn Marino 			return CC_REFRESH;
30532fe07f8SJohn Marino 		}
30632fe07f8SJohn Marino 	return CC_CURSOR;
30732fe07f8SJohn Marino }
30832fe07f8SJohn Marino 
30932fe07f8SJohn Marino 
31032fe07f8SJohn Marino /* ed_prev_word():
31132fe07f8SJohn Marino  *	Move to the beginning of the current word
31232fe07f8SJohn Marino  *	[M-b] [b]
31332fe07f8SJohn Marino  */
31412db70c8Szrj libedit_private el_action_t
31532fe07f8SJohn Marino /*ARGSUSED*/
ed_prev_word(EditLine * el,wint_t c)31612db70c8Szrj ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
31732fe07f8SJohn Marino {
31832fe07f8SJohn Marino 
31932fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.buffer)
32032fe07f8SJohn Marino 		return CC_ERROR;
32132fe07f8SJohn Marino 
32232fe07f8SJohn Marino 	el->el_line.cursor = c__prev_word(el->el_line.cursor,
32332fe07f8SJohn Marino 	    el->el_line.buffer,
32432fe07f8SJohn Marino 	    el->el_state.argument,
32532fe07f8SJohn Marino 	    ce__isword);
32632fe07f8SJohn Marino 
32732fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI)
32832fe07f8SJohn Marino 		if (el->el_chared.c_vcmd.action != NOP) {
32932fe07f8SJohn Marino 			cv_delfini(el);
33032fe07f8SJohn Marino 			return CC_REFRESH;
33132fe07f8SJohn Marino 		}
33232fe07f8SJohn Marino 	return CC_CURSOR;
33332fe07f8SJohn Marino }
33432fe07f8SJohn Marino 
33532fe07f8SJohn Marino 
33632fe07f8SJohn Marino /* ed_prev_char():
33732fe07f8SJohn Marino  *	Move to the left one character
33832fe07f8SJohn Marino  *	[^B] [^B]
33932fe07f8SJohn Marino  */
34012db70c8Szrj libedit_private el_action_t
34132fe07f8SJohn Marino /*ARGSUSED*/
ed_prev_char(EditLine * el,wint_t c)34212db70c8Szrj ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
34332fe07f8SJohn Marino {
34432fe07f8SJohn Marino 
34532fe07f8SJohn Marino 	if (el->el_line.cursor > el->el_line.buffer) {
34632fe07f8SJohn Marino 		el->el_line.cursor -= el->el_state.argument;
34732fe07f8SJohn Marino 		if (el->el_line.cursor < el->el_line.buffer)
34832fe07f8SJohn Marino 			el->el_line.cursor = el->el_line.buffer;
34932fe07f8SJohn Marino 
35032fe07f8SJohn Marino 		if (el->el_map.type == MAP_VI)
35132fe07f8SJohn Marino 			if (el->el_chared.c_vcmd.action != NOP) {
35232fe07f8SJohn Marino 				cv_delfini(el);
35332fe07f8SJohn Marino 				return CC_REFRESH;
35432fe07f8SJohn Marino 			}
35532fe07f8SJohn Marino 		return CC_CURSOR;
35632fe07f8SJohn Marino 	} else
35732fe07f8SJohn Marino 		return CC_ERROR;
35832fe07f8SJohn Marino }
35932fe07f8SJohn Marino 
36032fe07f8SJohn Marino 
36132fe07f8SJohn Marino /* ed_quoted_insert():
36232fe07f8SJohn Marino  *	Add the next character typed verbatim
36332fe07f8SJohn Marino  *	[^V] [^V]
36432fe07f8SJohn Marino  */
36512db70c8Szrj libedit_private el_action_t
366ae19eda8Szrj /*ARGSUSED*/
ed_quoted_insert(EditLine * el,wint_t c)367ae19eda8Szrj ed_quoted_insert(EditLine *el, wint_t c __attribute__((__unused__)))
36832fe07f8SJohn Marino {
36932fe07f8SJohn Marino 	int num;
370ae19eda8Szrj 	wchar_t ch;
37132fe07f8SJohn Marino 
37232fe07f8SJohn Marino 	tty_quotemode(el);
373ae19eda8Szrj 	num = el_wgetc(el, &ch);
37432fe07f8SJohn Marino 	tty_noquotemode(el);
37532fe07f8SJohn Marino 	if (num == 1)
376ae19eda8Szrj 		return ed_insert(el, ch);
37732fe07f8SJohn Marino 	else
37832fe07f8SJohn Marino 		return ed_end_of_file(el, 0);
37932fe07f8SJohn Marino }
38032fe07f8SJohn Marino 
38132fe07f8SJohn Marino 
38232fe07f8SJohn Marino /* ed_digit():
38332fe07f8SJohn Marino  *	Adds to argument or enters a digit
38432fe07f8SJohn Marino  */
38512db70c8Szrj libedit_private el_action_t
ed_digit(EditLine * el,wint_t c)38612db70c8Szrj ed_digit(EditLine *el, wint_t c)
38732fe07f8SJohn Marino {
38832fe07f8SJohn Marino 
38912db70c8Szrj 	if (!iswdigit(c))
39032fe07f8SJohn Marino 		return CC_ERROR;
39132fe07f8SJohn Marino 
39232fe07f8SJohn Marino 	if (el->el_state.doingarg) {
39332fe07f8SJohn Marino 			/* if doing an arg, add this in... */
39432fe07f8SJohn Marino 		if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
39532fe07f8SJohn Marino 			el->el_state.argument = c - '0';
39632fe07f8SJohn Marino 		else {
39732fe07f8SJohn Marino 			if (el->el_state.argument > 1000000)
39832fe07f8SJohn Marino 				return CC_ERROR;
39932fe07f8SJohn Marino 			el->el_state.argument =
40032fe07f8SJohn Marino 			    (el->el_state.argument * 10) + (c - '0');
40132fe07f8SJohn Marino 		}
40232fe07f8SJohn Marino 		return CC_ARGHACK;
40332fe07f8SJohn Marino 	}
40432fe07f8SJohn Marino 
40532fe07f8SJohn Marino 	return ed_insert(el, c);
40632fe07f8SJohn Marino }
40732fe07f8SJohn Marino 
40832fe07f8SJohn Marino 
40932fe07f8SJohn Marino /* ed_argument_digit():
41032fe07f8SJohn Marino  *	Digit that starts argument
41132fe07f8SJohn Marino  *	For ESC-n
41232fe07f8SJohn Marino  */
41312db70c8Szrj libedit_private el_action_t
ed_argument_digit(EditLine * el,wint_t c)41412db70c8Szrj ed_argument_digit(EditLine *el, wint_t c)
41532fe07f8SJohn Marino {
41632fe07f8SJohn Marino 
41712db70c8Szrj 	if (!iswdigit(c))
41832fe07f8SJohn Marino 		return CC_ERROR;
41932fe07f8SJohn Marino 
42032fe07f8SJohn Marino 	if (el->el_state.doingarg) {
42132fe07f8SJohn Marino 		if (el->el_state.argument > 1000000)
42232fe07f8SJohn Marino 			return CC_ERROR;
42332fe07f8SJohn Marino 		el->el_state.argument = (el->el_state.argument * 10) +
42432fe07f8SJohn Marino 		    (c - '0');
42532fe07f8SJohn Marino 	} else {		/* else starting an argument */
42632fe07f8SJohn Marino 		el->el_state.argument = c - '0';
42732fe07f8SJohn Marino 		el->el_state.doingarg = 1;
42832fe07f8SJohn Marino 	}
42932fe07f8SJohn Marino 	return CC_ARGHACK;
43032fe07f8SJohn Marino }
43132fe07f8SJohn Marino 
43232fe07f8SJohn Marino 
43332fe07f8SJohn Marino /* ed_unassigned():
43432fe07f8SJohn Marino  *	Indicates unbound character
43532fe07f8SJohn Marino  *	Bound to keys that are not assigned
43632fe07f8SJohn Marino  */
43712db70c8Szrj libedit_private el_action_t
43832fe07f8SJohn Marino /*ARGSUSED*/
ed_unassigned(EditLine * el,wint_t c)43932fe07f8SJohn Marino ed_unassigned(EditLine *el __attribute__((__unused__)),
44012db70c8Szrj     wint_t c __attribute__((__unused__)))
44132fe07f8SJohn Marino {
44232fe07f8SJohn Marino 
44332fe07f8SJohn Marino 	return CC_ERROR;
44432fe07f8SJohn Marino }
44532fe07f8SJohn Marino 
44632fe07f8SJohn Marino 
44712db70c8Szrj /* ed_ignore():
44812db70c8Szrj  *	Input characters that have no effect
44912db70c8Szrj  *	[^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
45032fe07f8SJohn Marino  */
45112db70c8Szrj libedit_private el_action_t
45232fe07f8SJohn Marino /*ARGSUSED*/
ed_ignore(EditLine * el,wint_t c)45312db70c8Szrj ed_ignore(EditLine *el __attribute__((__unused__)),
45412db70c8Szrj 	      wint_t c __attribute__((__unused__)))
45532fe07f8SJohn Marino {
45632fe07f8SJohn Marino 
45732fe07f8SJohn Marino 	return CC_NORM;
45832fe07f8SJohn Marino }
45932fe07f8SJohn Marino 
46032fe07f8SJohn Marino 
46132fe07f8SJohn Marino /* ed_newline():
46232fe07f8SJohn Marino  *	Execute command
46332fe07f8SJohn Marino  *	[^J]
46432fe07f8SJohn Marino  */
46512db70c8Szrj libedit_private el_action_t
46632fe07f8SJohn Marino /*ARGSUSED*/
ed_newline(EditLine * el,wint_t c)46712db70c8Szrj ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
46832fe07f8SJohn Marino {
46932fe07f8SJohn Marino 
47032fe07f8SJohn Marino 	re_goto_bottom(el);
47132fe07f8SJohn Marino 	*el->el_line.lastchar++ = '\n';
47232fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';
47332fe07f8SJohn Marino 	return CC_NEWLINE;
47432fe07f8SJohn Marino }
47532fe07f8SJohn Marino 
47632fe07f8SJohn Marino 
47732fe07f8SJohn Marino /* ed_delete_prev_char():
47832fe07f8SJohn Marino  *	Delete the character to the left of the cursor
47932fe07f8SJohn Marino  *	[^?]
48032fe07f8SJohn Marino  */
48112db70c8Szrj libedit_private el_action_t
48232fe07f8SJohn Marino /*ARGSUSED*/
ed_delete_prev_char(EditLine * el,wint_t c)48312db70c8Szrj ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
48432fe07f8SJohn Marino {
48532fe07f8SJohn Marino 
48632fe07f8SJohn Marino 	if (el->el_line.cursor <= el->el_line.buffer)
48732fe07f8SJohn Marino 		return CC_ERROR;
48832fe07f8SJohn Marino 
48932fe07f8SJohn Marino 	c_delbefore(el, el->el_state.argument);
49032fe07f8SJohn Marino 	el->el_line.cursor -= el->el_state.argument;
49132fe07f8SJohn Marino 	if (el->el_line.cursor < el->el_line.buffer)
49232fe07f8SJohn Marino 		el->el_line.cursor = el->el_line.buffer;
49332fe07f8SJohn Marino 	return CC_REFRESH;
49432fe07f8SJohn Marino }
49532fe07f8SJohn Marino 
49632fe07f8SJohn Marino 
49732fe07f8SJohn Marino /* ed_clear_screen():
49832fe07f8SJohn Marino  *	Clear screen leaving current line at the top
49932fe07f8SJohn Marino  *	[^L]
50032fe07f8SJohn Marino  */
50112db70c8Szrj libedit_private el_action_t
50232fe07f8SJohn Marino /*ARGSUSED*/
ed_clear_screen(EditLine * el,wint_t c)50312db70c8Szrj ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
50432fe07f8SJohn Marino {
50532fe07f8SJohn Marino 
50632fe07f8SJohn Marino 	terminal_clear_screen(el);	/* clear the whole real screen */
50732fe07f8SJohn Marino 	re_clear_display(el);	/* reset everything */
50832fe07f8SJohn Marino 	return CC_REFRESH;
50932fe07f8SJohn Marino }
51032fe07f8SJohn Marino 
51132fe07f8SJohn Marino 
51232fe07f8SJohn Marino /* ed_redisplay():
51332fe07f8SJohn Marino  *	Redisplay everything
51432fe07f8SJohn Marino  *	^R
51532fe07f8SJohn Marino  */
51612db70c8Szrj libedit_private el_action_t
51732fe07f8SJohn Marino /*ARGSUSED*/
ed_redisplay(EditLine * el,wint_t c)51832fe07f8SJohn Marino ed_redisplay(EditLine *el __attribute__((__unused__)),
51912db70c8Szrj 	     wint_t c __attribute__((__unused__)))
52032fe07f8SJohn Marino {
52132fe07f8SJohn Marino 
52232fe07f8SJohn Marino 	return CC_REDISPLAY;
52332fe07f8SJohn Marino }
52432fe07f8SJohn Marino 
52532fe07f8SJohn Marino 
52632fe07f8SJohn Marino /* ed_start_over():
52732fe07f8SJohn Marino  *	Erase current line and start from scratch
52832fe07f8SJohn Marino  *	[^G]
52932fe07f8SJohn Marino  */
53012db70c8Szrj libedit_private el_action_t
53132fe07f8SJohn Marino /*ARGSUSED*/
ed_start_over(EditLine * el,wint_t c)53212db70c8Szrj ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
53332fe07f8SJohn Marino {
53432fe07f8SJohn Marino 
53512db70c8Szrj 	ch_reset(el);
53632fe07f8SJohn Marino 	return CC_REFRESH;
53732fe07f8SJohn Marino }
53832fe07f8SJohn Marino 
53932fe07f8SJohn Marino 
54032fe07f8SJohn Marino /* ed_sequence_lead_in():
54132fe07f8SJohn Marino  *	First character in a bound sequence
54232fe07f8SJohn Marino  *	Placeholder for external keys
54332fe07f8SJohn Marino  */
54412db70c8Szrj libedit_private el_action_t
54532fe07f8SJohn Marino /*ARGSUSED*/
ed_sequence_lead_in(EditLine * el,wint_t c)54632fe07f8SJohn Marino ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
54712db70c8Szrj 		    wint_t c __attribute__((__unused__)))
54832fe07f8SJohn Marino {
54932fe07f8SJohn Marino 
55032fe07f8SJohn Marino 	return CC_NORM;
55132fe07f8SJohn Marino }
55232fe07f8SJohn Marino 
55332fe07f8SJohn Marino 
55432fe07f8SJohn Marino /* ed_prev_history():
55532fe07f8SJohn Marino  *	Move to the previous history line
55632fe07f8SJohn Marino  *	[^P] [k]
55732fe07f8SJohn Marino  */
55812db70c8Szrj libedit_private el_action_t
55932fe07f8SJohn Marino /*ARGSUSED*/
ed_prev_history(EditLine * el,wint_t c)56012db70c8Szrj ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
56132fe07f8SJohn Marino {
56232fe07f8SJohn Marino 	char beep = 0;
56332fe07f8SJohn Marino 	int sv_event = el->el_history.eventno;
56432fe07f8SJohn Marino 
56532fe07f8SJohn Marino 	el->el_chared.c_undo.len = -1;
56632fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';		/* just in case */
56732fe07f8SJohn Marino 
56832fe07f8SJohn Marino 	if (el->el_history.eventno == 0) {	/* save the current buffer
56932fe07f8SJohn Marino 						 * away */
57012db70c8Szrj 		(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
57132fe07f8SJohn Marino 		    EL_BUFSIZ);
57232fe07f8SJohn Marino 		el->el_history.last = el->el_history.buf +
57332fe07f8SJohn Marino 		    (el->el_line.lastchar - el->el_line.buffer);
57432fe07f8SJohn Marino 	}
57532fe07f8SJohn Marino 	el->el_history.eventno += el->el_state.argument;
57632fe07f8SJohn Marino 
57732fe07f8SJohn Marino 	if (hist_get(el) == CC_ERROR) {
57832fe07f8SJohn Marino 		if (el->el_map.type == MAP_VI) {
57932fe07f8SJohn Marino 			el->el_history.eventno = sv_event;
58032fe07f8SJohn Marino 		}
58132fe07f8SJohn Marino 		beep = 1;
58232fe07f8SJohn Marino 		/* el->el_history.eventno was fixed by first call */
58332fe07f8SJohn Marino 		(void) hist_get(el);
58432fe07f8SJohn Marino 	}
58532fe07f8SJohn Marino 	if (beep)
58632fe07f8SJohn Marino 		return CC_REFRESH_BEEP;
58732fe07f8SJohn Marino 	return CC_REFRESH;
58832fe07f8SJohn Marino }
58932fe07f8SJohn Marino 
59032fe07f8SJohn Marino 
59132fe07f8SJohn Marino /* ed_next_history():
59232fe07f8SJohn Marino  *	Move to the next history line
59332fe07f8SJohn Marino  *	[^N] [j]
59432fe07f8SJohn Marino  */
59512db70c8Szrj libedit_private el_action_t
59632fe07f8SJohn Marino /*ARGSUSED*/
ed_next_history(EditLine * el,wint_t c)59712db70c8Szrj ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
59832fe07f8SJohn Marino {
59932fe07f8SJohn Marino 	el_action_t beep = CC_REFRESH, rval;
60032fe07f8SJohn Marino 
60132fe07f8SJohn Marino 	el->el_chared.c_undo.len = -1;
60232fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';	/* just in case */
60332fe07f8SJohn Marino 
60432fe07f8SJohn Marino 	el->el_history.eventno -= el->el_state.argument;
60532fe07f8SJohn Marino 
60632fe07f8SJohn Marino 	if (el->el_history.eventno < 0) {
60732fe07f8SJohn Marino 		el->el_history.eventno = 0;
60832fe07f8SJohn Marino 		beep = CC_REFRESH_BEEP;
60932fe07f8SJohn Marino 	}
61032fe07f8SJohn Marino 	rval = hist_get(el);
61132fe07f8SJohn Marino 	if (rval == CC_REFRESH)
61232fe07f8SJohn Marino 		return beep;
61332fe07f8SJohn Marino 	return rval;
61432fe07f8SJohn Marino 
61532fe07f8SJohn Marino }
61632fe07f8SJohn Marino 
61732fe07f8SJohn Marino 
61832fe07f8SJohn Marino /* ed_search_prev_history():
61932fe07f8SJohn Marino  *	Search previous in history for a line matching the current
62032fe07f8SJohn Marino  *	next search history [M-P] [K]
62132fe07f8SJohn Marino  */
62212db70c8Szrj libedit_private el_action_t
62332fe07f8SJohn Marino /*ARGSUSED*/
ed_search_prev_history(EditLine * el,wint_t c)62412db70c8Szrj ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
62532fe07f8SJohn Marino {
62612db70c8Szrj 	const wchar_t *hp;
62732fe07f8SJohn Marino 	int h;
62812db70c8Szrj 	int found = 0;
62932fe07f8SJohn Marino 
63032fe07f8SJohn Marino 	el->el_chared.c_vcmd.action = NOP;
63132fe07f8SJohn Marino 	el->el_chared.c_undo.len = -1;
63232fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';	/* just in case */
63332fe07f8SJohn Marino 	if (el->el_history.eventno < 0) {
63432fe07f8SJohn Marino #ifdef DEBUG_EDIT
63532fe07f8SJohn Marino 		(void) fprintf(el->el_errfile,
63632fe07f8SJohn Marino 		    "e_prev_search_hist(): eventno < 0;\n");
63732fe07f8SJohn Marino #endif
63832fe07f8SJohn Marino 		el->el_history.eventno = 0;
63932fe07f8SJohn Marino 		return CC_ERROR;
64032fe07f8SJohn Marino 	}
64132fe07f8SJohn Marino 	if (el->el_history.eventno == 0) {
64212db70c8Szrj 		(void) wcsncpy(el->el_history.buf, el->el_line.buffer,
64332fe07f8SJohn Marino 		    EL_BUFSIZ);
64432fe07f8SJohn Marino 		el->el_history.last = el->el_history.buf +
64532fe07f8SJohn Marino 		    (el->el_line.lastchar - el->el_line.buffer);
64632fe07f8SJohn Marino 	}
64732fe07f8SJohn Marino 	if (el->el_history.ref == NULL)
64832fe07f8SJohn Marino 		return CC_ERROR;
64932fe07f8SJohn Marino 
65032fe07f8SJohn Marino 	hp = HIST_FIRST(el);
65132fe07f8SJohn Marino 	if (hp == NULL)
65232fe07f8SJohn Marino 		return CC_ERROR;
65332fe07f8SJohn Marino 
65432fe07f8SJohn Marino 	c_setpat(el);		/* Set search pattern !! */
65532fe07f8SJohn Marino 
65632fe07f8SJohn Marino 	for (h = 1; h <= el->el_history.eventno; h++)
65732fe07f8SJohn Marino 		hp = HIST_NEXT(el);
65832fe07f8SJohn Marino 
65932fe07f8SJohn Marino 	while (hp != NULL) {
66032fe07f8SJohn Marino #ifdef SDEBUG
661*cdf8408cSAntonio Huete Jimenez 		(void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp);
66232fe07f8SJohn Marino #endif
66312db70c8Szrj 		if ((wcsncmp(hp, el->el_line.buffer, (size_t)
66432fe07f8SJohn Marino 			    (el->el_line.lastchar - el->el_line.buffer)) ||
66532fe07f8SJohn Marino 			hp[el->el_line.lastchar - el->el_line.buffer]) &&
66632fe07f8SJohn Marino 		    c_hmatch(el, hp)) {
66712db70c8Szrj 			found = 1;
66832fe07f8SJohn Marino 			break;
66932fe07f8SJohn Marino 		}
67032fe07f8SJohn Marino 		h++;
67132fe07f8SJohn Marino 		hp = HIST_NEXT(el);
67232fe07f8SJohn Marino 	}
67332fe07f8SJohn Marino 
67432fe07f8SJohn Marino 	if (!found) {
67532fe07f8SJohn Marino #ifdef SDEBUG
67632fe07f8SJohn Marino 		(void) fprintf(el->el_errfile, "not found\n");
67732fe07f8SJohn Marino #endif
67832fe07f8SJohn Marino 		return CC_ERROR;
67932fe07f8SJohn Marino 	}
68032fe07f8SJohn Marino 	el->el_history.eventno = h;
68132fe07f8SJohn Marino 
68232fe07f8SJohn Marino 	return hist_get(el);
68332fe07f8SJohn Marino }
68432fe07f8SJohn Marino 
68532fe07f8SJohn Marino 
68632fe07f8SJohn Marino /* ed_search_next_history():
68732fe07f8SJohn Marino  *	Search next in history for a line matching the current
68832fe07f8SJohn Marino  *	[M-N] [J]
68932fe07f8SJohn Marino  */
69012db70c8Szrj libedit_private el_action_t
69132fe07f8SJohn Marino /*ARGSUSED*/
ed_search_next_history(EditLine * el,wint_t c)69212db70c8Szrj ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
69332fe07f8SJohn Marino {
69412db70c8Szrj 	const wchar_t *hp;
69532fe07f8SJohn Marino 	int h;
69612db70c8Szrj 	int found = 0;
69732fe07f8SJohn Marino 
69832fe07f8SJohn Marino 	el->el_chared.c_vcmd.action = NOP;
69932fe07f8SJohn Marino 	el->el_chared.c_undo.len = -1;
70032fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';	/* just in case */
70132fe07f8SJohn Marino 
70232fe07f8SJohn Marino 	if (el->el_history.eventno == 0)
70332fe07f8SJohn Marino 		return CC_ERROR;
70432fe07f8SJohn Marino 
70532fe07f8SJohn Marino 	if (el->el_history.ref == NULL)
70632fe07f8SJohn Marino 		return CC_ERROR;
70732fe07f8SJohn Marino 
70832fe07f8SJohn Marino 	hp = HIST_FIRST(el);
70932fe07f8SJohn Marino 	if (hp == NULL)
71032fe07f8SJohn Marino 		return CC_ERROR;
71132fe07f8SJohn Marino 
71232fe07f8SJohn Marino 	c_setpat(el);		/* Set search pattern !! */
71332fe07f8SJohn Marino 
71432fe07f8SJohn Marino 	for (h = 1; h < el->el_history.eventno && hp; h++) {
71532fe07f8SJohn Marino #ifdef SDEBUG
716*cdf8408cSAntonio Huete Jimenez 		(void) fprintf(el->el_errfile, "Comparing with \"%ls\"\n", hp);
71732fe07f8SJohn Marino #endif
71812db70c8Szrj 		if ((wcsncmp(hp, el->el_line.buffer, (size_t)
71932fe07f8SJohn Marino 			    (el->el_line.lastchar - el->el_line.buffer)) ||
72032fe07f8SJohn Marino 			hp[el->el_line.lastchar - el->el_line.buffer]) &&
72132fe07f8SJohn Marino 		    c_hmatch(el, hp))
72232fe07f8SJohn Marino 			found = h;
72332fe07f8SJohn Marino 		hp = HIST_NEXT(el);
72432fe07f8SJohn Marino 	}
72532fe07f8SJohn Marino 
72632fe07f8SJohn Marino 	if (!found) {		/* is it the current history number? */
72732fe07f8SJohn Marino 		if (!c_hmatch(el, el->el_history.buf)) {
72832fe07f8SJohn Marino #ifdef SDEBUG
72932fe07f8SJohn Marino 			(void) fprintf(el->el_errfile, "not found\n");
73032fe07f8SJohn Marino #endif
73132fe07f8SJohn Marino 			return CC_ERROR;
73232fe07f8SJohn Marino 		}
73332fe07f8SJohn Marino 	}
73432fe07f8SJohn Marino 	el->el_history.eventno = found;
73532fe07f8SJohn Marino 
73632fe07f8SJohn Marino 	return hist_get(el);
73732fe07f8SJohn Marino }
73832fe07f8SJohn Marino 
73932fe07f8SJohn Marino 
74032fe07f8SJohn Marino /* ed_prev_line():
74132fe07f8SJohn Marino  *	Move up one line
74232fe07f8SJohn Marino  *	Could be [k] [^p]
74332fe07f8SJohn Marino  */
74412db70c8Szrj libedit_private el_action_t
74532fe07f8SJohn Marino /*ARGSUSED*/
ed_prev_line(EditLine * el,wint_t c)74612db70c8Szrj ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
74732fe07f8SJohn Marino {
74812db70c8Szrj 	wchar_t *ptr;
74932fe07f8SJohn Marino 	int nchars = c_hpos(el);
75032fe07f8SJohn Marino 
75132fe07f8SJohn Marino 	/*
75232fe07f8SJohn Marino          * Move to the line requested
75332fe07f8SJohn Marino          */
75432fe07f8SJohn Marino 	if (*(ptr = el->el_line.cursor) == '\n')
75532fe07f8SJohn Marino 		ptr--;
75632fe07f8SJohn Marino 
75732fe07f8SJohn Marino 	for (; ptr >= el->el_line.buffer; ptr--)
75832fe07f8SJohn Marino 		if (*ptr == '\n' && --el->el_state.argument <= 0)
75932fe07f8SJohn Marino 			break;
76032fe07f8SJohn Marino 
76132fe07f8SJohn Marino 	if (el->el_state.argument > 0)
76232fe07f8SJohn Marino 		return CC_ERROR;
76332fe07f8SJohn Marino 
76432fe07f8SJohn Marino 	/*
76532fe07f8SJohn Marino          * Move to the beginning of the line
76632fe07f8SJohn Marino          */
76732fe07f8SJohn Marino 	for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
76832fe07f8SJohn Marino 		continue;
76932fe07f8SJohn Marino 
77032fe07f8SJohn Marino 	/*
77132fe07f8SJohn Marino          * Move to the character requested
77232fe07f8SJohn Marino          */
77332fe07f8SJohn Marino 	for (ptr++;
77432fe07f8SJohn Marino 	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
77532fe07f8SJohn Marino 	    ptr++)
77632fe07f8SJohn Marino 		continue;
77732fe07f8SJohn Marino 
77832fe07f8SJohn Marino 	el->el_line.cursor = ptr;
77932fe07f8SJohn Marino 	return CC_CURSOR;
78032fe07f8SJohn Marino }
78132fe07f8SJohn Marino 
78232fe07f8SJohn Marino 
78332fe07f8SJohn Marino /* ed_next_line():
78432fe07f8SJohn Marino  *	Move down one line
78532fe07f8SJohn Marino  *	Could be [j] [^n]
78632fe07f8SJohn Marino  */
78712db70c8Szrj libedit_private el_action_t
78832fe07f8SJohn Marino /*ARGSUSED*/
ed_next_line(EditLine * el,wint_t c)78912db70c8Szrj ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
79032fe07f8SJohn Marino {
79112db70c8Szrj 	wchar_t *ptr;
79232fe07f8SJohn Marino 	int nchars = c_hpos(el);
79332fe07f8SJohn Marino 
79432fe07f8SJohn Marino 	/*
79532fe07f8SJohn Marino          * Move to the line requested
79632fe07f8SJohn Marino          */
79732fe07f8SJohn Marino 	for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
79832fe07f8SJohn Marino 		if (*ptr == '\n' && --el->el_state.argument <= 0)
79932fe07f8SJohn Marino 			break;
80032fe07f8SJohn Marino 
80132fe07f8SJohn Marino 	if (el->el_state.argument > 0)
80232fe07f8SJohn Marino 		return CC_ERROR;
80332fe07f8SJohn Marino 
80432fe07f8SJohn Marino 	/*
80532fe07f8SJohn Marino          * Move to the character requested
80632fe07f8SJohn Marino          */
80732fe07f8SJohn Marino 	for (ptr++;
80832fe07f8SJohn Marino 	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
80932fe07f8SJohn Marino 	    ptr++)
81032fe07f8SJohn Marino 		continue;
81132fe07f8SJohn Marino 
81232fe07f8SJohn Marino 	el->el_line.cursor = ptr;
81332fe07f8SJohn Marino 	return CC_CURSOR;
81432fe07f8SJohn Marino }
81532fe07f8SJohn Marino 
81632fe07f8SJohn Marino 
81732fe07f8SJohn Marino /* ed_command():
81832fe07f8SJohn Marino  *	Editline extended command
81932fe07f8SJohn Marino  *	[M-X] [:]
82032fe07f8SJohn Marino  */
82112db70c8Szrj libedit_private el_action_t
82232fe07f8SJohn Marino /*ARGSUSED*/
ed_command(EditLine * el,wint_t c)82312db70c8Szrj ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
82432fe07f8SJohn Marino {
82512db70c8Szrj 	wchar_t tmpbuf[EL_BUFSIZ];
82632fe07f8SJohn Marino 	int tmplen;
82732fe07f8SJohn Marino 
82812db70c8Szrj 	tmplen = c_gets(el, tmpbuf, L"\n: ");
82932fe07f8SJohn Marino 	terminal__putc(el, '\n');
83032fe07f8SJohn Marino 
83132fe07f8SJohn Marino 	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
83232fe07f8SJohn Marino 		terminal_beep(el);
83332fe07f8SJohn Marino 
83432fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
83532fe07f8SJohn Marino 	re_clear_display(el);
83632fe07f8SJohn Marino 	return CC_REFRESH;
83732fe07f8SJohn Marino }
838