1*91f76417SBaptiste Daroussin /* $NetBSD: vi.c,v 1.64 2021/08/28 17:17:47 christos Exp $ */
2d0ef721eSBaptiste Daroussin
3d0ef721eSBaptiste Daroussin /*-
4d0ef721eSBaptiste Daroussin * Copyright (c) 1992, 1993
5d0ef721eSBaptiste Daroussin * The Regents of the University of California. All rights reserved.
6d0ef721eSBaptiste Daroussin *
7d0ef721eSBaptiste Daroussin * This code is derived from software contributed to Berkeley by
8d0ef721eSBaptiste Daroussin * Christos Zoulas of Cornell University.
9d0ef721eSBaptiste Daroussin *
10d0ef721eSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without
11d0ef721eSBaptiste Daroussin * modification, are permitted provided that the following conditions
12d0ef721eSBaptiste Daroussin * are met:
13d0ef721eSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright
14d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer.
15d0ef721eSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright
16d0ef721eSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the
17d0ef721eSBaptiste Daroussin * documentation and/or other materials provided with the distribution.
18d0ef721eSBaptiste Daroussin * 3. Neither the name of the University nor the names of its contributors
19d0ef721eSBaptiste Daroussin * may be used to endorse or promote products derived from this software
20d0ef721eSBaptiste Daroussin * without specific prior written permission.
21d0ef721eSBaptiste Daroussin *
22d0ef721eSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23d0ef721eSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24d0ef721eSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25d0ef721eSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26d0ef721eSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27d0ef721eSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28d0ef721eSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29d0ef721eSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30d0ef721eSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31d0ef721eSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32d0ef721eSBaptiste Daroussin * SUCH DAMAGE.
33d0ef721eSBaptiste Daroussin */
34d0ef721eSBaptiste Daroussin
35d0ef721eSBaptiste Daroussin #include "config.h"
36d0ef721eSBaptiste Daroussin #if !defined(lint) && !defined(SCCSID)
37d0ef721eSBaptiste Daroussin #if 0
38d0ef721eSBaptiste Daroussin static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
39d0ef721eSBaptiste Daroussin #else
40*91f76417SBaptiste Daroussin __RCSID("$NetBSD: vi.c,v 1.64 2021/08/28 17:17:47 christos Exp $");
41d0ef721eSBaptiste Daroussin #endif
42d0ef721eSBaptiste Daroussin #endif /* not lint && not SCCSID */
43d0ef721eSBaptiste Daroussin
44d0ef721eSBaptiste Daroussin /*
45d0ef721eSBaptiste Daroussin * vi.c: Vi mode commands.
46d0ef721eSBaptiste Daroussin */
47d0ef721eSBaptiste Daroussin #include <sys/wait.h>
48d0ef721eSBaptiste Daroussin #include <ctype.h>
49d0ef721eSBaptiste Daroussin #include <limits.h>
50d0ef721eSBaptiste Daroussin #include <stdlib.h>
51d0ef721eSBaptiste Daroussin #include <string.h>
52d0ef721eSBaptiste Daroussin #include <unistd.h>
53d0ef721eSBaptiste Daroussin
54d0ef721eSBaptiste Daroussin #include "el.h"
55d0ef721eSBaptiste Daroussin #include "common.h"
56d0ef721eSBaptiste Daroussin #include "emacs.h"
57d0ef721eSBaptiste Daroussin #include "fcns.h"
58d0ef721eSBaptiste Daroussin #include "vi.h"
59d0ef721eSBaptiste Daroussin
60d0ef721eSBaptiste Daroussin static el_action_t cv_action(EditLine *, wint_t);
61d0ef721eSBaptiste Daroussin static el_action_t cv_paste(EditLine *, wint_t);
62d0ef721eSBaptiste Daroussin
63d0ef721eSBaptiste Daroussin /* cv_action():
64d0ef721eSBaptiste Daroussin * Handle vi actions.
65d0ef721eSBaptiste Daroussin */
66d0ef721eSBaptiste Daroussin static el_action_t
cv_action(EditLine * el,wint_t c)67d0ef721eSBaptiste Daroussin cv_action(EditLine *el, wint_t c)
68d0ef721eSBaptiste Daroussin {
69d0ef721eSBaptiste Daroussin
70d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
71d0ef721eSBaptiste Daroussin /* 'cc', 'dd' and (possibly) friends */
72d0ef721eSBaptiste Daroussin if (c != (wint_t)el->el_chared.c_vcmd.action)
73d0ef721eSBaptiste Daroussin return CC_ERROR;
74d0ef721eSBaptiste Daroussin
75d0ef721eSBaptiste Daroussin if (!(c & YANK))
76d0ef721eSBaptiste Daroussin cv_undo(el);
77d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.buffer,
78d0ef721eSBaptiste Daroussin (int)(el->el_line.lastchar - el->el_line.buffer));
79d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP;
80d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = 0;
81d0ef721eSBaptiste Daroussin if (!(c & YANK)) {
82d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer;
83d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
84d0ef721eSBaptiste Daroussin }
85d0ef721eSBaptiste Daroussin if (c & INSERT)
86d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
87d0ef721eSBaptiste Daroussin
88d0ef721eSBaptiste Daroussin return CC_REFRESH;
89d0ef721eSBaptiste Daroussin }
90d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = el->el_line.cursor;
91d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = c;
92d0ef721eSBaptiste Daroussin return CC_ARGHACK;
93d0ef721eSBaptiste Daroussin }
94d0ef721eSBaptiste Daroussin
95d0ef721eSBaptiste Daroussin /* cv_paste():
96d0ef721eSBaptiste Daroussin * Paste previous deletion before or after the cursor
97d0ef721eSBaptiste Daroussin */
98d0ef721eSBaptiste Daroussin static el_action_t
cv_paste(EditLine * el,wint_t c)99d0ef721eSBaptiste Daroussin cv_paste(EditLine *el, wint_t c)
100d0ef721eSBaptiste Daroussin {
101d0ef721eSBaptiste Daroussin c_kill_t *k = &el->el_chared.c_kill;
102d0ef721eSBaptiste Daroussin size_t len = (size_t)(k->last - k->buf);
103d0ef721eSBaptiste Daroussin
104d0ef721eSBaptiste Daroussin if (k->buf == NULL || len == 0)
105d0ef721eSBaptiste Daroussin return CC_ERROR;
106d0ef721eSBaptiste Daroussin #ifdef DEBUG_PASTE
107d0ef721eSBaptiste Daroussin (void) fprintf(el->el_errfile, "Paste: \"%.*ls\"\n", (int)len,
108d0ef721eSBaptiste Daroussin k->buf);
109d0ef721eSBaptiste Daroussin #endif
110d0ef721eSBaptiste Daroussin
111d0ef721eSBaptiste Daroussin cv_undo(el);
112d0ef721eSBaptiste Daroussin
113d0ef721eSBaptiste Daroussin if (!c && el->el_line.cursor < el->el_line.lastchar)
114d0ef721eSBaptiste Daroussin el->el_line.cursor++;
115d0ef721eSBaptiste Daroussin
116d0ef721eSBaptiste Daroussin c_insert(el, (int)len);
117d0ef721eSBaptiste Daroussin if (el->el_line.cursor + len > el->el_line.lastchar)
118d0ef721eSBaptiste Daroussin return CC_ERROR;
119d0ef721eSBaptiste Daroussin (void) memcpy(el->el_line.cursor, k->buf, len *
120d0ef721eSBaptiste Daroussin sizeof(*el->el_line.cursor));
121d0ef721eSBaptiste Daroussin
122d0ef721eSBaptiste Daroussin return CC_REFRESH;
123d0ef721eSBaptiste Daroussin }
124d0ef721eSBaptiste Daroussin
125d0ef721eSBaptiste Daroussin
126d0ef721eSBaptiste Daroussin /* vi_paste_next():
127d0ef721eSBaptiste Daroussin * Vi paste previous deletion to the right of the cursor
128d0ef721eSBaptiste Daroussin * [p]
129d0ef721eSBaptiste Daroussin */
130d0ef721eSBaptiste Daroussin libedit_private el_action_t
131d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_paste_next(EditLine * el,wint_t c)132d0ef721eSBaptiste Daroussin vi_paste_next(EditLine *el, wint_t c __attribute__((__unused__)))
133d0ef721eSBaptiste Daroussin {
134d0ef721eSBaptiste Daroussin
135d0ef721eSBaptiste Daroussin return cv_paste(el, 0);
136d0ef721eSBaptiste Daroussin }
137d0ef721eSBaptiste Daroussin
138d0ef721eSBaptiste Daroussin
139d0ef721eSBaptiste Daroussin /* vi_paste_prev():
140d0ef721eSBaptiste Daroussin * Vi paste previous deletion to the left of the cursor
141d0ef721eSBaptiste Daroussin * [P]
142d0ef721eSBaptiste Daroussin */
143d0ef721eSBaptiste Daroussin libedit_private el_action_t
144d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_paste_prev(EditLine * el,wint_t c)145d0ef721eSBaptiste Daroussin vi_paste_prev(EditLine *el, wint_t c __attribute__((__unused__)))
146d0ef721eSBaptiste Daroussin {
147d0ef721eSBaptiste Daroussin
148d0ef721eSBaptiste Daroussin return cv_paste(el, 1);
149d0ef721eSBaptiste Daroussin }
150d0ef721eSBaptiste Daroussin
151d0ef721eSBaptiste Daroussin
152d0ef721eSBaptiste Daroussin /* vi_prev_big_word():
153d0ef721eSBaptiste Daroussin * Vi move to the previous space delimited word
154d0ef721eSBaptiste Daroussin * [B]
155d0ef721eSBaptiste Daroussin */
156d0ef721eSBaptiste Daroussin libedit_private el_action_t
157d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_prev_big_word(EditLine * el,wint_t c)158d0ef721eSBaptiste Daroussin vi_prev_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
159d0ef721eSBaptiste Daroussin {
160d0ef721eSBaptiste Daroussin
161d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.buffer)
162d0ef721eSBaptiste Daroussin return CC_ERROR;
163d0ef721eSBaptiste Daroussin
164d0ef721eSBaptiste Daroussin el->el_line.cursor = cv_prev_word(el->el_line.cursor,
165d0ef721eSBaptiste Daroussin el->el_line.buffer,
166d0ef721eSBaptiste Daroussin el->el_state.argument,
167d0ef721eSBaptiste Daroussin cv__isWord);
168d0ef721eSBaptiste Daroussin
169d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
170d0ef721eSBaptiste Daroussin cv_delfini(el);
171d0ef721eSBaptiste Daroussin return CC_REFRESH;
172d0ef721eSBaptiste Daroussin }
173d0ef721eSBaptiste Daroussin return CC_CURSOR;
174d0ef721eSBaptiste Daroussin }
175d0ef721eSBaptiste Daroussin
176d0ef721eSBaptiste Daroussin
177d0ef721eSBaptiste Daroussin /* vi_prev_word():
178d0ef721eSBaptiste Daroussin * Vi move to the previous word
179d0ef721eSBaptiste Daroussin * [b]
180d0ef721eSBaptiste Daroussin */
181d0ef721eSBaptiste Daroussin libedit_private el_action_t
182d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_prev_word(EditLine * el,wint_t c)183d0ef721eSBaptiste Daroussin vi_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
184d0ef721eSBaptiste Daroussin {
185d0ef721eSBaptiste Daroussin
186d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.buffer)
187d0ef721eSBaptiste Daroussin return CC_ERROR;
188d0ef721eSBaptiste Daroussin
189d0ef721eSBaptiste Daroussin el->el_line.cursor = cv_prev_word(el->el_line.cursor,
190d0ef721eSBaptiste Daroussin el->el_line.buffer,
191d0ef721eSBaptiste Daroussin el->el_state.argument,
192d0ef721eSBaptiste Daroussin cv__isword);
193d0ef721eSBaptiste Daroussin
194d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
195d0ef721eSBaptiste Daroussin cv_delfini(el);
196d0ef721eSBaptiste Daroussin return CC_REFRESH;
197d0ef721eSBaptiste Daroussin }
198d0ef721eSBaptiste Daroussin return CC_CURSOR;
199d0ef721eSBaptiste Daroussin }
200d0ef721eSBaptiste Daroussin
201d0ef721eSBaptiste Daroussin
202d0ef721eSBaptiste Daroussin /* vi_next_big_word():
203d0ef721eSBaptiste Daroussin * Vi move to the next space delimited word
204d0ef721eSBaptiste Daroussin * [W]
205d0ef721eSBaptiste Daroussin */
206d0ef721eSBaptiste Daroussin libedit_private el_action_t
207d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_next_big_word(EditLine * el,wint_t c)208d0ef721eSBaptiste Daroussin vi_next_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
209d0ef721eSBaptiste Daroussin {
210d0ef721eSBaptiste Daroussin
211d0ef721eSBaptiste Daroussin if (el->el_line.cursor >= el->el_line.lastchar - 1)
212d0ef721eSBaptiste Daroussin return CC_ERROR;
213d0ef721eSBaptiste Daroussin
214d0ef721eSBaptiste Daroussin el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
215d0ef721eSBaptiste Daroussin el->el_line.lastchar, el->el_state.argument, cv__isWord);
216d0ef721eSBaptiste Daroussin
217d0ef721eSBaptiste Daroussin if (el->el_map.type == MAP_VI)
218d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
219d0ef721eSBaptiste Daroussin cv_delfini(el);
220d0ef721eSBaptiste Daroussin return CC_REFRESH;
221d0ef721eSBaptiste Daroussin }
222d0ef721eSBaptiste Daroussin return CC_CURSOR;
223d0ef721eSBaptiste Daroussin }
224d0ef721eSBaptiste Daroussin
225d0ef721eSBaptiste Daroussin
226d0ef721eSBaptiste Daroussin /* vi_next_word():
227d0ef721eSBaptiste Daroussin * Vi move to the next word
228d0ef721eSBaptiste Daroussin * [w]
229d0ef721eSBaptiste Daroussin */
230d0ef721eSBaptiste Daroussin libedit_private el_action_t
231d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_next_word(EditLine * el,wint_t c)232d0ef721eSBaptiste Daroussin vi_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
233d0ef721eSBaptiste Daroussin {
234d0ef721eSBaptiste Daroussin
235d0ef721eSBaptiste Daroussin if (el->el_line.cursor >= el->el_line.lastchar - 1)
236d0ef721eSBaptiste Daroussin return CC_ERROR;
237d0ef721eSBaptiste Daroussin
238d0ef721eSBaptiste Daroussin el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
239d0ef721eSBaptiste Daroussin el->el_line.lastchar, el->el_state.argument, cv__isword);
240d0ef721eSBaptiste Daroussin
241d0ef721eSBaptiste Daroussin if (el->el_map.type == MAP_VI)
242d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
243d0ef721eSBaptiste Daroussin cv_delfini(el);
244d0ef721eSBaptiste Daroussin return CC_REFRESH;
245d0ef721eSBaptiste Daroussin }
246d0ef721eSBaptiste Daroussin return CC_CURSOR;
247d0ef721eSBaptiste Daroussin }
248d0ef721eSBaptiste Daroussin
249d0ef721eSBaptiste Daroussin
250d0ef721eSBaptiste Daroussin /* vi_change_case():
251d0ef721eSBaptiste Daroussin * Vi change case of character under the cursor and advance one character
252d0ef721eSBaptiste Daroussin * [~]
253d0ef721eSBaptiste Daroussin */
254d0ef721eSBaptiste Daroussin libedit_private el_action_t
vi_change_case(EditLine * el,wint_t c)255d0ef721eSBaptiste Daroussin vi_change_case(EditLine *el, wint_t c)
256d0ef721eSBaptiste Daroussin {
257d0ef721eSBaptiste Daroussin int i;
258d0ef721eSBaptiste Daroussin
259d0ef721eSBaptiste Daroussin if (el->el_line.cursor >= el->el_line.lastchar)
260d0ef721eSBaptiste Daroussin return CC_ERROR;
261d0ef721eSBaptiste Daroussin cv_undo(el);
262d0ef721eSBaptiste Daroussin for (i = 0; i < el->el_state.argument; i++) {
263d0ef721eSBaptiste Daroussin
264d0ef721eSBaptiste Daroussin c = *el->el_line.cursor;
265d0ef721eSBaptiste Daroussin if (iswupper(c))
266d0ef721eSBaptiste Daroussin *el->el_line.cursor = towlower(c);
267d0ef721eSBaptiste Daroussin else if (iswlower(c))
268d0ef721eSBaptiste Daroussin *el->el_line.cursor = towupper(c);
269d0ef721eSBaptiste Daroussin
270d0ef721eSBaptiste Daroussin if (++el->el_line.cursor >= el->el_line.lastchar) {
271d0ef721eSBaptiste Daroussin el->el_line.cursor--;
272d0ef721eSBaptiste Daroussin re_fastaddc(el);
273d0ef721eSBaptiste Daroussin break;
274d0ef721eSBaptiste Daroussin }
275d0ef721eSBaptiste Daroussin re_fastaddc(el);
276d0ef721eSBaptiste Daroussin }
277d0ef721eSBaptiste Daroussin return CC_NORM;
278d0ef721eSBaptiste Daroussin }
279d0ef721eSBaptiste Daroussin
280d0ef721eSBaptiste Daroussin
281d0ef721eSBaptiste Daroussin /* vi_change_meta():
282d0ef721eSBaptiste Daroussin * Vi change prefix command
283d0ef721eSBaptiste Daroussin * [c]
284d0ef721eSBaptiste Daroussin */
285d0ef721eSBaptiste Daroussin libedit_private el_action_t
286d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_change_meta(EditLine * el,wint_t c)287d0ef721eSBaptiste Daroussin vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__)))
288d0ef721eSBaptiste Daroussin {
289d0ef721eSBaptiste Daroussin
290d0ef721eSBaptiste Daroussin /*
291d0ef721eSBaptiste Daroussin * Delete with insert == change: first we delete and then we leave in
292d0ef721eSBaptiste Daroussin * insert mode.
293d0ef721eSBaptiste Daroussin */
294d0ef721eSBaptiste Daroussin return cv_action(el, DELETE | INSERT);
295d0ef721eSBaptiste Daroussin }
296d0ef721eSBaptiste Daroussin
297d0ef721eSBaptiste Daroussin
298d0ef721eSBaptiste Daroussin /* vi_insert_at_bol():
299d0ef721eSBaptiste Daroussin * Vi enter insert mode at the beginning of line
300d0ef721eSBaptiste Daroussin * [I]
301d0ef721eSBaptiste Daroussin */
302d0ef721eSBaptiste Daroussin libedit_private el_action_t
303d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_insert_at_bol(EditLine * el,wint_t c)304d0ef721eSBaptiste Daroussin vi_insert_at_bol(EditLine *el, wint_t c __attribute__((__unused__)))
305d0ef721eSBaptiste Daroussin {
306d0ef721eSBaptiste Daroussin
307d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
308d0ef721eSBaptiste Daroussin cv_undo(el);
309d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
310d0ef721eSBaptiste Daroussin return CC_CURSOR;
311d0ef721eSBaptiste Daroussin }
312d0ef721eSBaptiste Daroussin
313d0ef721eSBaptiste Daroussin
314d0ef721eSBaptiste Daroussin /* vi_replace_char():
315d0ef721eSBaptiste Daroussin * Vi replace character under the cursor with the next character typed
316d0ef721eSBaptiste Daroussin * [r]
317d0ef721eSBaptiste Daroussin */
318d0ef721eSBaptiste Daroussin libedit_private el_action_t
319d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_replace_char(EditLine * el,wint_t c)320d0ef721eSBaptiste Daroussin vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__)))
321d0ef721eSBaptiste Daroussin {
322d0ef721eSBaptiste Daroussin
323d0ef721eSBaptiste Daroussin if (el->el_line.cursor >= el->el_line.lastchar)
324d0ef721eSBaptiste Daroussin return CC_ERROR;
325d0ef721eSBaptiste Daroussin
326d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
327d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_REPLACE_1;
328d0ef721eSBaptiste Daroussin cv_undo(el);
329d0ef721eSBaptiste Daroussin return CC_ARGHACK;
330d0ef721eSBaptiste Daroussin }
331d0ef721eSBaptiste Daroussin
332d0ef721eSBaptiste Daroussin
333d0ef721eSBaptiste Daroussin /* vi_replace_mode():
334d0ef721eSBaptiste Daroussin * Vi enter replace mode
335d0ef721eSBaptiste Daroussin * [R]
336d0ef721eSBaptiste Daroussin */
337d0ef721eSBaptiste Daroussin libedit_private el_action_t
338d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_replace_mode(EditLine * el,wint_t c)339d0ef721eSBaptiste Daroussin vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__)))
340d0ef721eSBaptiste Daroussin {
341d0ef721eSBaptiste Daroussin
342d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
343d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_REPLACE;
344d0ef721eSBaptiste Daroussin cv_undo(el);
345d0ef721eSBaptiste Daroussin return CC_NORM;
346d0ef721eSBaptiste Daroussin }
347d0ef721eSBaptiste Daroussin
348d0ef721eSBaptiste Daroussin
349d0ef721eSBaptiste Daroussin /* vi_substitute_char():
350d0ef721eSBaptiste Daroussin * Vi replace character under the cursor and enter insert mode
351d0ef721eSBaptiste Daroussin * [s]
352d0ef721eSBaptiste Daroussin */
353d0ef721eSBaptiste Daroussin libedit_private el_action_t
354d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_substitute_char(EditLine * el,wint_t c)355d0ef721eSBaptiste Daroussin vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__)))
356d0ef721eSBaptiste Daroussin {
357d0ef721eSBaptiste Daroussin
358d0ef721eSBaptiste Daroussin c_delafter(el, el->el_state.argument);
359d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
360d0ef721eSBaptiste Daroussin return CC_REFRESH;
361d0ef721eSBaptiste Daroussin }
362d0ef721eSBaptiste Daroussin
363d0ef721eSBaptiste Daroussin
364d0ef721eSBaptiste Daroussin /* vi_substitute_line():
365d0ef721eSBaptiste Daroussin * Vi substitute entire line
366d0ef721eSBaptiste Daroussin * [S]
367d0ef721eSBaptiste Daroussin */
368d0ef721eSBaptiste Daroussin libedit_private el_action_t
369d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_substitute_line(EditLine * el,wint_t c)370d0ef721eSBaptiste Daroussin vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__)))
371d0ef721eSBaptiste Daroussin {
372d0ef721eSBaptiste Daroussin
373d0ef721eSBaptiste Daroussin cv_undo(el);
374d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.buffer,
375d0ef721eSBaptiste Daroussin (int)(el->el_line.lastchar - el->el_line.buffer));
376d0ef721eSBaptiste Daroussin (void) em_kill_line(el, 0);
377d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
378d0ef721eSBaptiste Daroussin return CC_REFRESH;
379d0ef721eSBaptiste Daroussin }
380d0ef721eSBaptiste Daroussin
381d0ef721eSBaptiste Daroussin
382d0ef721eSBaptiste Daroussin /* vi_change_to_eol():
383d0ef721eSBaptiste Daroussin * Vi change to end of line
384d0ef721eSBaptiste Daroussin * [C]
385d0ef721eSBaptiste Daroussin */
386d0ef721eSBaptiste Daroussin libedit_private el_action_t
387d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_change_to_eol(EditLine * el,wint_t c)388d0ef721eSBaptiste Daroussin vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__)))
389d0ef721eSBaptiste Daroussin {
390d0ef721eSBaptiste Daroussin
391d0ef721eSBaptiste Daroussin cv_undo(el);
392d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor,
393d0ef721eSBaptiste Daroussin (int)(el->el_line.lastchar - el->el_line.cursor));
394d0ef721eSBaptiste Daroussin (void) ed_kill_line(el, 0);
395d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
396d0ef721eSBaptiste Daroussin return CC_REFRESH;
397d0ef721eSBaptiste Daroussin }
398d0ef721eSBaptiste Daroussin
399d0ef721eSBaptiste Daroussin
400d0ef721eSBaptiste Daroussin /* vi_insert():
401d0ef721eSBaptiste Daroussin * Vi enter insert mode
402d0ef721eSBaptiste Daroussin * [i]
403d0ef721eSBaptiste Daroussin */
404d0ef721eSBaptiste Daroussin libedit_private el_action_t
405d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_insert(EditLine * el,wint_t c)406d0ef721eSBaptiste Daroussin vi_insert(EditLine *el, wint_t c __attribute__((__unused__)))
407d0ef721eSBaptiste Daroussin {
408d0ef721eSBaptiste Daroussin
409d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
410d0ef721eSBaptiste Daroussin cv_undo(el);
411d0ef721eSBaptiste Daroussin return CC_NORM;
412d0ef721eSBaptiste Daroussin }
413d0ef721eSBaptiste Daroussin
414d0ef721eSBaptiste Daroussin
415d0ef721eSBaptiste Daroussin /* vi_add():
416d0ef721eSBaptiste Daroussin * Vi enter insert mode after the cursor
417d0ef721eSBaptiste Daroussin * [a]
418d0ef721eSBaptiste Daroussin */
419d0ef721eSBaptiste Daroussin libedit_private el_action_t
420d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_add(EditLine * el,wint_t c)421d0ef721eSBaptiste Daroussin vi_add(EditLine *el, wint_t c __attribute__((__unused__)))
422d0ef721eSBaptiste Daroussin {
423d0ef721eSBaptiste Daroussin int ret;
424d0ef721eSBaptiste Daroussin
425d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
426d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.lastchar) {
427d0ef721eSBaptiste Daroussin el->el_line.cursor++;
428d0ef721eSBaptiste Daroussin if (el->el_line.cursor > el->el_line.lastchar)
429d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.lastchar;
430d0ef721eSBaptiste Daroussin ret = CC_CURSOR;
431d0ef721eSBaptiste Daroussin } else
432d0ef721eSBaptiste Daroussin ret = CC_NORM;
433d0ef721eSBaptiste Daroussin
434d0ef721eSBaptiste Daroussin cv_undo(el);
435d0ef721eSBaptiste Daroussin
436d0ef721eSBaptiste Daroussin return (el_action_t)ret;
437d0ef721eSBaptiste Daroussin }
438d0ef721eSBaptiste Daroussin
439d0ef721eSBaptiste Daroussin
440d0ef721eSBaptiste Daroussin /* vi_add_at_eol():
441d0ef721eSBaptiste Daroussin * Vi enter insert mode at end of line
442d0ef721eSBaptiste Daroussin * [A]
443d0ef721eSBaptiste Daroussin */
444d0ef721eSBaptiste Daroussin libedit_private el_action_t
445d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_add_at_eol(EditLine * el,wint_t c)446d0ef721eSBaptiste Daroussin vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__)))
447d0ef721eSBaptiste Daroussin {
448d0ef721eSBaptiste Daroussin
449d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
450d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.lastchar;
451d0ef721eSBaptiste Daroussin cv_undo(el);
452d0ef721eSBaptiste Daroussin return CC_CURSOR;
453d0ef721eSBaptiste Daroussin }
454d0ef721eSBaptiste Daroussin
455d0ef721eSBaptiste Daroussin
456d0ef721eSBaptiste Daroussin /* vi_delete_meta():
457d0ef721eSBaptiste Daroussin * Vi delete prefix command
458d0ef721eSBaptiste Daroussin * [d]
459d0ef721eSBaptiste Daroussin */
460d0ef721eSBaptiste Daroussin libedit_private el_action_t
461d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_delete_meta(EditLine * el,wint_t c)462d0ef721eSBaptiste Daroussin vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__)))
463d0ef721eSBaptiste Daroussin {
464d0ef721eSBaptiste Daroussin
465d0ef721eSBaptiste Daroussin return cv_action(el, DELETE);
466d0ef721eSBaptiste Daroussin }
467d0ef721eSBaptiste Daroussin
468d0ef721eSBaptiste Daroussin
469d0ef721eSBaptiste Daroussin /* vi_end_big_word():
470d0ef721eSBaptiste Daroussin * Vi move to the end of the current space delimited word
471d0ef721eSBaptiste Daroussin * [E]
472d0ef721eSBaptiste Daroussin */
473d0ef721eSBaptiste Daroussin libedit_private el_action_t
474d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_end_big_word(EditLine * el,wint_t c)475d0ef721eSBaptiste Daroussin vi_end_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
476d0ef721eSBaptiste Daroussin {
477d0ef721eSBaptiste Daroussin
478d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.lastchar)
479d0ef721eSBaptiste Daroussin return CC_ERROR;
480d0ef721eSBaptiste Daroussin
481d0ef721eSBaptiste Daroussin el->el_line.cursor = cv__endword(el->el_line.cursor,
482d0ef721eSBaptiste Daroussin el->el_line.lastchar, el->el_state.argument, cv__isWord);
483d0ef721eSBaptiste Daroussin
484d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
485d0ef721eSBaptiste Daroussin el->el_line.cursor++;
486d0ef721eSBaptiste Daroussin cv_delfini(el);
487d0ef721eSBaptiste Daroussin return CC_REFRESH;
488d0ef721eSBaptiste Daroussin }
489d0ef721eSBaptiste Daroussin return CC_CURSOR;
490d0ef721eSBaptiste Daroussin }
491d0ef721eSBaptiste Daroussin
492d0ef721eSBaptiste Daroussin
493d0ef721eSBaptiste Daroussin /* vi_end_word():
494d0ef721eSBaptiste Daroussin * Vi move to the end of the current word
495d0ef721eSBaptiste Daroussin * [e]
496d0ef721eSBaptiste Daroussin */
497d0ef721eSBaptiste Daroussin libedit_private el_action_t
498d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_end_word(EditLine * el,wint_t c)499d0ef721eSBaptiste Daroussin vi_end_word(EditLine *el, wint_t c __attribute__((__unused__)))
500d0ef721eSBaptiste Daroussin {
501d0ef721eSBaptiste Daroussin
502d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.lastchar)
503d0ef721eSBaptiste Daroussin return CC_ERROR;
504d0ef721eSBaptiste Daroussin
505d0ef721eSBaptiste Daroussin el->el_line.cursor = cv__endword(el->el_line.cursor,
506d0ef721eSBaptiste Daroussin el->el_line.lastchar, el->el_state.argument, cv__isword);
507d0ef721eSBaptiste Daroussin
508d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
509d0ef721eSBaptiste Daroussin el->el_line.cursor++;
510d0ef721eSBaptiste Daroussin cv_delfini(el);
511d0ef721eSBaptiste Daroussin return CC_REFRESH;
512d0ef721eSBaptiste Daroussin }
513d0ef721eSBaptiste Daroussin return CC_CURSOR;
514d0ef721eSBaptiste Daroussin }
515d0ef721eSBaptiste Daroussin
516d0ef721eSBaptiste Daroussin
517d0ef721eSBaptiste Daroussin /* vi_undo():
518d0ef721eSBaptiste Daroussin * Vi undo last change
519d0ef721eSBaptiste Daroussin * [u]
520d0ef721eSBaptiste Daroussin */
521d0ef721eSBaptiste Daroussin libedit_private el_action_t
522d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_undo(EditLine * el,wint_t c)523d0ef721eSBaptiste Daroussin vi_undo(EditLine *el, wint_t c __attribute__((__unused__)))
524d0ef721eSBaptiste Daroussin {
525d0ef721eSBaptiste Daroussin c_undo_t un = el->el_chared.c_undo;
526d0ef721eSBaptiste Daroussin
527d0ef721eSBaptiste Daroussin if (un.len == -1)
528d0ef721eSBaptiste Daroussin return CC_ERROR;
529d0ef721eSBaptiste Daroussin
530d0ef721eSBaptiste Daroussin /* switch line buffer and undo buffer */
531d0ef721eSBaptiste Daroussin el->el_chared.c_undo.buf = el->el_line.buffer;
532d0ef721eSBaptiste Daroussin el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
533d0ef721eSBaptiste Daroussin el->el_chared.c_undo.cursor =
534d0ef721eSBaptiste Daroussin (int)(el->el_line.cursor - el->el_line.buffer);
535d0ef721eSBaptiste Daroussin el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
536d0ef721eSBaptiste Daroussin el->el_line.buffer = un.buf;
537d0ef721eSBaptiste Daroussin el->el_line.cursor = un.buf + un.cursor;
538d0ef721eSBaptiste Daroussin el->el_line.lastchar = un.buf + un.len;
539d0ef721eSBaptiste Daroussin
540d0ef721eSBaptiste Daroussin return CC_REFRESH;
541d0ef721eSBaptiste Daroussin }
542d0ef721eSBaptiste Daroussin
543d0ef721eSBaptiste Daroussin
544d0ef721eSBaptiste Daroussin /* vi_command_mode():
545d0ef721eSBaptiste Daroussin * Vi enter command mode (use alternative key bindings)
546d0ef721eSBaptiste Daroussin * [<ESC>]
547d0ef721eSBaptiste Daroussin */
548d0ef721eSBaptiste Daroussin libedit_private el_action_t
549d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_command_mode(EditLine * el,wint_t c)550d0ef721eSBaptiste Daroussin vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__)))
551d0ef721eSBaptiste Daroussin {
552d0ef721eSBaptiste Daroussin
553d0ef721eSBaptiste Daroussin /* [Esc] cancels pending action */
554d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = NOP;
555d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = 0;
556d0ef721eSBaptiste Daroussin
557d0ef721eSBaptiste Daroussin el->el_state.doingarg = 0;
558d0ef721eSBaptiste Daroussin
559d0ef721eSBaptiste Daroussin el->el_state.inputmode = MODE_INSERT;
560d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.alt;
561d0ef721eSBaptiste Daroussin #ifdef VI_MOVE
562d0ef721eSBaptiste Daroussin if (el->el_line.cursor > el->el_line.buffer)
563d0ef721eSBaptiste Daroussin el->el_line.cursor--;
564d0ef721eSBaptiste Daroussin #endif
565d0ef721eSBaptiste Daroussin return CC_CURSOR;
566d0ef721eSBaptiste Daroussin }
567d0ef721eSBaptiste Daroussin
568d0ef721eSBaptiste Daroussin
569d0ef721eSBaptiste Daroussin /* vi_zero():
570d0ef721eSBaptiste Daroussin * Vi move to the beginning of line
571d0ef721eSBaptiste Daroussin * [0]
572d0ef721eSBaptiste Daroussin */
573d0ef721eSBaptiste Daroussin libedit_private el_action_t
vi_zero(EditLine * el,wint_t c)574d0ef721eSBaptiste Daroussin vi_zero(EditLine *el, wint_t c)
575d0ef721eSBaptiste Daroussin {
576d0ef721eSBaptiste Daroussin
577d0ef721eSBaptiste Daroussin if (el->el_state.doingarg)
578d0ef721eSBaptiste Daroussin return ed_argument_digit(el, c);
579d0ef721eSBaptiste Daroussin
580d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
581d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
582d0ef721eSBaptiste Daroussin cv_delfini(el);
583d0ef721eSBaptiste Daroussin return CC_REFRESH;
584d0ef721eSBaptiste Daroussin }
585d0ef721eSBaptiste Daroussin return CC_CURSOR;
586d0ef721eSBaptiste Daroussin }
587d0ef721eSBaptiste Daroussin
588d0ef721eSBaptiste Daroussin
589d0ef721eSBaptiste Daroussin /* vi_delete_prev_char():
590d0ef721eSBaptiste Daroussin * Vi move to previous character (backspace)
591d0ef721eSBaptiste Daroussin * [^H] in insert mode only
592d0ef721eSBaptiste Daroussin */
593d0ef721eSBaptiste Daroussin libedit_private el_action_t
594d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_delete_prev_char(EditLine * el,wint_t c)595d0ef721eSBaptiste Daroussin vi_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
596d0ef721eSBaptiste Daroussin {
597d0ef721eSBaptiste Daroussin
598d0ef721eSBaptiste Daroussin if (el->el_line.cursor <= el->el_line.buffer)
599d0ef721eSBaptiste Daroussin return CC_ERROR;
600d0ef721eSBaptiste Daroussin
601d0ef721eSBaptiste Daroussin c_delbefore1(el);
602d0ef721eSBaptiste Daroussin el->el_line.cursor--;
603d0ef721eSBaptiste Daroussin return CC_REFRESH;
604d0ef721eSBaptiste Daroussin }
605d0ef721eSBaptiste Daroussin
606d0ef721eSBaptiste Daroussin
607d0ef721eSBaptiste Daroussin /* vi_list_or_eof():
608d0ef721eSBaptiste Daroussin * Vi list choices for completion or indicate end of file if empty line
609d0ef721eSBaptiste Daroussin * [^D]
610d0ef721eSBaptiste Daroussin */
611d0ef721eSBaptiste Daroussin libedit_private el_action_t
612d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_list_or_eof(EditLine * el,wint_t c)613d0ef721eSBaptiste Daroussin vi_list_or_eof(EditLine *el, wint_t c)
614d0ef721eSBaptiste Daroussin {
615d0ef721eSBaptiste Daroussin
616d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.lastchar) {
617d0ef721eSBaptiste Daroussin if (el->el_line.cursor == el->el_line.buffer) {
618d0ef721eSBaptiste Daroussin terminal_writec(el, c); /* then do a EOF */
619d0ef721eSBaptiste Daroussin return CC_EOF;
620d0ef721eSBaptiste Daroussin } else {
621d0ef721eSBaptiste Daroussin /*
622d0ef721eSBaptiste Daroussin * Here we could list completions, but it is an
623d0ef721eSBaptiste Daroussin * error right now
624d0ef721eSBaptiste Daroussin */
625d0ef721eSBaptiste Daroussin terminal_beep(el);
626d0ef721eSBaptiste Daroussin return CC_ERROR;
627d0ef721eSBaptiste Daroussin }
628d0ef721eSBaptiste Daroussin } else {
629d0ef721eSBaptiste Daroussin #ifdef notyet
630d0ef721eSBaptiste Daroussin re_goto_bottom(el);
631d0ef721eSBaptiste Daroussin *el->el_line.lastchar = '\0'; /* just in case */
632d0ef721eSBaptiste Daroussin return CC_LIST_CHOICES;
633d0ef721eSBaptiste Daroussin #else
634d0ef721eSBaptiste Daroussin /*
635d0ef721eSBaptiste Daroussin * Just complain for now.
636d0ef721eSBaptiste Daroussin */
637d0ef721eSBaptiste Daroussin terminal_beep(el);
638d0ef721eSBaptiste Daroussin return CC_ERROR;
639d0ef721eSBaptiste Daroussin #endif
640d0ef721eSBaptiste Daroussin }
641d0ef721eSBaptiste Daroussin }
642d0ef721eSBaptiste Daroussin
643d0ef721eSBaptiste Daroussin
644d0ef721eSBaptiste Daroussin /* vi_kill_line_prev():
645d0ef721eSBaptiste Daroussin * Vi cut from beginning of line to cursor
646d0ef721eSBaptiste Daroussin * [^U]
647d0ef721eSBaptiste Daroussin */
648d0ef721eSBaptiste Daroussin libedit_private el_action_t
649d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_kill_line_prev(EditLine * el,wint_t c)650d0ef721eSBaptiste Daroussin vi_kill_line_prev(EditLine *el, wint_t c __attribute__((__unused__)))
651d0ef721eSBaptiste Daroussin {
652d0ef721eSBaptiste Daroussin wchar_t *kp, *cp;
653d0ef721eSBaptiste Daroussin
654d0ef721eSBaptiste Daroussin cp = el->el_line.buffer;
655d0ef721eSBaptiste Daroussin kp = el->el_chared.c_kill.buf;
656d0ef721eSBaptiste Daroussin while (cp < el->el_line.cursor)
657d0ef721eSBaptiste Daroussin *kp++ = *cp++; /* copy it */
658d0ef721eSBaptiste Daroussin el->el_chared.c_kill.last = kp;
659d0ef721eSBaptiste Daroussin c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
660d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer; /* zap! */
661d0ef721eSBaptiste Daroussin return CC_REFRESH;
662d0ef721eSBaptiste Daroussin }
663d0ef721eSBaptiste Daroussin
664d0ef721eSBaptiste Daroussin
665d0ef721eSBaptiste Daroussin /* vi_search_prev():
666d0ef721eSBaptiste Daroussin * Vi search history previous
667d0ef721eSBaptiste Daroussin * [?]
668d0ef721eSBaptiste Daroussin */
669d0ef721eSBaptiste Daroussin libedit_private el_action_t
670d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_search_prev(EditLine * el,wint_t c)671d0ef721eSBaptiste Daroussin vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
672d0ef721eSBaptiste Daroussin {
673d0ef721eSBaptiste Daroussin
674d0ef721eSBaptiste Daroussin return cv_search(el, ED_SEARCH_PREV_HISTORY);
675d0ef721eSBaptiste Daroussin }
676d0ef721eSBaptiste Daroussin
677d0ef721eSBaptiste Daroussin
678d0ef721eSBaptiste Daroussin /* vi_search_next():
679d0ef721eSBaptiste Daroussin * Vi search history next
680d0ef721eSBaptiste Daroussin * [/]
681d0ef721eSBaptiste Daroussin */
682d0ef721eSBaptiste Daroussin libedit_private el_action_t
683d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_search_next(EditLine * el,wint_t c)684d0ef721eSBaptiste Daroussin vi_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
685d0ef721eSBaptiste Daroussin {
686d0ef721eSBaptiste Daroussin
687d0ef721eSBaptiste Daroussin return cv_search(el, ED_SEARCH_NEXT_HISTORY);
688d0ef721eSBaptiste Daroussin }
689d0ef721eSBaptiste Daroussin
690d0ef721eSBaptiste Daroussin
691d0ef721eSBaptiste Daroussin /* vi_repeat_search_next():
692d0ef721eSBaptiste Daroussin * Vi repeat current search in the same search direction
693d0ef721eSBaptiste Daroussin * [n]
694d0ef721eSBaptiste Daroussin */
695d0ef721eSBaptiste Daroussin libedit_private el_action_t
696d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_repeat_search_next(EditLine * el,wint_t c)697d0ef721eSBaptiste Daroussin vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
698d0ef721eSBaptiste Daroussin {
699d0ef721eSBaptiste Daroussin
700d0ef721eSBaptiste Daroussin if (el->el_search.patlen == 0)
701d0ef721eSBaptiste Daroussin return CC_ERROR;
702d0ef721eSBaptiste Daroussin else
703d0ef721eSBaptiste Daroussin return cv_repeat_srch(el, el->el_search.patdir);
704d0ef721eSBaptiste Daroussin }
705d0ef721eSBaptiste Daroussin
706d0ef721eSBaptiste Daroussin
707d0ef721eSBaptiste Daroussin /* vi_repeat_search_prev():
708d0ef721eSBaptiste Daroussin * Vi repeat current search in the opposite search direction
709d0ef721eSBaptiste Daroussin * [N]
710d0ef721eSBaptiste Daroussin */
711d0ef721eSBaptiste Daroussin /*ARGSUSED*/
712d0ef721eSBaptiste Daroussin libedit_private el_action_t
vi_repeat_search_prev(EditLine * el,wint_t c)713d0ef721eSBaptiste Daroussin vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
714d0ef721eSBaptiste Daroussin {
715d0ef721eSBaptiste Daroussin
716d0ef721eSBaptiste Daroussin if (el->el_search.patlen == 0)
717d0ef721eSBaptiste Daroussin return CC_ERROR;
718d0ef721eSBaptiste Daroussin else
719d0ef721eSBaptiste Daroussin return (cv_repeat_srch(el,
720d0ef721eSBaptiste Daroussin el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
721d0ef721eSBaptiste Daroussin ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
722d0ef721eSBaptiste Daroussin }
723d0ef721eSBaptiste Daroussin
724d0ef721eSBaptiste Daroussin
725d0ef721eSBaptiste Daroussin /* vi_next_char():
726d0ef721eSBaptiste Daroussin * Vi move to the character specified next
727d0ef721eSBaptiste Daroussin * [f]
728d0ef721eSBaptiste Daroussin */
729d0ef721eSBaptiste Daroussin libedit_private el_action_t
730d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_next_char(EditLine * el,wint_t c)731d0ef721eSBaptiste Daroussin vi_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
732d0ef721eSBaptiste Daroussin {
733d0ef721eSBaptiste Daroussin return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
734d0ef721eSBaptiste Daroussin }
735d0ef721eSBaptiste Daroussin
736d0ef721eSBaptiste Daroussin
737d0ef721eSBaptiste Daroussin /* vi_prev_char():
738d0ef721eSBaptiste Daroussin * Vi move to the character specified previous
739d0ef721eSBaptiste Daroussin * [F]
740d0ef721eSBaptiste Daroussin */
741d0ef721eSBaptiste Daroussin libedit_private el_action_t
742d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_prev_char(EditLine * el,wint_t c)743d0ef721eSBaptiste Daroussin vi_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
744d0ef721eSBaptiste Daroussin {
745d0ef721eSBaptiste Daroussin return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
746d0ef721eSBaptiste Daroussin }
747d0ef721eSBaptiste Daroussin
748d0ef721eSBaptiste Daroussin
749d0ef721eSBaptiste Daroussin /* vi_to_next_char():
750d0ef721eSBaptiste Daroussin * Vi move up to the character specified next
751d0ef721eSBaptiste Daroussin * [t]
752d0ef721eSBaptiste Daroussin */
753d0ef721eSBaptiste Daroussin libedit_private el_action_t
754d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_to_next_char(EditLine * el,wint_t c)755d0ef721eSBaptiste Daroussin vi_to_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
756d0ef721eSBaptiste Daroussin {
757d0ef721eSBaptiste Daroussin return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
758d0ef721eSBaptiste Daroussin }
759d0ef721eSBaptiste Daroussin
760d0ef721eSBaptiste Daroussin
761d0ef721eSBaptiste Daroussin /* vi_to_prev_char():
762d0ef721eSBaptiste Daroussin * Vi move up to the character specified previous
763d0ef721eSBaptiste Daroussin * [T]
764d0ef721eSBaptiste Daroussin */
765d0ef721eSBaptiste Daroussin libedit_private el_action_t
766d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_to_prev_char(EditLine * el,wint_t c)767d0ef721eSBaptiste Daroussin vi_to_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
768d0ef721eSBaptiste Daroussin {
769d0ef721eSBaptiste Daroussin return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
770d0ef721eSBaptiste Daroussin }
771d0ef721eSBaptiste Daroussin
772d0ef721eSBaptiste Daroussin
773d0ef721eSBaptiste Daroussin /* vi_repeat_next_char():
774d0ef721eSBaptiste Daroussin * Vi repeat current character search in the same search direction
775d0ef721eSBaptiste Daroussin * [;]
776d0ef721eSBaptiste Daroussin */
777d0ef721eSBaptiste Daroussin libedit_private el_action_t
778d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_repeat_next_char(EditLine * el,wint_t c)779d0ef721eSBaptiste Daroussin vi_repeat_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
780d0ef721eSBaptiste Daroussin {
781d0ef721eSBaptiste Daroussin
782d0ef721eSBaptiste Daroussin return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
783d0ef721eSBaptiste Daroussin el->el_state.argument, el->el_search.chatflg);
784d0ef721eSBaptiste Daroussin }
785d0ef721eSBaptiste Daroussin
786d0ef721eSBaptiste Daroussin
787d0ef721eSBaptiste Daroussin /* vi_repeat_prev_char():
788d0ef721eSBaptiste Daroussin * Vi repeat current character search in the opposite search direction
789d0ef721eSBaptiste Daroussin * [,]
790d0ef721eSBaptiste Daroussin */
791d0ef721eSBaptiste Daroussin libedit_private el_action_t
792d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_repeat_prev_char(EditLine * el,wint_t c)793d0ef721eSBaptiste Daroussin vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
794d0ef721eSBaptiste Daroussin {
795d0ef721eSBaptiste Daroussin el_action_t r;
796d0ef721eSBaptiste Daroussin int dir = el->el_search.chadir;
797d0ef721eSBaptiste Daroussin
798d0ef721eSBaptiste Daroussin r = cv_csearch(el, -dir, el->el_search.chacha,
799d0ef721eSBaptiste Daroussin el->el_state.argument, el->el_search.chatflg);
800d0ef721eSBaptiste Daroussin el->el_search.chadir = dir;
801d0ef721eSBaptiste Daroussin return r;
802d0ef721eSBaptiste Daroussin }
803d0ef721eSBaptiste Daroussin
804d0ef721eSBaptiste Daroussin
805d0ef721eSBaptiste Daroussin /* vi_match():
806d0ef721eSBaptiste Daroussin * Vi go to matching () {} or []
807d0ef721eSBaptiste Daroussin * [%]
808d0ef721eSBaptiste Daroussin */
809d0ef721eSBaptiste Daroussin libedit_private el_action_t
810d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_match(EditLine * el,wint_t c)811d0ef721eSBaptiste Daroussin vi_match(EditLine *el, wint_t c __attribute__((__unused__)))
812d0ef721eSBaptiste Daroussin {
813d0ef721eSBaptiste Daroussin const wchar_t match_chars[] = L"()[]{}";
814d0ef721eSBaptiste Daroussin wchar_t *cp;
815d0ef721eSBaptiste Daroussin size_t delta, i, count;
816d0ef721eSBaptiste Daroussin wchar_t o_ch, c_ch;
817d0ef721eSBaptiste Daroussin
818d0ef721eSBaptiste Daroussin *el->el_line.lastchar = '\0'; /* just in case */
819d0ef721eSBaptiste Daroussin
820d0ef721eSBaptiste Daroussin i = wcscspn(el->el_line.cursor, match_chars);
821d0ef721eSBaptiste Daroussin o_ch = el->el_line.cursor[i];
822d0ef721eSBaptiste Daroussin if (o_ch == 0)
823d0ef721eSBaptiste Daroussin return CC_ERROR;
824d0ef721eSBaptiste Daroussin delta = (size_t)(wcschr(match_chars, o_ch) - match_chars);
825d0ef721eSBaptiste Daroussin c_ch = match_chars[delta ^ 1];
826d0ef721eSBaptiste Daroussin count = 1;
827d0ef721eSBaptiste Daroussin delta = 1 - (delta & 1) * 2;
828d0ef721eSBaptiste Daroussin
829d0ef721eSBaptiste Daroussin for (cp = &el->el_line.cursor[i]; count; ) {
830d0ef721eSBaptiste Daroussin cp += delta;
831d0ef721eSBaptiste Daroussin if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
832d0ef721eSBaptiste Daroussin return CC_ERROR;
833d0ef721eSBaptiste Daroussin if (*cp == o_ch)
834d0ef721eSBaptiste Daroussin count++;
835d0ef721eSBaptiste Daroussin else if (*cp == c_ch)
836d0ef721eSBaptiste Daroussin count--;
837d0ef721eSBaptiste Daroussin }
838d0ef721eSBaptiste Daroussin
839d0ef721eSBaptiste Daroussin el->el_line.cursor = cp;
840d0ef721eSBaptiste Daroussin
841d0ef721eSBaptiste Daroussin if (el->el_chared.c_vcmd.action != NOP) {
842d0ef721eSBaptiste Daroussin /* NB posix says char under cursor should NOT be deleted
843d0ef721eSBaptiste Daroussin for -ve delta - this is different to netbsd vi. */
844d0ef721eSBaptiste Daroussin if (delta > 0)
845d0ef721eSBaptiste Daroussin el->el_line.cursor++;
846d0ef721eSBaptiste Daroussin cv_delfini(el);
847d0ef721eSBaptiste Daroussin return CC_REFRESH;
848d0ef721eSBaptiste Daroussin }
849d0ef721eSBaptiste Daroussin return CC_CURSOR;
850d0ef721eSBaptiste Daroussin }
851d0ef721eSBaptiste Daroussin
852d0ef721eSBaptiste Daroussin /* vi_undo_line():
853d0ef721eSBaptiste Daroussin * Vi undo all changes to line
854d0ef721eSBaptiste Daroussin * [U]
855d0ef721eSBaptiste Daroussin */
856d0ef721eSBaptiste Daroussin libedit_private el_action_t
857d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_undo_line(EditLine * el,wint_t c)858d0ef721eSBaptiste Daroussin vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__)))
859d0ef721eSBaptiste Daroussin {
860d0ef721eSBaptiste Daroussin
861d0ef721eSBaptiste Daroussin cv_undo(el);
862d0ef721eSBaptiste Daroussin return hist_get(el);
863d0ef721eSBaptiste Daroussin }
864d0ef721eSBaptiste Daroussin
865d0ef721eSBaptiste Daroussin /* vi_to_column():
866d0ef721eSBaptiste Daroussin * Vi go to specified column
867d0ef721eSBaptiste Daroussin * [|]
868d0ef721eSBaptiste Daroussin * NB netbsd vi goes to screen column 'n', posix says nth character
869d0ef721eSBaptiste Daroussin */
870d0ef721eSBaptiste Daroussin libedit_private el_action_t
871d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_to_column(EditLine * el,wint_t c)872d0ef721eSBaptiste Daroussin vi_to_column(EditLine *el, wint_t c __attribute__((__unused__)))
873d0ef721eSBaptiste Daroussin {
874d0ef721eSBaptiste Daroussin
875d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
876d0ef721eSBaptiste Daroussin el->el_state.argument--;
877d0ef721eSBaptiste Daroussin return ed_next_char(el, 0);
878d0ef721eSBaptiste Daroussin }
879d0ef721eSBaptiste Daroussin
880d0ef721eSBaptiste Daroussin /* vi_yank_end():
881d0ef721eSBaptiste Daroussin * Vi yank to end of line
882d0ef721eSBaptiste Daroussin * [Y]
883d0ef721eSBaptiste Daroussin */
884d0ef721eSBaptiste Daroussin libedit_private el_action_t
885d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_yank_end(EditLine * el,wint_t c)886d0ef721eSBaptiste Daroussin vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__)))
887d0ef721eSBaptiste Daroussin {
888d0ef721eSBaptiste Daroussin
889d0ef721eSBaptiste Daroussin cv_yank(el, el->el_line.cursor,
890d0ef721eSBaptiste Daroussin (int)(el->el_line.lastchar - el->el_line.cursor));
891d0ef721eSBaptiste Daroussin return CC_REFRESH;
892d0ef721eSBaptiste Daroussin }
893d0ef721eSBaptiste Daroussin
894d0ef721eSBaptiste Daroussin /* vi_yank():
895d0ef721eSBaptiste Daroussin * Vi yank
896d0ef721eSBaptiste Daroussin * [y]
897d0ef721eSBaptiste Daroussin */
898d0ef721eSBaptiste Daroussin libedit_private el_action_t
899d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_yank(EditLine * el,wint_t c)900d0ef721eSBaptiste Daroussin vi_yank(EditLine *el, wint_t c __attribute__((__unused__)))
901d0ef721eSBaptiste Daroussin {
902d0ef721eSBaptiste Daroussin
903d0ef721eSBaptiste Daroussin return cv_action(el, YANK);
904d0ef721eSBaptiste Daroussin }
905d0ef721eSBaptiste Daroussin
906d0ef721eSBaptiste Daroussin /* vi_comment_out():
907d0ef721eSBaptiste Daroussin * Vi comment out current command
908d0ef721eSBaptiste Daroussin * [#]
909d0ef721eSBaptiste Daroussin */
910d0ef721eSBaptiste Daroussin libedit_private el_action_t
911d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_comment_out(EditLine * el,wint_t c)912d0ef721eSBaptiste Daroussin vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__)))
913d0ef721eSBaptiste Daroussin {
914d0ef721eSBaptiste Daroussin
915d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
916d0ef721eSBaptiste Daroussin c_insert(el, 1);
917d0ef721eSBaptiste Daroussin *el->el_line.cursor = '#';
918d0ef721eSBaptiste Daroussin re_refresh(el);
919d0ef721eSBaptiste Daroussin return ed_newline(el, 0);
920d0ef721eSBaptiste Daroussin }
921d0ef721eSBaptiste Daroussin
922d0ef721eSBaptiste Daroussin /* vi_alias():
923d0ef721eSBaptiste Daroussin * Vi include shell alias
924d0ef721eSBaptiste Daroussin * [@]
925d0ef721eSBaptiste Daroussin * NB: posix implies that we should enter insert mode, however
926d0ef721eSBaptiste Daroussin * this is against historical precedent...
927d0ef721eSBaptiste Daroussin */
928d0ef721eSBaptiste Daroussin libedit_private el_action_t
929d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_alias(EditLine * el,wint_t c)930d0ef721eSBaptiste Daroussin vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
931d0ef721eSBaptiste Daroussin {
932d0ef721eSBaptiste Daroussin char alias_name[3];
933d0ef721eSBaptiste Daroussin const char *alias_text;
934d0ef721eSBaptiste Daroussin
935d0ef721eSBaptiste Daroussin if (el->el_chared.c_aliasfun == NULL)
936d0ef721eSBaptiste Daroussin return CC_ERROR;
937d0ef721eSBaptiste Daroussin
938d0ef721eSBaptiste Daroussin alias_name[0] = '_';
939d0ef721eSBaptiste Daroussin alias_name[2] = 0;
940d0ef721eSBaptiste Daroussin if (el_getc(el, &alias_name[1]) != 1)
941d0ef721eSBaptiste Daroussin return CC_ERROR;
942d0ef721eSBaptiste Daroussin
943d0ef721eSBaptiste Daroussin alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg,
944d0ef721eSBaptiste Daroussin alias_name);
945d0ef721eSBaptiste Daroussin if (alias_text != NULL)
946d0ef721eSBaptiste Daroussin el_wpush(el, ct_decode_string(alias_text, &el->el_scratch));
947d0ef721eSBaptiste Daroussin return CC_NORM;
948d0ef721eSBaptiste Daroussin }
949d0ef721eSBaptiste Daroussin
950d0ef721eSBaptiste Daroussin /* vi_to_history_line():
951d0ef721eSBaptiste Daroussin * Vi go to specified history file line.
952d0ef721eSBaptiste Daroussin * [G]
953d0ef721eSBaptiste Daroussin */
954d0ef721eSBaptiste Daroussin libedit_private el_action_t
955d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_to_history_line(EditLine * el,wint_t c)956d0ef721eSBaptiste Daroussin vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
957d0ef721eSBaptiste Daroussin {
958d0ef721eSBaptiste Daroussin int sv_event_no = el->el_history.eventno;
959d0ef721eSBaptiste Daroussin el_action_t rval;
960d0ef721eSBaptiste Daroussin
961d0ef721eSBaptiste Daroussin
962d0ef721eSBaptiste Daroussin if (el->el_history.eventno == 0) {
963d0ef721eSBaptiste Daroussin (void) wcsncpy(el->el_history.buf, el->el_line.buffer,
964d0ef721eSBaptiste Daroussin EL_BUFSIZ);
965d0ef721eSBaptiste Daroussin el->el_history.last = el->el_history.buf +
966d0ef721eSBaptiste Daroussin (el->el_line.lastchar - el->el_line.buffer);
967d0ef721eSBaptiste Daroussin }
968d0ef721eSBaptiste Daroussin
969d0ef721eSBaptiste Daroussin /* Lack of a 'count' means oldest, not 1 */
970d0ef721eSBaptiste Daroussin if (!el->el_state.doingarg) {
971d0ef721eSBaptiste Daroussin el->el_history.eventno = 0x7fffffff;
972d0ef721eSBaptiste Daroussin hist_get(el);
973d0ef721eSBaptiste Daroussin } else {
974d0ef721eSBaptiste Daroussin /* This is brain dead, all the rest of this code counts
975d0ef721eSBaptiste Daroussin * upwards going into the past. Here we need count in the
976d0ef721eSBaptiste Daroussin * other direction (to match the output of fc -l).
977d0ef721eSBaptiste Daroussin * I could change the world, but this seems to suffice.
978d0ef721eSBaptiste Daroussin */
979d0ef721eSBaptiste Daroussin el->el_history.eventno = 1;
980d0ef721eSBaptiste Daroussin if (hist_get(el) == CC_ERROR)
981d0ef721eSBaptiste Daroussin return CC_ERROR;
982d0ef721eSBaptiste Daroussin el->el_history.eventno = 1 + el->el_history.ev.num
983d0ef721eSBaptiste Daroussin - el->el_state.argument;
984d0ef721eSBaptiste Daroussin if (el->el_history.eventno < 0) {
985d0ef721eSBaptiste Daroussin el->el_history.eventno = sv_event_no;
986d0ef721eSBaptiste Daroussin return CC_ERROR;
987d0ef721eSBaptiste Daroussin }
988d0ef721eSBaptiste Daroussin }
989d0ef721eSBaptiste Daroussin rval = hist_get(el);
990d0ef721eSBaptiste Daroussin if (rval == CC_ERROR)
991d0ef721eSBaptiste Daroussin el->el_history.eventno = sv_event_no;
992d0ef721eSBaptiste Daroussin return rval;
993d0ef721eSBaptiste Daroussin }
994d0ef721eSBaptiste Daroussin
995d0ef721eSBaptiste Daroussin /* vi_histedit():
996d0ef721eSBaptiste Daroussin * Vi edit history line with vi
997d0ef721eSBaptiste Daroussin * [v]
998d0ef721eSBaptiste Daroussin */
999d0ef721eSBaptiste Daroussin libedit_private el_action_t
1000d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_histedit(EditLine * el,wint_t c)1001d0ef721eSBaptiste Daroussin vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
1002d0ef721eSBaptiste Daroussin {
1003d0ef721eSBaptiste Daroussin int fd;
1004d0ef721eSBaptiste Daroussin pid_t pid;
1005d0ef721eSBaptiste Daroussin ssize_t st;
1006d0ef721eSBaptiste Daroussin int status;
1007d0ef721eSBaptiste Daroussin char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
1008d0ef721eSBaptiste Daroussin char *cp = NULL;
1009d0ef721eSBaptiste Daroussin size_t len;
1010d0ef721eSBaptiste Daroussin wchar_t *line = NULL;
1011*91f76417SBaptiste Daroussin const char *editor;
1012d0ef721eSBaptiste Daroussin
1013d0ef721eSBaptiste Daroussin if (el->el_state.doingarg) {
1014d0ef721eSBaptiste Daroussin if (vi_to_history_line(el, 0) == CC_ERROR)
1015d0ef721eSBaptiste Daroussin return CC_ERROR;
1016d0ef721eSBaptiste Daroussin }
1017d0ef721eSBaptiste Daroussin
1018*91f76417SBaptiste Daroussin if ((editor = getenv("EDITOR")) == NULL)
1019*91f76417SBaptiste Daroussin editor = "vi";
1020d0ef721eSBaptiste Daroussin fd = mkstemp(tempfile);
1021d0ef721eSBaptiste Daroussin if (fd < 0)
1022d0ef721eSBaptiste Daroussin return CC_ERROR;
1023d0ef721eSBaptiste Daroussin len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
1024d0ef721eSBaptiste Daroussin #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
1025d0ef721eSBaptiste Daroussin cp = el_calloc(TMP_BUFSIZ, sizeof(*cp));
1026d0ef721eSBaptiste Daroussin if (cp == NULL)
1027d0ef721eSBaptiste Daroussin goto error;
1028d0ef721eSBaptiste Daroussin line = el_calloc(len + 1, sizeof(*line));
1029d0ef721eSBaptiste Daroussin if (line == NULL)
1030d0ef721eSBaptiste Daroussin goto error;
1031d0ef721eSBaptiste Daroussin wcsncpy(line, el->el_line.buffer, len);
1032d0ef721eSBaptiste Daroussin line[len] = '\0';
1033d0ef721eSBaptiste Daroussin wcstombs(cp, line, TMP_BUFSIZ - 1);
1034d0ef721eSBaptiste Daroussin cp[TMP_BUFSIZ - 1] = '\0';
1035d0ef721eSBaptiste Daroussin len = strlen(cp);
1036d0ef721eSBaptiste Daroussin write(fd, cp, len);
1037d0ef721eSBaptiste Daroussin write(fd, "\n", (size_t)1);
1038d0ef721eSBaptiste Daroussin pid = fork();
1039d0ef721eSBaptiste Daroussin switch (pid) {
1040d0ef721eSBaptiste Daroussin case -1:
1041d0ef721eSBaptiste Daroussin goto error;
1042d0ef721eSBaptiste Daroussin case 0:
1043d0ef721eSBaptiste Daroussin close(fd);
1044*91f76417SBaptiste Daroussin execlp(editor, editor, tempfile, (char *)NULL);
1045d0ef721eSBaptiste Daroussin exit(0);
1046d0ef721eSBaptiste Daroussin /*NOTREACHED*/
1047d0ef721eSBaptiste Daroussin default:
1048d0ef721eSBaptiste Daroussin while (waitpid(pid, &status, 0) != pid)
1049d0ef721eSBaptiste Daroussin continue;
1050d0ef721eSBaptiste Daroussin lseek(fd, (off_t)0, SEEK_SET);
1051d0ef721eSBaptiste Daroussin st = read(fd, cp, TMP_BUFSIZ - 1);
1052d0ef721eSBaptiste Daroussin if (st > 0) {
1053d0ef721eSBaptiste Daroussin cp[st] = '\0';
1054d0ef721eSBaptiste Daroussin len = (size_t)(el->el_line.limit - el->el_line.buffer);
1055d0ef721eSBaptiste Daroussin len = mbstowcs(el->el_line.buffer, cp, len);
1056d0ef721eSBaptiste Daroussin if (len > 0 && el->el_line.buffer[len - 1] == '\n')
1057d0ef721eSBaptiste Daroussin --len;
1058d0ef721eSBaptiste Daroussin }
1059d0ef721eSBaptiste Daroussin else
1060d0ef721eSBaptiste Daroussin len = 0;
1061d0ef721eSBaptiste Daroussin el->el_line.cursor = el->el_line.buffer;
1062d0ef721eSBaptiste Daroussin el->el_line.lastchar = el->el_line.buffer + len;
1063d0ef721eSBaptiste Daroussin el_free(cp);
1064d0ef721eSBaptiste Daroussin el_free(line);
1065d0ef721eSBaptiste Daroussin break;
1066d0ef721eSBaptiste Daroussin }
1067d0ef721eSBaptiste Daroussin
1068d0ef721eSBaptiste Daroussin close(fd);
1069d0ef721eSBaptiste Daroussin unlink(tempfile);
1070d0ef721eSBaptiste Daroussin /* return CC_REFRESH; */
1071d0ef721eSBaptiste Daroussin return ed_newline(el, 0);
1072d0ef721eSBaptiste Daroussin error:
1073d0ef721eSBaptiste Daroussin el_free(line);
1074d0ef721eSBaptiste Daroussin el_free(cp);
1075d0ef721eSBaptiste Daroussin close(fd);
1076d0ef721eSBaptiste Daroussin unlink(tempfile);
1077d0ef721eSBaptiste Daroussin return CC_ERROR;
1078d0ef721eSBaptiste Daroussin }
1079d0ef721eSBaptiste Daroussin
1080d0ef721eSBaptiste Daroussin /* vi_history_word():
1081d0ef721eSBaptiste Daroussin * Vi append word from previous input line
1082d0ef721eSBaptiste Daroussin * [_]
1083d0ef721eSBaptiste Daroussin * Who knows where this one came from!
1084d0ef721eSBaptiste Daroussin * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
1085d0ef721eSBaptiste Daroussin */
1086d0ef721eSBaptiste Daroussin libedit_private el_action_t
1087d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_history_word(EditLine * el,wint_t c)1088d0ef721eSBaptiste Daroussin vi_history_word(EditLine *el, wint_t c __attribute__((__unused__)))
1089d0ef721eSBaptiste Daroussin {
1090d0ef721eSBaptiste Daroussin const wchar_t *wp = HIST_FIRST(el);
1091d0ef721eSBaptiste Daroussin const wchar_t *wep, *wsp;
1092d0ef721eSBaptiste Daroussin int len;
1093d0ef721eSBaptiste Daroussin wchar_t *cp;
1094d0ef721eSBaptiste Daroussin const wchar_t *lim;
1095d0ef721eSBaptiste Daroussin
1096d0ef721eSBaptiste Daroussin if (wp == NULL)
1097d0ef721eSBaptiste Daroussin return CC_ERROR;
1098d0ef721eSBaptiste Daroussin
1099d0ef721eSBaptiste Daroussin wep = wsp = NULL;
1100d0ef721eSBaptiste Daroussin do {
1101d0ef721eSBaptiste Daroussin while (iswspace(*wp))
1102d0ef721eSBaptiste Daroussin wp++;
1103d0ef721eSBaptiste Daroussin if (*wp == 0)
1104d0ef721eSBaptiste Daroussin break;
1105d0ef721eSBaptiste Daroussin wsp = wp;
1106d0ef721eSBaptiste Daroussin while (*wp && !iswspace(*wp))
1107d0ef721eSBaptiste Daroussin wp++;
1108d0ef721eSBaptiste Daroussin wep = wp;
1109d0ef721eSBaptiste Daroussin } while ((!el->el_state.doingarg || --el->el_state.argument > 0)
1110d0ef721eSBaptiste Daroussin && *wp != 0);
1111d0ef721eSBaptiste Daroussin
1112d0ef721eSBaptiste Daroussin if (wsp == NULL || (el->el_state.doingarg && el->el_state.argument != 0))
1113d0ef721eSBaptiste Daroussin return CC_ERROR;
1114d0ef721eSBaptiste Daroussin
1115d0ef721eSBaptiste Daroussin cv_undo(el);
1116d0ef721eSBaptiste Daroussin len = (int)(wep - wsp);
1117d0ef721eSBaptiste Daroussin if (el->el_line.cursor < el->el_line.lastchar)
1118d0ef721eSBaptiste Daroussin el->el_line.cursor++;
1119d0ef721eSBaptiste Daroussin c_insert(el, len + 1);
1120d0ef721eSBaptiste Daroussin cp = el->el_line.cursor;
1121d0ef721eSBaptiste Daroussin lim = el->el_line.limit;
1122d0ef721eSBaptiste Daroussin if (cp < lim)
1123d0ef721eSBaptiste Daroussin *cp++ = ' ';
1124d0ef721eSBaptiste Daroussin while (wsp < wep && cp < lim)
1125d0ef721eSBaptiste Daroussin *cp++ = *wsp++;
1126d0ef721eSBaptiste Daroussin el->el_line.cursor = cp;
1127d0ef721eSBaptiste Daroussin
1128d0ef721eSBaptiste Daroussin el->el_map.current = el->el_map.key;
1129d0ef721eSBaptiste Daroussin return CC_REFRESH;
1130d0ef721eSBaptiste Daroussin }
1131d0ef721eSBaptiste Daroussin
1132d0ef721eSBaptiste Daroussin /* vi_redo():
1133d0ef721eSBaptiste Daroussin * Vi redo last non-motion command
1134d0ef721eSBaptiste Daroussin * [.]
1135d0ef721eSBaptiste Daroussin */
1136d0ef721eSBaptiste Daroussin libedit_private el_action_t
1137d0ef721eSBaptiste Daroussin /*ARGSUSED*/
vi_redo(EditLine * el,wint_t c)1138d0ef721eSBaptiste Daroussin vi_redo(EditLine *el, wint_t c __attribute__((__unused__)))
1139d0ef721eSBaptiste Daroussin {
1140d0ef721eSBaptiste Daroussin c_redo_t *r = &el->el_chared.c_redo;
1141d0ef721eSBaptiste Daroussin
1142d0ef721eSBaptiste Daroussin if (!el->el_state.doingarg && r->count) {
1143d0ef721eSBaptiste Daroussin el->el_state.doingarg = 1;
1144d0ef721eSBaptiste Daroussin el->el_state.argument = r->count;
1145d0ef721eSBaptiste Daroussin }
1146d0ef721eSBaptiste Daroussin
1147d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.pos = el->el_line.cursor;
1148d0ef721eSBaptiste Daroussin el->el_chared.c_vcmd.action = r->action;
1149d0ef721eSBaptiste Daroussin if (r->pos != r->buf) {
1150d0ef721eSBaptiste Daroussin if (r->pos + 1 > r->lim)
1151d0ef721eSBaptiste Daroussin /* sanity */
1152d0ef721eSBaptiste Daroussin r->pos = r->lim - 1;
1153d0ef721eSBaptiste Daroussin r->pos[0] = 0;
1154d0ef721eSBaptiste Daroussin el_wpush(el, r->buf);
1155d0ef721eSBaptiste Daroussin }
1156d0ef721eSBaptiste Daroussin
1157d0ef721eSBaptiste Daroussin el->el_state.thiscmd = r->cmd;
1158d0ef721eSBaptiste Daroussin el->el_state.thisch = r->ch;
1159d0ef721eSBaptiste Daroussin return (*el->el_map.func[r->cmd])(el, r->ch);
1160d0ef721eSBaptiste Daroussin }
1161