xref: /dflybsd-src/contrib/libedit/src/vi.c (revision 698e9e6cd5f042847de67460caaa3fde98cdfe99)
1*cdf8408cSAntonio Huete Jimenez /*	$NetBSD: vi.c,v 1.64 2021/08/28 17:17:47 christos 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[] = "@(#)vi.c	8.1 (Berkeley) 6/4/93";
3932fe07f8SJohn Marino #else
40*cdf8408cSAntonio Huete Jimenez __RCSID("$NetBSD: vi.c,v 1.64 2021/08/28 17:17:47 christos Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino 
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino  * vi.c: Vi mode commands.
4632fe07f8SJohn Marino  */
4712db70c8Szrj #include <sys/wait.h>
4812db70c8Szrj #include <ctype.h>
4912db70c8Szrj #include <limits.h>
5012db70c8Szrj #include <stdlib.h>
5112db70c8Szrj #include <string.h>
5212db70c8Szrj #include <unistd.h>
5332fe07f8SJohn Marino 
5412db70c8Szrj #include "el.h"
5512db70c8Szrj #include "common.h"
5612db70c8Szrj #include "emacs.h"
5712db70c8Szrj #include "fcns.h"
5812db70c8Szrj #include "vi.h"
5912db70c8Szrj 
6012db70c8Szrj static el_action_t	cv_action(EditLine *, wint_t);
6112db70c8Szrj static el_action_t	cv_paste(EditLine *, wint_t);
6232fe07f8SJohn Marino 
6332fe07f8SJohn Marino /* cv_action():
6432fe07f8SJohn Marino  *	Handle vi actions.
6532fe07f8SJohn Marino  */
6612db70c8Szrj static el_action_t
cv_action(EditLine * el,wint_t c)6712db70c8Szrj cv_action(EditLine *el, wint_t c)
6832fe07f8SJohn Marino {
6932fe07f8SJohn Marino 
7032fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
7132fe07f8SJohn Marino 		/* 'cc', 'dd' and (possibly) friends */
7212db70c8Szrj 		if (c != (wint_t)el->el_chared.c_vcmd.action)
7332fe07f8SJohn Marino 			return CC_ERROR;
7432fe07f8SJohn Marino 
7532fe07f8SJohn Marino 		if (!(c & YANK))
7632fe07f8SJohn Marino 			cv_undo(el);
7732fe07f8SJohn Marino 		cv_yank(el, el->el_line.buffer,
7832fe07f8SJohn Marino 		    (int)(el->el_line.lastchar - el->el_line.buffer));
7932fe07f8SJohn Marino 		el->el_chared.c_vcmd.action = NOP;
8032fe07f8SJohn Marino 		el->el_chared.c_vcmd.pos = 0;
8132fe07f8SJohn Marino 		if (!(c & YANK)) {
8232fe07f8SJohn Marino 			el->el_line.lastchar = el->el_line.buffer;
8332fe07f8SJohn Marino 			el->el_line.cursor = el->el_line.buffer;
8432fe07f8SJohn Marino 		}
8532fe07f8SJohn Marino 		if (c & INSERT)
8632fe07f8SJohn Marino 			el->el_map.current = el->el_map.key;
8732fe07f8SJohn Marino 
8832fe07f8SJohn Marino 		return CC_REFRESH;
8932fe07f8SJohn Marino 	}
9032fe07f8SJohn Marino 	el->el_chared.c_vcmd.pos = el->el_line.cursor;
9132fe07f8SJohn Marino 	el->el_chared.c_vcmd.action = c;
9232fe07f8SJohn Marino 	return CC_ARGHACK;
9332fe07f8SJohn Marino }
9432fe07f8SJohn Marino 
9532fe07f8SJohn Marino /* cv_paste():
9632fe07f8SJohn Marino  *	Paste previous deletion before or after the cursor
9732fe07f8SJohn Marino  */
9812db70c8Szrj static el_action_t
cv_paste(EditLine * el,wint_t c)9912db70c8Szrj cv_paste(EditLine *el, wint_t c)
10032fe07f8SJohn Marino {
10132fe07f8SJohn Marino 	c_kill_t *k = &el->el_chared.c_kill;
10232fe07f8SJohn Marino 	size_t len = (size_t)(k->last - k->buf);
10332fe07f8SJohn Marino 
10432fe07f8SJohn Marino 	if (k->buf == NULL || len == 0)
10532fe07f8SJohn Marino 		return CC_ERROR;
10632fe07f8SJohn Marino #ifdef DEBUG_PASTE
10712db70c8Szrj 	(void) fprintf(el->el_errfile, "Paste: \"%.*ls\"\n", (int)len,
10812db70c8Szrj 	    k->buf);
10932fe07f8SJohn Marino #endif
11032fe07f8SJohn Marino 
11132fe07f8SJohn Marino 	cv_undo(el);
11232fe07f8SJohn Marino 
11332fe07f8SJohn Marino 	if (!c && el->el_line.cursor < el->el_line.lastchar)
11432fe07f8SJohn Marino 		el->el_line.cursor++;
11532fe07f8SJohn Marino 
11632fe07f8SJohn Marino 	c_insert(el, (int)len);
11732fe07f8SJohn Marino 	if (el->el_line.cursor + len > el->el_line.lastchar)
11832fe07f8SJohn Marino 		return CC_ERROR;
11932fe07f8SJohn Marino 	(void) memcpy(el->el_line.cursor, k->buf, len *
12032fe07f8SJohn Marino 	    sizeof(*el->el_line.cursor));
12132fe07f8SJohn Marino 
12232fe07f8SJohn Marino 	return CC_REFRESH;
12332fe07f8SJohn Marino }
12432fe07f8SJohn Marino 
12532fe07f8SJohn Marino 
12632fe07f8SJohn Marino /* vi_paste_next():
12732fe07f8SJohn Marino  *	Vi paste previous deletion to the right of the cursor
12832fe07f8SJohn Marino  *	[p]
12932fe07f8SJohn Marino  */
13012db70c8Szrj libedit_private el_action_t
13132fe07f8SJohn Marino /*ARGSUSED*/
vi_paste_next(EditLine * el,wint_t c)13212db70c8Szrj vi_paste_next(EditLine *el, wint_t c __attribute__((__unused__)))
13332fe07f8SJohn Marino {
13432fe07f8SJohn Marino 
13532fe07f8SJohn Marino 	return cv_paste(el, 0);
13632fe07f8SJohn Marino }
13732fe07f8SJohn Marino 
13832fe07f8SJohn Marino 
13932fe07f8SJohn Marino /* vi_paste_prev():
14032fe07f8SJohn Marino  *	Vi paste previous deletion to the left of the cursor
14132fe07f8SJohn Marino  *	[P]
14232fe07f8SJohn Marino  */
14312db70c8Szrj libedit_private el_action_t
14432fe07f8SJohn Marino /*ARGSUSED*/
vi_paste_prev(EditLine * el,wint_t c)14512db70c8Szrj vi_paste_prev(EditLine *el, wint_t c __attribute__((__unused__)))
14632fe07f8SJohn Marino {
14732fe07f8SJohn Marino 
14832fe07f8SJohn Marino 	return cv_paste(el, 1);
14932fe07f8SJohn Marino }
15032fe07f8SJohn Marino 
15132fe07f8SJohn Marino 
15232fe07f8SJohn Marino /* vi_prev_big_word():
15332fe07f8SJohn Marino  *	Vi move to the previous space delimited word
15432fe07f8SJohn Marino  *	[B]
15532fe07f8SJohn Marino  */
15612db70c8Szrj libedit_private el_action_t
15732fe07f8SJohn Marino /*ARGSUSED*/
vi_prev_big_word(EditLine * el,wint_t c)15812db70c8Szrj vi_prev_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
15932fe07f8SJohn Marino {
16032fe07f8SJohn Marino 
16132fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.buffer)
16232fe07f8SJohn Marino 		return CC_ERROR;
16332fe07f8SJohn Marino 
16432fe07f8SJohn Marino 	el->el_line.cursor = cv_prev_word(el->el_line.cursor,
16532fe07f8SJohn Marino 	    el->el_line.buffer,
16632fe07f8SJohn Marino 	    el->el_state.argument,
16732fe07f8SJohn Marino 	    cv__isWord);
16832fe07f8SJohn Marino 
16932fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
17032fe07f8SJohn Marino 		cv_delfini(el);
17132fe07f8SJohn Marino 		return CC_REFRESH;
17232fe07f8SJohn Marino 	}
17332fe07f8SJohn Marino 	return CC_CURSOR;
17432fe07f8SJohn Marino }
17532fe07f8SJohn Marino 
17632fe07f8SJohn Marino 
17732fe07f8SJohn Marino /* vi_prev_word():
17832fe07f8SJohn Marino  *	Vi move to the previous word
17932fe07f8SJohn Marino  *	[b]
18032fe07f8SJohn Marino  */
18112db70c8Szrj libedit_private el_action_t
18232fe07f8SJohn Marino /*ARGSUSED*/
vi_prev_word(EditLine * el,wint_t c)18312db70c8Szrj vi_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
18432fe07f8SJohn Marino {
18532fe07f8SJohn Marino 
18632fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.buffer)
18732fe07f8SJohn Marino 		return CC_ERROR;
18832fe07f8SJohn Marino 
18932fe07f8SJohn Marino 	el->el_line.cursor = cv_prev_word(el->el_line.cursor,
19032fe07f8SJohn Marino 	    el->el_line.buffer,
19132fe07f8SJohn Marino 	    el->el_state.argument,
19232fe07f8SJohn Marino 	    cv__isword);
19332fe07f8SJohn Marino 
19432fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
19532fe07f8SJohn Marino 		cv_delfini(el);
19632fe07f8SJohn Marino 		return CC_REFRESH;
19732fe07f8SJohn Marino 	}
19832fe07f8SJohn Marino 	return CC_CURSOR;
19932fe07f8SJohn Marino }
20032fe07f8SJohn Marino 
20132fe07f8SJohn Marino 
20232fe07f8SJohn Marino /* vi_next_big_word():
20332fe07f8SJohn Marino  *	Vi move to the next space delimited word
20432fe07f8SJohn Marino  *	[W]
20532fe07f8SJohn Marino  */
20612db70c8Szrj libedit_private el_action_t
20732fe07f8SJohn Marino /*ARGSUSED*/
vi_next_big_word(EditLine * el,wint_t c)20812db70c8Szrj vi_next_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
20932fe07f8SJohn Marino {
21032fe07f8SJohn Marino 
21132fe07f8SJohn Marino 	if (el->el_line.cursor >= el->el_line.lastchar - 1)
21232fe07f8SJohn Marino 		return CC_ERROR;
21332fe07f8SJohn Marino 
21432fe07f8SJohn Marino 	el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
21532fe07f8SJohn Marino 	    el->el_line.lastchar, el->el_state.argument, cv__isWord);
21632fe07f8SJohn Marino 
21732fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI)
21832fe07f8SJohn Marino 		if (el->el_chared.c_vcmd.action != NOP) {
21932fe07f8SJohn Marino 			cv_delfini(el);
22032fe07f8SJohn Marino 			return CC_REFRESH;
22132fe07f8SJohn Marino 		}
22232fe07f8SJohn Marino 	return CC_CURSOR;
22332fe07f8SJohn Marino }
22432fe07f8SJohn Marino 
22532fe07f8SJohn Marino 
22632fe07f8SJohn Marino /* vi_next_word():
22732fe07f8SJohn Marino  *	Vi move to the next word
22832fe07f8SJohn Marino  *	[w]
22932fe07f8SJohn Marino  */
23012db70c8Szrj libedit_private el_action_t
23132fe07f8SJohn Marino /*ARGSUSED*/
vi_next_word(EditLine * el,wint_t c)23212db70c8Szrj vi_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
23332fe07f8SJohn Marino {
23432fe07f8SJohn Marino 
23532fe07f8SJohn Marino 	if (el->el_line.cursor >= el->el_line.lastchar - 1)
23632fe07f8SJohn Marino 		return CC_ERROR;
23732fe07f8SJohn Marino 
23832fe07f8SJohn Marino 	el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
23932fe07f8SJohn Marino 	    el->el_line.lastchar, el->el_state.argument, cv__isword);
24032fe07f8SJohn Marino 
24132fe07f8SJohn Marino 	if (el->el_map.type == MAP_VI)
24232fe07f8SJohn Marino 		if (el->el_chared.c_vcmd.action != NOP) {
24332fe07f8SJohn Marino 			cv_delfini(el);
24432fe07f8SJohn Marino 			return CC_REFRESH;
24532fe07f8SJohn Marino 		}
24632fe07f8SJohn Marino 	return CC_CURSOR;
24732fe07f8SJohn Marino }
24832fe07f8SJohn Marino 
24932fe07f8SJohn Marino 
25032fe07f8SJohn Marino /* vi_change_case():
25132fe07f8SJohn Marino  *	Vi change case of character under the cursor and advance one character
25232fe07f8SJohn Marino  *	[~]
25332fe07f8SJohn Marino  */
25412db70c8Szrj libedit_private el_action_t
vi_change_case(EditLine * el,wint_t c)25512db70c8Szrj vi_change_case(EditLine *el, wint_t c)
25632fe07f8SJohn Marino {
25732fe07f8SJohn Marino 	int i;
25832fe07f8SJohn Marino 
25932fe07f8SJohn Marino 	if (el->el_line.cursor >= el->el_line.lastchar)
26032fe07f8SJohn Marino 		return CC_ERROR;
26132fe07f8SJohn Marino 	cv_undo(el);
26232fe07f8SJohn Marino 	for (i = 0; i < el->el_state.argument; i++) {
26332fe07f8SJohn Marino 
26432fe07f8SJohn Marino 		c = *el->el_line.cursor;
26512db70c8Szrj 		if (iswupper(c))
26612db70c8Szrj 			*el->el_line.cursor = towlower(c);
26712db70c8Szrj 		else if (iswlower(c))
26812db70c8Szrj 			*el->el_line.cursor = towupper(c);
26932fe07f8SJohn Marino 
27032fe07f8SJohn Marino 		if (++el->el_line.cursor >= el->el_line.lastchar) {
27132fe07f8SJohn Marino 			el->el_line.cursor--;
27232fe07f8SJohn Marino 			re_fastaddc(el);
27332fe07f8SJohn Marino 			break;
27432fe07f8SJohn Marino 		}
27532fe07f8SJohn Marino 		re_fastaddc(el);
27632fe07f8SJohn Marino 	}
27732fe07f8SJohn Marino 	return CC_NORM;
27832fe07f8SJohn Marino }
27932fe07f8SJohn Marino 
28032fe07f8SJohn Marino 
28132fe07f8SJohn Marino /* vi_change_meta():
28232fe07f8SJohn Marino  *	Vi change prefix command
28332fe07f8SJohn Marino  *	[c]
28432fe07f8SJohn Marino  */
28512db70c8Szrj libedit_private el_action_t
28632fe07f8SJohn Marino /*ARGSUSED*/
vi_change_meta(EditLine * el,wint_t c)28712db70c8Szrj vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__)))
28832fe07f8SJohn Marino {
28932fe07f8SJohn Marino 
29032fe07f8SJohn Marino 	/*
29132fe07f8SJohn Marino          * Delete with insert == change: first we delete and then we leave in
29232fe07f8SJohn Marino          * insert mode.
29332fe07f8SJohn Marino          */
29432fe07f8SJohn Marino 	return cv_action(el, DELETE | INSERT);
29532fe07f8SJohn Marino }
29632fe07f8SJohn Marino 
29732fe07f8SJohn Marino 
29832fe07f8SJohn Marino /* vi_insert_at_bol():
29932fe07f8SJohn Marino  *	Vi enter insert mode at the beginning of line
30032fe07f8SJohn Marino  *	[I]
30132fe07f8SJohn Marino  */
30212db70c8Szrj libedit_private el_action_t
30332fe07f8SJohn Marino /*ARGSUSED*/
vi_insert_at_bol(EditLine * el,wint_t c)30412db70c8Szrj vi_insert_at_bol(EditLine *el, wint_t c __attribute__((__unused__)))
30532fe07f8SJohn Marino {
30632fe07f8SJohn Marino 
30732fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.buffer;
30832fe07f8SJohn Marino 	cv_undo(el);
30932fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
31032fe07f8SJohn Marino 	return CC_CURSOR;
31132fe07f8SJohn Marino }
31232fe07f8SJohn Marino 
31332fe07f8SJohn Marino 
31432fe07f8SJohn Marino /* vi_replace_char():
31532fe07f8SJohn Marino  *	Vi replace character under the cursor with the next character typed
31632fe07f8SJohn Marino  *	[r]
31732fe07f8SJohn Marino  */
31812db70c8Szrj libedit_private el_action_t
31932fe07f8SJohn Marino /*ARGSUSED*/
vi_replace_char(EditLine * el,wint_t c)32012db70c8Szrj vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__)))
32132fe07f8SJohn Marino {
32232fe07f8SJohn Marino 
32332fe07f8SJohn Marino 	if (el->el_line.cursor >= el->el_line.lastchar)
32432fe07f8SJohn Marino 		return CC_ERROR;
32532fe07f8SJohn Marino 
32632fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
32732fe07f8SJohn Marino 	el->el_state.inputmode = MODE_REPLACE_1;
32832fe07f8SJohn Marino 	cv_undo(el);
32932fe07f8SJohn Marino 	return CC_ARGHACK;
33032fe07f8SJohn Marino }
33132fe07f8SJohn Marino 
33232fe07f8SJohn Marino 
33332fe07f8SJohn Marino /* vi_replace_mode():
33432fe07f8SJohn Marino  *	Vi enter replace mode
33532fe07f8SJohn Marino  *	[R]
33632fe07f8SJohn Marino  */
33712db70c8Szrj libedit_private el_action_t
33832fe07f8SJohn Marino /*ARGSUSED*/
vi_replace_mode(EditLine * el,wint_t c)33912db70c8Szrj vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__)))
34032fe07f8SJohn Marino {
34132fe07f8SJohn Marino 
34232fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
34332fe07f8SJohn Marino 	el->el_state.inputmode = MODE_REPLACE;
34432fe07f8SJohn Marino 	cv_undo(el);
34532fe07f8SJohn Marino 	return CC_NORM;
34632fe07f8SJohn Marino }
34732fe07f8SJohn Marino 
34832fe07f8SJohn Marino 
34932fe07f8SJohn Marino /* vi_substitute_char():
35032fe07f8SJohn Marino  *	Vi replace character under the cursor and enter insert mode
35132fe07f8SJohn Marino  *	[s]
35232fe07f8SJohn Marino  */
35312db70c8Szrj libedit_private el_action_t
35432fe07f8SJohn Marino /*ARGSUSED*/
vi_substitute_char(EditLine * el,wint_t c)35512db70c8Szrj vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__)))
35632fe07f8SJohn Marino {
35732fe07f8SJohn Marino 
35832fe07f8SJohn Marino 	c_delafter(el, el->el_state.argument);
35932fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
36032fe07f8SJohn Marino 	return CC_REFRESH;
36132fe07f8SJohn Marino }
36232fe07f8SJohn Marino 
36332fe07f8SJohn Marino 
36432fe07f8SJohn Marino /* vi_substitute_line():
36532fe07f8SJohn Marino  *	Vi substitute entire line
36632fe07f8SJohn Marino  *	[S]
36732fe07f8SJohn Marino  */
36812db70c8Szrj libedit_private el_action_t
36932fe07f8SJohn Marino /*ARGSUSED*/
vi_substitute_line(EditLine * el,wint_t c)37012db70c8Szrj vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__)))
37132fe07f8SJohn Marino {
37232fe07f8SJohn Marino 
37332fe07f8SJohn Marino 	cv_undo(el);
37432fe07f8SJohn Marino 	cv_yank(el, el->el_line.buffer,
37532fe07f8SJohn Marino 	    (int)(el->el_line.lastchar - el->el_line.buffer));
37632fe07f8SJohn Marino 	(void) em_kill_line(el, 0);
37732fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
37832fe07f8SJohn Marino 	return CC_REFRESH;
37932fe07f8SJohn Marino }
38032fe07f8SJohn Marino 
38132fe07f8SJohn Marino 
38232fe07f8SJohn Marino /* vi_change_to_eol():
38332fe07f8SJohn Marino  *	Vi change to end of line
38432fe07f8SJohn Marino  *	[C]
38532fe07f8SJohn Marino  */
38612db70c8Szrj libedit_private el_action_t
38732fe07f8SJohn Marino /*ARGSUSED*/
vi_change_to_eol(EditLine * el,wint_t c)38812db70c8Szrj vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__)))
38932fe07f8SJohn Marino {
39032fe07f8SJohn Marino 
39132fe07f8SJohn Marino 	cv_undo(el);
39232fe07f8SJohn Marino 	cv_yank(el, el->el_line.cursor,
39332fe07f8SJohn Marino 	    (int)(el->el_line.lastchar - el->el_line.cursor));
39432fe07f8SJohn Marino 	(void) ed_kill_line(el, 0);
39532fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
39632fe07f8SJohn Marino 	return CC_REFRESH;
39732fe07f8SJohn Marino }
39832fe07f8SJohn Marino 
39932fe07f8SJohn Marino 
40032fe07f8SJohn Marino /* vi_insert():
40132fe07f8SJohn Marino  *	Vi enter insert mode
40232fe07f8SJohn Marino  *	[i]
40332fe07f8SJohn Marino  */
40412db70c8Szrj libedit_private el_action_t
40532fe07f8SJohn Marino /*ARGSUSED*/
vi_insert(EditLine * el,wint_t c)40612db70c8Szrj vi_insert(EditLine *el, wint_t c __attribute__((__unused__)))
40732fe07f8SJohn Marino {
40832fe07f8SJohn Marino 
40932fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
41032fe07f8SJohn Marino 	cv_undo(el);
41132fe07f8SJohn Marino 	return CC_NORM;
41232fe07f8SJohn Marino }
41332fe07f8SJohn Marino 
41432fe07f8SJohn Marino 
41532fe07f8SJohn Marino /* vi_add():
41632fe07f8SJohn Marino  *	Vi enter insert mode after the cursor
41732fe07f8SJohn Marino  *	[a]
41832fe07f8SJohn Marino  */
41912db70c8Szrj libedit_private el_action_t
42032fe07f8SJohn Marino /*ARGSUSED*/
vi_add(EditLine * el,wint_t c)42112db70c8Szrj vi_add(EditLine *el, wint_t c __attribute__((__unused__)))
42232fe07f8SJohn Marino {
42332fe07f8SJohn Marino 	int ret;
42432fe07f8SJohn Marino 
42532fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
42632fe07f8SJohn Marino 	if (el->el_line.cursor < el->el_line.lastchar) {
42732fe07f8SJohn Marino 		el->el_line.cursor++;
42832fe07f8SJohn Marino 		if (el->el_line.cursor > el->el_line.lastchar)
42932fe07f8SJohn Marino 			el->el_line.cursor = el->el_line.lastchar;
43032fe07f8SJohn Marino 		ret = CC_CURSOR;
43132fe07f8SJohn Marino 	} else
43232fe07f8SJohn Marino 		ret = CC_NORM;
43332fe07f8SJohn Marino 
43432fe07f8SJohn Marino 	cv_undo(el);
43532fe07f8SJohn Marino 
43632fe07f8SJohn Marino 	return (el_action_t)ret;
43732fe07f8SJohn Marino }
43832fe07f8SJohn Marino 
43932fe07f8SJohn Marino 
44032fe07f8SJohn Marino /* vi_add_at_eol():
44132fe07f8SJohn Marino  *	Vi enter insert mode at end of line
44232fe07f8SJohn Marino  *	[A]
44332fe07f8SJohn Marino  */
44412db70c8Szrj libedit_private el_action_t
44532fe07f8SJohn Marino /*ARGSUSED*/
vi_add_at_eol(EditLine * el,wint_t c)44612db70c8Szrj vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__)))
44732fe07f8SJohn Marino {
44832fe07f8SJohn Marino 
44932fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
45032fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.lastchar;
45132fe07f8SJohn Marino 	cv_undo(el);
45232fe07f8SJohn Marino 	return CC_CURSOR;
45332fe07f8SJohn Marino }
45432fe07f8SJohn Marino 
45532fe07f8SJohn Marino 
45632fe07f8SJohn Marino /* vi_delete_meta():
45732fe07f8SJohn Marino  *	Vi delete prefix command
45832fe07f8SJohn Marino  *	[d]
45932fe07f8SJohn Marino  */
46012db70c8Szrj libedit_private el_action_t
46132fe07f8SJohn Marino /*ARGSUSED*/
vi_delete_meta(EditLine * el,wint_t c)46212db70c8Szrj vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__)))
46332fe07f8SJohn Marino {
46432fe07f8SJohn Marino 
46532fe07f8SJohn Marino 	return cv_action(el, DELETE);
46632fe07f8SJohn Marino }
46732fe07f8SJohn Marino 
46832fe07f8SJohn Marino 
46932fe07f8SJohn Marino /* vi_end_big_word():
47032fe07f8SJohn Marino  *	Vi move to the end of the current space delimited word
47132fe07f8SJohn Marino  *	[E]
47232fe07f8SJohn Marino  */
47312db70c8Szrj libedit_private el_action_t
47432fe07f8SJohn Marino /*ARGSUSED*/
vi_end_big_word(EditLine * el,wint_t c)47512db70c8Szrj vi_end_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
47632fe07f8SJohn Marino {
47732fe07f8SJohn Marino 
47832fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.lastchar)
47932fe07f8SJohn Marino 		return CC_ERROR;
48032fe07f8SJohn Marino 
48132fe07f8SJohn Marino 	el->el_line.cursor = cv__endword(el->el_line.cursor,
48232fe07f8SJohn Marino 	    el->el_line.lastchar, el->el_state.argument, cv__isWord);
48332fe07f8SJohn Marino 
48432fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
48532fe07f8SJohn Marino 		el->el_line.cursor++;
48632fe07f8SJohn Marino 		cv_delfini(el);
48732fe07f8SJohn Marino 		return CC_REFRESH;
48832fe07f8SJohn Marino 	}
48932fe07f8SJohn Marino 	return CC_CURSOR;
49032fe07f8SJohn Marino }
49132fe07f8SJohn Marino 
49232fe07f8SJohn Marino 
49332fe07f8SJohn Marino /* vi_end_word():
49432fe07f8SJohn Marino  *	Vi move to the end of the current word
49532fe07f8SJohn Marino  *	[e]
49632fe07f8SJohn Marino  */
49712db70c8Szrj libedit_private el_action_t
49832fe07f8SJohn Marino /*ARGSUSED*/
vi_end_word(EditLine * el,wint_t c)49912db70c8Szrj vi_end_word(EditLine *el, wint_t c __attribute__((__unused__)))
50032fe07f8SJohn Marino {
50132fe07f8SJohn Marino 
50232fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.lastchar)
50332fe07f8SJohn Marino 		return CC_ERROR;
50432fe07f8SJohn Marino 
50532fe07f8SJohn Marino 	el->el_line.cursor = cv__endword(el->el_line.cursor,
50632fe07f8SJohn Marino 	    el->el_line.lastchar, el->el_state.argument, cv__isword);
50732fe07f8SJohn Marino 
50832fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
50932fe07f8SJohn Marino 		el->el_line.cursor++;
51032fe07f8SJohn Marino 		cv_delfini(el);
51132fe07f8SJohn Marino 		return CC_REFRESH;
51232fe07f8SJohn Marino 	}
51332fe07f8SJohn Marino 	return CC_CURSOR;
51432fe07f8SJohn Marino }
51532fe07f8SJohn Marino 
51632fe07f8SJohn Marino 
51732fe07f8SJohn Marino /* vi_undo():
51832fe07f8SJohn Marino  *	Vi undo last change
51932fe07f8SJohn Marino  *	[u]
52032fe07f8SJohn Marino  */
52112db70c8Szrj libedit_private el_action_t
52232fe07f8SJohn Marino /*ARGSUSED*/
vi_undo(EditLine * el,wint_t c)52312db70c8Szrj vi_undo(EditLine *el, wint_t c __attribute__((__unused__)))
52432fe07f8SJohn Marino {
52532fe07f8SJohn Marino 	c_undo_t un = el->el_chared.c_undo;
52632fe07f8SJohn Marino 
52732fe07f8SJohn Marino 	if (un.len == -1)
52832fe07f8SJohn Marino 		return CC_ERROR;
52932fe07f8SJohn Marino 
53032fe07f8SJohn Marino 	/* switch line buffer and undo buffer */
53132fe07f8SJohn Marino 	el->el_chared.c_undo.buf = el->el_line.buffer;
53232fe07f8SJohn Marino 	el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
53332fe07f8SJohn Marino 	el->el_chared.c_undo.cursor =
53432fe07f8SJohn Marino 	    (int)(el->el_line.cursor - el->el_line.buffer);
53532fe07f8SJohn Marino 	el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
53632fe07f8SJohn Marino 	el->el_line.buffer = un.buf;
53732fe07f8SJohn Marino 	el->el_line.cursor = un.buf + un.cursor;
53832fe07f8SJohn Marino 	el->el_line.lastchar = un.buf + un.len;
53932fe07f8SJohn Marino 
54032fe07f8SJohn Marino 	return CC_REFRESH;
54132fe07f8SJohn Marino }
54232fe07f8SJohn Marino 
54332fe07f8SJohn Marino 
54432fe07f8SJohn Marino /* vi_command_mode():
54532fe07f8SJohn Marino  *	Vi enter command mode (use alternative key bindings)
54632fe07f8SJohn Marino  *	[<ESC>]
54732fe07f8SJohn Marino  */
54812db70c8Szrj libedit_private el_action_t
54932fe07f8SJohn Marino /*ARGSUSED*/
vi_command_mode(EditLine * el,wint_t c)55012db70c8Szrj vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__)))
55132fe07f8SJohn Marino {
55232fe07f8SJohn Marino 
55332fe07f8SJohn Marino 	/* [Esc] cancels pending action */
55432fe07f8SJohn Marino 	el->el_chared.c_vcmd.action = NOP;
55532fe07f8SJohn Marino 	el->el_chared.c_vcmd.pos = 0;
55632fe07f8SJohn Marino 
55732fe07f8SJohn Marino 	el->el_state.doingarg = 0;
55832fe07f8SJohn Marino 
55932fe07f8SJohn Marino 	el->el_state.inputmode = MODE_INSERT;
56032fe07f8SJohn Marino 	el->el_map.current = el->el_map.alt;
56132fe07f8SJohn Marino #ifdef VI_MOVE
56232fe07f8SJohn Marino 	if (el->el_line.cursor > el->el_line.buffer)
56332fe07f8SJohn Marino 		el->el_line.cursor--;
56432fe07f8SJohn Marino #endif
56532fe07f8SJohn Marino 	return CC_CURSOR;
56632fe07f8SJohn Marino }
56732fe07f8SJohn Marino 
56832fe07f8SJohn Marino 
56932fe07f8SJohn Marino /* vi_zero():
57032fe07f8SJohn Marino  *	Vi move to the beginning of line
57132fe07f8SJohn Marino  *	[0]
57232fe07f8SJohn Marino  */
57312db70c8Szrj libedit_private el_action_t
vi_zero(EditLine * el,wint_t c)57412db70c8Szrj vi_zero(EditLine *el, wint_t c)
57532fe07f8SJohn Marino {
57632fe07f8SJohn Marino 
57732fe07f8SJohn Marino 	if (el->el_state.doingarg)
57832fe07f8SJohn Marino 		return ed_argument_digit(el, c);
57932fe07f8SJohn Marino 
58032fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.buffer;
58132fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
58232fe07f8SJohn Marino 		cv_delfini(el);
58332fe07f8SJohn Marino 		return CC_REFRESH;
58432fe07f8SJohn Marino 	}
58532fe07f8SJohn Marino 	return CC_CURSOR;
58632fe07f8SJohn Marino }
58732fe07f8SJohn Marino 
58832fe07f8SJohn Marino 
58932fe07f8SJohn Marino /* vi_delete_prev_char():
59032fe07f8SJohn Marino  *	Vi move to previous character (backspace)
59132fe07f8SJohn Marino  *	[^H] in insert mode only
59232fe07f8SJohn Marino  */
59312db70c8Szrj libedit_private el_action_t
59432fe07f8SJohn Marino /*ARGSUSED*/
vi_delete_prev_char(EditLine * el,wint_t c)59512db70c8Szrj vi_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
59632fe07f8SJohn Marino {
59732fe07f8SJohn Marino 
59832fe07f8SJohn Marino 	if (el->el_line.cursor <= el->el_line.buffer)
59932fe07f8SJohn Marino 		return CC_ERROR;
60032fe07f8SJohn Marino 
60132fe07f8SJohn Marino 	c_delbefore1(el);
60232fe07f8SJohn Marino 	el->el_line.cursor--;
60332fe07f8SJohn Marino 	return CC_REFRESH;
60432fe07f8SJohn Marino }
60532fe07f8SJohn Marino 
60632fe07f8SJohn Marino 
60732fe07f8SJohn Marino /* vi_list_or_eof():
60832fe07f8SJohn Marino  *	Vi list choices for completion or indicate end of file if empty line
60932fe07f8SJohn Marino  *	[^D]
61032fe07f8SJohn Marino  */
61112db70c8Szrj libedit_private el_action_t
61232fe07f8SJohn Marino /*ARGSUSED*/
vi_list_or_eof(EditLine * el,wint_t c)61312db70c8Szrj vi_list_or_eof(EditLine *el, wint_t c)
61432fe07f8SJohn Marino {
61532fe07f8SJohn Marino 
61632fe07f8SJohn Marino 	if (el->el_line.cursor == el->el_line.lastchar) {
61732fe07f8SJohn Marino 		if (el->el_line.cursor == el->el_line.buffer) {
61832fe07f8SJohn Marino 			terminal_writec(el, c);	/* then do a EOF */
61932fe07f8SJohn Marino 			return CC_EOF;
62032fe07f8SJohn Marino 		} else {
62132fe07f8SJohn Marino 			/*
62232fe07f8SJohn Marino 			 * Here we could list completions, but it is an
62332fe07f8SJohn Marino 			 * error right now
62432fe07f8SJohn Marino 			 */
62532fe07f8SJohn Marino 			terminal_beep(el);
62632fe07f8SJohn Marino 			return CC_ERROR;
62732fe07f8SJohn Marino 		}
62832fe07f8SJohn Marino 	} else {
62932fe07f8SJohn Marino #ifdef notyet
63032fe07f8SJohn Marino 		re_goto_bottom(el);
63132fe07f8SJohn Marino 		*el->el_line.lastchar = '\0';	/* just in case */
63232fe07f8SJohn Marino 		return CC_LIST_CHOICES;
63332fe07f8SJohn Marino #else
63432fe07f8SJohn Marino 		/*
63532fe07f8SJohn Marino 		 * Just complain for now.
63632fe07f8SJohn Marino 		 */
63732fe07f8SJohn Marino 		terminal_beep(el);
63832fe07f8SJohn Marino 		return CC_ERROR;
63932fe07f8SJohn Marino #endif
64032fe07f8SJohn Marino 	}
64132fe07f8SJohn Marino }
64232fe07f8SJohn Marino 
64332fe07f8SJohn Marino 
64432fe07f8SJohn Marino /* vi_kill_line_prev():
64532fe07f8SJohn Marino  *	Vi cut from beginning of line to cursor
64632fe07f8SJohn Marino  *	[^U]
64732fe07f8SJohn Marino  */
64812db70c8Szrj libedit_private el_action_t
64932fe07f8SJohn Marino /*ARGSUSED*/
vi_kill_line_prev(EditLine * el,wint_t c)65012db70c8Szrj vi_kill_line_prev(EditLine *el, wint_t c __attribute__((__unused__)))
65132fe07f8SJohn Marino {
65212db70c8Szrj 	wchar_t *kp, *cp;
65332fe07f8SJohn Marino 
65432fe07f8SJohn Marino 	cp = el->el_line.buffer;
65532fe07f8SJohn Marino 	kp = el->el_chared.c_kill.buf;
65632fe07f8SJohn Marino 	while (cp < el->el_line.cursor)
65732fe07f8SJohn Marino 		*kp++ = *cp++;	/* copy it */
65832fe07f8SJohn Marino 	el->el_chared.c_kill.last = kp;
65932fe07f8SJohn Marino 	c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
66032fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.buffer;	/* zap! */
66132fe07f8SJohn Marino 	return CC_REFRESH;
66232fe07f8SJohn Marino }
66332fe07f8SJohn Marino 
66432fe07f8SJohn Marino 
66532fe07f8SJohn Marino /* vi_search_prev():
66632fe07f8SJohn Marino  *	Vi search history previous
66732fe07f8SJohn Marino  *	[?]
66832fe07f8SJohn Marino  */
66912db70c8Szrj libedit_private el_action_t
67032fe07f8SJohn Marino /*ARGSUSED*/
vi_search_prev(EditLine * el,wint_t c)67112db70c8Szrj vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
67232fe07f8SJohn Marino {
67332fe07f8SJohn Marino 
67432fe07f8SJohn Marino 	return cv_search(el, ED_SEARCH_PREV_HISTORY);
67532fe07f8SJohn Marino }
67632fe07f8SJohn Marino 
67732fe07f8SJohn Marino 
67832fe07f8SJohn Marino /* vi_search_next():
67932fe07f8SJohn Marino  *	Vi search history next
68032fe07f8SJohn Marino  *	[/]
68132fe07f8SJohn Marino  */
68212db70c8Szrj libedit_private el_action_t
68332fe07f8SJohn Marino /*ARGSUSED*/
vi_search_next(EditLine * el,wint_t c)68412db70c8Szrj vi_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
68532fe07f8SJohn Marino {
68632fe07f8SJohn Marino 
68732fe07f8SJohn Marino 	return cv_search(el, ED_SEARCH_NEXT_HISTORY);
68832fe07f8SJohn Marino }
68932fe07f8SJohn Marino 
69032fe07f8SJohn Marino 
69132fe07f8SJohn Marino /* vi_repeat_search_next():
69232fe07f8SJohn Marino  *	Vi repeat current search in the same search direction
69332fe07f8SJohn Marino  *	[n]
69432fe07f8SJohn Marino  */
69512db70c8Szrj libedit_private el_action_t
69632fe07f8SJohn Marino /*ARGSUSED*/
vi_repeat_search_next(EditLine * el,wint_t c)69712db70c8Szrj vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
69832fe07f8SJohn Marino {
69932fe07f8SJohn Marino 
70032fe07f8SJohn Marino 	if (el->el_search.patlen == 0)
70132fe07f8SJohn Marino 		return CC_ERROR;
70232fe07f8SJohn Marino 	else
70332fe07f8SJohn Marino 		return cv_repeat_srch(el, el->el_search.patdir);
70432fe07f8SJohn Marino }
70532fe07f8SJohn Marino 
70632fe07f8SJohn Marino 
70732fe07f8SJohn Marino /* vi_repeat_search_prev():
70832fe07f8SJohn Marino  *	Vi repeat current search in the opposite search direction
70932fe07f8SJohn Marino  *	[N]
71032fe07f8SJohn Marino  */
71132fe07f8SJohn Marino /*ARGSUSED*/
71212db70c8Szrj libedit_private el_action_t
vi_repeat_search_prev(EditLine * el,wint_t c)71312db70c8Szrj vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
71432fe07f8SJohn Marino {
71532fe07f8SJohn Marino 
71632fe07f8SJohn Marino 	if (el->el_search.patlen == 0)
71732fe07f8SJohn Marino 		return CC_ERROR;
71832fe07f8SJohn Marino 	else
71932fe07f8SJohn Marino 		return (cv_repeat_srch(el,
72032fe07f8SJohn Marino 		    el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
72132fe07f8SJohn Marino 		    ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
72232fe07f8SJohn Marino }
72332fe07f8SJohn Marino 
72432fe07f8SJohn Marino 
72532fe07f8SJohn Marino /* vi_next_char():
72632fe07f8SJohn Marino  *	Vi move to the character specified next
72732fe07f8SJohn Marino  *	[f]
72832fe07f8SJohn Marino  */
72912db70c8Szrj libedit_private el_action_t
73032fe07f8SJohn Marino /*ARGSUSED*/
vi_next_char(EditLine * el,wint_t c)73112db70c8Szrj vi_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
73232fe07f8SJohn Marino {
73332fe07f8SJohn Marino 	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
73432fe07f8SJohn Marino }
73532fe07f8SJohn Marino 
73632fe07f8SJohn Marino 
73732fe07f8SJohn Marino /* vi_prev_char():
73832fe07f8SJohn Marino  *	Vi move to the character specified previous
73932fe07f8SJohn Marino  *	[F]
74032fe07f8SJohn Marino  */
74112db70c8Szrj libedit_private el_action_t
74232fe07f8SJohn Marino /*ARGSUSED*/
vi_prev_char(EditLine * el,wint_t c)74312db70c8Szrj vi_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
74432fe07f8SJohn Marino {
74532fe07f8SJohn Marino 	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
74632fe07f8SJohn Marino }
74732fe07f8SJohn Marino 
74832fe07f8SJohn Marino 
74932fe07f8SJohn Marino /* vi_to_next_char():
75032fe07f8SJohn Marino  *	Vi move up to the character specified next
75132fe07f8SJohn Marino  *	[t]
75232fe07f8SJohn Marino  */
75312db70c8Szrj libedit_private el_action_t
75432fe07f8SJohn Marino /*ARGSUSED*/
vi_to_next_char(EditLine * el,wint_t c)75512db70c8Szrj vi_to_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
75632fe07f8SJohn Marino {
75732fe07f8SJohn Marino 	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
75832fe07f8SJohn Marino }
75932fe07f8SJohn Marino 
76032fe07f8SJohn Marino 
76132fe07f8SJohn Marino /* vi_to_prev_char():
76232fe07f8SJohn Marino  *	Vi move up to the character specified previous
76332fe07f8SJohn Marino  *	[T]
76432fe07f8SJohn Marino  */
76512db70c8Szrj libedit_private el_action_t
76632fe07f8SJohn Marino /*ARGSUSED*/
vi_to_prev_char(EditLine * el,wint_t c)76712db70c8Szrj vi_to_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
76832fe07f8SJohn Marino {
76932fe07f8SJohn Marino 	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
77032fe07f8SJohn Marino }
77132fe07f8SJohn Marino 
77232fe07f8SJohn Marino 
77332fe07f8SJohn Marino /* vi_repeat_next_char():
77432fe07f8SJohn Marino  *	Vi repeat current character search in the same search direction
77532fe07f8SJohn Marino  *	[;]
77632fe07f8SJohn Marino  */
77712db70c8Szrj libedit_private el_action_t
77832fe07f8SJohn Marino /*ARGSUSED*/
vi_repeat_next_char(EditLine * el,wint_t c)77912db70c8Szrj vi_repeat_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
78032fe07f8SJohn Marino {
78132fe07f8SJohn Marino 
78232fe07f8SJohn Marino 	return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
78332fe07f8SJohn Marino 		el->el_state.argument, el->el_search.chatflg);
78432fe07f8SJohn Marino }
78532fe07f8SJohn Marino 
78632fe07f8SJohn Marino 
78732fe07f8SJohn Marino /* vi_repeat_prev_char():
78832fe07f8SJohn Marino  *	Vi repeat current character search in the opposite search direction
78932fe07f8SJohn Marino  *	[,]
79032fe07f8SJohn Marino  */
79112db70c8Szrj libedit_private el_action_t
79232fe07f8SJohn Marino /*ARGSUSED*/
vi_repeat_prev_char(EditLine * el,wint_t c)79312db70c8Szrj vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
79432fe07f8SJohn Marino {
79532fe07f8SJohn Marino 	el_action_t r;
79632fe07f8SJohn Marino 	int dir = el->el_search.chadir;
79732fe07f8SJohn Marino 
79832fe07f8SJohn Marino 	r = cv_csearch(el, -dir, el->el_search.chacha,
79932fe07f8SJohn Marino 		el->el_state.argument, el->el_search.chatflg);
80032fe07f8SJohn Marino 	el->el_search.chadir = dir;
80132fe07f8SJohn Marino 	return r;
80232fe07f8SJohn Marino }
80332fe07f8SJohn Marino 
80432fe07f8SJohn Marino 
80532fe07f8SJohn Marino /* vi_match():
80632fe07f8SJohn Marino  *	Vi go to matching () {} or []
80732fe07f8SJohn Marino  *	[%]
80832fe07f8SJohn Marino  */
80912db70c8Szrj libedit_private el_action_t
81032fe07f8SJohn Marino /*ARGSUSED*/
vi_match(EditLine * el,wint_t c)81112db70c8Szrj vi_match(EditLine *el, wint_t c __attribute__((__unused__)))
81232fe07f8SJohn Marino {
81312db70c8Szrj 	const wchar_t match_chars[] = L"()[]{}";
81412db70c8Szrj 	wchar_t *cp;
81532fe07f8SJohn Marino 	size_t delta, i, count;
81612db70c8Szrj 	wchar_t o_ch, c_ch;
81732fe07f8SJohn Marino 
81832fe07f8SJohn Marino 	*el->el_line.lastchar = '\0';		/* just in case */
81932fe07f8SJohn Marino 
82012db70c8Szrj 	i = wcscspn(el->el_line.cursor, match_chars);
82132fe07f8SJohn Marino 	o_ch = el->el_line.cursor[i];
82232fe07f8SJohn Marino 	if (o_ch == 0)
82332fe07f8SJohn Marino 		return CC_ERROR;
82412db70c8Szrj 	delta = (size_t)(wcschr(match_chars, o_ch) - match_chars);
82532fe07f8SJohn Marino 	c_ch = match_chars[delta ^ 1];
82632fe07f8SJohn Marino 	count = 1;
82732fe07f8SJohn Marino 	delta = 1 - (delta & 1) * 2;
82832fe07f8SJohn Marino 
82932fe07f8SJohn Marino 	for (cp = &el->el_line.cursor[i]; count; ) {
83032fe07f8SJohn Marino 		cp += delta;
83132fe07f8SJohn Marino 		if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
83232fe07f8SJohn Marino 			return CC_ERROR;
83332fe07f8SJohn Marino 		if (*cp == o_ch)
83432fe07f8SJohn Marino 			count++;
83532fe07f8SJohn Marino 		else if (*cp == c_ch)
83632fe07f8SJohn Marino 			count--;
83732fe07f8SJohn Marino 	}
83832fe07f8SJohn Marino 
83932fe07f8SJohn Marino 	el->el_line.cursor = cp;
84032fe07f8SJohn Marino 
84132fe07f8SJohn Marino 	if (el->el_chared.c_vcmd.action != NOP) {
84232fe07f8SJohn Marino 		/* NB posix says char under cursor should NOT be deleted
84332fe07f8SJohn Marino 		   for -ve delta - this is different to netbsd vi. */
84432fe07f8SJohn Marino 		if (delta > 0)
84532fe07f8SJohn Marino 			el->el_line.cursor++;
84632fe07f8SJohn Marino 		cv_delfini(el);
84732fe07f8SJohn Marino 		return CC_REFRESH;
84832fe07f8SJohn Marino 	}
84932fe07f8SJohn Marino 	return CC_CURSOR;
85032fe07f8SJohn Marino }
85132fe07f8SJohn Marino 
85232fe07f8SJohn Marino /* vi_undo_line():
85332fe07f8SJohn Marino  *	Vi undo all changes to line
85432fe07f8SJohn Marino  *	[U]
85532fe07f8SJohn Marino  */
85612db70c8Szrj libedit_private el_action_t
85732fe07f8SJohn Marino /*ARGSUSED*/
vi_undo_line(EditLine * el,wint_t c)85812db70c8Szrj vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__)))
85932fe07f8SJohn Marino {
86032fe07f8SJohn Marino 
86132fe07f8SJohn Marino 	cv_undo(el);
86232fe07f8SJohn Marino 	return hist_get(el);
86332fe07f8SJohn Marino }
86432fe07f8SJohn Marino 
86532fe07f8SJohn Marino /* vi_to_column():
86632fe07f8SJohn Marino  *	Vi go to specified column
86732fe07f8SJohn Marino  *	[|]
86832fe07f8SJohn Marino  * NB netbsd vi goes to screen column 'n', posix says nth character
86932fe07f8SJohn Marino  */
87012db70c8Szrj libedit_private el_action_t
87132fe07f8SJohn Marino /*ARGSUSED*/
vi_to_column(EditLine * el,wint_t c)87212db70c8Szrj vi_to_column(EditLine *el, wint_t c __attribute__((__unused__)))
87332fe07f8SJohn Marino {
87432fe07f8SJohn Marino 
87532fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.buffer;
87632fe07f8SJohn Marino 	el->el_state.argument--;
87732fe07f8SJohn Marino 	return ed_next_char(el, 0);
87832fe07f8SJohn Marino }
87932fe07f8SJohn Marino 
88032fe07f8SJohn Marino /* vi_yank_end():
88132fe07f8SJohn Marino  *	Vi yank to end of line
88232fe07f8SJohn Marino  *	[Y]
88332fe07f8SJohn Marino  */
88412db70c8Szrj libedit_private el_action_t
88532fe07f8SJohn Marino /*ARGSUSED*/
vi_yank_end(EditLine * el,wint_t c)88612db70c8Szrj vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__)))
88732fe07f8SJohn Marino {
88832fe07f8SJohn Marino 
88932fe07f8SJohn Marino 	cv_yank(el, el->el_line.cursor,
89032fe07f8SJohn Marino 	    (int)(el->el_line.lastchar - el->el_line.cursor));
89132fe07f8SJohn Marino 	return CC_REFRESH;
89232fe07f8SJohn Marino }
89332fe07f8SJohn Marino 
89432fe07f8SJohn Marino /* vi_yank():
89532fe07f8SJohn Marino  *	Vi yank
89632fe07f8SJohn Marino  *	[y]
89732fe07f8SJohn Marino  */
89812db70c8Szrj libedit_private el_action_t
89932fe07f8SJohn Marino /*ARGSUSED*/
vi_yank(EditLine * el,wint_t c)90012db70c8Szrj vi_yank(EditLine *el, wint_t c __attribute__((__unused__)))
90132fe07f8SJohn Marino {
90232fe07f8SJohn Marino 
90332fe07f8SJohn Marino 	return cv_action(el, YANK);
90432fe07f8SJohn Marino }
90532fe07f8SJohn Marino 
90632fe07f8SJohn Marino /* vi_comment_out():
90732fe07f8SJohn Marino  *	Vi comment out current command
90832fe07f8SJohn Marino  *	[#]
90932fe07f8SJohn Marino  */
91012db70c8Szrj libedit_private el_action_t
91132fe07f8SJohn Marino /*ARGSUSED*/
vi_comment_out(EditLine * el,wint_t c)91212db70c8Szrj vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__)))
91332fe07f8SJohn Marino {
91432fe07f8SJohn Marino 
91532fe07f8SJohn Marino 	el->el_line.cursor = el->el_line.buffer;
91632fe07f8SJohn Marino 	c_insert(el, 1);
91732fe07f8SJohn Marino 	*el->el_line.cursor = '#';
91832fe07f8SJohn Marino 	re_refresh(el);
91932fe07f8SJohn Marino 	return ed_newline(el, 0);
92032fe07f8SJohn Marino }
92132fe07f8SJohn Marino 
92232fe07f8SJohn Marino /* vi_alias():
92332fe07f8SJohn Marino  *	Vi include shell alias
92432fe07f8SJohn Marino  *	[@]
92532fe07f8SJohn Marino  * NB: posix implies that we should enter insert mode, however
92632fe07f8SJohn Marino  * this is against historical precedent...
92732fe07f8SJohn Marino  */
92812db70c8Szrj libedit_private el_action_t
92932fe07f8SJohn Marino /*ARGSUSED*/
vi_alias(EditLine * el,wint_t c)93012db70c8Szrj vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
93132fe07f8SJohn Marino {
93232fe07f8SJohn Marino 	char alias_name[3];
93384b940c1SJohn Marino 	const char *alias_text;
93432fe07f8SJohn Marino 
93584b940c1SJohn Marino 	if (el->el_chared.c_aliasfun == NULL)
93632fe07f8SJohn Marino 		return CC_ERROR;
93732fe07f8SJohn Marino 
93832fe07f8SJohn Marino 	alias_name[0] = '_';
93932fe07f8SJohn Marino 	alias_name[2] = 0;
94032fe07f8SJohn Marino 	if (el_getc(el, &alias_name[1]) != 1)
94132fe07f8SJohn Marino 		return CC_ERROR;
94232fe07f8SJohn Marino 
94384b940c1SJohn Marino 	alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg,
94484b940c1SJohn Marino 	    alias_name);
94532fe07f8SJohn Marino 	if (alias_text != NULL)
94612db70c8Szrj 		el_wpush(el, ct_decode_string(alias_text, &el->el_scratch));
94732fe07f8SJohn Marino 	return CC_NORM;
94832fe07f8SJohn Marino }
94932fe07f8SJohn Marino 
95032fe07f8SJohn Marino /* vi_to_history_line():
95132fe07f8SJohn Marino  *	Vi go to specified history file line.
95232fe07f8SJohn Marino  *	[G]
95332fe07f8SJohn Marino  */
95412db70c8Szrj libedit_private el_action_t
95532fe07f8SJohn Marino /*ARGSUSED*/
vi_to_history_line(EditLine * el,wint_t c)95612db70c8Szrj vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
95732fe07f8SJohn Marino {
95832fe07f8SJohn Marino 	int sv_event_no = el->el_history.eventno;
95932fe07f8SJohn Marino 	el_action_t rval;
96032fe07f8SJohn Marino 
96132fe07f8SJohn Marino 
96232fe07f8SJohn Marino 	if (el->el_history.eventno == 0) {
96312db70c8Szrj 		 (void) wcsncpy(el->el_history.buf, el->el_line.buffer,
96432fe07f8SJohn Marino 		     EL_BUFSIZ);
96532fe07f8SJohn Marino 		 el->el_history.last = el->el_history.buf +
96632fe07f8SJohn Marino 			 (el->el_line.lastchar - el->el_line.buffer);
96732fe07f8SJohn Marino 	}
96832fe07f8SJohn Marino 
96932fe07f8SJohn Marino 	/* Lack of a 'count' means oldest, not 1 */
97032fe07f8SJohn Marino 	if (!el->el_state.doingarg) {
97132fe07f8SJohn Marino 		el->el_history.eventno = 0x7fffffff;
97232fe07f8SJohn Marino 		hist_get(el);
97332fe07f8SJohn Marino 	} else {
97432fe07f8SJohn Marino 		/* This is brain dead, all the rest of this code counts
97532fe07f8SJohn Marino 		 * upwards going into the past.  Here we need count in the
97632fe07f8SJohn Marino 		 * other direction (to match the output of fc -l).
97732fe07f8SJohn Marino 		 * I could change the world, but this seems to suffice.
97832fe07f8SJohn Marino 		 */
97932fe07f8SJohn Marino 		el->el_history.eventno = 1;
98032fe07f8SJohn Marino 		if (hist_get(el) == CC_ERROR)
98132fe07f8SJohn Marino 			return CC_ERROR;
98232fe07f8SJohn Marino 		el->el_history.eventno = 1 + el->el_history.ev.num
98332fe07f8SJohn Marino 					- el->el_state.argument;
98432fe07f8SJohn Marino 		if (el->el_history.eventno < 0) {
98532fe07f8SJohn Marino 			el->el_history.eventno = sv_event_no;
98632fe07f8SJohn Marino 			return CC_ERROR;
98732fe07f8SJohn Marino 		}
98832fe07f8SJohn Marino 	}
98932fe07f8SJohn Marino 	rval = hist_get(el);
99032fe07f8SJohn Marino 	if (rval == CC_ERROR)
99132fe07f8SJohn Marino 		el->el_history.eventno = sv_event_no;
99232fe07f8SJohn Marino 	return rval;
99332fe07f8SJohn Marino }
99432fe07f8SJohn Marino 
99532fe07f8SJohn Marino /* vi_histedit():
99632fe07f8SJohn Marino  *	Vi edit history line with vi
99732fe07f8SJohn Marino  *	[v]
99832fe07f8SJohn Marino  */
99912db70c8Szrj libedit_private el_action_t
100032fe07f8SJohn Marino /*ARGSUSED*/
vi_histedit(EditLine * el,wint_t c)100112db70c8Szrj vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
100232fe07f8SJohn Marino {
100332fe07f8SJohn Marino 	int fd;
100432fe07f8SJohn Marino 	pid_t pid;
100532fe07f8SJohn Marino 	ssize_t st;
100632fe07f8SJohn Marino 	int status;
100732fe07f8SJohn Marino 	char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
100832fe07f8SJohn Marino 	char *cp = NULL;
100932fe07f8SJohn Marino 	size_t len;
101012db70c8Szrj 	wchar_t *line = NULL;
1011*cdf8408cSAntonio Huete Jimenez 	const char *editor;
101232fe07f8SJohn Marino 
101332fe07f8SJohn Marino 	if (el->el_state.doingarg) {
101432fe07f8SJohn Marino 		if (vi_to_history_line(el, 0) == CC_ERROR)
101532fe07f8SJohn Marino 			return CC_ERROR;
101632fe07f8SJohn Marino 	}
101732fe07f8SJohn Marino 
1018*cdf8408cSAntonio Huete Jimenez 	if ((editor = getenv("EDITOR")) == NULL)
1019*cdf8408cSAntonio Huete Jimenez 		editor = "vi";
102032fe07f8SJohn Marino 	fd = mkstemp(tempfile);
102132fe07f8SJohn Marino 	if (fd < 0)
102232fe07f8SJohn Marino 		return CC_ERROR;
102332fe07f8SJohn Marino 	len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
102432fe07f8SJohn Marino #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
102560ecde0cSDaniel Fojt 	cp = el_calloc(TMP_BUFSIZ, sizeof(*cp));
102632fe07f8SJohn Marino 	if (cp == NULL)
102732fe07f8SJohn Marino 		goto error;
102860ecde0cSDaniel Fojt 	line = el_calloc(len + 1, sizeof(*line));
102932fe07f8SJohn Marino 	if (line == NULL)
103032fe07f8SJohn Marino 		goto error;
103112db70c8Szrj 	wcsncpy(line, el->el_line.buffer, len);
103232fe07f8SJohn Marino 	line[len] = '\0';
103312db70c8Szrj 	wcstombs(cp, line, TMP_BUFSIZ - 1);
103432fe07f8SJohn Marino 	cp[TMP_BUFSIZ - 1] = '\0';
103532fe07f8SJohn Marino 	len = strlen(cp);
103632fe07f8SJohn Marino 	write(fd, cp, len);
103732fe07f8SJohn Marino 	write(fd, "\n", (size_t)1);
103832fe07f8SJohn Marino 	pid = fork();
103932fe07f8SJohn Marino 	switch (pid) {
104032fe07f8SJohn Marino 	case -1:
104132fe07f8SJohn Marino 		goto error;
104232fe07f8SJohn Marino 	case 0:
104332fe07f8SJohn Marino 		close(fd);
1044*cdf8408cSAntonio Huete Jimenez 		execlp(editor, editor, tempfile, (char *)NULL);
104532fe07f8SJohn Marino 		exit(0);
104632fe07f8SJohn Marino 		/*NOTREACHED*/
104732fe07f8SJohn Marino 	default:
104832fe07f8SJohn Marino 		while (waitpid(pid, &status, 0) != pid)
104932fe07f8SJohn Marino 			continue;
105032fe07f8SJohn Marino 		lseek(fd, (off_t)0, SEEK_SET);
105112db70c8Szrj 		st = read(fd, cp, TMP_BUFSIZ - 1);
105232fe07f8SJohn Marino 		if (st > 0) {
105312db70c8Szrj 			cp[st] = '\0';
105412db70c8Szrj 			len = (size_t)(el->el_line.limit - el->el_line.buffer);
105512db70c8Szrj 			len = mbstowcs(el->el_line.buffer, cp, len);
105632fe07f8SJohn Marino 			if (len > 0 && el->el_line.buffer[len - 1] == '\n')
105732fe07f8SJohn Marino 				--len;
105832fe07f8SJohn Marino 		}
105932fe07f8SJohn Marino 		else
106032fe07f8SJohn Marino 			len = 0;
106132fe07f8SJohn Marino                 el->el_line.cursor = el->el_line.buffer;
106232fe07f8SJohn Marino                 el->el_line.lastchar = el->el_line.buffer + len;
106332fe07f8SJohn Marino 		el_free(cp);
106432fe07f8SJohn Marino                 el_free(line);
106532fe07f8SJohn Marino 		break;
106632fe07f8SJohn Marino 	}
106732fe07f8SJohn Marino 
106832fe07f8SJohn Marino 	close(fd);
106932fe07f8SJohn Marino 	unlink(tempfile);
107032fe07f8SJohn Marino 	/* return CC_REFRESH; */
107132fe07f8SJohn Marino 	return ed_newline(el, 0);
107232fe07f8SJohn Marino error:
107332fe07f8SJohn Marino 	el_free(line);
107432fe07f8SJohn Marino 	el_free(cp);
107532fe07f8SJohn Marino 	close(fd);
107632fe07f8SJohn Marino 	unlink(tempfile);
107732fe07f8SJohn Marino 	return CC_ERROR;
107832fe07f8SJohn Marino }
107932fe07f8SJohn Marino 
108032fe07f8SJohn Marino /* vi_history_word():
108132fe07f8SJohn Marino  *	Vi append word from previous input line
108232fe07f8SJohn Marino  *	[_]
108332fe07f8SJohn Marino  * Who knows where this one came from!
108432fe07f8SJohn Marino  * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
108532fe07f8SJohn Marino  */
108612db70c8Szrj libedit_private el_action_t
108732fe07f8SJohn Marino /*ARGSUSED*/
vi_history_word(EditLine * el,wint_t c)108812db70c8Szrj vi_history_word(EditLine *el, wint_t c __attribute__((__unused__)))
108932fe07f8SJohn Marino {
109012db70c8Szrj 	const wchar_t *wp = HIST_FIRST(el);
109112db70c8Szrj 	const wchar_t *wep, *wsp;
109232fe07f8SJohn Marino 	int len;
109312db70c8Szrj 	wchar_t *cp;
109412db70c8Szrj 	const wchar_t *lim;
109532fe07f8SJohn Marino 
109632fe07f8SJohn Marino 	if (wp == NULL)
109732fe07f8SJohn Marino 		return CC_ERROR;
109832fe07f8SJohn Marino 
109912db70c8Szrj 	wep = wsp = NULL;
110032fe07f8SJohn Marino 	do {
110112db70c8Szrj 		while (iswspace(*wp))
110232fe07f8SJohn Marino 			wp++;
110332fe07f8SJohn Marino 		if (*wp == 0)
110432fe07f8SJohn Marino 			break;
110532fe07f8SJohn Marino 		wsp = wp;
110612db70c8Szrj 		while (*wp && !iswspace(*wp))
110732fe07f8SJohn Marino 			wp++;
110832fe07f8SJohn Marino 		wep = wp;
110932fe07f8SJohn Marino 	} while ((!el->el_state.doingarg || --el->el_state.argument > 0)
111032fe07f8SJohn Marino 	    && *wp != 0);
111132fe07f8SJohn Marino 
111212db70c8Szrj 	if (wsp == NULL || (el->el_state.doingarg && el->el_state.argument != 0))
111332fe07f8SJohn Marino 		return CC_ERROR;
111432fe07f8SJohn Marino 
111532fe07f8SJohn Marino 	cv_undo(el);
111632fe07f8SJohn Marino 	len = (int)(wep - wsp);
111732fe07f8SJohn Marino 	if (el->el_line.cursor < el->el_line.lastchar)
111832fe07f8SJohn Marino 		el->el_line.cursor++;
111932fe07f8SJohn Marino 	c_insert(el, len + 1);
112032fe07f8SJohn Marino 	cp = el->el_line.cursor;
112132fe07f8SJohn Marino 	lim = el->el_line.limit;
112232fe07f8SJohn Marino 	if (cp < lim)
112332fe07f8SJohn Marino 		*cp++ = ' ';
112432fe07f8SJohn Marino 	while (wsp < wep && cp < lim)
112532fe07f8SJohn Marino 		*cp++ = *wsp++;
112632fe07f8SJohn Marino 	el->el_line.cursor = cp;
112732fe07f8SJohn Marino 
112832fe07f8SJohn Marino 	el->el_map.current = el->el_map.key;
112932fe07f8SJohn Marino 	return CC_REFRESH;
113032fe07f8SJohn Marino }
113132fe07f8SJohn Marino 
113232fe07f8SJohn Marino /* vi_redo():
113332fe07f8SJohn Marino  *	Vi redo last non-motion command
113432fe07f8SJohn Marino  *	[.]
113532fe07f8SJohn Marino  */
113612db70c8Szrj libedit_private el_action_t
113732fe07f8SJohn Marino /*ARGSUSED*/
vi_redo(EditLine * el,wint_t c)113812db70c8Szrj vi_redo(EditLine *el, wint_t c __attribute__((__unused__)))
113932fe07f8SJohn Marino {
114032fe07f8SJohn Marino 	c_redo_t *r = &el->el_chared.c_redo;
114132fe07f8SJohn Marino 
114232fe07f8SJohn Marino 	if (!el->el_state.doingarg && r->count) {
114332fe07f8SJohn Marino 		el->el_state.doingarg = 1;
114432fe07f8SJohn Marino 		el->el_state.argument = r->count;
114532fe07f8SJohn Marino 	}
114632fe07f8SJohn Marino 
114732fe07f8SJohn Marino 	el->el_chared.c_vcmd.pos = el->el_line.cursor;
114832fe07f8SJohn Marino 	el->el_chared.c_vcmd.action = r->action;
114932fe07f8SJohn Marino 	if (r->pos != r->buf) {
115032fe07f8SJohn Marino 		if (r->pos + 1 > r->lim)
115132fe07f8SJohn Marino 			/* sanity */
115232fe07f8SJohn Marino 			r->pos = r->lim - 1;
115332fe07f8SJohn Marino 		r->pos[0] = 0;
115412db70c8Szrj 		el_wpush(el, r->buf);
115532fe07f8SJohn Marino 	}
115632fe07f8SJohn Marino 
115732fe07f8SJohn Marino 	el->el_state.thiscmd = r->cmd;
115832fe07f8SJohn Marino 	el->el_state.thisch = r->ch;
115932fe07f8SJohn Marino 	return (*el->el_map.func[r->cmd])(el, r->ch);
116032fe07f8SJohn Marino }
1161