xref: /minix3/lib/libedit/vi.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $	*/
23e1db26aSLionel Sambuc 
33e1db26aSLionel Sambuc /*-
43e1db26aSLionel Sambuc  * Copyright (c) 1992, 1993
53e1db26aSLionel Sambuc  *	The Regents of the University of California.  All rights reserved.
63e1db26aSLionel Sambuc  *
73e1db26aSLionel Sambuc  * This code is derived from software contributed to Berkeley by
83e1db26aSLionel Sambuc  * Christos Zoulas of Cornell University.
93e1db26aSLionel Sambuc  *
103e1db26aSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
113e1db26aSLionel Sambuc  * modification, are permitted provided that the following conditions
123e1db26aSLionel Sambuc  * are met:
133e1db26aSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
143e1db26aSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
153e1db26aSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
163e1db26aSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
173e1db26aSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
183e1db26aSLionel Sambuc  * 3. Neither the name of the University nor the names of its contributors
193e1db26aSLionel Sambuc  *    may be used to endorse or promote products derived from this software
203e1db26aSLionel Sambuc  *    without specific prior written permission.
213e1db26aSLionel Sambuc  *
223e1db26aSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233e1db26aSLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243e1db26aSLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253e1db26aSLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263e1db26aSLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273e1db26aSLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283e1db26aSLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293e1db26aSLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303e1db26aSLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313e1db26aSLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323e1db26aSLionel Sambuc  * SUCH DAMAGE.
333e1db26aSLionel Sambuc  */
343e1db26aSLionel Sambuc 
353e1db26aSLionel Sambuc #include "config.h"
363e1db26aSLionel Sambuc #include <stdlib.h>
373e1db26aSLionel Sambuc #include <unistd.h>
383e1db26aSLionel Sambuc #include <limits.h>
393e1db26aSLionel Sambuc #include <sys/wait.h>
403e1db26aSLionel Sambuc 
413e1db26aSLionel Sambuc #if !defined(lint) && !defined(SCCSID)
423e1db26aSLionel Sambuc #if 0
433e1db26aSLionel Sambuc static char sccsid[] = "@(#)vi.c	8.1 (Berkeley) 6/4/93";
443e1db26aSLionel Sambuc #else
45*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $");
463e1db26aSLionel Sambuc #endif
473e1db26aSLionel Sambuc #endif /* not lint && not SCCSID */
483e1db26aSLionel Sambuc 
493e1db26aSLionel Sambuc /*
503e1db26aSLionel Sambuc  * vi.c: Vi mode commands.
513e1db26aSLionel Sambuc  */
523e1db26aSLionel Sambuc #include "el.h"
533e1db26aSLionel Sambuc 
543e1db26aSLionel Sambuc private el_action_t	cv_action(EditLine *, Int);
553e1db26aSLionel Sambuc private el_action_t	cv_paste(EditLine *, Int);
563e1db26aSLionel Sambuc 
573e1db26aSLionel Sambuc /* cv_action():
583e1db26aSLionel Sambuc  *	Handle vi actions.
593e1db26aSLionel Sambuc  */
603e1db26aSLionel Sambuc private el_action_t
cv_action(EditLine * el,Int c)613e1db26aSLionel Sambuc cv_action(EditLine *el, Int c)
623e1db26aSLionel Sambuc {
633e1db26aSLionel Sambuc 
643e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
653e1db26aSLionel Sambuc 		/* 'cc', 'dd' and (possibly) friends */
663e1db26aSLionel Sambuc 		if (c != (Int)el->el_chared.c_vcmd.action)
673e1db26aSLionel Sambuc 			return CC_ERROR;
683e1db26aSLionel Sambuc 
693e1db26aSLionel Sambuc 		if (!(c & YANK))
703e1db26aSLionel Sambuc 			cv_undo(el);
713e1db26aSLionel Sambuc 		cv_yank(el, el->el_line.buffer,
723e1db26aSLionel Sambuc 		    (int)(el->el_line.lastchar - el->el_line.buffer));
733e1db26aSLionel Sambuc 		el->el_chared.c_vcmd.action = NOP;
743e1db26aSLionel Sambuc 		el->el_chared.c_vcmd.pos = 0;
753e1db26aSLionel Sambuc 		if (!(c & YANK)) {
763e1db26aSLionel Sambuc 			el->el_line.lastchar = el->el_line.buffer;
773e1db26aSLionel Sambuc 			el->el_line.cursor = el->el_line.buffer;
783e1db26aSLionel Sambuc 		}
793e1db26aSLionel Sambuc 		if (c & INSERT)
803e1db26aSLionel Sambuc 			el->el_map.current = el->el_map.key;
813e1db26aSLionel Sambuc 
823e1db26aSLionel Sambuc 		return CC_REFRESH;
833e1db26aSLionel Sambuc 	}
843e1db26aSLionel Sambuc 	el->el_chared.c_vcmd.pos = el->el_line.cursor;
853e1db26aSLionel Sambuc 	el->el_chared.c_vcmd.action = c;
863e1db26aSLionel Sambuc 	return CC_ARGHACK;
873e1db26aSLionel Sambuc }
883e1db26aSLionel Sambuc 
893e1db26aSLionel Sambuc /* cv_paste():
903e1db26aSLionel Sambuc  *	Paste previous deletion before or after the cursor
913e1db26aSLionel Sambuc  */
923e1db26aSLionel Sambuc private el_action_t
cv_paste(EditLine * el,Int c)933e1db26aSLionel Sambuc cv_paste(EditLine *el, Int c)
943e1db26aSLionel Sambuc {
953e1db26aSLionel Sambuc 	c_kill_t *k = &el->el_chared.c_kill;
963e1db26aSLionel Sambuc 	size_t len = (size_t)(k->last - k->buf);
973e1db26aSLionel Sambuc 
983e1db26aSLionel Sambuc 	if (k->buf == NULL || len == 0)
993e1db26aSLionel Sambuc 		return CC_ERROR;
1003e1db26aSLionel Sambuc #ifdef DEBUG_PASTE
1013e1db26aSLionel Sambuc 	(void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
1023e1db26aSLionel Sambuc #endif
1033e1db26aSLionel Sambuc 
1043e1db26aSLionel Sambuc 	cv_undo(el);
1053e1db26aSLionel Sambuc 
1063e1db26aSLionel Sambuc 	if (!c && el->el_line.cursor < el->el_line.lastchar)
1073e1db26aSLionel Sambuc 		el->el_line.cursor++;
1083e1db26aSLionel Sambuc 
1093e1db26aSLionel Sambuc 	c_insert(el, (int)len);
1103e1db26aSLionel Sambuc 	if (el->el_line.cursor + len > el->el_line.lastchar)
1113e1db26aSLionel Sambuc 		return CC_ERROR;
1123e1db26aSLionel Sambuc 	(void) memcpy(el->el_line.cursor, k->buf, len *
1133e1db26aSLionel Sambuc 	    sizeof(*el->el_line.cursor));
1143e1db26aSLionel Sambuc 
1153e1db26aSLionel Sambuc 	return CC_REFRESH;
1163e1db26aSLionel Sambuc }
1173e1db26aSLionel Sambuc 
1183e1db26aSLionel Sambuc 
1193e1db26aSLionel Sambuc /* vi_paste_next():
1203e1db26aSLionel Sambuc  *	Vi paste previous deletion to the right of the cursor
1213e1db26aSLionel Sambuc  *	[p]
1223e1db26aSLionel Sambuc  */
1233e1db26aSLionel Sambuc protected el_action_t
1243e1db26aSLionel Sambuc /*ARGSUSED*/
vi_paste_next(EditLine * el,Int c)1253e1db26aSLionel Sambuc vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
1263e1db26aSLionel Sambuc {
1273e1db26aSLionel Sambuc 
1283e1db26aSLionel Sambuc 	return cv_paste(el, 0);
1293e1db26aSLionel Sambuc }
1303e1db26aSLionel Sambuc 
1313e1db26aSLionel Sambuc 
1323e1db26aSLionel Sambuc /* vi_paste_prev():
1333e1db26aSLionel Sambuc  *	Vi paste previous deletion to the left of the cursor
1343e1db26aSLionel Sambuc  *	[P]
1353e1db26aSLionel Sambuc  */
1363e1db26aSLionel Sambuc protected el_action_t
1373e1db26aSLionel Sambuc /*ARGSUSED*/
vi_paste_prev(EditLine * el,Int c)1383e1db26aSLionel Sambuc vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
1393e1db26aSLionel Sambuc {
1403e1db26aSLionel Sambuc 
1413e1db26aSLionel Sambuc 	return cv_paste(el, 1);
1423e1db26aSLionel Sambuc }
1433e1db26aSLionel Sambuc 
1443e1db26aSLionel Sambuc 
1453e1db26aSLionel Sambuc /* vi_prev_big_word():
1463e1db26aSLionel Sambuc  *	Vi move to the previous space delimited word
1473e1db26aSLionel Sambuc  *	[B]
1483e1db26aSLionel Sambuc  */
1493e1db26aSLionel Sambuc protected el_action_t
1503e1db26aSLionel Sambuc /*ARGSUSED*/
vi_prev_big_word(EditLine * el,Int c)1513e1db26aSLionel Sambuc vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
1523e1db26aSLionel Sambuc {
1533e1db26aSLionel Sambuc 
1543e1db26aSLionel Sambuc 	if (el->el_line.cursor == el->el_line.buffer)
1553e1db26aSLionel Sambuc 		return CC_ERROR;
1563e1db26aSLionel Sambuc 
1573e1db26aSLionel Sambuc 	el->el_line.cursor = cv_prev_word(el->el_line.cursor,
1583e1db26aSLionel Sambuc 	    el->el_line.buffer,
1593e1db26aSLionel Sambuc 	    el->el_state.argument,
1603e1db26aSLionel Sambuc 	    cv__isWord);
1613e1db26aSLionel Sambuc 
1623e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
1633e1db26aSLionel Sambuc 		cv_delfini(el);
1643e1db26aSLionel Sambuc 		return CC_REFRESH;
1653e1db26aSLionel Sambuc 	}
1663e1db26aSLionel Sambuc 	return CC_CURSOR;
1673e1db26aSLionel Sambuc }
1683e1db26aSLionel Sambuc 
1693e1db26aSLionel Sambuc 
1703e1db26aSLionel Sambuc /* vi_prev_word():
1713e1db26aSLionel Sambuc  *	Vi move to the previous word
1723e1db26aSLionel Sambuc  *	[b]
1733e1db26aSLionel Sambuc  */
1743e1db26aSLionel Sambuc protected el_action_t
1753e1db26aSLionel Sambuc /*ARGSUSED*/
vi_prev_word(EditLine * el,Int c)1763e1db26aSLionel Sambuc vi_prev_word(EditLine *el, Int c __attribute__((__unused__)))
1773e1db26aSLionel Sambuc {
1783e1db26aSLionel Sambuc 
1793e1db26aSLionel Sambuc 	if (el->el_line.cursor == el->el_line.buffer)
1803e1db26aSLionel Sambuc 		return CC_ERROR;
1813e1db26aSLionel Sambuc 
1823e1db26aSLionel Sambuc 	el->el_line.cursor = cv_prev_word(el->el_line.cursor,
1833e1db26aSLionel Sambuc 	    el->el_line.buffer,
1843e1db26aSLionel Sambuc 	    el->el_state.argument,
1853e1db26aSLionel Sambuc 	    cv__isword);
1863e1db26aSLionel Sambuc 
1873e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
1883e1db26aSLionel Sambuc 		cv_delfini(el);
1893e1db26aSLionel Sambuc 		return CC_REFRESH;
1903e1db26aSLionel Sambuc 	}
1913e1db26aSLionel Sambuc 	return CC_CURSOR;
1923e1db26aSLionel Sambuc }
1933e1db26aSLionel Sambuc 
1943e1db26aSLionel Sambuc 
1953e1db26aSLionel Sambuc /* vi_next_big_word():
1963e1db26aSLionel Sambuc  *	Vi move to the next space delimited word
1973e1db26aSLionel Sambuc  *	[W]
1983e1db26aSLionel Sambuc  */
1993e1db26aSLionel Sambuc protected el_action_t
2003e1db26aSLionel Sambuc /*ARGSUSED*/
vi_next_big_word(EditLine * el,Int c)2013e1db26aSLionel Sambuc vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
2023e1db26aSLionel Sambuc {
2033e1db26aSLionel Sambuc 
2043e1db26aSLionel Sambuc 	if (el->el_line.cursor >= el->el_line.lastchar - 1)
2053e1db26aSLionel Sambuc 		return CC_ERROR;
2063e1db26aSLionel Sambuc 
2073e1db26aSLionel Sambuc 	el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
2083e1db26aSLionel Sambuc 	    el->el_line.lastchar, el->el_state.argument, cv__isWord);
2093e1db26aSLionel Sambuc 
2103e1db26aSLionel Sambuc 	if (el->el_map.type == MAP_VI)
2113e1db26aSLionel Sambuc 		if (el->el_chared.c_vcmd.action != NOP) {
2123e1db26aSLionel Sambuc 			cv_delfini(el);
2133e1db26aSLionel Sambuc 			return CC_REFRESH;
2143e1db26aSLionel Sambuc 		}
2153e1db26aSLionel Sambuc 	return CC_CURSOR;
2163e1db26aSLionel Sambuc }
2173e1db26aSLionel Sambuc 
2183e1db26aSLionel Sambuc 
2193e1db26aSLionel Sambuc /* vi_next_word():
2203e1db26aSLionel Sambuc  *	Vi move to the next word
2213e1db26aSLionel Sambuc  *	[w]
2223e1db26aSLionel Sambuc  */
2233e1db26aSLionel Sambuc protected el_action_t
2243e1db26aSLionel Sambuc /*ARGSUSED*/
vi_next_word(EditLine * el,Int c)2253e1db26aSLionel Sambuc vi_next_word(EditLine *el, Int c __attribute__((__unused__)))
2263e1db26aSLionel Sambuc {
2273e1db26aSLionel Sambuc 
2283e1db26aSLionel Sambuc 	if (el->el_line.cursor >= el->el_line.lastchar - 1)
2293e1db26aSLionel Sambuc 		return CC_ERROR;
2303e1db26aSLionel Sambuc 
2313e1db26aSLionel Sambuc 	el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
2323e1db26aSLionel Sambuc 	    el->el_line.lastchar, el->el_state.argument, cv__isword);
2333e1db26aSLionel Sambuc 
2343e1db26aSLionel Sambuc 	if (el->el_map.type == MAP_VI)
2353e1db26aSLionel Sambuc 		if (el->el_chared.c_vcmd.action != NOP) {
2363e1db26aSLionel Sambuc 			cv_delfini(el);
2373e1db26aSLionel Sambuc 			return CC_REFRESH;
2383e1db26aSLionel Sambuc 		}
2393e1db26aSLionel Sambuc 	return CC_CURSOR;
2403e1db26aSLionel Sambuc }
2413e1db26aSLionel Sambuc 
2423e1db26aSLionel Sambuc 
2433e1db26aSLionel Sambuc /* vi_change_case():
2443e1db26aSLionel Sambuc  *	Vi change case of character under the cursor and advance one character
2453e1db26aSLionel Sambuc  *	[~]
2463e1db26aSLionel Sambuc  */
2473e1db26aSLionel Sambuc protected el_action_t
vi_change_case(EditLine * el,Int c)2483e1db26aSLionel Sambuc vi_change_case(EditLine *el, Int c)
2493e1db26aSLionel Sambuc {
2503e1db26aSLionel Sambuc 	int i;
2513e1db26aSLionel Sambuc 
2523e1db26aSLionel Sambuc 	if (el->el_line.cursor >= el->el_line.lastchar)
2533e1db26aSLionel Sambuc 		return CC_ERROR;
2543e1db26aSLionel Sambuc 	cv_undo(el);
2553e1db26aSLionel Sambuc 	for (i = 0; i < el->el_state.argument; i++) {
2563e1db26aSLionel Sambuc 
2573e1db26aSLionel Sambuc 		c = *el->el_line.cursor;
2583e1db26aSLionel Sambuc 		if (Isupper(c))
2593e1db26aSLionel Sambuc 			*el->el_line.cursor = Tolower(c);
2603e1db26aSLionel Sambuc 		else if (Islower(c))
2613e1db26aSLionel Sambuc 			*el->el_line.cursor = Toupper(c);
2623e1db26aSLionel Sambuc 
2633e1db26aSLionel Sambuc 		if (++el->el_line.cursor >= el->el_line.lastchar) {
2643e1db26aSLionel Sambuc 			el->el_line.cursor--;
2653e1db26aSLionel Sambuc 			re_fastaddc(el);
2663e1db26aSLionel Sambuc 			break;
2673e1db26aSLionel Sambuc 		}
2683e1db26aSLionel Sambuc 		re_fastaddc(el);
2693e1db26aSLionel Sambuc 	}
2703e1db26aSLionel Sambuc 	return CC_NORM;
2713e1db26aSLionel Sambuc }
2723e1db26aSLionel Sambuc 
2733e1db26aSLionel Sambuc 
2743e1db26aSLionel Sambuc /* vi_change_meta():
2753e1db26aSLionel Sambuc  *	Vi change prefix command
2763e1db26aSLionel Sambuc  *	[c]
2773e1db26aSLionel Sambuc  */
2783e1db26aSLionel Sambuc protected el_action_t
2793e1db26aSLionel Sambuc /*ARGSUSED*/
vi_change_meta(EditLine * el,Int c)2803e1db26aSLionel Sambuc vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
2813e1db26aSLionel Sambuc {
2823e1db26aSLionel Sambuc 
2833e1db26aSLionel Sambuc 	/*
2843e1db26aSLionel Sambuc          * Delete with insert == change: first we delete and then we leave in
2853e1db26aSLionel Sambuc          * insert mode.
2863e1db26aSLionel Sambuc          */
2873e1db26aSLionel Sambuc 	return cv_action(el, DELETE | INSERT);
2883e1db26aSLionel Sambuc }
2893e1db26aSLionel Sambuc 
2903e1db26aSLionel Sambuc 
2913e1db26aSLionel Sambuc /* vi_insert_at_bol():
2923e1db26aSLionel Sambuc  *	Vi enter insert mode at the beginning of line
2933e1db26aSLionel Sambuc  *	[I]
2943e1db26aSLionel Sambuc  */
2953e1db26aSLionel Sambuc protected el_action_t
2963e1db26aSLionel Sambuc /*ARGSUSED*/
vi_insert_at_bol(EditLine * el,Int c)2973e1db26aSLionel Sambuc vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__)))
2983e1db26aSLionel Sambuc {
2993e1db26aSLionel Sambuc 
3003e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.buffer;
3013e1db26aSLionel Sambuc 	cv_undo(el);
3023e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
3033e1db26aSLionel Sambuc 	return CC_CURSOR;
3043e1db26aSLionel Sambuc }
3053e1db26aSLionel Sambuc 
3063e1db26aSLionel Sambuc 
3073e1db26aSLionel Sambuc /* vi_replace_char():
3083e1db26aSLionel Sambuc  *	Vi replace character under the cursor with the next character typed
3093e1db26aSLionel Sambuc  *	[r]
3103e1db26aSLionel Sambuc  */
3113e1db26aSLionel Sambuc protected el_action_t
3123e1db26aSLionel Sambuc /*ARGSUSED*/
vi_replace_char(EditLine * el,Int c)3133e1db26aSLionel Sambuc vi_replace_char(EditLine *el, Int c __attribute__((__unused__)))
3143e1db26aSLionel Sambuc {
3153e1db26aSLionel Sambuc 
3163e1db26aSLionel Sambuc 	if (el->el_line.cursor >= el->el_line.lastchar)
3173e1db26aSLionel Sambuc 		return CC_ERROR;
3183e1db26aSLionel Sambuc 
3193e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
3203e1db26aSLionel Sambuc 	el->el_state.inputmode = MODE_REPLACE_1;
3213e1db26aSLionel Sambuc 	cv_undo(el);
3223e1db26aSLionel Sambuc 	return CC_ARGHACK;
3233e1db26aSLionel Sambuc }
3243e1db26aSLionel Sambuc 
3253e1db26aSLionel Sambuc 
3263e1db26aSLionel Sambuc /* vi_replace_mode():
3273e1db26aSLionel Sambuc  *	Vi enter replace mode
3283e1db26aSLionel Sambuc  *	[R]
3293e1db26aSLionel Sambuc  */
3303e1db26aSLionel Sambuc protected el_action_t
3313e1db26aSLionel Sambuc /*ARGSUSED*/
vi_replace_mode(EditLine * el,Int c)3323e1db26aSLionel Sambuc vi_replace_mode(EditLine *el, Int c __attribute__((__unused__)))
3333e1db26aSLionel Sambuc {
3343e1db26aSLionel Sambuc 
3353e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
3363e1db26aSLionel Sambuc 	el->el_state.inputmode = MODE_REPLACE;
3373e1db26aSLionel Sambuc 	cv_undo(el);
3383e1db26aSLionel Sambuc 	return CC_NORM;
3393e1db26aSLionel Sambuc }
3403e1db26aSLionel Sambuc 
3413e1db26aSLionel Sambuc 
3423e1db26aSLionel Sambuc /* vi_substitute_char():
3433e1db26aSLionel Sambuc  *	Vi replace character under the cursor and enter insert mode
3443e1db26aSLionel Sambuc  *	[s]
3453e1db26aSLionel Sambuc  */
3463e1db26aSLionel Sambuc protected el_action_t
3473e1db26aSLionel Sambuc /*ARGSUSED*/
vi_substitute_char(EditLine * el,Int c)3483e1db26aSLionel Sambuc vi_substitute_char(EditLine *el, Int c __attribute__((__unused__)))
3493e1db26aSLionel Sambuc {
3503e1db26aSLionel Sambuc 
3513e1db26aSLionel Sambuc 	c_delafter(el, el->el_state.argument);
3523e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
3533e1db26aSLionel Sambuc 	return CC_REFRESH;
3543e1db26aSLionel Sambuc }
3553e1db26aSLionel Sambuc 
3563e1db26aSLionel Sambuc 
3573e1db26aSLionel Sambuc /* vi_substitute_line():
3583e1db26aSLionel Sambuc  *	Vi substitute entire line
3593e1db26aSLionel Sambuc  *	[S]
3603e1db26aSLionel Sambuc  */
3613e1db26aSLionel Sambuc protected el_action_t
3623e1db26aSLionel Sambuc /*ARGSUSED*/
vi_substitute_line(EditLine * el,Int c)3633e1db26aSLionel Sambuc vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
3643e1db26aSLionel Sambuc {
3653e1db26aSLionel Sambuc 
3663e1db26aSLionel Sambuc 	cv_undo(el);
3673e1db26aSLionel Sambuc 	cv_yank(el, el->el_line.buffer,
3683e1db26aSLionel Sambuc 	    (int)(el->el_line.lastchar - el->el_line.buffer));
3693e1db26aSLionel Sambuc 	(void) em_kill_line(el, 0);
3703e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
3713e1db26aSLionel Sambuc 	return CC_REFRESH;
3723e1db26aSLionel Sambuc }
3733e1db26aSLionel Sambuc 
3743e1db26aSLionel Sambuc 
3753e1db26aSLionel Sambuc /* vi_change_to_eol():
3763e1db26aSLionel Sambuc  *	Vi change to end of line
3773e1db26aSLionel Sambuc  *	[C]
3783e1db26aSLionel Sambuc  */
3793e1db26aSLionel Sambuc protected el_action_t
3803e1db26aSLionel Sambuc /*ARGSUSED*/
vi_change_to_eol(EditLine * el,Int c)3813e1db26aSLionel Sambuc vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__)))
3823e1db26aSLionel Sambuc {
3833e1db26aSLionel Sambuc 
3843e1db26aSLionel Sambuc 	cv_undo(el);
3853e1db26aSLionel Sambuc 	cv_yank(el, el->el_line.cursor,
3863e1db26aSLionel Sambuc 	    (int)(el->el_line.lastchar - el->el_line.cursor));
3873e1db26aSLionel Sambuc 	(void) ed_kill_line(el, 0);
3883e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
3893e1db26aSLionel Sambuc 	return CC_REFRESH;
3903e1db26aSLionel Sambuc }
3913e1db26aSLionel Sambuc 
3923e1db26aSLionel Sambuc 
3933e1db26aSLionel Sambuc /* vi_insert():
3943e1db26aSLionel Sambuc  *	Vi enter insert mode
3953e1db26aSLionel Sambuc  *	[i]
3963e1db26aSLionel Sambuc  */
3973e1db26aSLionel Sambuc protected el_action_t
3983e1db26aSLionel Sambuc /*ARGSUSED*/
vi_insert(EditLine * el,Int c)3993e1db26aSLionel Sambuc vi_insert(EditLine *el, Int c __attribute__((__unused__)))
4003e1db26aSLionel Sambuc {
4013e1db26aSLionel Sambuc 
4023e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
4033e1db26aSLionel Sambuc 	cv_undo(el);
4043e1db26aSLionel Sambuc 	return CC_NORM;
4053e1db26aSLionel Sambuc }
4063e1db26aSLionel Sambuc 
4073e1db26aSLionel Sambuc 
4083e1db26aSLionel Sambuc /* vi_add():
4093e1db26aSLionel Sambuc  *	Vi enter insert mode after the cursor
4103e1db26aSLionel Sambuc  *	[a]
4113e1db26aSLionel Sambuc  */
4123e1db26aSLionel Sambuc protected el_action_t
4133e1db26aSLionel Sambuc /*ARGSUSED*/
vi_add(EditLine * el,Int c)4143e1db26aSLionel Sambuc vi_add(EditLine *el, Int c __attribute__((__unused__)))
4153e1db26aSLionel Sambuc {
4163e1db26aSLionel Sambuc 	int ret;
4173e1db26aSLionel Sambuc 
4183e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
4193e1db26aSLionel Sambuc 	if (el->el_line.cursor < el->el_line.lastchar) {
4203e1db26aSLionel Sambuc 		el->el_line.cursor++;
4213e1db26aSLionel Sambuc 		if (el->el_line.cursor > el->el_line.lastchar)
4223e1db26aSLionel Sambuc 			el->el_line.cursor = el->el_line.lastchar;
4233e1db26aSLionel Sambuc 		ret = CC_CURSOR;
4243e1db26aSLionel Sambuc 	} else
4253e1db26aSLionel Sambuc 		ret = CC_NORM;
4263e1db26aSLionel Sambuc 
4273e1db26aSLionel Sambuc 	cv_undo(el);
4283e1db26aSLionel Sambuc 
4293e1db26aSLionel Sambuc 	return (el_action_t)ret;
4303e1db26aSLionel Sambuc }
4313e1db26aSLionel Sambuc 
4323e1db26aSLionel Sambuc 
4333e1db26aSLionel Sambuc /* vi_add_at_eol():
4343e1db26aSLionel Sambuc  *	Vi enter insert mode at end of line
4353e1db26aSLionel Sambuc  *	[A]
4363e1db26aSLionel Sambuc  */
4373e1db26aSLionel Sambuc protected el_action_t
4383e1db26aSLionel Sambuc /*ARGSUSED*/
vi_add_at_eol(EditLine * el,Int c)4393e1db26aSLionel Sambuc vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__)))
4403e1db26aSLionel Sambuc {
4413e1db26aSLionel Sambuc 
4423e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
4433e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.lastchar;
4443e1db26aSLionel Sambuc 	cv_undo(el);
4453e1db26aSLionel Sambuc 	return CC_CURSOR;
4463e1db26aSLionel Sambuc }
4473e1db26aSLionel Sambuc 
4483e1db26aSLionel Sambuc 
4493e1db26aSLionel Sambuc /* vi_delete_meta():
4503e1db26aSLionel Sambuc  *	Vi delete prefix command
4513e1db26aSLionel Sambuc  *	[d]
4523e1db26aSLionel Sambuc  */
4533e1db26aSLionel Sambuc protected el_action_t
4543e1db26aSLionel Sambuc /*ARGSUSED*/
vi_delete_meta(EditLine * el,Int c)4553e1db26aSLionel Sambuc vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
4563e1db26aSLionel Sambuc {
4573e1db26aSLionel Sambuc 
4583e1db26aSLionel Sambuc 	return cv_action(el, DELETE);
4593e1db26aSLionel Sambuc }
4603e1db26aSLionel Sambuc 
4613e1db26aSLionel Sambuc 
4623e1db26aSLionel Sambuc /* vi_end_big_word():
4633e1db26aSLionel Sambuc  *	Vi move to the end of the current space delimited word
4643e1db26aSLionel Sambuc  *	[E]
4653e1db26aSLionel Sambuc  */
4663e1db26aSLionel Sambuc protected el_action_t
4673e1db26aSLionel Sambuc /*ARGSUSED*/
vi_end_big_word(EditLine * el,Int c)4683e1db26aSLionel Sambuc vi_end_big_word(EditLine *el, Int c __attribute__((__unused__)))
4693e1db26aSLionel Sambuc {
4703e1db26aSLionel Sambuc 
4713e1db26aSLionel Sambuc 	if (el->el_line.cursor == el->el_line.lastchar)
4723e1db26aSLionel Sambuc 		return CC_ERROR;
4733e1db26aSLionel Sambuc 
4743e1db26aSLionel Sambuc 	el->el_line.cursor = cv__endword(el->el_line.cursor,
4753e1db26aSLionel Sambuc 	    el->el_line.lastchar, el->el_state.argument, cv__isWord);
4763e1db26aSLionel Sambuc 
4773e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
4783e1db26aSLionel Sambuc 		el->el_line.cursor++;
4793e1db26aSLionel Sambuc 		cv_delfini(el);
4803e1db26aSLionel Sambuc 		return CC_REFRESH;
4813e1db26aSLionel Sambuc 	}
4823e1db26aSLionel Sambuc 	return CC_CURSOR;
4833e1db26aSLionel Sambuc }
4843e1db26aSLionel Sambuc 
4853e1db26aSLionel Sambuc 
4863e1db26aSLionel Sambuc /* vi_end_word():
4873e1db26aSLionel Sambuc  *	Vi move to the end of the current word
4883e1db26aSLionel Sambuc  *	[e]
4893e1db26aSLionel Sambuc  */
4903e1db26aSLionel Sambuc protected el_action_t
4913e1db26aSLionel Sambuc /*ARGSUSED*/
vi_end_word(EditLine * el,Int c)4923e1db26aSLionel Sambuc vi_end_word(EditLine *el, Int c __attribute__((__unused__)))
4933e1db26aSLionel Sambuc {
4943e1db26aSLionel Sambuc 
4953e1db26aSLionel Sambuc 	if (el->el_line.cursor == el->el_line.lastchar)
4963e1db26aSLionel Sambuc 		return CC_ERROR;
4973e1db26aSLionel Sambuc 
4983e1db26aSLionel Sambuc 	el->el_line.cursor = cv__endword(el->el_line.cursor,
4993e1db26aSLionel Sambuc 	    el->el_line.lastchar, el->el_state.argument, cv__isword);
5003e1db26aSLionel Sambuc 
5013e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
5023e1db26aSLionel Sambuc 		el->el_line.cursor++;
5033e1db26aSLionel Sambuc 		cv_delfini(el);
5043e1db26aSLionel Sambuc 		return CC_REFRESH;
5053e1db26aSLionel Sambuc 	}
5063e1db26aSLionel Sambuc 	return CC_CURSOR;
5073e1db26aSLionel Sambuc }
5083e1db26aSLionel Sambuc 
5093e1db26aSLionel Sambuc 
5103e1db26aSLionel Sambuc /* vi_undo():
5113e1db26aSLionel Sambuc  *	Vi undo last change
5123e1db26aSLionel Sambuc  *	[u]
5133e1db26aSLionel Sambuc  */
5143e1db26aSLionel Sambuc protected el_action_t
5153e1db26aSLionel Sambuc /*ARGSUSED*/
vi_undo(EditLine * el,Int c)5163e1db26aSLionel Sambuc vi_undo(EditLine *el, Int c __attribute__((__unused__)))
5173e1db26aSLionel Sambuc {
5183e1db26aSLionel Sambuc 	c_undo_t un = el->el_chared.c_undo;
5193e1db26aSLionel Sambuc 
5203e1db26aSLionel Sambuc 	if (un.len == -1)
5213e1db26aSLionel Sambuc 		return CC_ERROR;
5223e1db26aSLionel Sambuc 
5233e1db26aSLionel Sambuc 	/* switch line buffer and undo buffer */
5243e1db26aSLionel Sambuc 	el->el_chared.c_undo.buf = el->el_line.buffer;
5253e1db26aSLionel Sambuc 	el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
5263e1db26aSLionel Sambuc 	el->el_chared.c_undo.cursor =
5273e1db26aSLionel Sambuc 	    (int)(el->el_line.cursor - el->el_line.buffer);
5283e1db26aSLionel Sambuc 	el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
5293e1db26aSLionel Sambuc 	el->el_line.buffer = un.buf;
5303e1db26aSLionel Sambuc 	el->el_line.cursor = un.buf + un.cursor;
5313e1db26aSLionel Sambuc 	el->el_line.lastchar = un.buf + un.len;
5323e1db26aSLionel Sambuc 
5333e1db26aSLionel Sambuc 	return CC_REFRESH;
5343e1db26aSLionel Sambuc }
5353e1db26aSLionel Sambuc 
5363e1db26aSLionel Sambuc 
5373e1db26aSLionel Sambuc /* vi_command_mode():
5383e1db26aSLionel Sambuc  *	Vi enter command mode (use alternative key bindings)
5393e1db26aSLionel Sambuc  *	[<ESC>]
5403e1db26aSLionel Sambuc  */
5413e1db26aSLionel Sambuc protected el_action_t
5423e1db26aSLionel Sambuc /*ARGSUSED*/
vi_command_mode(EditLine * el,Int c)5433e1db26aSLionel Sambuc vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
5443e1db26aSLionel Sambuc {
5453e1db26aSLionel Sambuc 
5463e1db26aSLionel Sambuc 	/* [Esc] cancels pending action */
5473e1db26aSLionel Sambuc 	el->el_chared.c_vcmd.action = NOP;
5483e1db26aSLionel Sambuc 	el->el_chared.c_vcmd.pos = 0;
5493e1db26aSLionel Sambuc 
5503e1db26aSLionel Sambuc 	el->el_state.doingarg = 0;
5513e1db26aSLionel Sambuc 
5523e1db26aSLionel Sambuc 	el->el_state.inputmode = MODE_INSERT;
5533e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.alt;
5543e1db26aSLionel Sambuc #ifdef VI_MOVE
5553e1db26aSLionel Sambuc 	if (el->el_line.cursor > el->el_line.buffer)
5563e1db26aSLionel Sambuc 		el->el_line.cursor--;
5573e1db26aSLionel Sambuc #endif
5583e1db26aSLionel Sambuc 	return CC_CURSOR;
5593e1db26aSLionel Sambuc }
5603e1db26aSLionel Sambuc 
5613e1db26aSLionel Sambuc 
5623e1db26aSLionel Sambuc /* vi_zero():
5633e1db26aSLionel Sambuc  *	Vi move to the beginning of line
5643e1db26aSLionel Sambuc  *	[0]
5653e1db26aSLionel Sambuc  */
5663e1db26aSLionel Sambuc protected el_action_t
vi_zero(EditLine * el,Int c)5673e1db26aSLionel Sambuc vi_zero(EditLine *el, Int c)
5683e1db26aSLionel Sambuc {
5693e1db26aSLionel Sambuc 
5703e1db26aSLionel Sambuc 	if (el->el_state.doingarg)
5713e1db26aSLionel Sambuc 		return ed_argument_digit(el, c);
5723e1db26aSLionel Sambuc 
5733e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.buffer;
5743e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
5753e1db26aSLionel Sambuc 		cv_delfini(el);
5763e1db26aSLionel Sambuc 		return CC_REFRESH;
5773e1db26aSLionel Sambuc 	}
5783e1db26aSLionel Sambuc 	return CC_CURSOR;
5793e1db26aSLionel Sambuc }
5803e1db26aSLionel Sambuc 
5813e1db26aSLionel Sambuc 
5823e1db26aSLionel Sambuc /* vi_delete_prev_char():
5833e1db26aSLionel Sambuc  * 	Vi move to previous character (backspace)
5843e1db26aSLionel Sambuc  *	[^H] in insert mode only
5853e1db26aSLionel Sambuc  */
5863e1db26aSLionel Sambuc protected el_action_t
5873e1db26aSLionel Sambuc /*ARGSUSED*/
vi_delete_prev_char(EditLine * el,Int c)5883e1db26aSLionel Sambuc vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
5893e1db26aSLionel Sambuc {
5903e1db26aSLionel Sambuc 
5913e1db26aSLionel Sambuc 	if (el->el_line.cursor <= el->el_line.buffer)
5923e1db26aSLionel Sambuc 		return CC_ERROR;
5933e1db26aSLionel Sambuc 
5943e1db26aSLionel Sambuc 	c_delbefore1(el);
5953e1db26aSLionel Sambuc 	el->el_line.cursor--;
5963e1db26aSLionel Sambuc 	return CC_REFRESH;
5973e1db26aSLionel Sambuc }
5983e1db26aSLionel Sambuc 
5993e1db26aSLionel Sambuc 
6003e1db26aSLionel Sambuc /* vi_list_or_eof():
6013e1db26aSLionel Sambuc  *	Vi list choices for completion or indicate end of file if empty line
6023e1db26aSLionel Sambuc  *	[^D]
6033e1db26aSLionel Sambuc  */
6043e1db26aSLionel Sambuc protected el_action_t
6053e1db26aSLionel Sambuc /*ARGSUSED*/
vi_list_or_eof(EditLine * el,Int c)6063e1db26aSLionel Sambuc vi_list_or_eof(EditLine *el, Int c)
6073e1db26aSLionel Sambuc {
6083e1db26aSLionel Sambuc 
6093e1db26aSLionel Sambuc 	if (el->el_line.cursor == el->el_line.lastchar) {
6103e1db26aSLionel Sambuc 		if (el->el_line.cursor == el->el_line.buffer) {
6113e1db26aSLionel Sambuc 			terminal_writec(el, c);	/* then do a EOF */
6123e1db26aSLionel Sambuc 			return CC_EOF;
6133e1db26aSLionel Sambuc 		} else {
6143e1db26aSLionel Sambuc 			/*
6153e1db26aSLionel Sambuc 			 * Here we could list completions, but it is an
6163e1db26aSLionel Sambuc 			 * error right now
6173e1db26aSLionel Sambuc 			 */
6183e1db26aSLionel Sambuc 			terminal_beep(el);
6193e1db26aSLionel Sambuc 			return CC_ERROR;
6203e1db26aSLionel Sambuc 		}
6213e1db26aSLionel Sambuc 	} else {
6223e1db26aSLionel Sambuc #ifdef notyet
6233e1db26aSLionel Sambuc 		re_goto_bottom(el);
6243e1db26aSLionel Sambuc 		*el->el_line.lastchar = '\0';	/* just in case */
6253e1db26aSLionel Sambuc 		return CC_LIST_CHOICES;
6263e1db26aSLionel Sambuc #else
6273e1db26aSLionel Sambuc 		/*
6283e1db26aSLionel Sambuc 		 * Just complain for now.
6293e1db26aSLionel Sambuc 		 */
6303e1db26aSLionel Sambuc 		terminal_beep(el);
6313e1db26aSLionel Sambuc 		return CC_ERROR;
6323e1db26aSLionel Sambuc #endif
6333e1db26aSLionel Sambuc 	}
6343e1db26aSLionel Sambuc }
6353e1db26aSLionel Sambuc 
6363e1db26aSLionel Sambuc 
6373e1db26aSLionel Sambuc /* vi_kill_line_prev():
6383e1db26aSLionel Sambuc  *	Vi cut from beginning of line to cursor
6393e1db26aSLionel Sambuc  *	[^U]
6403e1db26aSLionel Sambuc  */
6413e1db26aSLionel Sambuc protected el_action_t
6423e1db26aSLionel Sambuc /*ARGSUSED*/
vi_kill_line_prev(EditLine * el,Int c)6433e1db26aSLionel Sambuc vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__)))
6443e1db26aSLionel Sambuc {
6453e1db26aSLionel Sambuc 	Char *kp, *cp;
6463e1db26aSLionel Sambuc 
6473e1db26aSLionel Sambuc 	cp = el->el_line.buffer;
6483e1db26aSLionel Sambuc 	kp = el->el_chared.c_kill.buf;
6493e1db26aSLionel Sambuc 	while (cp < el->el_line.cursor)
6503e1db26aSLionel Sambuc 		*kp++ = *cp++;	/* copy it */
6513e1db26aSLionel Sambuc 	el->el_chared.c_kill.last = kp;
6523e1db26aSLionel Sambuc 	c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
6533e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.buffer;	/* zap! */
6543e1db26aSLionel Sambuc 	return CC_REFRESH;
6553e1db26aSLionel Sambuc }
6563e1db26aSLionel Sambuc 
6573e1db26aSLionel Sambuc 
6583e1db26aSLionel Sambuc /* vi_search_prev():
6593e1db26aSLionel Sambuc  *	Vi search history previous
6603e1db26aSLionel Sambuc  *	[?]
6613e1db26aSLionel Sambuc  */
6623e1db26aSLionel Sambuc protected el_action_t
6633e1db26aSLionel Sambuc /*ARGSUSED*/
vi_search_prev(EditLine * el,Int c)6643e1db26aSLionel Sambuc vi_search_prev(EditLine *el, Int c __attribute__((__unused__)))
6653e1db26aSLionel Sambuc {
6663e1db26aSLionel Sambuc 
6673e1db26aSLionel Sambuc 	return cv_search(el, ED_SEARCH_PREV_HISTORY);
6683e1db26aSLionel Sambuc }
6693e1db26aSLionel Sambuc 
6703e1db26aSLionel Sambuc 
6713e1db26aSLionel Sambuc /* vi_search_next():
6723e1db26aSLionel Sambuc  *	Vi search history next
6733e1db26aSLionel Sambuc  *	[/]
6743e1db26aSLionel Sambuc  */
6753e1db26aSLionel Sambuc protected el_action_t
6763e1db26aSLionel Sambuc /*ARGSUSED*/
vi_search_next(EditLine * el,Int c)6773e1db26aSLionel Sambuc vi_search_next(EditLine *el, Int c __attribute__((__unused__)))
6783e1db26aSLionel Sambuc {
6793e1db26aSLionel Sambuc 
6803e1db26aSLionel Sambuc 	return cv_search(el, ED_SEARCH_NEXT_HISTORY);
6813e1db26aSLionel Sambuc }
6823e1db26aSLionel Sambuc 
6833e1db26aSLionel Sambuc 
6843e1db26aSLionel Sambuc /* vi_repeat_search_next():
6853e1db26aSLionel Sambuc  *	Vi repeat current search in the same search direction
6863e1db26aSLionel Sambuc  *	[n]
6873e1db26aSLionel Sambuc  */
6883e1db26aSLionel Sambuc protected el_action_t
6893e1db26aSLionel Sambuc /*ARGSUSED*/
vi_repeat_search_next(EditLine * el,Int c)6903e1db26aSLionel Sambuc vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__)))
6913e1db26aSLionel Sambuc {
6923e1db26aSLionel Sambuc 
6933e1db26aSLionel Sambuc 	if (el->el_search.patlen == 0)
6943e1db26aSLionel Sambuc 		return CC_ERROR;
6953e1db26aSLionel Sambuc 	else
6963e1db26aSLionel Sambuc 		return cv_repeat_srch(el, el->el_search.patdir);
6973e1db26aSLionel Sambuc }
6983e1db26aSLionel Sambuc 
6993e1db26aSLionel Sambuc 
7003e1db26aSLionel Sambuc /* vi_repeat_search_prev():
7013e1db26aSLionel Sambuc  *	Vi repeat current search in the opposite search direction
7023e1db26aSLionel Sambuc  *	[N]
7033e1db26aSLionel Sambuc  */
7043e1db26aSLionel Sambuc /*ARGSUSED*/
7053e1db26aSLionel Sambuc protected el_action_t
vi_repeat_search_prev(EditLine * el,Int c)7063e1db26aSLionel Sambuc vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__)))
7073e1db26aSLionel Sambuc {
7083e1db26aSLionel Sambuc 
7093e1db26aSLionel Sambuc 	if (el->el_search.patlen == 0)
7103e1db26aSLionel Sambuc 		return CC_ERROR;
7113e1db26aSLionel Sambuc 	else
7123e1db26aSLionel Sambuc 		return (cv_repeat_srch(el,
7133e1db26aSLionel Sambuc 		    el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
7143e1db26aSLionel Sambuc 		    ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
7153e1db26aSLionel Sambuc }
7163e1db26aSLionel Sambuc 
7173e1db26aSLionel Sambuc 
7183e1db26aSLionel Sambuc /* vi_next_char():
7193e1db26aSLionel Sambuc  *	Vi move to the character specified next
7203e1db26aSLionel Sambuc  *	[f]
7213e1db26aSLionel Sambuc  */
7223e1db26aSLionel Sambuc protected el_action_t
7233e1db26aSLionel Sambuc /*ARGSUSED*/
vi_next_char(EditLine * el,Int c)7243e1db26aSLionel Sambuc vi_next_char(EditLine *el, Int c __attribute__((__unused__)))
7253e1db26aSLionel Sambuc {
7263e1db26aSLionel Sambuc 	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
7273e1db26aSLionel Sambuc }
7283e1db26aSLionel Sambuc 
7293e1db26aSLionel Sambuc 
7303e1db26aSLionel Sambuc /* vi_prev_char():
7313e1db26aSLionel Sambuc  *	Vi move to the character specified previous
7323e1db26aSLionel Sambuc  *	[F]
7333e1db26aSLionel Sambuc  */
7343e1db26aSLionel Sambuc protected el_action_t
7353e1db26aSLionel Sambuc /*ARGSUSED*/
vi_prev_char(EditLine * el,Int c)7363e1db26aSLionel Sambuc vi_prev_char(EditLine *el, Int c __attribute__((__unused__)))
7373e1db26aSLionel Sambuc {
7383e1db26aSLionel Sambuc 	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
7393e1db26aSLionel Sambuc }
7403e1db26aSLionel Sambuc 
7413e1db26aSLionel Sambuc 
7423e1db26aSLionel Sambuc /* vi_to_next_char():
7433e1db26aSLionel Sambuc  *	Vi move up to the character specified next
7443e1db26aSLionel Sambuc  *	[t]
7453e1db26aSLionel Sambuc  */
7463e1db26aSLionel Sambuc protected el_action_t
7473e1db26aSLionel Sambuc /*ARGSUSED*/
vi_to_next_char(EditLine * el,Int c)7483e1db26aSLionel Sambuc vi_to_next_char(EditLine *el, Int c __attribute__((__unused__)))
7493e1db26aSLionel Sambuc {
7503e1db26aSLionel Sambuc 	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
7513e1db26aSLionel Sambuc }
7523e1db26aSLionel Sambuc 
7533e1db26aSLionel Sambuc 
7543e1db26aSLionel Sambuc /* vi_to_prev_char():
7553e1db26aSLionel Sambuc  *	Vi move up to the character specified previous
7563e1db26aSLionel Sambuc  *	[T]
7573e1db26aSLionel Sambuc  */
7583e1db26aSLionel Sambuc protected el_action_t
7593e1db26aSLionel Sambuc /*ARGSUSED*/
vi_to_prev_char(EditLine * el,Int c)7603e1db26aSLionel Sambuc vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__)))
7613e1db26aSLionel Sambuc {
7623e1db26aSLionel Sambuc 	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
7633e1db26aSLionel Sambuc }
7643e1db26aSLionel Sambuc 
7653e1db26aSLionel Sambuc 
7663e1db26aSLionel Sambuc /* vi_repeat_next_char():
7673e1db26aSLionel Sambuc  *	Vi repeat current character search in the same search direction
7683e1db26aSLionel Sambuc  *	[;]
7693e1db26aSLionel Sambuc  */
7703e1db26aSLionel Sambuc protected el_action_t
7713e1db26aSLionel Sambuc /*ARGSUSED*/
vi_repeat_next_char(EditLine * el,Int c)7723e1db26aSLionel Sambuc vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__)))
7733e1db26aSLionel Sambuc {
7743e1db26aSLionel Sambuc 
7753e1db26aSLionel Sambuc 	return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
7763e1db26aSLionel Sambuc 		el->el_state.argument, el->el_search.chatflg);
7773e1db26aSLionel Sambuc }
7783e1db26aSLionel Sambuc 
7793e1db26aSLionel Sambuc 
7803e1db26aSLionel Sambuc /* vi_repeat_prev_char():
7813e1db26aSLionel Sambuc  *	Vi repeat current character search in the opposite search direction
7823e1db26aSLionel Sambuc  *	[,]
7833e1db26aSLionel Sambuc  */
7843e1db26aSLionel Sambuc protected el_action_t
7853e1db26aSLionel Sambuc /*ARGSUSED*/
vi_repeat_prev_char(EditLine * el,Int c)7863e1db26aSLionel Sambuc vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__)))
7873e1db26aSLionel Sambuc {
7883e1db26aSLionel Sambuc 	el_action_t r;
7893e1db26aSLionel Sambuc 	int dir = el->el_search.chadir;
7903e1db26aSLionel Sambuc 
7913e1db26aSLionel Sambuc 	r = cv_csearch(el, -dir, el->el_search.chacha,
7923e1db26aSLionel Sambuc 		el->el_state.argument, el->el_search.chatflg);
7933e1db26aSLionel Sambuc 	el->el_search.chadir = dir;
7943e1db26aSLionel Sambuc 	return r;
7953e1db26aSLionel Sambuc }
7963e1db26aSLionel Sambuc 
7973e1db26aSLionel Sambuc 
7983e1db26aSLionel Sambuc /* vi_match():
7993e1db26aSLionel Sambuc  *	Vi go to matching () {} or []
8003e1db26aSLionel Sambuc  *	[%]
8013e1db26aSLionel Sambuc  */
8023e1db26aSLionel Sambuc protected el_action_t
8033e1db26aSLionel Sambuc /*ARGSUSED*/
vi_match(EditLine * el,Int c)8043e1db26aSLionel Sambuc vi_match(EditLine *el, Int c __attribute__((__unused__)))
8053e1db26aSLionel Sambuc {
8063e1db26aSLionel Sambuc 	const Char match_chars[] = STR("()[]{}");
8073e1db26aSLionel Sambuc 	Char *cp;
8083e1db26aSLionel Sambuc 	size_t delta, i, count;
8093e1db26aSLionel Sambuc 	Char o_ch, c_ch;
8103e1db26aSLionel Sambuc 
8113e1db26aSLionel Sambuc 	*el->el_line.lastchar = '\0';		/* just in case */
8123e1db26aSLionel Sambuc 
8133e1db26aSLionel Sambuc 	i = Strcspn(el->el_line.cursor, match_chars);
8143e1db26aSLionel Sambuc 	o_ch = el->el_line.cursor[i];
8153e1db26aSLionel Sambuc 	if (o_ch == 0)
8163e1db26aSLionel Sambuc 		return CC_ERROR;
8173e1db26aSLionel Sambuc 	delta = (size_t)(Strchr(match_chars, o_ch) - match_chars);
8183e1db26aSLionel Sambuc 	c_ch = match_chars[delta ^ 1];
8193e1db26aSLionel Sambuc 	count = 1;
8203e1db26aSLionel Sambuc 	delta = 1 - (delta & 1) * 2;
8213e1db26aSLionel Sambuc 
8223e1db26aSLionel Sambuc 	for (cp = &el->el_line.cursor[i]; count; ) {
8233e1db26aSLionel Sambuc 		cp += delta;
8243e1db26aSLionel Sambuc 		if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
8253e1db26aSLionel Sambuc 			return CC_ERROR;
8263e1db26aSLionel Sambuc 		if (*cp == o_ch)
8273e1db26aSLionel Sambuc 			count++;
8283e1db26aSLionel Sambuc 		else if (*cp == c_ch)
8293e1db26aSLionel Sambuc 			count--;
8303e1db26aSLionel Sambuc 	}
8313e1db26aSLionel Sambuc 
8323e1db26aSLionel Sambuc 	el->el_line.cursor = cp;
8333e1db26aSLionel Sambuc 
8343e1db26aSLionel Sambuc 	if (el->el_chared.c_vcmd.action != NOP) {
8353e1db26aSLionel Sambuc 		/* NB posix says char under cursor should NOT be deleted
8363e1db26aSLionel Sambuc 		   for -ve delta - this is different to netbsd vi. */
8373e1db26aSLionel Sambuc 		if (delta > 0)
8383e1db26aSLionel Sambuc 			el->el_line.cursor++;
8393e1db26aSLionel Sambuc 		cv_delfini(el);
8403e1db26aSLionel Sambuc 		return CC_REFRESH;
8413e1db26aSLionel Sambuc 	}
8423e1db26aSLionel Sambuc 	return CC_CURSOR;
8433e1db26aSLionel Sambuc }
8443e1db26aSLionel Sambuc 
8453e1db26aSLionel Sambuc /* vi_undo_line():
8463e1db26aSLionel Sambuc  *	Vi undo all changes to line
8473e1db26aSLionel Sambuc  *	[U]
8483e1db26aSLionel Sambuc  */
8493e1db26aSLionel Sambuc protected el_action_t
8503e1db26aSLionel Sambuc /*ARGSUSED*/
vi_undo_line(EditLine * el,Int c)8513e1db26aSLionel Sambuc vi_undo_line(EditLine *el, Int c __attribute__((__unused__)))
8523e1db26aSLionel Sambuc {
8533e1db26aSLionel Sambuc 
8543e1db26aSLionel Sambuc 	cv_undo(el);
8553e1db26aSLionel Sambuc 	return hist_get(el);
8563e1db26aSLionel Sambuc }
8573e1db26aSLionel Sambuc 
8583e1db26aSLionel Sambuc /* vi_to_column():
8593e1db26aSLionel Sambuc  *	Vi go to specified column
8603e1db26aSLionel Sambuc  *	[|]
8613e1db26aSLionel Sambuc  * NB netbsd vi goes to screen column 'n', posix says nth character
8623e1db26aSLionel Sambuc  */
8633e1db26aSLionel Sambuc protected el_action_t
8643e1db26aSLionel Sambuc /*ARGSUSED*/
vi_to_column(EditLine * el,Int c)8653e1db26aSLionel Sambuc vi_to_column(EditLine *el, Int c __attribute__((__unused__)))
8663e1db26aSLionel Sambuc {
8673e1db26aSLionel Sambuc 
8683e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.buffer;
8693e1db26aSLionel Sambuc 	el->el_state.argument--;
8703e1db26aSLionel Sambuc 	return ed_next_char(el, 0);
8713e1db26aSLionel Sambuc }
8723e1db26aSLionel Sambuc 
8733e1db26aSLionel Sambuc /* vi_yank_end():
8743e1db26aSLionel Sambuc  *	Vi yank to end of line
8753e1db26aSLionel Sambuc  *	[Y]
8763e1db26aSLionel Sambuc  */
8773e1db26aSLionel Sambuc protected el_action_t
8783e1db26aSLionel Sambuc /*ARGSUSED*/
vi_yank_end(EditLine * el,Int c)8793e1db26aSLionel Sambuc vi_yank_end(EditLine *el, Int c __attribute__((__unused__)))
8803e1db26aSLionel Sambuc {
8813e1db26aSLionel Sambuc 
8823e1db26aSLionel Sambuc 	cv_yank(el, el->el_line.cursor,
8833e1db26aSLionel Sambuc 	    (int)(el->el_line.lastchar - el->el_line.cursor));
8843e1db26aSLionel Sambuc 	return CC_REFRESH;
8853e1db26aSLionel Sambuc }
8863e1db26aSLionel Sambuc 
8873e1db26aSLionel Sambuc /* vi_yank():
8883e1db26aSLionel Sambuc  *	Vi yank
8893e1db26aSLionel Sambuc  *	[y]
8903e1db26aSLionel Sambuc  */
8913e1db26aSLionel Sambuc protected el_action_t
8923e1db26aSLionel Sambuc /*ARGSUSED*/
vi_yank(EditLine * el,Int c)8933e1db26aSLionel Sambuc vi_yank(EditLine *el, Int c __attribute__((__unused__)))
8943e1db26aSLionel Sambuc {
8953e1db26aSLionel Sambuc 
8963e1db26aSLionel Sambuc 	return cv_action(el, YANK);
8973e1db26aSLionel Sambuc }
8983e1db26aSLionel Sambuc 
8993e1db26aSLionel Sambuc /* vi_comment_out():
9003e1db26aSLionel Sambuc  *	Vi comment out current command
9013e1db26aSLionel Sambuc  *	[#]
9023e1db26aSLionel Sambuc  */
9033e1db26aSLionel Sambuc protected el_action_t
9043e1db26aSLionel Sambuc /*ARGSUSED*/
vi_comment_out(EditLine * el,Int c)9053e1db26aSLionel Sambuc vi_comment_out(EditLine *el, Int c __attribute__((__unused__)))
9063e1db26aSLionel Sambuc {
9073e1db26aSLionel Sambuc 
9083e1db26aSLionel Sambuc 	el->el_line.cursor = el->el_line.buffer;
9093e1db26aSLionel Sambuc 	c_insert(el, 1);
9103e1db26aSLionel Sambuc 	*el->el_line.cursor = '#';
9113e1db26aSLionel Sambuc 	re_refresh(el);
9123e1db26aSLionel Sambuc 	return ed_newline(el, 0);
9133e1db26aSLionel Sambuc }
9143e1db26aSLionel Sambuc 
9153e1db26aSLionel Sambuc /* vi_alias():
9163e1db26aSLionel Sambuc  *	Vi include shell alias
9173e1db26aSLionel Sambuc  *	[@]
9183e1db26aSLionel Sambuc  * NB: posix implies that we should enter insert mode, however
9193e1db26aSLionel Sambuc  * this is against historical precedent...
9203e1db26aSLionel Sambuc  */
9213e1db26aSLionel Sambuc protected el_action_t
9223e1db26aSLionel Sambuc /*ARGSUSED*/
vi_alias(EditLine * el,Int c)9233e1db26aSLionel Sambuc vi_alias(EditLine *el, Int c __attribute__((__unused__)))
9243e1db26aSLionel Sambuc {
9253e1db26aSLionel Sambuc 	char alias_name[3];
926*0a6a1f1dSLionel Sambuc 	const char *alias_text;
9273e1db26aSLionel Sambuc 
928*0a6a1f1dSLionel Sambuc 	if (el->el_chared.c_aliasfun == NULL)
9293e1db26aSLionel Sambuc 		return CC_ERROR;
9303e1db26aSLionel Sambuc 
9313e1db26aSLionel Sambuc 	alias_name[0] = '_';
9323e1db26aSLionel Sambuc 	alias_name[2] = 0;
9333e1db26aSLionel Sambuc 	if (el_getc(el, &alias_name[1]) != 1)
9343e1db26aSLionel Sambuc 		return CC_ERROR;
9353e1db26aSLionel Sambuc 
936*0a6a1f1dSLionel Sambuc 	alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg,
937*0a6a1f1dSLionel Sambuc 	    alias_name);
9383e1db26aSLionel Sambuc 	if (alias_text != NULL)
9393e1db26aSLionel Sambuc 		FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
9403e1db26aSLionel Sambuc 	return CC_NORM;
9413e1db26aSLionel Sambuc }
9423e1db26aSLionel Sambuc 
9433e1db26aSLionel Sambuc /* vi_to_history_line():
9443e1db26aSLionel Sambuc  *	Vi go to specified history file line.
9453e1db26aSLionel Sambuc  *	[G]
9463e1db26aSLionel Sambuc  */
9473e1db26aSLionel Sambuc protected el_action_t
9483e1db26aSLionel Sambuc /*ARGSUSED*/
vi_to_history_line(EditLine * el,Int c)9493e1db26aSLionel Sambuc vi_to_history_line(EditLine *el, Int c __attribute__((__unused__)))
9503e1db26aSLionel Sambuc {
9513e1db26aSLionel Sambuc 	int sv_event_no = el->el_history.eventno;
9523e1db26aSLionel Sambuc 	el_action_t rval;
9533e1db26aSLionel Sambuc 
9543e1db26aSLionel Sambuc 
9553e1db26aSLionel Sambuc 	if (el->el_history.eventno == 0) {
9563e1db26aSLionel Sambuc 		 (void) Strncpy(el->el_history.buf, el->el_line.buffer,
9573e1db26aSLionel Sambuc 		     EL_BUFSIZ);
9583e1db26aSLionel Sambuc 		 el->el_history.last = el->el_history.buf +
9593e1db26aSLionel Sambuc 			 (el->el_line.lastchar - el->el_line.buffer);
9603e1db26aSLionel Sambuc 	}
9613e1db26aSLionel Sambuc 
9623e1db26aSLionel Sambuc 	/* Lack of a 'count' means oldest, not 1 */
9633e1db26aSLionel Sambuc 	if (!el->el_state.doingarg) {
9643e1db26aSLionel Sambuc 		el->el_history.eventno = 0x7fffffff;
9653e1db26aSLionel Sambuc 		hist_get(el);
9663e1db26aSLionel Sambuc 	} else {
9673e1db26aSLionel Sambuc 		/* This is brain dead, all the rest of this code counts
9683e1db26aSLionel Sambuc 		 * upwards going into the past.  Here we need count in the
9693e1db26aSLionel Sambuc 		 * other direction (to match the output of fc -l).
9703e1db26aSLionel Sambuc 		 * I could change the world, but this seems to suffice.
9713e1db26aSLionel Sambuc 		 */
9723e1db26aSLionel Sambuc 		el->el_history.eventno = 1;
9733e1db26aSLionel Sambuc 		if (hist_get(el) == CC_ERROR)
9743e1db26aSLionel Sambuc 			return CC_ERROR;
9753e1db26aSLionel Sambuc 		el->el_history.eventno = 1 + el->el_history.ev.num
9763e1db26aSLionel Sambuc 					- el->el_state.argument;
9773e1db26aSLionel Sambuc 		if (el->el_history.eventno < 0) {
9783e1db26aSLionel Sambuc 			el->el_history.eventno = sv_event_no;
9793e1db26aSLionel Sambuc 			return CC_ERROR;
9803e1db26aSLionel Sambuc 		}
9813e1db26aSLionel Sambuc 	}
9823e1db26aSLionel Sambuc 	rval = hist_get(el);
9833e1db26aSLionel Sambuc 	if (rval == CC_ERROR)
9843e1db26aSLionel Sambuc 		el->el_history.eventno = sv_event_no;
9853e1db26aSLionel Sambuc 	return rval;
9863e1db26aSLionel Sambuc }
9873e1db26aSLionel Sambuc 
9883e1db26aSLionel Sambuc /* vi_histedit():
9893e1db26aSLionel Sambuc  *	Vi edit history line with vi
9903e1db26aSLionel Sambuc  *	[v]
9913e1db26aSLionel Sambuc  */
9923e1db26aSLionel Sambuc protected el_action_t
9933e1db26aSLionel Sambuc /*ARGSUSED*/
vi_histedit(EditLine * el,Int c)9943e1db26aSLionel Sambuc vi_histedit(EditLine *el, Int c __attribute__((__unused__)))
9953e1db26aSLionel Sambuc {
9963e1db26aSLionel Sambuc 	int fd;
9973e1db26aSLionel Sambuc 	pid_t pid;
9983e1db26aSLionel Sambuc 	ssize_t st;
9993e1db26aSLionel Sambuc 	int status;
10003e1db26aSLionel Sambuc 	char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
10013e1db26aSLionel Sambuc 	char *cp = NULL;
10023e1db26aSLionel Sambuc 	size_t len;
10033e1db26aSLionel Sambuc 	Char *line = NULL;
10043e1db26aSLionel Sambuc 
10053e1db26aSLionel Sambuc 	if (el->el_state.doingarg) {
10063e1db26aSLionel Sambuc 		if (vi_to_history_line(el, 0) == CC_ERROR)
10073e1db26aSLionel Sambuc 			return CC_ERROR;
10083e1db26aSLionel Sambuc 	}
10093e1db26aSLionel Sambuc 
10103e1db26aSLionel Sambuc 	fd = mkstemp(tempfile);
10113e1db26aSLionel Sambuc 	if (fd < 0)
10123e1db26aSLionel Sambuc 		return CC_ERROR;
10133e1db26aSLionel Sambuc 	len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
10143e1db26aSLionel Sambuc #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
10153e1db26aSLionel Sambuc 	cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
10163e1db26aSLionel Sambuc 	if (cp == NULL)
10173e1db26aSLionel Sambuc 		goto error;
10183e1db26aSLionel Sambuc 	line = el_malloc(len * sizeof(*line) + 1);
10193e1db26aSLionel Sambuc 	if (line == NULL)
10203e1db26aSLionel Sambuc 		goto error;
10213e1db26aSLionel Sambuc 	Strncpy(line, el->el_line.buffer, len);
10223e1db26aSLionel Sambuc 	line[len] = '\0';
10233e1db26aSLionel Sambuc 	ct_wcstombs(cp, line, TMP_BUFSIZ - 1);
10243e1db26aSLionel Sambuc 	cp[TMP_BUFSIZ - 1] = '\0';
10253e1db26aSLionel Sambuc 	len = strlen(cp);
10263e1db26aSLionel Sambuc 	write(fd, cp, len);
10273e1db26aSLionel Sambuc 	write(fd, "\n", (size_t)1);
10283e1db26aSLionel Sambuc 	pid = fork();
10293e1db26aSLionel Sambuc 	switch (pid) {
10303e1db26aSLionel Sambuc 	case -1:
10313e1db26aSLionel Sambuc 		goto error;
10323e1db26aSLionel Sambuc 	case 0:
10333e1db26aSLionel Sambuc 		close(fd);
10343e1db26aSLionel Sambuc 		execlp("vi", "vi", tempfile, (char *)NULL);
10353e1db26aSLionel Sambuc 		exit(0);
10363e1db26aSLionel Sambuc 		/*NOTREACHED*/
10373e1db26aSLionel Sambuc 	default:
10383e1db26aSLionel Sambuc 		while (waitpid(pid, &status, 0) != pid)
10393e1db26aSLionel Sambuc 			continue;
10403e1db26aSLionel Sambuc 		lseek(fd, (off_t)0, SEEK_SET);
10413e1db26aSLionel Sambuc 		st = read(fd, cp, TMP_BUFSIZ);
10423e1db26aSLionel Sambuc 		if (st > 0) {
10433e1db26aSLionel Sambuc 			len = (size_t)(el->el_line.lastchar -
10443e1db26aSLionel Sambuc 			    el->el_line.buffer);
10453e1db26aSLionel Sambuc 			len = ct_mbstowcs(el->el_line.buffer, cp, len);
10463e1db26aSLionel Sambuc 			if (len > 0 && el->el_line.buffer[len -1] == '\n')
10473e1db26aSLionel Sambuc 				--len;
10483e1db26aSLionel Sambuc 		}
10493e1db26aSLionel Sambuc 		else
10503e1db26aSLionel Sambuc 			len = 0;
10513e1db26aSLionel Sambuc                 el->el_line.cursor = el->el_line.buffer;
10523e1db26aSLionel Sambuc                 el->el_line.lastchar = el->el_line.buffer + len;
10533e1db26aSLionel Sambuc 		el_free(cp);
10543e1db26aSLionel Sambuc                 el_free(line);
10553e1db26aSLionel Sambuc 		break;
10563e1db26aSLionel Sambuc 	}
10573e1db26aSLionel Sambuc 
10583e1db26aSLionel Sambuc 	close(fd);
10593e1db26aSLionel Sambuc 	unlink(tempfile);
10603e1db26aSLionel Sambuc 	/* return CC_REFRESH; */
10613e1db26aSLionel Sambuc 	return ed_newline(el, 0);
10623e1db26aSLionel Sambuc error:
10633e1db26aSLionel Sambuc 	el_free(line);
10643e1db26aSLionel Sambuc 	el_free(cp);
10653e1db26aSLionel Sambuc 	close(fd);
10663e1db26aSLionel Sambuc 	unlink(tempfile);
10673e1db26aSLionel Sambuc 	return CC_ERROR;
10683e1db26aSLionel Sambuc }
10693e1db26aSLionel Sambuc 
10703e1db26aSLionel Sambuc /* vi_history_word():
10713e1db26aSLionel Sambuc  *	Vi append word from previous input line
10723e1db26aSLionel Sambuc  *	[_]
10733e1db26aSLionel Sambuc  * Who knows where this one came from!
10743e1db26aSLionel Sambuc  * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
10753e1db26aSLionel Sambuc  */
10763e1db26aSLionel Sambuc protected el_action_t
10773e1db26aSLionel Sambuc /*ARGSUSED*/
vi_history_word(EditLine * el,Int c)10783e1db26aSLionel Sambuc vi_history_word(EditLine *el, Int c __attribute__((__unused__)))
10793e1db26aSLionel Sambuc {
10803e1db26aSLionel Sambuc 	const Char *wp = HIST_FIRST(el);
10813e1db26aSLionel Sambuc 	const Char *wep, *wsp;
10823e1db26aSLionel Sambuc 	int len;
10833e1db26aSLionel Sambuc 	Char *cp;
10843e1db26aSLionel Sambuc 	const Char *lim;
10853e1db26aSLionel Sambuc 
10863e1db26aSLionel Sambuc 	if (wp == NULL)
10873e1db26aSLionel Sambuc 		return CC_ERROR;
10883e1db26aSLionel Sambuc 
10893e1db26aSLionel Sambuc 	wep = wsp = 0;
10903e1db26aSLionel Sambuc 	do {
10913e1db26aSLionel Sambuc 		while (Isspace(*wp))
10923e1db26aSLionel Sambuc 			wp++;
10933e1db26aSLionel Sambuc 		if (*wp == 0)
10943e1db26aSLionel Sambuc 			break;
10953e1db26aSLionel Sambuc 		wsp = wp;
10963e1db26aSLionel Sambuc 		while (*wp && !Isspace(*wp))
10973e1db26aSLionel Sambuc 			wp++;
10983e1db26aSLionel Sambuc 		wep = wp;
10993e1db26aSLionel Sambuc 	} while ((!el->el_state.doingarg || --el->el_state.argument > 0)
11003e1db26aSLionel Sambuc 	    && *wp != 0);
11013e1db26aSLionel Sambuc 
11023e1db26aSLionel Sambuc 	if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
11033e1db26aSLionel Sambuc 		return CC_ERROR;
11043e1db26aSLionel Sambuc 
11053e1db26aSLionel Sambuc 	cv_undo(el);
11063e1db26aSLionel Sambuc 	len = (int)(wep - wsp);
11073e1db26aSLionel Sambuc 	if (el->el_line.cursor < el->el_line.lastchar)
11083e1db26aSLionel Sambuc 		el->el_line.cursor++;
11093e1db26aSLionel Sambuc 	c_insert(el, len + 1);
11103e1db26aSLionel Sambuc 	cp = el->el_line.cursor;
11113e1db26aSLionel Sambuc 	lim = el->el_line.limit;
11123e1db26aSLionel Sambuc 	if (cp < lim)
11133e1db26aSLionel Sambuc 		*cp++ = ' ';
11143e1db26aSLionel Sambuc 	while (wsp < wep && cp < lim)
11153e1db26aSLionel Sambuc 		*cp++ = *wsp++;
11163e1db26aSLionel Sambuc 	el->el_line.cursor = cp;
11173e1db26aSLionel Sambuc 
11183e1db26aSLionel Sambuc 	el->el_map.current = el->el_map.key;
11193e1db26aSLionel Sambuc 	return CC_REFRESH;
11203e1db26aSLionel Sambuc }
11213e1db26aSLionel Sambuc 
11223e1db26aSLionel Sambuc /* vi_redo():
11233e1db26aSLionel Sambuc  *	Vi redo last non-motion command
11243e1db26aSLionel Sambuc  *	[.]
11253e1db26aSLionel Sambuc  */
11263e1db26aSLionel Sambuc protected el_action_t
11273e1db26aSLionel Sambuc /*ARGSUSED*/
vi_redo(EditLine * el,Int c)11283e1db26aSLionel Sambuc vi_redo(EditLine *el, Int c __attribute__((__unused__)))
11293e1db26aSLionel Sambuc {
11303e1db26aSLionel Sambuc 	c_redo_t *r = &el->el_chared.c_redo;
11313e1db26aSLionel Sambuc 
11323e1db26aSLionel Sambuc 	if (!el->el_state.doingarg && r->count) {
11333e1db26aSLionel Sambuc 		el->el_state.doingarg = 1;
11343e1db26aSLionel Sambuc 		el->el_state.argument = r->count;
11353e1db26aSLionel Sambuc 	}
11363e1db26aSLionel Sambuc 
11373e1db26aSLionel Sambuc 	el->el_chared.c_vcmd.pos = el->el_line.cursor;
11383e1db26aSLionel Sambuc 	el->el_chared.c_vcmd.action = r->action;
11393e1db26aSLionel Sambuc 	if (r->pos != r->buf) {
11403e1db26aSLionel Sambuc 		if (r->pos + 1 > r->lim)
11413e1db26aSLionel Sambuc 			/* sanity */
11423e1db26aSLionel Sambuc 			r->pos = r->lim - 1;
11433e1db26aSLionel Sambuc 		r->pos[0] = 0;
11443e1db26aSLionel Sambuc 		FUN(el,push)(el, r->buf);
11453e1db26aSLionel Sambuc 	}
11463e1db26aSLionel Sambuc 
11473e1db26aSLionel Sambuc 	el->el_state.thiscmd = r->cmd;
11483e1db26aSLionel Sambuc 	el->el_state.thisch = r->ch;
11493e1db26aSLionel Sambuc 	return (*el->el_map.func[r->cmd])(el, r->ch);
11503e1db26aSLionel Sambuc }
1151