1*6b445a62SJohn Marino /* vi_mode.c -- A vi emulation mode for Bash.
2*6b445a62SJohn Marino Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
3*6b445a62SJohn Marino
4*6b445a62SJohn Marino /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
5*6b445a62SJohn Marino
6*6b445a62SJohn Marino This file is part of the GNU Readline Library (Readline), a library
7*6b445a62SJohn Marino for reading lines of text with interactive input and history editing.
8*6b445a62SJohn Marino
9*6b445a62SJohn Marino Readline is free software: you can redistribute it and/or modify
10*6b445a62SJohn Marino it under the terms of the GNU General Public License as published by
11*6b445a62SJohn Marino the Free Software Foundation, either version 3 of the License, or
12*6b445a62SJohn Marino (at your option) any later version.
13*6b445a62SJohn Marino
14*6b445a62SJohn Marino Readline is distributed in the hope that it will be useful,
15*6b445a62SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
16*6b445a62SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17*6b445a62SJohn Marino GNU General Public License for more details.
18*6b445a62SJohn Marino
19*6b445a62SJohn Marino You should have received a copy of the GNU General Public License
20*6b445a62SJohn Marino along with Readline. If not, see <http://www.gnu.org/licenses/>.
21*6b445a62SJohn Marino */
22*6b445a62SJohn Marino
23*6b445a62SJohn Marino #define READLINE_LIBRARY
24*6b445a62SJohn Marino
25*6b445a62SJohn Marino /* **************************************************************** */
26*6b445a62SJohn Marino /* */
27*6b445a62SJohn Marino /* VI Emulation Mode */
28*6b445a62SJohn Marino /* */
29*6b445a62SJohn Marino /* **************************************************************** */
30*6b445a62SJohn Marino #include "rlconf.h"
31*6b445a62SJohn Marino
32*6b445a62SJohn Marino #if defined (VI_MODE)
33*6b445a62SJohn Marino
34*6b445a62SJohn Marino #if defined (HAVE_CONFIG_H)
35*6b445a62SJohn Marino # include <config.h>
36*6b445a62SJohn Marino #endif
37*6b445a62SJohn Marino
38*6b445a62SJohn Marino #include <sys/types.h>
39*6b445a62SJohn Marino
40*6b445a62SJohn Marino #if defined (HAVE_STDLIB_H)
41*6b445a62SJohn Marino # include <stdlib.h>
42*6b445a62SJohn Marino #else
43*6b445a62SJohn Marino # include "ansi_stdlib.h"
44*6b445a62SJohn Marino #endif /* HAVE_STDLIB_H */
45*6b445a62SJohn Marino
46*6b445a62SJohn Marino #if defined (HAVE_UNISTD_H)
47*6b445a62SJohn Marino # include <unistd.h>
48*6b445a62SJohn Marino #endif
49*6b445a62SJohn Marino
50*6b445a62SJohn Marino #include <stdio.h>
51*6b445a62SJohn Marino
52*6b445a62SJohn Marino /* Some standard library routines. */
53*6b445a62SJohn Marino #include "rldefs.h"
54*6b445a62SJohn Marino #include "rlmbutil.h"
55*6b445a62SJohn Marino
56*6b445a62SJohn Marino #include "readline.h"
57*6b445a62SJohn Marino #include "history.h"
58*6b445a62SJohn Marino
59*6b445a62SJohn Marino #include "rlprivate.h"
60*6b445a62SJohn Marino #include "xmalloc.h"
61*6b445a62SJohn Marino
62*6b445a62SJohn Marino #ifndef member
63*6b445a62SJohn Marino #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
64*6b445a62SJohn Marino #endif
65*6b445a62SJohn Marino
66*6b445a62SJohn Marino int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
67*6b445a62SJohn Marino
68*6b445a62SJohn Marino _rl_vimotion_cxt *_rl_vimvcxt = 0;
69*6b445a62SJohn Marino
70*6b445a62SJohn Marino /* Non-zero means enter insertion mode. */
71*6b445a62SJohn Marino static int _rl_vi_doing_insert;
72*6b445a62SJohn Marino
73*6b445a62SJohn Marino /* Command keys which do movement for xxx_to commands. */
74*6b445a62SJohn Marino static const char * const vi_motion = " hl^$0ftFT;,%wbeWBE|`";
75*6b445a62SJohn Marino
76*6b445a62SJohn Marino /* Keymap used for vi replace characters. Created dynamically since
77*6b445a62SJohn Marino rarely used. */
78*6b445a62SJohn Marino static Keymap vi_replace_map;
79*6b445a62SJohn Marino
80*6b445a62SJohn Marino /* The number of characters inserted in the last replace operation. */
81*6b445a62SJohn Marino static int vi_replace_count;
82*6b445a62SJohn Marino
83*6b445a62SJohn Marino /* If non-zero, we have text inserted after a c[motion] command that put
84*6b445a62SJohn Marino us implicitly into insert mode. Some people want this text to be
85*6b445a62SJohn Marino attached to the command so that it is `redoable' with `.'. */
86*6b445a62SJohn Marino static int vi_continued_command;
87*6b445a62SJohn Marino static char *vi_insert_buffer;
88*6b445a62SJohn Marino static int vi_insert_buffer_size;
89*6b445a62SJohn Marino
90*6b445a62SJohn Marino static int _rl_vi_last_repeat = 1;
91*6b445a62SJohn Marino static int _rl_vi_last_arg_sign = 1;
92*6b445a62SJohn Marino static int _rl_vi_last_motion;
93*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
94*6b445a62SJohn Marino static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
95*6b445a62SJohn Marino static int _rl_vi_last_search_mblen;
96*6b445a62SJohn Marino #else
97*6b445a62SJohn Marino static int _rl_vi_last_search_char;
98*6b445a62SJohn Marino #endif
99*6b445a62SJohn Marino static int _rl_vi_last_replacement;
100*6b445a62SJohn Marino
101*6b445a62SJohn Marino static int _rl_vi_last_key_before_insert;
102*6b445a62SJohn Marino
103*6b445a62SJohn Marino static int vi_redoing;
104*6b445a62SJohn Marino
105*6b445a62SJohn Marino /* Text modification commands. These are the `redoable' commands. */
106*6b445a62SJohn Marino static const char * const vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
107*6b445a62SJohn Marino
108*6b445a62SJohn Marino /* Arrays for the saved marks. */
109*6b445a62SJohn Marino static int vi_mark_chars['z' - 'a' + 1];
110*6b445a62SJohn Marino
111*6b445a62SJohn Marino static void _rl_vi_stuff_insert PARAMS((int));
112*6b445a62SJohn Marino static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
113*6b445a62SJohn Marino
114*6b445a62SJohn Marino static void _rl_vi_backup PARAMS((void));
115*6b445a62SJohn Marino
116*6b445a62SJohn Marino static int _rl_vi_arg_dispatch PARAMS((int));
117*6b445a62SJohn Marino static int rl_digit_loop1 PARAMS((void));
118*6b445a62SJohn Marino
119*6b445a62SJohn Marino static int _rl_vi_set_mark PARAMS((void));
120*6b445a62SJohn Marino static int _rl_vi_goto_mark PARAMS((void));
121*6b445a62SJohn Marino
122*6b445a62SJohn Marino static void _rl_vi_append_forward PARAMS((int));
123*6b445a62SJohn Marino
124*6b445a62SJohn Marino static int _rl_vi_callback_getchar PARAMS((char *, int));
125*6b445a62SJohn Marino
126*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
127*6b445a62SJohn Marino static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
128*6b445a62SJohn Marino static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
129*6b445a62SJohn Marino static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
130*6b445a62SJohn Marino static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
131*6b445a62SJohn Marino #endif
132*6b445a62SJohn Marino
133*6b445a62SJohn Marino static int rl_domove_read_callback PARAMS((_rl_vimotion_cxt *));
134*6b445a62SJohn Marino static int rl_domove_motion_callback PARAMS((_rl_vimotion_cxt *));
135*6b445a62SJohn Marino static int rl_vi_domove_getchar PARAMS((_rl_vimotion_cxt *));
136*6b445a62SJohn Marino
137*6b445a62SJohn Marino static int vi_change_dispatch PARAMS((_rl_vimotion_cxt *));
138*6b445a62SJohn Marino static int vi_delete_dispatch PARAMS((_rl_vimotion_cxt *));
139*6b445a62SJohn Marino static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *));
140*6b445a62SJohn Marino
141*6b445a62SJohn Marino static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));
142*6b445a62SJohn Marino
143*6b445a62SJohn Marino void
_rl_vi_initialize_line()144*6b445a62SJohn Marino _rl_vi_initialize_line ()
145*6b445a62SJohn Marino {
146*6b445a62SJohn Marino register int i, n;
147*6b445a62SJohn Marino
148*6b445a62SJohn Marino n = sizeof (vi_mark_chars) / sizeof (vi_mark_chars[0]);
149*6b445a62SJohn Marino for (i = 0; i < n; i++)
150*6b445a62SJohn Marino vi_mark_chars[i] = -1;
151*6b445a62SJohn Marino
152*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_VICMDONCE);
153*6b445a62SJohn Marino }
154*6b445a62SJohn Marino
155*6b445a62SJohn Marino void
_rl_vi_reset_last()156*6b445a62SJohn Marino _rl_vi_reset_last ()
157*6b445a62SJohn Marino {
158*6b445a62SJohn Marino _rl_vi_last_command = 'i';
159*6b445a62SJohn Marino _rl_vi_last_repeat = 1;
160*6b445a62SJohn Marino _rl_vi_last_arg_sign = 1;
161*6b445a62SJohn Marino _rl_vi_last_motion = 0;
162*6b445a62SJohn Marino }
163*6b445a62SJohn Marino
164*6b445a62SJohn Marino void
_rl_vi_set_last(key,repeat,sign)165*6b445a62SJohn Marino _rl_vi_set_last (key, repeat, sign)
166*6b445a62SJohn Marino int key, repeat, sign;
167*6b445a62SJohn Marino {
168*6b445a62SJohn Marino _rl_vi_last_command = key;
169*6b445a62SJohn Marino _rl_vi_last_repeat = repeat;
170*6b445a62SJohn Marino _rl_vi_last_arg_sign = sign;
171*6b445a62SJohn Marino }
172*6b445a62SJohn Marino
173*6b445a62SJohn Marino /* A convenience function that calls _rl_vi_set_last to save the last command
174*6b445a62SJohn Marino information and enters insertion mode. */
175*6b445a62SJohn Marino void
rl_vi_start_inserting(key,repeat,sign)176*6b445a62SJohn Marino rl_vi_start_inserting (key, repeat, sign)
177*6b445a62SJohn Marino int key, repeat, sign;
178*6b445a62SJohn Marino {
179*6b445a62SJohn Marino _rl_vi_set_last (key, repeat, sign);
180*6b445a62SJohn Marino rl_vi_insertion_mode (1, key);
181*6b445a62SJohn Marino }
182*6b445a62SJohn Marino
183*6b445a62SJohn Marino /* Is the command C a VI mode text modification command? */
184*6b445a62SJohn Marino int
_rl_vi_textmod_command(c)185*6b445a62SJohn Marino _rl_vi_textmod_command (c)
186*6b445a62SJohn Marino int c;
187*6b445a62SJohn Marino {
188*6b445a62SJohn Marino return (member (c, vi_textmod));
189*6b445a62SJohn Marino }
190*6b445a62SJohn Marino
191*6b445a62SJohn Marino static void
_rl_vi_stuff_insert(count)192*6b445a62SJohn Marino _rl_vi_stuff_insert (count)
193*6b445a62SJohn Marino int count;
194*6b445a62SJohn Marino {
195*6b445a62SJohn Marino rl_begin_undo_group ();
196*6b445a62SJohn Marino while (count--)
197*6b445a62SJohn Marino rl_insert_text (vi_insert_buffer);
198*6b445a62SJohn Marino rl_end_undo_group ();
199*6b445a62SJohn Marino }
200*6b445a62SJohn Marino
201*6b445a62SJohn Marino /* Bound to `.'. Called from command mode, so we know that we have to
202*6b445a62SJohn Marino redo a text modification command. The default for _rl_vi_last_command
203*6b445a62SJohn Marino puts you back into insert mode. */
204*6b445a62SJohn Marino int
rl_vi_redo(count,c)205*6b445a62SJohn Marino rl_vi_redo (count, c)
206*6b445a62SJohn Marino int count, c;
207*6b445a62SJohn Marino {
208*6b445a62SJohn Marino int r;
209*6b445a62SJohn Marino
210*6b445a62SJohn Marino if (!rl_explicit_arg)
211*6b445a62SJohn Marino {
212*6b445a62SJohn Marino rl_numeric_arg = _rl_vi_last_repeat;
213*6b445a62SJohn Marino rl_arg_sign = _rl_vi_last_arg_sign;
214*6b445a62SJohn Marino }
215*6b445a62SJohn Marino
216*6b445a62SJohn Marino r = 0;
217*6b445a62SJohn Marino vi_redoing = 1;
218*6b445a62SJohn Marino /* If we're redoing an insert with `i', stuff in the inserted text
219*6b445a62SJohn Marino and do not go into insertion mode. */
220*6b445a62SJohn Marino if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
221*6b445a62SJohn Marino {
222*6b445a62SJohn Marino _rl_vi_stuff_insert (count);
223*6b445a62SJohn Marino /* And back up point over the last character inserted. */
224*6b445a62SJohn Marino if (rl_point > 0)
225*6b445a62SJohn Marino _rl_vi_backup ();
226*6b445a62SJohn Marino }
227*6b445a62SJohn Marino /* Ditto for redoing an insert with `I', but move to the beginning of the
228*6b445a62SJohn Marino line like the `I' command does. */
229*6b445a62SJohn Marino else if (_rl_vi_last_command == 'I' && vi_insert_buffer && *vi_insert_buffer)
230*6b445a62SJohn Marino {
231*6b445a62SJohn Marino rl_beg_of_line (1, 'I');
232*6b445a62SJohn Marino _rl_vi_stuff_insert (count);
233*6b445a62SJohn Marino if (rl_point > 0)
234*6b445a62SJohn Marino _rl_vi_backup ();
235*6b445a62SJohn Marino }
236*6b445a62SJohn Marino /* Ditto for redoing an insert with `a', but move forward a character first
237*6b445a62SJohn Marino like the `a' command does. */
238*6b445a62SJohn Marino else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer)
239*6b445a62SJohn Marino {
240*6b445a62SJohn Marino _rl_vi_append_forward ('a');
241*6b445a62SJohn Marino _rl_vi_stuff_insert (count);
242*6b445a62SJohn Marino if (rl_point > 0)
243*6b445a62SJohn Marino _rl_vi_backup ();
244*6b445a62SJohn Marino }
245*6b445a62SJohn Marino /* Ditto for redoing an insert with `A', but move to the end of the line
246*6b445a62SJohn Marino like the `A' command does. */
247*6b445a62SJohn Marino else if (_rl_vi_last_command == 'A' && vi_insert_buffer && *vi_insert_buffer)
248*6b445a62SJohn Marino {
249*6b445a62SJohn Marino rl_end_of_line (1, 'A');
250*6b445a62SJohn Marino _rl_vi_stuff_insert (count);
251*6b445a62SJohn Marino if (rl_point > 0)
252*6b445a62SJohn Marino _rl_vi_backup ();
253*6b445a62SJohn Marino }
254*6b445a62SJohn Marino else
255*6b445a62SJohn Marino r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
256*6b445a62SJohn Marino vi_redoing = 0;
257*6b445a62SJohn Marino
258*6b445a62SJohn Marino return (r);
259*6b445a62SJohn Marino }
260*6b445a62SJohn Marino
261*6b445a62SJohn Marino /* A placeholder for further expansion. */
262*6b445a62SJohn Marino int
rl_vi_undo(count,key)263*6b445a62SJohn Marino rl_vi_undo (count, key)
264*6b445a62SJohn Marino int count, key;
265*6b445a62SJohn Marino {
266*6b445a62SJohn Marino return (rl_undo_command (count, key));
267*6b445a62SJohn Marino }
268*6b445a62SJohn Marino
269*6b445a62SJohn Marino /* Yank the nth arg from the previous line into this line at point. */
270*6b445a62SJohn Marino int
rl_vi_yank_arg(count,key)271*6b445a62SJohn Marino rl_vi_yank_arg (count, key)
272*6b445a62SJohn Marino int count, key;
273*6b445a62SJohn Marino {
274*6b445a62SJohn Marino /* Readline thinks that the first word on a line is the 0th, while vi
275*6b445a62SJohn Marino thinks the first word on a line is the 1st. Compensate. */
276*6b445a62SJohn Marino if (rl_explicit_arg)
277*6b445a62SJohn Marino rl_yank_nth_arg (count - 1, 0);
278*6b445a62SJohn Marino else
279*6b445a62SJohn Marino rl_yank_nth_arg ('$', 0);
280*6b445a62SJohn Marino
281*6b445a62SJohn Marino return (0);
282*6b445a62SJohn Marino }
283*6b445a62SJohn Marino
284*6b445a62SJohn Marino /* With an argument, move back that many history lines, else move to the
285*6b445a62SJohn Marino beginning of history. */
286*6b445a62SJohn Marino int
rl_vi_fetch_history(count,c)287*6b445a62SJohn Marino rl_vi_fetch_history (count, c)
288*6b445a62SJohn Marino int count, c;
289*6b445a62SJohn Marino {
290*6b445a62SJohn Marino int wanted;
291*6b445a62SJohn Marino
292*6b445a62SJohn Marino /* Giving an argument of n means we want the nth command in the history
293*6b445a62SJohn Marino file. The command number is interpreted the same way that the bash
294*6b445a62SJohn Marino `history' command does it -- that is, giving an argument count of 450
295*6b445a62SJohn Marino to this command would get the command listed as number 450 in the
296*6b445a62SJohn Marino output of `history'. */
297*6b445a62SJohn Marino if (rl_explicit_arg)
298*6b445a62SJohn Marino {
299*6b445a62SJohn Marino wanted = history_base + where_history () - count;
300*6b445a62SJohn Marino if (wanted <= 0)
301*6b445a62SJohn Marino rl_beginning_of_history (0, 0);
302*6b445a62SJohn Marino else
303*6b445a62SJohn Marino rl_get_previous_history (wanted, c);
304*6b445a62SJohn Marino }
305*6b445a62SJohn Marino else
306*6b445a62SJohn Marino rl_beginning_of_history (count, 0);
307*6b445a62SJohn Marino return (0);
308*6b445a62SJohn Marino }
309*6b445a62SJohn Marino
310*6b445a62SJohn Marino /* Search again for the last thing searched for. */
311*6b445a62SJohn Marino int
rl_vi_search_again(count,key)312*6b445a62SJohn Marino rl_vi_search_again (count, key)
313*6b445a62SJohn Marino int count, key;
314*6b445a62SJohn Marino {
315*6b445a62SJohn Marino switch (key)
316*6b445a62SJohn Marino {
317*6b445a62SJohn Marino case 'n':
318*6b445a62SJohn Marino rl_noninc_reverse_search_again (count, key);
319*6b445a62SJohn Marino break;
320*6b445a62SJohn Marino
321*6b445a62SJohn Marino case 'N':
322*6b445a62SJohn Marino rl_noninc_forward_search_again (count, key);
323*6b445a62SJohn Marino break;
324*6b445a62SJohn Marino }
325*6b445a62SJohn Marino return (0);
326*6b445a62SJohn Marino }
327*6b445a62SJohn Marino
328*6b445a62SJohn Marino /* Do a vi style search. */
329*6b445a62SJohn Marino int
rl_vi_search(count,key)330*6b445a62SJohn Marino rl_vi_search (count, key)
331*6b445a62SJohn Marino int count, key;
332*6b445a62SJohn Marino {
333*6b445a62SJohn Marino switch (key)
334*6b445a62SJohn Marino {
335*6b445a62SJohn Marino case '?':
336*6b445a62SJohn Marino _rl_free_saved_history_line ();
337*6b445a62SJohn Marino rl_noninc_forward_search (count, key);
338*6b445a62SJohn Marino break;
339*6b445a62SJohn Marino
340*6b445a62SJohn Marino case '/':
341*6b445a62SJohn Marino _rl_free_saved_history_line ();
342*6b445a62SJohn Marino rl_noninc_reverse_search (count, key);
343*6b445a62SJohn Marino break;
344*6b445a62SJohn Marino
345*6b445a62SJohn Marino default:
346*6b445a62SJohn Marino rl_ding ();
347*6b445a62SJohn Marino break;
348*6b445a62SJohn Marino }
349*6b445a62SJohn Marino return (0);
350*6b445a62SJohn Marino }
351*6b445a62SJohn Marino
352*6b445a62SJohn Marino /* Completion, from vi's point of view. */
353*6b445a62SJohn Marino int
rl_vi_complete(ignore,key)354*6b445a62SJohn Marino rl_vi_complete (ignore, key)
355*6b445a62SJohn Marino int ignore, key;
356*6b445a62SJohn Marino {
357*6b445a62SJohn Marino if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
358*6b445a62SJohn Marino {
359*6b445a62SJohn Marino if (!whitespace (rl_line_buffer[rl_point + 1]))
360*6b445a62SJohn Marino rl_vi_end_word (1, 'E');
361*6b445a62SJohn Marino rl_point++;
362*6b445a62SJohn Marino }
363*6b445a62SJohn Marino
364*6b445a62SJohn Marino if (key == '*')
365*6b445a62SJohn Marino rl_complete_internal ('*'); /* Expansion and replacement. */
366*6b445a62SJohn Marino else if (key == '=')
367*6b445a62SJohn Marino rl_complete_internal ('?'); /* List possible completions. */
368*6b445a62SJohn Marino else if (key == '\\')
369*6b445a62SJohn Marino rl_complete_internal (TAB); /* Standard Readline completion. */
370*6b445a62SJohn Marino else
371*6b445a62SJohn Marino rl_complete (0, key);
372*6b445a62SJohn Marino
373*6b445a62SJohn Marino if (key == '*' || key == '\\')
374*6b445a62SJohn Marino rl_vi_start_inserting (key, 1, rl_arg_sign);
375*6b445a62SJohn Marino
376*6b445a62SJohn Marino return (0);
377*6b445a62SJohn Marino }
378*6b445a62SJohn Marino
379*6b445a62SJohn Marino /* Tilde expansion for vi mode. */
380*6b445a62SJohn Marino int
rl_vi_tilde_expand(ignore,key)381*6b445a62SJohn Marino rl_vi_tilde_expand (ignore, key)
382*6b445a62SJohn Marino int ignore, key;
383*6b445a62SJohn Marino {
384*6b445a62SJohn Marino rl_tilde_expand (0, key);
385*6b445a62SJohn Marino rl_vi_start_inserting (key, 1, rl_arg_sign);
386*6b445a62SJohn Marino return (0);
387*6b445a62SJohn Marino }
388*6b445a62SJohn Marino
389*6b445a62SJohn Marino /* Previous word in vi mode. */
390*6b445a62SJohn Marino int
rl_vi_prev_word(count,key)391*6b445a62SJohn Marino rl_vi_prev_word (count, key)
392*6b445a62SJohn Marino int count, key;
393*6b445a62SJohn Marino {
394*6b445a62SJohn Marino if (count < 0)
395*6b445a62SJohn Marino return (rl_vi_next_word (-count, key));
396*6b445a62SJohn Marino
397*6b445a62SJohn Marino if (rl_point == 0)
398*6b445a62SJohn Marino {
399*6b445a62SJohn Marino rl_ding ();
400*6b445a62SJohn Marino return (0);
401*6b445a62SJohn Marino }
402*6b445a62SJohn Marino
403*6b445a62SJohn Marino if (_rl_uppercase_p (key))
404*6b445a62SJohn Marino rl_vi_bWord (count, key);
405*6b445a62SJohn Marino else
406*6b445a62SJohn Marino rl_vi_bword (count, key);
407*6b445a62SJohn Marino
408*6b445a62SJohn Marino return (0);
409*6b445a62SJohn Marino }
410*6b445a62SJohn Marino
411*6b445a62SJohn Marino /* Next word in vi mode. */
412*6b445a62SJohn Marino int
rl_vi_next_word(count,key)413*6b445a62SJohn Marino rl_vi_next_word (count, key)
414*6b445a62SJohn Marino int count, key;
415*6b445a62SJohn Marino {
416*6b445a62SJohn Marino if (count < 0)
417*6b445a62SJohn Marino return (rl_vi_prev_word (-count, key));
418*6b445a62SJohn Marino
419*6b445a62SJohn Marino if (rl_point >= (rl_end - 1))
420*6b445a62SJohn Marino {
421*6b445a62SJohn Marino rl_ding ();
422*6b445a62SJohn Marino return (0);
423*6b445a62SJohn Marino }
424*6b445a62SJohn Marino
425*6b445a62SJohn Marino if (_rl_uppercase_p (key))
426*6b445a62SJohn Marino rl_vi_fWord (count, key);
427*6b445a62SJohn Marino else
428*6b445a62SJohn Marino rl_vi_fword (count, key);
429*6b445a62SJohn Marino return (0);
430*6b445a62SJohn Marino }
431*6b445a62SJohn Marino
432*6b445a62SJohn Marino /* Move to the end of the ?next? word. */
433*6b445a62SJohn Marino int
rl_vi_end_word(count,key)434*6b445a62SJohn Marino rl_vi_end_word (count, key)
435*6b445a62SJohn Marino int count, key;
436*6b445a62SJohn Marino {
437*6b445a62SJohn Marino if (count < 0)
438*6b445a62SJohn Marino {
439*6b445a62SJohn Marino rl_ding ();
440*6b445a62SJohn Marino return -1;
441*6b445a62SJohn Marino }
442*6b445a62SJohn Marino
443*6b445a62SJohn Marino if (_rl_uppercase_p (key))
444*6b445a62SJohn Marino rl_vi_eWord (count, key);
445*6b445a62SJohn Marino else
446*6b445a62SJohn Marino rl_vi_eword (count, key);
447*6b445a62SJohn Marino return (0);
448*6b445a62SJohn Marino }
449*6b445a62SJohn Marino
450*6b445a62SJohn Marino /* Move forward a word the way that 'W' does. */
451*6b445a62SJohn Marino int
rl_vi_fWord(count,ignore)452*6b445a62SJohn Marino rl_vi_fWord (count, ignore)
453*6b445a62SJohn Marino int count, ignore;
454*6b445a62SJohn Marino {
455*6b445a62SJohn Marino while (count-- && rl_point < (rl_end - 1))
456*6b445a62SJohn Marino {
457*6b445a62SJohn Marino /* Skip until whitespace. */
458*6b445a62SJohn Marino while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
459*6b445a62SJohn Marino rl_point++;
460*6b445a62SJohn Marino
461*6b445a62SJohn Marino /* Now skip whitespace. */
462*6b445a62SJohn Marino while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
463*6b445a62SJohn Marino rl_point++;
464*6b445a62SJohn Marino }
465*6b445a62SJohn Marino return (0);
466*6b445a62SJohn Marino }
467*6b445a62SJohn Marino
468*6b445a62SJohn Marino int
rl_vi_bWord(count,ignore)469*6b445a62SJohn Marino rl_vi_bWord (count, ignore)
470*6b445a62SJohn Marino int count, ignore;
471*6b445a62SJohn Marino {
472*6b445a62SJohn Marino while (count-- && rl_point > 0)
473*6b445a62SJohn Marino {
474*6b445a62SJohn Marino /* If we are at the start of a word, move back to whitespace so
475*6b445a62SJohn Marino we will go back to the start of the previous word. */
476*6b445a62SJohn Marino if (!whitespace (rl_line_buffer[rl_point]) &&
477*6b445a62SJohn Marino whitespace (rl_line_buffer[rl_point - 1]))
478*6b445a62SJohn Marino rl_point--;
479*6b445a62SJohn Marino
480*6b445a62SJohn Marino while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
481*6b445a62SJohn Marino rl_point--;
482*6b445a62SJohn Marino
483*6b445a62SJohn Marino if (rl_point > 0)
484*6b445a62SJohn Marino {
485*6b445a62SJohn Marino while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
486*6b445a62SJohn Marino rl_point++;
487*6b445a62SJohn Marino }
488*6b445a62SJohn Marino }
489*6b445a62SJohn Marino return (0);
490*6b445a62SJohn Marino }
491*6b445a62SJohn Marino
492*6b445a62SJohn Marino int
rl_vi_eWord(count,ignore)493*6b445a62SJohn Marino rl_vi_eWord (count, ignore)
494*6b445a62SJohn Marino int count, ignore;
495*6b445a62SJohn Marino {
496*6b445a62SJohn Marino while (count-- && rl_point < (rl_end - 1))
497*6b445a62SJohn Marino {
498*6b445a62SJohn Marino if (!whitespace (rl_line_buffer[rl_point]))
499*6b445a62SJohn Marino rl_point++;
500*6b445a62SJohn Marino
501*6b445a62SJohn Marino /* Move to the next non-whitespace character (to the start of the
502*6b445a62SJohn Marino next word). */
503*6b445a62SJohn Marino while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
504*6b445a62SJohn Marino rl_point++;
505*6b445a62SJohn Marino
506*6b445a62SJohn Marino if (rl_point && rl_point < rl_end)
507*6b445a62SJohn Marino {
508*6b445a62SJohn Marino /* Skip whitespace. */
509*6b445a62SJohn Marino while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
510*6b445a62SJohn Marino rl_point++;
511*6b445a62SJohn Marino
512*6b445a62SJohn Marino /* Skip until whitespace. */
513*6b445a62SJohn Marino while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
514*6b445a62SJohn Marino rl_point++;
515*6b445a62SJohn Marino
516*6b445a62SJohn Marino /* Move back to the last character of the word. */
517*6b445a62SJohn Marino rl_point--;
518*6b445a62SJohn Marino }
519*6b445a62SJohn Marino }
520*6b445a62SJohn Marino return (0);
521*6b445a62SJohn Marino }
522*6b445a62SJohn Marino
523*6b445a62SJohn Marino int
rl_vi_fword(count,ignore)524*6b445a62SJohn Marino rl_vi_fword (count, ignore)
525*6b445a62SJohn Marino int count, ignore;
526*6b445a62SJohn Marino {
527*6b445a62SJohn Marino while (count-- && rl_point < (rl_end - 1))
528*6b445a62SJohn Marino {
529*6b445a62SJohn Marino /* Move to white space (really non-identifer). */
530*6b445a62SJohn Marino if (_rl_isident (rl_line_buffer[rl_point]))
531*6b445a62SJohn Marino {
532*6b445a62SJohn Marino while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
533*6b445a62SJohn Marino rl_point++;
534*6b445a62SJohn Marino }
535*6b445a62SJohn Marino else /* if (!whitespace (rl_line_buffer[rl_point])) */
536*6b445a62SJohn Marino {
537*6b445a62SJohn Marino while (!_rl_isident (rl_line_buffer[rl_point]) &&
538*6b445a62SJohn Marino !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
539*6b445a62SJohn Marino rl_point++;
540*6b445a62SJohn Marino }
541*6b445a62SJohn Marino
542*6b445a62SJohn Marino /* Move past whitespace. */
543*6b445a62SJohn Marino while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
544*6b445a62SJohn Marino rl_point++;
545*6b445a62SJohn Marino }
546*6b445a62SJohn Marino return (0);
547*6b445a62SJohn Marino }
548*6b445a62SJohn Marino
549*6b445a62SJohn Marino int
rl_vi_bword(count,ignore)550*6b445a62SJohn Marino rl_vi_bword (count, ignore)
551*6b445a62SJohn Marino int count, ignore;
552*6b445a62SJohn Marino {
553*6b445a62SJohn Marino while (count-- && rl_point > 0)
554*6b445a62SJohn Marino {
555*6b445a62SJohn Marino int last_is_ident;
556*6b445a62SJohn Marino
557*6b445a62SJohn Marino /* If we are at the start of a word, move back to whitespace
558*6b445a62SJohn Marino so we will go back to the start of the previous word. */
559*6b445a62SJohn Marino if (!whitespace (rl_line_buffer[rl_point]) &&
560*6b445a62SJohn Marino whitespace (rl_line_buffer[rl_point - 1]))
561*6b445a62SJohn Marino rl_point--;
562*6b445a62SJohn Marino
563*6b445a62SJohn Marino /* If this character and the previous character are `opposite', move
564*6b445a62SJohn Marino back so we don't get messed up by the rl_point++ down there in
565*6b445a62SJohn Marino the while loop. Without this code, words like `l;' screw up the
566*6b445a62SJohn Marino function. */
567*6b445a62SJohn Marino last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
568*6b445a62SJohn Marino if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
569*6b445a62SJohn Marino (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
570*6b445a62SJohn Marino rl_point--;
571*6b445a62SJohn Marino
572*6b445a62SJohn Marino while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
573*6b445a62SJohn Marino rl_point--;
574*6b445a62SJohn Marino
575*6b445a62SJohn Marino if (rl_point > 0)
576*6b445a62SJohn Marino {
577*6b445a62SJohn Marino if (_rl_isident (rl_line_buffer[rl_point]))
578*6b445a62SJohn Marino while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
579*6b445a62SJohn Marino else
580*6b445a62SJohn Marino while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
581*6b445a62SJohn Marino !whitespace (rl_line_buffer[rl_point]));
582*6b445a62SJohn Marino rl_point++;
583*6b445a62SJohn Marino }
584*6b445a62SJohn Marino }
585*6b445a62SJohn Marino return (0);
586*6b445a62SJohn Marino }
587*6b445a62SJohn Marino
588*6b445a62SJohn Marino int
rl_vi_eword(count,ignore)589*6b445a62SJohn Marino rl_vi_eword (count, ignore)
590*6b445a62SJohn Marino int count, ignore;
591*6b445a62SJohn Marino {
592*6b445a62SJohn Marino while (count-- && rl_point < rl_end - 1)
593*6b445a62SJohn Marino {
594*6b445a62SJohn Marino if (!whitespace (rl_line_buffer[rl_point]))
595*6b445a62SJohn Marino rl_point++;
596*6b445a62SJohn Marino
597*6b445a62SJohn Marino while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
598*6b445a62SJohn Marino rl_point++;
599*6b445a62SJohn Marino
600*6b445a62SJohn Marino if (rl_point < rl_end)
601*6b445a62SJohn Marino {
602*6b445a62SJohn Marino if (_rl_isident (rl_line_buffer[rl_point]))
603*6b445a62SJohn Marino while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
604*6b445a62SJohn Marino else
605*6b445a62SJohn Marino while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
606*6b445a62SJohn Marino && !whitespace (rl_line_buffer[rl_point]));
607*6b445a62SJohn Marino }
608*6b445a62SJohn Marino rl_point--;
609*6b445a62SJohn Marino }
610*6b445a62SJohn Marino return (0);
611*6b445a62SJohn Marino }
612*6b445a62SJohn Marino
613*6b445a62SJohn Marino int
rl_vi_insert_beg(count,key)614*6b445a62SJohn Marino rl_vi_insert_beg (count, key)
615*6b445a62SJohn Marino int count, key;
616*6b445a62SJohn Marino {
617*6b445a62SJohn Marino rl_beg_of_line (1, key);
618*6b445a62SJohn Marino rl_vi_insert_mode (1, key);
619*6b445a62SJohn Marino return (0);
620*6b445a62SJohn Marino }
621*6b445a62SJohn Marino
622*6b445a62SJohn Marino static void
_rl_vi_append_forward(key)623*6b445a62SJohn Marino _rl_vi_append_forward (key)
624*6b445a62SJohn Marino int key;
625*6b445a62SJohn Marino {
626*6b445a62SJohn Marino int point;
627*6b445a62SJohn Marino
628*6b445a62SJohn Marino if (rl_point < rl_end)
629*6b445a62SJohn Marino {
630*6b445a62SJohn Marino if (MB_CUR_MAX == 1 || rl_byte_oriented)
631*6b445a62SJohn Marino rl_point++;
632*6b445a62SJohn Marino else
633*6b445a62SJohn Marino {
634*6b445a62SJohn Marino point = rl_point;
635*6b445a62SJohn Marino #if 0
636*6b445a62SJohn Marino rl_forward_char (1, key);
637*6b445a62SJohn Marino #else
638*6b445a62SJohn Marino rl_point = _rl_forward_char_internal (1);
639*6b445a62SJohn Marino #endif
640*6b445a62SJohn Marino if (point == rl_point)
641*6b445a62SJohn Marino rl_point = rl_end;
642*6b445a62SJohn Marino }
643*6b445a62SJohn Marino }
644*6b445a62SJohn Marino }
645*6b445a62SJohn Marino
646*6b445a62SJohn Marino int
rl_vi_append_mode(count,key)647*6b445a62SJohn Marino rl_vi_append_mode (count, key)
648*6b445a62SJohn Marino int count, key;
649*6b445a62SJohn Marino {
650*6b445a62SJohn Marino _rl_vi_append_forward (key);
651*6b445a62SJohn Marino rl_vi_start_inserting (key, 1, rl_arg_sign);
652*6b445a62SJohn Marino return (0);
653*6b445a62SJohn Marino }
654*6b445a62SJohn Marino
655*6b445a62SJohn Marino int
rl_vi_append_eol(count,key)656*6b445a62SJohn Marino rl_vi_append_eol (count, key)
657*6b445a62SJohn Marino int count, key;
658*6b445a62SJohn Marino {
659*6b445a62SJohn Marino rl_end_of_line (1, key);
660*6b445a62SJohn Marino rl_vi_append_mode (1, key);
661*6b445a62SJohn Marino return (0);
662*6b445a62SJohn Marino }
663*6b445a62SJohn Marino
664*6b445a62SJohn Marino /* What to do in the case of C-d. */
665*6b445a62SJohn Marino int
rl_vi_eof_maybe(count,c)666*6b445a62SJohn Marino rl_vi_eof_maybe (count, c)
667*6b445a62SJohn Marino int count, c;
668*6b445a62SJohn Marino {
669*6b445a62SJohn Marino return (rl_newline (1, '\n'));
670*6b445a62SJohn Marino }
671*6b445a62SJohn Marino
672*6b445a62SJohn Marino /* Insertion mode stuff. */
673*6b445a62SJohn Marino
674*6b445a62SJohn Marino /* Switching from one mode to the other really just involves
675*6b445a62SJohn Marino switching keymaps. */
676*6b445a62SJohn Marino int
rl_vi_insertion_mode(count,key)677*6b445a62SJohn Marino rl_vi_insertion_mode (count, key)
678*6b445a62SJohn Marino int count, key;
679*6b445a62SJohn Marino {
680*6b445a62SJohn Marino _rl_keymap = vi_insertion_keymap;
681*6b445a62SJohn Marino _rl_vi_last_key_before_insert = key;
682*6b445a62SJohn Marino return (0);
683*6b445a62SJohn Marino }
684*6b445a62SJohn Marino
685*6b445a62SJohn Marino int
rl_vi_insert_mode(count,key)686*6b445a62SJohn Marino rl_vi_insert_mode (count, key)
687*6b445a62SJohn Marino int count, key;
688*6b445a62SJohn Marino {
689*6b445a62SJohn Marino rl_vi_start_inserting (key, 1, rl_arg_sign);
690*6b445a62SJohn Marino return (0);
691*6b445a62SJohn Marino }
692*6b445a62SJohn Marino
693*6b445a62SJohn Marino static void
_rl_vi_save_insert(up)694*6b445a62SJohn Marino _rl_vi_save_insert (up)
695*6b445a62SJohn Marino UNDO_LIST *up;
696*6b445a62SJohn Marino {
697*6b445a62SJohn Marino int len, start, end;
698*6b445a62SJohn Marino
699*6b445a62SJohn Marino if (up == 0 || up->what != UNDO_INSERT)
700*6b445a62SJohn Marino {
701*6b445a62SJohn Marino if (vi_insert_buffer_size >= 1)
702*6b445a62SJohn Marino vi_insert_buffer[0] = '\0';
703*6b445a62SJohn Marino return;
704*6b445a62SJohn Marino }
705*6b445a62SJohn Marino
706*6b445a62SJohn Marino start = up->start;
707*6b445a62SJohn Marino end = up->end;
708*6b445a62SJohn Marino len = end - start + 1;
709*6b445a62SJohn Marino if (len >= vi_insert_buffer_size)
710*6b445a62SJohn Marino {
711*6b445a62SJohn Marino vi_insert_buffer_size += (len + 32) - (len % 32);
712*6b445a62SJohn Marino vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
713*6b445a62SJohn Marino }
714*6b445a62SJohn Marino strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
715*6b445a62SJohn Marino vi_insert_buffer[len-1] = '\0';
716*6b445a62SJohn Marino }
717*6b445a62SJohn Marino
718*6b445a62SJohn Marino void
_rl_vi_done_inserting()719*6b445a62SJohn Marino _rl_vi_done_inserting ()
720*6b445a62SJohn Marino {
721*6b445a62SJohn Marino if (_rl_vi_doing_insert)
722*6b445a62SJohn Marino {
723*6b445a62SJohn Marino /* The `C', `s', and `S' commands set this. */
724*6b445a62SJohn Marino rl_end_undo_group ();
725*6b445a62SJohn Marino /* Now, the text between rl_undo_list->next->start and
726*6b445a62SJohn Marino rl_undo_list->next->end is what was inserted while in insert
727*6b445a62SJohn Marino mode. It gets copied to VI_INSERT_BUFFER because it depends
728*6b445a62SJohn Marino on absolute indices into the line which may change (though they
729*6b445a62SJohn Marino probably will not). */
730*6b445a62SJohn Marino _rl_vi_doing_insert = 0;
731*6b445a62SJohn Marino _rl_vi_save_insert (rl_undo_list->next);
732*6b445a62SJohn Marino vi_continued_command = 1;
733*6b445a62SJohn Marino }
734*6b445a62SJohn Marino else
735*6b445a62SJohn Marino {
736*6b445a62SJohn Marino if (rl_undo_list && (_rl_vi_last_key_before_insert == 'i' ||
737*6b445a62SJohn Marino _rl_vi_last_key_before_insert == 'a' ||
738*6b445a62SJohn Marino _rl_vi_last_key_before_insert == 'I' ||
739*6b445a62SJohn Marino _rl_vi_last_key_before_insert == 'A'))
740*6b445a62SJohn Marino _rl_vi_save_insert (rl_undo_list);
741*6b445a62SJohn Marino /* XXX - Other keys probably need to be checked. */
742*6b445a62SJohn Marino else if (_rl_vi_last_key_before_insert == 'C')
743*6b445a62SJohn Marino rl_end_undo_group ();
744*6b445a62SJohn Marino while (_rl_undo_group_level > 0)
745*6b445a62SJohn Marino rl_end_undo_group ();
746*6b445a62SJohn Marino vi_continued_command = 0;
747*6b445a62SJohn Marino }
748*6b445a62SJohn Marino }
749*6b445a62SJohn Marino
750*6b445a62SJohn Marino int
rl_vi_movement_mode(count,key)751*6b445a62SJohn Marino rl_vi_movement_mode (count, key)
752*6b445a62SJohn Marino int count, key;
753*6b445a62SJohn Marino {
754*6b445a62SJohn Marino if (rl_point > 0)
755*6b445a62SJohn Marino rl_backward_char (1, key);
756*6b445a62SJohn Marino
757*6b445a62SJohn Marino _rl_keymap = vi_movement_keymap;
758*6b445a62SJohn Marino _rl_vi_done_inserting ();
759*6b445a62SJohn Marino
760*6b445a62SJohn Marino /* This is how POSIX.2 says `U' should behave -- everything up until the
761*6b445a62SJohn Marino first time you go into command mode should not be undone. */
762*6b445a62SJohn Marino if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
763*6b445a62SJohn Marino rl_free_undo_list ();
764*6b445a62SJohn Marino
765*6b445a62SJohn Marino RL_SETSTATE (RL_STATE_VICMDONCE);
766*6b445a62SJohn Marino return (0);
767*6b445a62SJohn Marino }
768*6b445a62SJohn Marino
769*6b445a62SJohn Marino int
rl_vi_arg_digit(count,c)770*6b445a62SJohn Marino rl_vi_arg_digit (count, c)
771*6b445a62SJohn Marino int count, c;
772*6b445a62SJohn Marino {
773*6b445a62SJohn Marino if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
774*6b445a62SJohn Marino return (rl_beg_of_line (1, c));
775*6b445a62SJohn Marino else
776*6b445a62SJohn Marino return (rl_digit_argument (count, c));
777*6b445a62SJohn Marino }
778*6b445a62SJohn Marino
779*6b445a62SJohn Marino /* Change the case of the next COUNT characters. */
780*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
781*6b445a62SJohn Marino static int
_rl_vi_change_mbchar_case(count)782*6b445a62SJohn Marino _rl_vi_change_mbchar_case (count)
783*6b445a62SJohn Marino int count;
784*6b445a62SJohn Marino {
785*6b445a62SJohn Marino wchar_t wc;
786*6b445a62SJohn Marino char mb[MB_LEN_MAX+1];
787*6b445a62SJohn Marino int mlen, p;
788*6b445a62SJohn Marino size_t m;
789*6b445a62SJohn Marino mbstate_t ps;
790*6b445a62SJohn Marino
791*6b445a62SJohn Marino memset (&ps, 0, sizeof (mbstate_t));
792*6b445a62SJohn Marino if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
793*6b445a62SJohn Marino count--;
794*6b445a62SJohn Marino while (count-- && rl_point < rl_end)
795*6b445a62SJohn Marino {
796*6b445a62SJohn Marino m = mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
797*6b445a62SJohn Marino if (MB_INVALIDCH (m))
798*6b445a62SJohn Marino wc = (wchar_t)rl_line_buffer[rl_point];
799*6b445a62SJohn Marino else if (MB_NULLWCH (m))
800*6b445a62SJohn Marino wc = L'\0';
801*6b445a62SJohn Marino if (iswupper (wc))
802*6b445a62SJohn Marino wc = towlower (wc);
803*6b445a62SJohn Marino else if (iswlower (wc))
804*6b445a62SJohn Marino wc = towupper (wc);
805*6b445a62SJohn Marino else
806*6b445a62SJohn Marino {
807*6b445a62SJohn Marino /* Just skip over chars neither upper nor lower case */
808*6b445a62SJohn Marino rl_forward_char (1, 0);
809*6b445a62SJohn Marino continue;
810*6b445a62SJohn Marino }
811*6b445a62SJohn Marino
812*6b445a62SJohn Marino /* Vi is kind of strange here. */
813*6b445a62SJohn Marino if (wc)
814*6b445a62SJohn Marino {
815*6b445a62SJohn Marino p = rl_point;
816*6b445a62SJohn Marino mlen = wcrtomb (mb, wc, &ps);
817*6b445a62SJohn Marino if (mlen >= 0)
818*6b445a62SJohn Marino mb[mlen] = '\0';
819*6b445a62SJohn Marino rl_begin_undo_group ();
820*6b445a62SJohn Marino rl_vi_delete (1, 0);
821*6b445a62SJohn Marino if (rl_point < p) /* Did we retreat at EOL? */
822*6b445a62SJohn Marino rl_point++; /* XXX - should we advance more than 1 for mbchar? */
823*6b445a62SJohn Marino rl_insert_text (mb);
824*6b445a62SJohn Marino rl_end_undo_group ();
825*6b445a62SJohn Marino rl_vi_check ();
826*6b445a62SJohn Marino }
827*6b445a62SJohn Marino else
828*6b445a62SJohn Marino rl_forward_char (1, 0);
829*6b445a62SJohn Marino }
830*6b445a62SJohn Marino
831*6b445a62SJohn Marino return 0;
832*6b445a62SJohn Marino }
833*6b445a62SJohn Marino #endif
834*6b445a62SJohn Marino
835*6b445a62SJohn Marino int
rl_vi_change_case(count,ignore)836*6b445a62SJohn Marino rl_vi_change_case (count, ignore)
837*6b445a62SJohn Marino int count, ignore;
838*6b445a62SJohn Marino {
839*6b445a62SJohn Marino int c, p;
840*6b445a62SJohn Marino
841*6b445a62SJohn Marino /* Don't try this on an empty line. */
842*6b445a62SJohn Marino if (rl_point >= rl_end)
843*6b445a62SJohn Marino return (0);
844*6b445a62SJohn Marino
845*6b445a62SJohn Marino c = 0;
846*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
847*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
848*6b445a62SJohn Marino return (_rl_vi_change_mbchar_case (count));
849*6b445a62SJohn Marino #endif
850*6b445a62SJohn Marino
851*6b445a62SJohn Marino while (count-- && rl_point < rl_end)
852*6b445a62SJohn Marino {
853*6b445a62SJohn Marino if (_rl_uppercase_p (rl_line_buffer[rl_point]))
854*6b445a62SJohn Marino c = _rl_to_lower (rl_line_buffer[rl_point]);
855*6b445a62SJohn Marino else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
856*6b445a62SJohn Marino c = _rl_to_upper (rl_line_buffer[rl_point]);
857*6b445a62SJohn Marino else
858*6b445a62SJohn Marino {
859*6b445a62SJohn Marino /* Just skip over characters neither upper nor lower case. */
860*6b445a62SJohn Marino rl_forward_char (1, c);
861*6b445a62SJohn Marino continue;
862*6b445a62SJohn Marino }
863*6b445a62SJohn Marino
864*6b445a62SJohn Marino /* Vi is kind of strange here. */
865*6b445a62SJohn Marino if (c)
866*6b445a62SJohn Marino {
867*6b445a62SJohn Marino p = rl_point;
868*6b445a62SJohn Marino rl_begin_undo_group ();
869*6b445a62SJohn Marino rl_vi_delete (1, c);
870*6b445a62SJohn Marino if (rl_point < p) /* Did we retreat at EOL? */
871*6b445a62SJohn Marino rl_point++;
872*6b445a62SJohn Marino _rl_insert_char (1, c);
873*6b445a62SJohn Marino rl_end_undo_group ();
874*6b445a62SJohn Marino rl_vi_check ();
875*6b445a62SJohn Marino }
876*6b445a62SJohn Marino else
877*6b445a62SJohn Marino rl_forward_char (1, c);
878*6b445a62SJohn Marino }
879*6b445a62SJohn Marino return (0);
880*6b445a62SJohn Marino }
881*6b445a62SJohn Marino
882*6b445a62SJohn Marino int
rl_vi_put(count,key)883*6b445a62SJohn Marino rl_vi_put (count, key)
884*6b445a62SJohn Marino int count, key;
885*6b445a62SJohn Marino {
886*6b445a62SJohn Marino if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
887*6b445a62SJohn Marino rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
888*6b445a62SJohn Marino
889*6b445a62SJohn Marino while (count--)
890*6b445a62SJohn Marino rl_yank (1, key);
891*6b445a62SJohn Marino
892*6b445a62SJohn Marino rl_backward_char (1, key);
893*6b445a62SJohn Marino return (0);
894*6b445a62SJohn Marino }
895*6b445a62SJohn Marino
896*6b445a62SJohn Marino static void
_rl_vi_backup()897*6b445a62SJohn Marino _rl_vi_backup ()
898*6b445a62SJohn Marino {
899*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
900*6b445a62SJohn Marino rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
901*6b445a62SJohn Marino else
902*6b445a62SJohn Marino rl_point--;
903*6b445a62SJohn Marino }
904*6b445a62SJohn Marino
905*6b445a62SJohn Marino int
rl_vi_check()906*6b445a62SJohn Marino rl_vi_check ()
907*6b445a62SJohn Marino {
908*6b445a62SJohn Marino if (rl_point && rl_point == rl_end)
909*6b445a62SJohn Marino {
910*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
911*6b445a62SJohn Marino rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
912*6b445a62SJohn Marino else
913*6b445a62SJohn Marino rl_point--;
914*6b445a62SJohn Marino }
915*6b445a62SJohn Marino return (0);
916*6b445a62SJohn Marino }
917*6b445a62SJohn Marino
918*6b445a62SJohn Marino int
rl_vi_column(count,key)919*6b445a62SJohn Marino rl_vi_column (count, key)
920*6b445a62SJohn Marino int count, key;
921*6b445a62SJohn Marino {
922*6b445a62SJohn Marino if (count > rl_end)
923*6b445a62SJohn Marino rl_end_of_line (1, key);
924*6b445a62SJohn Marino else
925*6b445a62SJohn Marino rl_point = count - 1;
926*6b445a62SJohn Marino return (0);
927*6b445a62SJohn Marino }
928*6b445a62SJohn Marino
929*6b445a62SJohn Marino /* Process C as part of the current numeric argument. Return -1 if the
930*6b445a62SJohn Marino argument should be aborted, 0 if we should not read any more chars, and
931*6b445a62SJohn Marino 1 if we should continue to read chars. */
932*6b445a62SJohn Marino static int
_rl_vi_arg_dispatch(c)933*6b445a62SJohn Marino _rl_vi_arg_dispatch (c)
934*6b445a62SJohn Marino int c;
935*6b445a62SJohn Marino {
936*6b445a62SJohn Marino int key;
937*6b445a62SJohn Marino
938*6b445a62SJohn Marino key = c;
939*6b445a62SJohn Marino if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
940*6b445a62SJohn Marino {
941*6b445a62SJohn Marino rl_numeric_arg *= 4;
942*6b445a62SJohn Marino return 1;
943*6b445a62SJohn Marino }
944*6b445a62SJohn Marino
945*6b445a62SJohn Marino c = UNMETA (c);
946*6b445a62SJohn Marino
947*6b445a62SJohn Marino if (_rl_digit_p (c))
948*6b445a62SJohn Marino {
949*6b445a62SJohn Marino if (rl_explicit_arg)
950*6b445a62SJohn Marino rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
951*6b445a62SJohn Marino else
952*6b445a62SJohn Marino rl_numeric_arg = _rl_digit_value (c);
953*6b445a62SJohn Marino rl_explicit_arg = 1;
954*6b445a62SJohn Marino return 1; /* keep going */
955*6b445a62SJohn Marino }
956*6b445a62SJohn Marino else
957*6b445a62SJohn Marino {
958*6b445a62SJohn Marino rl_clear_message ();
959*6b445a62SJohn Marino rl_stuff_char (key);
960*6b445a62SJohn Marino return 0; /* done */
961*6b445a62SJohn Marino }
962*6b445a62SJohn Marino }
963*6b445a62SJohn Marino
964*6b445a62SJohn Marino /* A simplified loop for vi. Don't dispatch key at end.
965*6b445a62SJohn Marino Don't recognize minus sign?
966*6b445a62SJohn Marino Should this do rl_save_prompt/rl_restore_prompt? */
967*6b445a62SJohn Marino static int
rl_digit_loop1()968*6b445a62SJohn Marino rl_digit_loop1 ()
969*6b445a62SJohn Marino {
970*6b445a62SJohn Marino int c, r;
971*6b445a62SJohn Marino
972*6b445a62SJohn Marino while (1)
973*6b445a62SJohn Marino {
974*6b445a62SJohn Marino if (_rl_arg_overflow ())
975*6b445a62SJohn Marino return 1;
976*6b445a62SJohn Marino
977*6b445a62SJohn Marino c = _rl_arg_getchar ();
978*6b445a62SJohn Marino
979*6b445a62SJohn Marino r = _rl_vi_arg_dispatch (c);
980*6b445a62SJohn Marino if (r <= 0)
981*6b445a62SJohn Marino break;
982*6b445a62SJohn Marino }
983*6b445a62SJohn Marino
984*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_NUMERICARG);
985*6b445a62SJohn Marino return (0);
986*6b445a62SJohn Marino }
987*6b445a62SJohn Marino
988*6b445a62SJohn Marino static void
_rl_mvcxt_init(m,op,key)989*6b445a62SJohn Marino _rl_mvcxt_init (m, op, key)
990*6b445a62SJohn Marino _rl_vimotion_cxt *m;
991*6b445a62SJohn Marino int op, key;
992*6b445a62SJohn Marino {
993*6b445a62SJohn Marino m->op = op;
994*6b445a62SJohn Marino m->state = m->flags = 0;
995*6b445a62SJohn Marino m->ncxt = 0;
996*6b445a62SJohn Marino m->numeric_arg = -1;
997*6b445a62SJohn Marino m->start = rl_point;
998*6b445a62SJohn Marino m->end = rl_end;
999*6b445a62SJohn Marino m->key = key;
1000*6b445a62SJohn Marino m->motion = -1;
1001*6b445a62SJohn Marino }
1002*6b445a62SJohn Marino
1003*6b445a62SJohn Marino static _rl_vimotion_cxt *
_rl_mvcxt_alloc(op,key)1004*6b445a62SJohn Marino _rl_mvcxt_alloc (op, key)
1005*6b445a62SJohn Marino int op, key;
1006*6b445a62SJohn Marino {
1007*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1008*6b445a62SJohn Marino
1009*6b445a62SJohn Marino m = xmalloc (sizeof (_rl_vimotion_cxt));
1010*6b445a62SJohn Marino _rl_mvcxt_init (m, op, key);
1011*6b445a62SJohn Marino return m;
1012*6b445a62SJohn Marino }
1013*6b445a62SJohn Marino
1014*6b445a62SJohn Marino static void
_rl_mvcxt_dispose(m)1015*6b445a62SJohn Marino _rl_mvcxt_dispose (m)
1016*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1017*6b445a62SJohn Marino {
1018*6b445a62SJohn Marino xfree (m);
1019*6b445a62SJohn Marino }
1020*6b445a62SJohn Marino
1021*6b445a62SJohn Marino static int
rl_domove_motion_callback(m)1022*6b445a62SJohn Marino rl_domove_motion_callback (m)
1023*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1024*6b445a62SJohn Marino {
1025*6b445a62SJohn Marino int c, save, r;
1026*6b445a62SJohn Marino int old_end;
1027*6b445a62SJohn Marino
1028*6b445a62SJohn Marino _rl_vi_last_motion = c = m->motion;
1029*6b445a62SJohn Marino
1030*6b445a62SJohn Marino /* Append a blank character temporarily so that the motion routines
1031*6b445a62SJohn Marino work right at the end of the line. */
1032*6b445a62SJohn Marino old_end = rl_end;
1033*6b445a62SJohn Marino rl_line_buffer[rl_end++] = ' ';
1034*6b445a62SJohn Marino rl_line_buffer[rl_end] = '\0';
1035*6b445a62SJohn Marino
1036*6b445a62SJohn Marino _rl_dispatch (c, _rl_keymap);
1037*6b445a62SJohn Marino
1038*6b445a62SJohn Marino /* Remove the blank that we added. */
1039*6b445a62SJohn Marino rl_end = old_end;
1040*6b445a62SJohn Marino rl_line_buffer[rl_end] = '\0';
1041*6b445a62SJohn Marino if (rl_point > rl_end)
1042*6b445a62SJohn Marino rl_point = rl_end;
1043*6b445a62SJohn Marino
1044*6b445a62SJohn Marino /* No change in position means the command failed. */
1045*6b445a62SJohn Marino if (rl_mark == rl_point)
1046*6b445a62SJohn Marino return (-1);
1047*6b445a62SJohn Marino
1048*6b445a62SJohn Marino /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
1049*6b445a62SJohn Marino word. If we are not at the end of the line, and we are on a
1050*6b445a62SJohn Marino non-whitespace character, move back one (presumably to whitespace). */
1051*6b445a62SJohn Marino if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
1052*6b445a62SJohn Marino !whitespace (rl_line_buffer[rl_point]))
1053*6b445a62SJohn Marino rl_point--;
1054*6b445a62SJohn Marino
1055*6b445a62SJohn Marino /* If cw or cW, back up to the end of a word, so the behaviour of ce
1056*6b445a62SJohn Marino or cE is the actual result. Brute-force, no subtlety. */
1057*6b445a62SJohn Marino if (m->key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
1058*6b445a62SJohn Marino {
1059*6b445a62SJohn Marino /* Don't move farther back than where we started. */
1060*6b445a62SJohn Marino while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
1061*6b445a62SJohn Marino rl_point--;
1062*6b445a62SJohn Marino
1063*6b445a62SJohn Marino /* Posix.2 says that if cw or cW moves the cursor towards the end of
1064*6b445a62SJohn Marino the line, the character under the cursor should be deleted. */
1065*6b445a62SJohn Marino if (rl_point == rl_mark)
1066*6b445a62SJohn Marino rl_point++;
1067*6b445a62SJohn Marino else
1068*6b445a62SJohn Marino {
1069*6b445a62SJohn Marino /* Move past the end of the word so that the kill doesn't
1070*6b445a62SJohn Marino remove the last letter of the previous word. Only do this
1071*6b445a62SJohn Marino if we are not at the end of the line. */
1072*6b445a62SJohn Marino if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
1073*6b445a62SJohn Marino rl_point++;
1074*6b445a62SJohn Marino }
1075*6b445a62SJohn Marino }
1076*6b445a62SJohn Marino
1077*6b445a62SJohn Marino if (rl_mark < rl_point)
1078*6b445a62SJohn Marino SWAP (rl_point, rl_mark);
1079*6b445a62SJohn Marino
1080*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1081*6b445a62SJohn Marino if (RL_ISSTATE (RL_STATE_CALLBACK))
1082*6b445a62SJohn Marino (*rl_redisplay_function)(); /* make sure motion is displayed */
1083*6b445a62SJohn Marino #endif
1084*6b445a62SJohn Marino
1085*6b445a62SJohn Marino r = vidomove_dispatch (m);
1086*6b445a62SJohn Marino
1087*6b445a62SJohn Marino return (r);
1088*6b445a62SJohn Marino }
1089*6b445a62SJohn Marino
1090*6b445a62SJohn Marino #define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))
1091*6b445a62SJohn Marino
1092*6b445a62SJohn Marino static int
rl_domove_read_callback(m)1093*6b445a62SJohn Marino rl_domove_read_callback (m)
1094*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1095*6b445a62SJohn Marino {
1096*6b445a62SJohn Marino int c, save;
1097*6b445a62SJohn Marino
1098*6b445a62SJohn Marino c = m->motion;
1099*6b445a62SJohn Marino
1100*6b445a62SJohn Marino if (member (c, vi_motion))
1101*6b445a62SJohn Marino {
1102*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1103*6b445a62SJohn Marino /* If we just read a vi-mode motion command numeric argument, turn off
1104*6b445a62SJohn Marino the `reading numeric arg' state */
1105*6b445a62SJohn Marino if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG())
1106*6b445a62SJohn Marino RL_UNSETSTATE (RL_STATE_NUMERICARG);
1107*6b445a62SJohn Marino #endif
1108*6b445a62SJohn Marino /* Should do everything, including turning off RL_STATE_VIMOTION */
1109*6b445a62SJohn Marino return (rl_domove_motion_callback (m));
1110*6b445a62SJohn Marino }
1111*6b445a62SJohn Marino else if (m->key == c && (m->key == 'd' || m->key == 'y' || m->key == 'c'))
1112*6b445a62SJohn Marino {
1113*6b445a62SJohn Marino rl_mark = rl_end;
1114*6b445a62SJohn Marino rl_beg_of_line (1, c);
1115*6b445a62SJohn Marino _rl_vi_last_motion = c;
1116*6b445a62SJohn Marino RL_UNSETSTATE (RL_STATE_VIMOTION);
1117*6b445a62SJohn Marino return (vidomove_dispatch (m));
1118*6b445a62SJohn Marino }
1119*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1120*6b445a62SJohn Marino /* XXX - these need to handle rl_universal_argument bindings */
1121*6b445a62SJohn Marino /* Reading vi motion char continuing numeric argument */
1122*6b445a62SJohn Marino else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG())
1123*6b445a62SJohn Marino {
1124*6b445a62SJohn Marino return (_rl_vi_arg_dispatch (c));
1125*6b445a62SJohn Marino }
1126*6b445a62SJohn Marino /* Readine vi motion char starting numeric argument */
1127*6b445a62SJohn Marino else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_VIMOTION) && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
1128*6b445a62SJohn Marino {
1129*6b445a62SJohn Marino RL_SETSTATE (RL_STATE_NUMERICARG);
1130*6b445a62SJohn Marino return (_rl_vi_arg_dispatch (c));
1131*6b445a62SJohn Marino }
1132*6b445a62SJohn Marino #endif
1133*6b445a62SJohn Marino else if (_rl_digit_p (c))
1134*6b445a62SJohn Marino {
1135*6b445a62SJohn Marino /* This code path taken when not in callback mode */
1136*6b445a62SJohn Marino save = rl_numeric_arg;
1137*6b445a62SJohn Marino rl_numeric_arg = _rl_digit_value (c);
1138*6b445a62SJohn Marino rl_explicit_arg = 1;
1139*6b445a62SJohn Marino RL_SETSTATE (RL_STATE_NUMERICARG);
1140*6b445a62SJohn Marino rl_digit_loop1 ();
1141*6b445a62SJohn Marino rl_numeric_arg *= save;
1142*6b445a62SJohn Marino c = rl_vi_domove_getchar (m);
1143*6b445a62SJohn Marino if (c < 0)
1144*6b445a62SJohn Marino {
1145*6b445a62SJohn Marino m->motion = 0;
1146*6b445a62SJohn Marino return -1;
1147*6b445a62SJohn Marino }
1148*6b445a62SJohn Marino m->motion = c;
1149*6b445a62SJohn Marino return (rl_domove_motion_callback (m));
1150*6b445a62SJohn Marino }
1151*6b445a62SJohn Marino else
1152*6b445a62SJohn Marino {
1153*6b445a62SJohn Marino RL_UNSETSTATE (RL_STATE_VIMOTION);
1154*6b445a62SJohn Marino RL_UNSETSTATE (RL_STATE_NUMERICARG);
1155*6b445a62SJohn Marino return (1);
1156*6b445a62SJohn Marino }
1157*6b445a62SJohn Marino }
1158*6b445a62SJohn Marino
1159*6b445a62SJohn Marino static int
rl_vi_domove_getchar(m)1160*6b445a62SJohn Marino rl_vi_domove_getchar (m)
1161*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1162*6b445a62SJohn Marino {
1163*6b445a62SJohn Marino int c;
1164*6b445a62SJohn Marino
1165*6b445a62SJohn Marino RL_SETSTATE(RL_STATE_MOREINPUT);
1166*6b445a62SJohn Marino c = rl_read_key ();
1167*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_MOREINPUT);
1168*6b445a62SJohn Marino
1169*6b445a62SJohn Marino return c;
1170*6b445a62SJohn Marino }
1171*6b445a62SJohn Marino
1172*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1173*6b445a62SJohn Marino int
_rl_vi_domove_callback(m)1174*6b445a62SJohn Marino _rl_vi_domove_callback (m)
1175*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1176*6b445a62SJohn Marino {
1177*6b445a62SJohn Marino int c, r;
1178*6b445a62SJohn Marino
1179*6b445a62SJohn Marino m->motion = c = rl_vi_domove_getchar (m);
1180*6b445a62SJohn Marino /* XXX - what to do if this returns -1? Should we return 1 for eof to
1181*6b445a62SJohn Marino callback code? */
1182*6b445a62SJohn Marino r = rl_domove_read_callback (m);
1183*6b445a62SJohn Marino
1184*6b445a62SJohn Marino return ((r == 0) ? r : 1); /* normalize return values */
1185*6b445a62SJohn Marino }
1186*6b445a62SJohn Marino #endif
1187*6b445a62SJohn Marino
1188*6b445a62SJohn Marino /* This code path taken when not in callback mode. */
1189*6b445a62SJohn Marino int
rl_vi_domove(x,ignore)1190*6b445a62SJohn Marino rl_vi_domove (x, ignore)
1191*6b445a62SJohn Marino int x, *ignore;
1192*6b445a62SJohn Marino {
1193*6b445a62SJohn Marino int r;
1194*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1195*6b445a62SJohn Marino
1196*6b445a62SJohn Marino m = _rl_vimvcxt;
1197*6b445a62SJohn Marino *ignore = m->motion = rl_vi_domove_getchar (m);
1198*6b445a62SJohn Marino
1199*6b445a62SJohn Marino if (m->motion < 0)
1200*6b445a62SJohn Marino {
1201*6b445a62SJohn Marino m->motion = 0;
1202*6b445a62SJohn Marino return -1;
1203*6b445a62SJohn Marino }
1204*6b445a62SJohn Marino
1205*6b445a62SJohn Marino return (rl_domove_read_callback (m));
1206*6b445a62SJohn Marino }
1207*6b445a62SJohn Marino
1208*6b445a62SJohn Marino static int
vi_delete_dispatch(m)1209*6b445a62SJohn Marino vi_delete_dispatch (m)
1210*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1211*6b445a62SJohn Marino {
1212*6b445a62SJohn Marino /* These are the motion commands that do not require adjusting the
1213*6b445a62SJohn Marino mark. */
1214*6b445a62SJohn Marino if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
1215*6b445a62SJohn Marino (rl_mark < rl_end))
1216*6b445a62SJohn Marino rl_mark++;
1217*6b445a62SJohn Marino
1218*6b445a62SJohn Marino rl_kill_text (rl_point, rl_mark);
1219*6b445a62SJohn Marino return (0);
1220*6b445a62SJohn Marino }
1221*6b445a62SJohn Marino
1222*6b445a62SJohn Marino int
rl_vi_delete_to(count,key)1223*6b445a62SJohn Marino rl_vi_delete_to (count, key)
1224*6b445a62SJohn Marino int count, key;
1225*6b445a62SJohn Marino {
1226*6b445a62SJohn Marino int c, r;
1227*6b445a62SJohn Marino
1228*6b445a62SJohn Marino _rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
1229*6b445a62SJohn Marino _rl_vimvcxt->start = rl_point;
1230*6b445a62SJohn Marino
1231*6b445a62SJohn Marino rl_mark = rl_point;
1232*6b445a62SJohn Marino if (_rl_uppercase_p (key))
1233*6b445a62SJohn Marino {
1234*6b445a62SJohn Marino _rl_vimvcxt->motion = '$';
1235*6b445a62SJohn Marino r = rl_domove_motion_callback (_rl_vimvcxt);
1236*6b445a62SJohn Marino }
1237*6b445a62SJohn Marino else if (vi_redoing)
1238*6b445a62SJohn Marino {
1239*6b445a62SJohn Marino _rl_vimvcxt->motion = _rl_vi_last_motion;
1240*6b445a62SJohn Marino r = rl_domove_motion_callback (_rl_vimvcxt);
1241*6b445a62SJohn Marino }
1242*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1243*6b445a62SJohn Marino else if (RL_ISSTATE (RL_STATE_CALLBACK))
1244*6b445a62SJohn Marino {
1245*6b445a62SJohn Marino RL_SETSTATE (RL_STATE_VIMOTION);
1246*6b445a62SJohn Marino return (0);
1247*6b445a62SJohn Marino }
1248*6b445a62SJohn Marino #endif
1249*6b445a62SJohn Marino else
1250*6b445a62SJohn Marino r = rl_vi_domove (key, &c);
1251*6b445a62SJohn Marino
1252*6b445a62SJohn Marino if (r < 0)
1253*6b445a62SJohn Marino {
1254*6b445a62SJohn Marino rl_ding ();
1255*6b445a62SJohn Marino r = -1;
1256*6b445a62SJohn Marino }
1257*6b445a62SJohn Marino
1258*6b445a62SJohn Marino _rl_mvcxt_dispose (_rl_vimvcxt);
1259*6b445a62SJohn Marino _rl_vimvcxt = 0;
1260*6b445a62SJohn Marino
1261*6b445a62SJohn Marino return r;
1262*6b445a62SJohn Marino }
1263*6b445a62SJohn Marino
1264*6b445a62SJohn Marino static int
vi_change_dispatch(m)1265*6b445a62SJohn Marino vi_change_dispatch (m)
1266*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1267*6b445a62SJohn Marino {
1268*6b445a62SJohn Marino /* These are the motion commands that do not require adjusting the
1269*6b445a62SJohn Marino mark. c[wW] are handled by special-case code in rl_vi_domove(),
1270*6b445a62SJohn Marino and already leave the mark at the correct location. */
1271*6b445a62SJohn Marino if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
1272*6b445a62SJohn Marino (rl_mark < rl_end))
1273*6b445a62SJohn Marino rl_mark++;
1274*6b445a62SJohn Marino
1275*6b445a62SJohn Marino /* The cursor never moves with c[wW]. */
1276*6b445a62SJohn Marino if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
1277*6b445a62SJohn Marino rl_point = m->start;
1278*6b445a62SJohn Marino
1279*6b445a62SJohn Marino if (vi_redoing)
1280*6b445a62SJohn Marino {
1281*6b445a62SJohn Marino if (vi_insert_buffer && *vi_insert_buffer)
1282*6b445a62SJohn Marino rl_begin_undo_group ();
1283*6b445a62SJohn Marino rl_delete_text (rl_point, rl_mark);
1284*6b445a62SJohn Marino if (vi_insert_buffer && *vi_insert_buffer)
1285*6b445a62SJohn Marino {
1286*6b445a62SJohn Marino rl_insert_text (vi_insert_buffer);
1287*6b445a62SJohn Marino rl_end_undo_group ();
1288*6b445a62SJohn Marino }
1289*6b445a62SJohn Marino }
1290*6b445a62SJohn Marino else
1291*6b445a62SJohn Marino {
1292*6b445a62SJohn Marino rl_begin_undo_group (); /* to make the `u' command work */
1293*6b445a62SJohn Marino rl_kill_text (rl_point, rl_mark);
1294*6b445a62SJohn Marino /* `C' does not save the text inserted for undoing or redoing. */
1295*6b445a62SJohn Marino if (_rl_uppercase_p (m->key) == 0)
1296*6b445a62SJohn Marino _rl_vi_doing_insert = 1;
1297*6b445a62SJohn Marino /* XXX -- TODO -- use m->numericarg? */
1298*6b445a62SJohn Marino rl_vi_start_inserting (m->key, rl_numeric_arg, rl_arg_sign);
1299*6b445a62SJohn Marino }
1300*6b445a62SJohn Marino
1301*6b445a62SJohn Marino return (0);
1302*6b445a62SJohn Marino }
1303*6b445a62SJohn Marino
1304*6b445a62SJohn Marino int
rl_vi_change_to(count,key)1305*6b445a62SJohn Marino rl_vi_change_to (count, key)
1306*6b445a62SJohn Marino int count, key;
1307*6b445a62SJohn Marino {
1308*6b445a62SJohn Marino int c, r;
1309*6b445a62SJohn Marino
1310*6b445a62SJohn Marino _rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
1311*6b445a62SJohn Marino _rl_vimvcxt->start = rl_point;
1312*6b445a62SJohn Marino
1313*6b445a62SJohn Marino rl_mark = rl_point;
1314*6b445a62SJohn Marino if (_rl_uppercase_p (key))
1315*6b445a62SJohn Marino {
1316*6b445a62SJohn Marino _rl_vimvcxt->motion = '$';
1317*6b445a62SJohn Marino r = rl_domove_motion_callback (_rl_vimvcxt);
1318*6b445a62SJohn Marino }
1319*6b445a62SJohn Marino else if (vi_redoing)
1320*6b445a62SJohn Marino {
1321*6b445a62SJohn Marino _rl_vimvcxt->motion = _rl_vi_last_motion;
1322*6b445a62SJohn Marino r = rl_domove_motion_callback (_rl_vimvcxt);
1323*6b445a62SJohn Marino }
1324*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1325*6b445a62SJohn Marino else if (RL_ISSTATE (RL_STATE_CALLBACK))
1326*6b445a62SJohn Marino {
1327*6b445a62SJohn Marino RL_SETSTATE (RL_STATE_VIMOTION);
1328*6b445a62SJohn Marino return (0);
1329*6b445a62SJohn Marino }
1330*6b445a62SJohn Marino #endif
1331*6b445a62SJohn Marino else
1332*6b445a62SJohn Marino r = rl_vi_domove (key, &c);
1333*6b445a62SJohn Marino
1334*6b445a62SJohn Marino if (r < 0)
1335*6b445a62SJohn Marino {
1336*6b445a62SJohn Marino rl_ding ();
1337*6b445a62SJohn Marino r = -1; /* normalize return value */
1338*6b445a62SJohn Marino }
1339*6b445a62SJohn Marino
1340*6b445a62SJohn Marino _rl_mvcxt_dispose (_rl_vimvcxt);
1341*6b445a62SJohn Marino _rl_vimvcxt = 0;
1342*6b445a62SJohn Marino
1343*6b445a62SJohn Marino return r;
1344*6b445a62SJohn Marino }
1345*6b445a62SJohn Marino
1346*6b445a62SJohn Marino static int
vi_yank_dispatch(m)1347*6b445a62SJohn Marino vi_yank_dispatch (m)
1348*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1349*6b445a62SJohn Marino {
1350*6b445a62SJohn Marino /* These are the motion commands that do not require adjusting the
1351*6b445a62SJohn Marino mark. */
1352*6b445a62SJohn Marino if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
1353*6b445a62SJohn Marino (rl_mark < rl_end))
1354*6b445a62SJohn Marino rl_mark++;
1355*6b445a62SJohn Marino
1356*6b445a62SJohn Marino rl_begin_undo_group ();
1357*6b445a62SJohn Marino rl_kill_text (rl_point, rl_mark);
1358*6b445a62SJohn Marino rl_end_undo_group ();
1359*6b445a62SJohn Marino rl_do_undo ();
1360*6b445a62SJohn Marino rl_point = m->start;
1361*6b445a62SJohn Marino
1362*6b445a62SJohn Marino return (0);
1363*6b445a62SJohn Marino }
1364*6b445a62SJohn Marino
1365*6b445a62SJohn Marino int
rl_vi_yank_to(count,key)1366*6b445a62SJohn Marino rl_vi_yank_to (count, key)
1367*6b445a62SJohn Marino int count, key;
1368*6b445a62SJohn Marino {
1369*6b445a62SJohn Marino int c, r;
1370*6b445a62SJohn Marino
1371*6b445a62SJohn Marino _rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
1372*6b445a62SJohn Marino _rl_vimvcxt->start = rl_point;
1373*6b445a62SJohn Marino
1374*6b445a62SJohn Marino rl_mark = rl_point;
1375*6b445a62SJohn Marino if (_rl_uppercase_p (key))
1376*6b445a62SJohn Marino {
1377*6b445a62SJohn Marino _rl_vimvcxt->motion = '$';
1378*6b445a62SJohn Marino r = rl_domove_motion_callback (_rl_vimvcxt);
1379*6b445a62SJohn Marino }
1380*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1381*6b445a62SJohn Marino else if (RL_ISSTATE (RL_STATE_CALLBACK))
1382*6b445a62SJohn Marino {
1383*6b445a62SJohn Marino RL_SETSTATE (RL_STATE_VIMOTION);
1384*6b445a62SJohn Marino return (0);
1385*6b445a62SJohn Marino }
1386*6b445a62SJohn Marino #endif
1387*6b445a62SJohn Marino else
1388*6b445a62SJohn Marino r = rl_vi_domove (key, &c);
1389*6b445a62SJohn Marino
1390*6b445a62SJohn Marino if (r < 0)
1391*6b445a62SJohn Marino {
1392*6b445a62SJohn Marino rl_ding ();
1393*6b445a62SJohn Marino r = -1;
1394*6b445a62SJohn Marino }
1395*6b445a62SJohn Marino
1396*6b445a62SJohn Marino _rl_mvcxt_dispose (_rl_vimvcxt);
1397*6b445a62SJohn Marino _rl_vimvcxt = 0;
1398*6b445a62SJohn Marino
1399*6b445a62SJohn Marino return r;
1400*6b445a62SJohn Marino }
1401*6b445a62SJohn Marino
1402*6b445a62SJohn Marino static int
vidomove_dispatch(m)1403*6b445a62SJohn Marino vidomove_dispatch (m)
1404*6b445a62SJohn Marino _rl_vimotion_cxt *m;
1405*6b445a62SJohn Marino {
1406*6b445a62SJohn Marino int r;
1407*6b445a62SJohn Marino
1408*6b445a62SJohn Marino switch (m->op)
1409*6b445a62SJohn Marino {
1410*6b445a62SJohn Marino case VIM_DELETE:
1411*6b445a62SJohn Marino r = vi_delete_dispatch (m);
1412*6b445a62SJohn Marino break;
1413*6b445a62SJohn Marino case VIM_CHANGE:
1414*6b445a62SJohn Marino r = vi_change_dispatch (m);
1415*6b445a62SJohn Marino break;
1416*6b445a62SJohn Marino case VIM_YANK:
1417*6b445a62SJohn Marino r = vi_yank_dispatch (m);
1418*6b445a62SJohn Marino break;
1419*6b445a62SJohn Marino default:
1420*6b445a62SJohn Marino _rl_errmsg ("vidomove_dispatch: unknown operator %d", m->op);
1421*6b445a62SJohn Marino r = 1;
1422*6b445a62SJohn Marino break;
1423*6b445a62SJohn Marino }
1424*6b445a62SJohn Marino
1425*6b445a62SJohn Marino RL_UNSETSTATE (RL_STATE_VIMOTION);
1426*6b445a62SJohn Marino return r;
1427*6b445a62SJohn Marino }
1428*6b445a62SJohn Marino
1429*6b445a62SJohn Marino int
rl_vi_rubout(count,key)1430*6b445a62SJohn Marino rl_vi_rubout (count, key)
1431*6b445a62SJohn Marino int count, key;
1432*6b445a62SJohn Marino {
1433*6b445a62SJohn Marino int opoint;
1434*6b445a62SJohn Marino
1435*6b445a62SJohn Marino if (count < 0)
1436*6b445a62SJohn Marino return (rl_vi_delete (-count, key));
1437*6b445a62SJohn Marino
1438*6b445a62SJohn Marino if (rl_point == 0)
1439*6b445a62SJohn Marino {
1440*6b445a62SJohn Marino rl_ding ();
1441*6b445a62SJohn Marino return -1;
1442*6b445a62SJohn Marino }
1443*6b445a62SJohn Marino
1444*6b445a62SJohn Marino opoint = rl_point;
1445*6b445a62SJohn Marino if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1446*6b445a62SJohn Marino rl_backward_char (count, key);
1447*6b445a62SJohn Marino else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1448*6b445a62SJohn Marino rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1449*6b445a62SJohn Marino else
1450*6b445a62SJohn Marino rl_point -= count;
1451*6b445a62SJohn Marino
1452*6b445a62SJohn Marino if (rl_point < 0)
1453*6b445a62SJohn Marino rl_point = 0;
1454*6b445a62SJohn Marino
1455*6b445a62SJohn Marino rl_kill_text (rl_point, opoint);
1456*6b445a62SJohn Marino
1457*6b445a62SJohn Marino return (0);
1458*6b445a62SJohn Marino }
1459*6b445a62SJohn Marino
1460*6b445a62SJohn Marino int
rl_vi_delete(count,key)1461*6b445a62SJohn Marino rl_vi_delete (count, key)
1462*6b445a62SJohn Marino int count, key;
1463*6b445a62SJohn Marino {
1464*6b445a62SJohn Marino int end;
1465*6b445a62SJohn Marino
1466*6b445a62SJohn Marino if (count < 0)
1467*6b445a62SJohn Marino return (rl_vi_rubout (-count, key));
1468*6b445a62SJohn Marino
1469*6b445a62SJohn Marino if (rl_end == 0)
1470*6b445a62SJohn Marino {
1471*6b445a62SJohn Marino rl_ding ();
1472*6b445a62SJohn Marino return -1;
1473*6b445a62SJohn Marino }
1474*6b445a62SJohn Marino
1475*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1476*6b445a62SJohn Marino end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1477*6b445a62SJohn Marino else
1478*6b445a62SJohn Marino end = rl_point + count;
1479*6b445a62SJohn Marino
1480*6b445a62SJohn Marino if (end >= rl_end)
1481*6b445a62SJohn Marino end = rl_end;
1482*6b445a62SJohn Marino
1483*6b445a62SJohn Marino rl_kill_text (rl_point, end);
1484*6b445a62SJohn Marino
1485*6b445a62SJohn Marino if (rl_point > 0 && rl_point == rl_end)
1486*6b445a62SJohn Marino rl_backward_char (1, key);
1487*6b445a62SJohn Marino
1488*6b445a62SJohn Marino return (0);
1489*6b445a62SJohn Marino }
1490*6b445a62SJohn Marino
1491*6b445a62SJohn Marino int
rl_vi_back_to_indent(count,key)1492*6b445a62SJohn Marino rl_vi_back_to_indent (count, key)
1493*6b445a62SJohn Marino int count, key;
1494*6b445a62SJohn Marino {
1495*6b445a62SJohn Marino rl_beg_of_line (1, key);
1496*6b445a62SJohn Marino while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1497*6b445a62SJohn Marino rl_point++;
1498*6b445a62SJohn Marino return (0);
1499*6b445a62SJohn Marino }
1500*6b445a62SJohn Marino
1501*6b445a62SJohn Marino int
rl_vi_first_print(count,key)1502*6b445a62SJohn Marino rl_vi_first_print (count, key)
1503*6b445a62SJohn Marino int count, key;
1504*6b445a62SJohn Marino {
1505*6b445a62SJohn Marino return (rl_vi_back_to_indent (1, key));
1506*6b445a62SJohn Marino }
1507*6b445a62SJohn Marino
1508*6b445a62SJohn Marino static int _rl_cs_dir, _rl_cs_orig_dir;
1509*6b445a62SJohn Marino
1510*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1511*6b445a62SJohn Marino static int
_rl_vi_callback_char_search(data)1512*6b445a62SJohn Marino _rl_vi_callback_char_search (data)
1513*6b445a62SJohn Marino _rl_callback_generic_arg *data;
1514*6b445a62SJohn Marino {
1515*6b445a62SJohn Marino int c;
1516*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1517*6b445a62SJohn Marino c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1518*6b445a62SJohn Marino #else
1519*6b445a62SJohn Marino RL_SETSTATE(RL_STATE_MOREINPUT);
1520*6b445a62SJohn Marino c = rl_read_key ();
1521*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_MOREINPUT);
1522*6b445a62SJohn Marino #endif
1523*6b445a62SJohn Marino
1524*6b445a62SJohn Marino if (c <= 0)
1525*6b445a62SJohn Marino return -1;
1526*6b445a62SJohn Marino
1527*6b445a62SJohn Marino #if !defined (HANDLE_MULTIBYTE)
1528*6b445a62SJohn Marino _rl_vi_last_search_char = c;
1529*6b445a62SJohn Marino #endif
1530*6b445a62SJohn Marino
1531*6b445a62SJohn Marino _rl_callback_func = 0;
1532*6b445a62SJohn Marino _rl_want_redisplay = 1;
1533*6b445a62SJohn Marino
1534*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1535*6b445a62SJohn Marino return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
1536*6b445a62SJohn Marino #else
1537*6b445a62SJohn Marino return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
1538*6b445a62SJohn Marino #endif
1539*6b445a62SJohn Marino }
1540*6b445a62SJohn Marino #endif
1541*6b445a62SJohn Marino
1542*6b445a62SJohn Marino int
rl_vi_char_search(count,key)1543*6b445a62SJohn Marino rl_vi_char_search (count, key)
1544*6b445a62SJohn Marino int count, key;
1545*6b445a62SJohn Marino {
1546*6b445a62SJohn Marino int c;
1547*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1548*6b445a62SJohn Marino static char *target;
1549*6b445a62SJohn Marino static int tlen;
1550*6b445a62SJohn Marino #else
1551*6b445a62SJohn Marino static char target;
1552*6b445a62SJohn Marino #endif
1553*6b445a62SJohn Marino
1554*6b445a62SJohn Marino if (key == ';' || key == ',')
1555*6b445a62SJohn Marino {
1556*6b445a62SJohn Marino if (_rl_cs_orig_dir == 0)
1557*6b445a62SJohn Marino return -1;
1558*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1559*6b445a62SJohn Marino if (_rl_vi_last_search_mblen == 0)
1560*6b445a62SJohn Marino return -1;
1561*6b445a62SJohn Marino #else
1562*6b445a62SJohn Marino if (_rl_vi_last_search_char == 0)
1563*6b445a62SJohn Marino return -1;
1564*6b445a62SJohn Marino #endif
1565*6b445a62SJohn Marino _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
1566*6b445a62SJohn Marino }
1567*6b445a62SJohn Marino else
1568*6b445a62SJohn Marino {
1569*6b445a62SJohn Marino switch (key)
1570*6b445a62SJohn Marino {
1571*6b445a62SJohn Marino case 't':
1572*6b445a62SJohn Marino _rl_cs_orig_dir = _rl_cs_dir = FTO;
1573*6b445a62SJohn Marino break;
1574*6b445a62SJohn Marino
1575*6b445a62SJohn Marino case 'T':
1576*6b445a62SJohn Marino _rl_cs_orig_dir = _rl_cs_dir = BTO;
1577*6b445a62SJohn Marino break;
1578*6b445a62SJohn Marino
1579*6b445a62SJohn Marino case 'f':
1580*6b445a62SJohn Marino _rl_cs_orig_dir = _rl_cs_dir = FFIND;
1581*6b445a62SJohn Marino break;
1582*6b445a62SJohn Marino
1583*6b445a62SJohn Marino case 'F':
1584*6b445a62SJohn Marino _rl_cs_orig_dir = _rl_cs_dir = BFIND;
1585*6b445a62SJohn Marino break;
1586*6b445a62SJohn Marino }
1587*6b445a62SJohn Marino
1588*6b445a62SJohn Marino if (vi_redoing)
1589*6b445a62SJohn Marino {
1590*6b445a62SJohn Marino /* set target and tlen below */
1591*6b445a62SJohn Marino }
1592*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1593*6b445a62SJohn Marino else if (RL_ISSTATE (RL_STATE_CALLBACK))
1594*6b445a62SJohn Marino {
1595*6b445a62SJohn Marino _rl_callback_data = _rl_callback_data_alloc (count);
1596*6b445a62SJohn Marino _rl_callback_data->i1 = _rl_cs_dir;
1597*6b445a62SJohn Marino _rl_callback_func = _rl_vi_callback_char_search;
1598*6b445a62SJohn Marino return (0);
1599*6b445a62SJohn Marino }
1600*6b445a62SJohn Marino #endif
1601*6b445a62SJohn Marino else
1602*6b445a62SJohn Marino {
1603*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1604*6b445a62SJohn Marino c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1605*6b445a62SJohn Marino if (c <= 0)
1606*6b445a62SJohn Marino return -1;
1607*6b445a62SJohn Marino _rl_vi_last_search_mblen = c;
1608*6b445a62SJohn Marino #else
1609*6b445a62SJohn Marino RL_SETSTATE(RL_STATE_MOREINPUT);
1610*6b445a62SJohn Marino c = rl_read_key ();
1611*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_MOREINPUT);
1612*6b445a62SJohn Marino if (c < 0)
1613*6b445a62SJohn Marino return -1;
1614*6b445a62SJohn Marino _rl_vi_last_search_char = c;
1615*6b445a62SJohn Marino #endif
1616*6b445a62SJohn Marino }
1617*6b445a62SJohn Marino }
1618*6b445a62SJohn Marino
1619*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1620*6b445a62SJohn Marino target = _rl_vi_last_search_mbchar;
1621*6b445a62SJohn Marino tlen = _rl_vi_last_search_mblen;
1622*6b445a62SJohn Marino #else
1623*6b445a62SJohn Marino target = _rl_vi_last_search_char;
1624*6b445a62SJohn Marino #endif
1625*6b445a62SJohn Marino
1626*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1627*6b445a62SJohn Marino return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
1628*6b445a62SJohn Marino #else
1629*6b445a62SJohn Marino return (_rl_char_search_internal (count, _rl_cs_dir, target));
1630*6b445a62SJohn Marino #endif
1631*6b445a62SJohn Marino }
1632*6b445a62SJohn Marino
1633*6b445a62SJohn Marino /* Match brackets */
1634*6b445a62SJohn Marino int
rl_vi_match(ignore,key)1635*6b445a62SJohn Marino rl_vi_match (ignore, key)
1636*6b445a62SJohn Marino int ignore, key;
1637*6b445a62SJohn Marino {
1638*6b445a62SJohn Marino int count = 1, brack, pos, tmp, pre;
1639*6b445a62SJohn Marino
1640*6b445a62SJohn Marino pos = rl_point;
1641*6b445a62SJohn Marino if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1642*6b445a62SJohn Marino {
1643*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1644*6b445a62SJohn Marino {
1645*6b445a62SJohn Marino while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1646*6b445a62SJohn Marino {
1647*6b445a62SJohn Marino pre = rl_point;
1648*6b445a62SJohn Marino rl_forward_char (1, key);
1649*6b445a62SJohn Marino if (pre == rl_point)
1650*6b445a62SJohn Marino break;
1651*6b445a62SJohn Marino }
1652*6b445a62SJohn Marino }
1653*6b445a62SJohn Marino else
1654*6b445a62SJohn Marino while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1655*6b445a62SJohn Marino rl_point < rl_end - 1)
1656*6b445a62SJohn Marino rl_forward_char (1, key);
1657*6b445a62SJohn Marino
1658*6b445a62SJohn Marino if (brack <= 0)
1659*6b445a62SJohn Marino {
1660*6b445a62SJohn Marino rl_point = pos;
1661*6b445a62SJohn Marino rl_ding ();
1662*6b445a62SJohn Marino return -1;
1663*6b445a62SJohn Marino }
1664*6b445a62SJohn Marino }
1665*6b445a62SJohn Marino
1666*6b445a62SJohn Marino pos = rl_point;
1667*6b445a62SJohn Marino
1668*6b445a62SJohn Marino if (brack < 0)
1669*6b445a62SJohn Marino {
1670*6b445a62SJohn Marino while (count)
1671*6b445a62SJohn Marino {
1672*6b445a62SJohn Marino tmp = pos;
1673*6b445a62SJohn Marino if (MB_CUR_MAX == 1 || rl_byte_oriented)
1674*6b445a62SJohn Marino pos--;
1675*6b445a62SJohn Marino else
1676*6b445a62SJohn Marino {
1677*6b445a62SJohn Marino pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1678*6b445a62SJohn Marino if (tmp == pos)
1679*6b445a62SJohn Marino pos--;
1680*6b445a62SJohn Marino }
1681*6b445a62SJohn Marino if (pos >= 0)
1682*6b445a62SJohn Marino {
1683*6b445a62SJohn Marino int b = rl_vi_bracktype (rl_line_buffer[pos]);
1684*6b445a62SJohn Marino if (b == -brack)
1685*6b445a62SJohn Marino count--;
1686*6b445a62SJohn Marino else if (b == brack)
1687*6b445a62SJohn Marino count++;
1688*6b445a62SJohn Marino }
1689*6b445a62SJohn Marino else
1690*6b445a62SJohn Marino {
1691*6b445a62SJohn Marino rl_ding ();
1692*6b445a62SJohn Marino return -1;
1693*6b445a62SJohn Marino }
1694*6b445a62SJohn Marino }
1695*6b445a62SJohn Marino }
1696*6b445a62SJohn Marino else
1697*6b445a62SJohn Marino { /* brack > 0 */
1698*6b445a62SJohn Marino while (count)
1699*6b445a62SJohn Marino {
1700*6b445a62SJohn Marino if (MB_CUR_MAX == 1 || rl_byte_oriented)
1701*6b445a62SJohn Marino pos++;
1702*6b445a62SJohn Marino else
1703*6b445a62SJohn Marino pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
1704*6b445a62SJohn Marino
1705*6b445a62SJohn Marino if (pos < rl_end)
1706*6b445a62SJohn Marino {
1707*6b445a62SJohn Marino int b = rl_vi_bracktype (rl_line_buffer[pos]);
1708*6b445a62SJohn Marino if (b == -brack)
1709*6b445a62SJohn Marino count--;
1710*6b445a62SJohn Marino else if (b == brack)
1711*6b445a62SJohn Marino count++;
1712*6b445a62SJohn Marino }
1713*6b445a62SJohn Marino else
1714*6b445a62SJohn Marino {
1715*6b445a62SJohn Marino rl_ding ();
1716*6b445a62SJohn Marino return -1;
1717*6b445a62SJohn Marino }
1718*6b445a62SJohn Marino }
1719*6b445a62SJohn Marino }
1720*6b445a62SJohn Marino rl_point = pos;
1721*6b445a62SJohn Marino return (0);
1722*6b445a62SJohn Marino }
1723*6b445a62SJohn Marino
1724*6b445a62SJohn Marino int
rl_vi_bracktype(c)1725*6b445a62SJohn Marino rl_vi_bracktype (c)
1726*6b445a62SJohn Marino int c;
1727*6b445a62SJohn Marino {
1728*6b445a62SJohn Marino switch (c)
1729*6b445a62SJohn Marino {
1730*6b445a62SJohn Marino case '(': return 1;
1731*6b445a62SJohn Marino case ')': return -1;
1732*6b445a62SJohn Marino case '[': return 2;
1733*6b445a62SJohn Marino case ']': return -2;
1734*6b445a62SJohn Marino case '{': return 3;
1735*6b445a62SJohn Marino case '}': return -3;
1736*6b445a62SJohn Marino default: return 0;
1737*6b445a62SJohn Marino }
1738*6b445a62SJohn Marino }
1739*6b445a62SJohn Marino
1740*6b445a62SJohn Marino static int
_rl_vi_change_char(count,c,mb)1741*6b445a62SJohn Marino _rl_vi_change_char (count, c, mb)
1742*6b445a62SJohn Marino int count, c;
1743*6b445a62SJohn Marino char *mb;
1744*6b445a62SJohn Marino {
1745*6b445a62SJohn Marino int p;
1746*6b445a62SJohn Marino
1747*6b445a62SJohn Marino if (c == '\033' || c == CTRL ('C'))
1748*6b445a62SJohn Marino return -1;
1749*6b445a62SJohn Marino
1750*6b445a62SJohn Marino rl_begin_undo_group ();
1751*6b445a62SJohn Marino while (count-- && rl_point < rl_end)
1752*6b445a62SJohn Marino {
1753*6b445a62SJohn Marino p = rl_point;
1754*6b445a62SJohn Marino rl_vi_delete (1, c);
1755*6b445a62SJohn Marino if (rl_point < p) /* Did we retreat at EOL? */
1756*6b445a62SJohn Marino rl_point++;
1757*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1758*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1759*6b445a62SJohn Marino rl_insert_text (mb);
1760*6b445a62SJohn Marino else
1761*6b445a62SJohn Marino #endif
1762*6b445a62SJohn Marino _rl_insert_char (1, c);
1763*6b445a62SJohn Marino }
1764*6b445a62SJohn Marino
1765*6b445a62SJohn Marino /* The cursor shall be left on the last character changed. */
1766*6b445a62SJohn Marino rl_backward_char (1, c);
1767*6b445a62SJohn Marino
1768*6b445a62SJohn Marino rl_end_undo_group ();
1769*6b445a62SJohn Marino
1770*6b445a62SJohn Marino return (0);
1771*6b445a62SJohn Marino }
1772*6b445a62SJohn Marino
1773*6b445a62SJohn Marino static int
_rl_vi_callback_getchar(mb,mlen)1774*6b445a62SJohn Marino _rl_vi_callback_getchar (mb, mlen)
1775*6b445a62SJohn Marino char *mb;
1776*6b445a62SJohn Marino int mlen;
1777*6b445a62SJohn Marino {
1778*6b445a62SJohn Marino int c;
1779*6b445a62SJohn Marino
1780*6b445a62SJohn Marino RL_SETSTATE(RL_STATE_MOREINPUT);
1781*6b445a62SJohn Marino c = rl_read_key ();
1782*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_MOREINPUT);
1783*6b445a62SJohn Marino
1784*6b445a62SJohn Marino if (c < 0)
1785*6b445a62SJohn Marino return -1;
1786*6b445a62SJohn Marino
1787*6b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
1788*6b445a62SJohn Marino if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1789*6b445a62SJohn Marino c = _rl_read_mbstring (c, mb, mlen);
1790*6b445a62SJohn Marino #endif
1791*6b445a62SJohn Marino
1792*6b445a62SJohn Marino return c;
1793*6b445a62SJohn Marino }
1794*6b445a62SJohn Marino
1795*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1796*6b445a62SJohn Marino static int
_rl_vi_callback_change_char(data)1797*6b445a62SJohn Marino _rl_vi_callback_change_char (data)
1798*6b445a62SJohn Marino _rl_callback_generic_arg *data;
1799*6b445a62SJohn Marino {
1800*6b445a62SJohn Marino int c;
1801*6b445a62SJohn Marino char mb[MB_LEN_MAX];
1802*6b445a62SJohn Marino
1803*6b445a62SJohn Marino _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1804*6b445a62SJohn Marino
1805*6b445a62SJohn Marino if (c < 0)
1806*6b445a62SJohn Marino return -1;
1807*6b445a62SJohn Marino
1808*6b445a62SJohn Marino _rl_callback_func = 0;
1809*6b445a62SJohn Marino _rl_want_redisplay = 1;
1810*6b445a62SJohn Marino
1811*6b445a62SJohn Marino return (_rl_vi_change_char (data->count, c, mb));
1812*6b445a62SJohn Marino }
1813*6b445a62SJohn Marino #endif
1814*6b445a62SJohn Marino
1815*6b445a62SJohn Marino int
rl_vi_change_char(count,key)1816*6b445a62SJohn Marino rl_vi_change_char (count, key)
1817*6b445a62SJohn Marino int count, key;
1818*6b445a62SJohn Marino {
1819*6b445a62SJohn Marino int c;
1820*6b445a62SJohn Marino char mb[MB_LEN_MAX];
1821*6b445a62SJohn Marino
1822*6b445a62SJohn Marino if (vi_redoing)
1823*6b445a62SJohn Marino {
1824*6b445a62SJohn Marino c = _rl_vi_last_replacement;
1825*6b445a62SJohn Marino mb[0] = c;
1826*6b445a62SJohn Marino mb[1] = '\0';
1827*6b445a62SJohn Marino }
1828*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1829*6b445a62SJohn Marino else if (RL_ISSTATE (RL_STATE_CALLBACK))
1830*6b445a62SJohn Marino {
1831*6b445a62SJohn Marino _rl_callback_data = _rl_callback_data_alloc (count);
1832*6b445a62SJohn Marino _rl_callback_func = _rl_vi_callback_change_char;
1833*6b445a62SJohn Marino return (0);
1834*6b445a62SJohn Marino }
1835*6b445a62SJohn Marino #endif
1836*6b445a62SJohn Marino else
1837*6b445a62SJohn Marino _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1838*6b445a62SJohn Marino
1839*6b445a62SJohn Marino if (c < 0)
1840*6b445a62SJohn Marino return -1;
1841*6b445a62SJohn Marino
1842*6b445a62SJohn Marino return (_rl_vi_change_char (count, c, mb));
1843*6b445a62SJohn Marino }
1844*6b445a62SJohn Marino
1845*6b445a62SJohn Marino int
rl_vi_subst(count,key)1846*6b445a62SJohn Marino rl_vi_subst (count, key)
1847*6b445a62SJohn Marino int count, key;
1848*6b445a62SJohn Marino {
1849*6b445a62SJohn Marino /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1850*6b445a62SJohn Marino if (vi_redoing == 0)
1851*6b445a62SJohn Marino rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1852*6b445a62SJohn Marino
1853*6b445a62SJohn Marino return (rl_vi_change_to (count, 'c'));
1854*6b445a62SJohn Marino }
1855*6b445a62SJohn Marino
1856*6b445a62SJohn Marino int
rl_vi_overstrike(count,key)1857*6b445a62SJohn Marino rl_vi_overstrike (count, key)
1858*6b445a62SJohn Marino int count, key;
1859*6b445a62SJohn Marino {
1860*6b445a62SJohn Marino if (_rl_vi_doing_insert == 0)
1861*6b445a62SJohn Marino {
1862*6b445a62SJohn Marino _rl_vi_doing_insert = 1;
1863*6b445a62SJohn Marino rl_begin_undo_group ();
1864*6b445a62SJohn Marino }
1865*6b445a62SJohn Marino
1866*6b445a62SJohn Marino if (count > 0)
1867*6b445a62SJohn Marino {
1868*6b445a62SJohn Marino _rl_overwrite_char (count, key);
1869*6b445a62SJohn Marino vi_replace_count += count;
1870*6b445a62SJohn Marino }
1871*6b445a62SJohn Marino
1872*6b445a62SJohn Marino return (0);
1873*6b445a62SJohn Marino }
1874*6b445a62SJohn Marino
1875*6b445a62SJohn Marino int
rl_vi_overstrike_delete(count,key)1876*6b445a62SJohn Marino rl_vi_overstrike_delete (count, key)
1877*6b445a62SJohn Marino int count, key;
1878*6b445a62SJohn Marino {
1879*6b445a62SJohn Marino int i, s;
1880*6b445a62SJohn Marino
1881*6b445a62SJohn Marino for (i = 0; i < count; i++)
1882*6b445a62SJohn Marino {
1883*6b445a62SJohn Marino if (vi_replace_count == 0)
1884*6b445a62SJohn Marino {
1885*6b445a62SJohn Marino rl_ding ();
1886*6b445a62SJohn Marino break;
1887*6b445a62SJohn Marino }
1888*6b445a62SJohn Marino s = rl_point;
1889*6b445a62SJohn Marino
1890*6b445a62SJohn Marino if (rl_do_undo ())
1891*6b445a62SJohn Marino vi_replace_count--;
1892*6b445a62SJohn Marino
1893*6b445a62SJohn Marino if (rl_point == s)
1894*6b445a62SJohn Marino rl_backward_char (1, key);
1895*6b445a62SJohn Marino }
1896*6b445a62SJohn Marino
1897*6b445a62SJohn Marino if (vi_replace_count == 0 && _rl_vi_doing_insert)
1898*6b445a62SJohn Marino {
1899*6b445a62SJohn Marino rl_end_undo_group ();
1900*6b445a62SJohn Marino rl_do_undo ();
1901*6b445a62SJohn Marino _rl_vi_doing_insert = 0;
1902*6b445a62SJohn Marino }
1903*6b445a62SJohn Marino return (0);
1904*6b445a62SJohn Marino }
1905*6b445a62SJohn Marino
1906*6b445a62SJohn Marino int
rl_vi_replace(count,key)1907*6b445a62SJohn Marino rl_vi_replace (count, key)
1908*6b445a62SJohn Marino int count, key;
1909*6b445a62SJohn Marino {
1910*6b445a62SJohn Marino int i;
1911*6b445a62SJohn Marino
1912*6b445a62SJohn Marino vi_replace_count = 0;
1913*6b445a62SJohn Marino
1914*6b445a62SJohn Marino if (!vi_replace_map)
1915*6b445a62SJohn Marino {
1916*6b445a62SJohn Marino vi_replace_map = rl_make_bare_keymap ();
1917*6b445a62SJohn Marino
1918*6b445a62SJohn Marino for (i = ' '; i < KEYMAP_SIZE; i++)
1919*6b445a62SJohn Marino vi_replace_map[i].function = rl_vi_overstrike;
1920*6b445a62SJohn Marino
1921*6b445a62SJohn Marino vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1922*6b445a62SJohn Marino vi_replace_map[ESC].function = rl_vi_movement_mode;
1923*6b445a62SJohn Marino vi_replace_map[RETURN].function = rl_newline;
1924*6b445a62SJohn Marino vi_replace_map[NEWLINE].function = rl_newline;
1925*6b445a62SJohn Marino
1926*6b445a62SJohn Marino /* If the normal vi insertion keymap has ^H bound to erase, do the
1927*6b445a62SJohn Marino same here. Probably should remove the assignment to RUBOUT up
1928*6b445a62SJohn Marino there, but I don't think it will make a difference in real life. */
1929*6b445a62SJohn Marino if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1930*6b445a62SJohn Marino vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1931*6b445a62SJohn Marino vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1932*6b445a62SJohn Marino
1933*6b445a62SJohn Marino }
1934*6b445a62SJohn Marino _rl_keymap = vi_replace_map;
1935*6b445a62SJohn Marino return (0);
1936*6b445a62SJohn Marino }
1937*6b445a62SJohn Marino
1938*6b445a62SJohn Marino #if 0
1939*6b445a62SJohn Marino /* Try to complete the word we are standing on or the word that ends with
1940*6b445a62SJohn Marino the previous character. A space matches everything. Word delimiters are
1941*6b445a62SJohn Marino space and ;. */
1942*6b445a62SJohn Marino int
1943*6b445a62SJohn Marino rl_vi_possible_completions()
1944*6b445a62SJohn Marino {
1945*6b445a62SJohn Marino int save_pos = rl_point;
1946*6b445a62SJohn Marino
1947*6b445a62SJohn Marino if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1948*6b445a62SJohn Marino {
1949*6b445a62SJohn Marino while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1950*6b445a62SJohn Marino rl_line_buffer[rl_point] != ';')
1951*6b445a62SJohn Marino rl_point++;
1952*6b445a62SJohn Marino }
1953*6b445a62SJohn Marino else if (rl_line_buffer[rl_point - 1] == ';')
1954*6b445a62SJohn Marino {
1955*6b445a62SJohn Marino rl_ding ();
1956*6b445a62SJohn Marino return (0);
1957*6b445a62SJohn Marino }
1958*6b445a62SJohn Marino
1959*6b445a62SJohn Marino rl_possible_completions ();
1960*6b445a62SJohn Marino rl_point = save_pos;
1961*6b445a62SJohn Marino
1962*6b445a62SJohn Marino return (0);
1963*6b445a62SJohn Marino }
1964*6b445a62SJohn Marino #endif
1965*6b445a62SJohn Marino
1966*6b445a62SJohn Marino /* Functions to save and restore marks. */
1967*6b445a62SJohn Marino static int
_rl_vi_set_mark()1968*6b445a62SJohn Marino _rl_vi_set_mark ()
1969*6b445a62SJohn Marino {
1970*6b445a62SJohn Marino int ch;
1971*6b445a62SJohn Marino
1972*6b445a62SJohn Marino RL_SETSTATE(RL_STATE_MOREINPUT);
1973*6b445a62SJohn Marino ch = rl_read_key ();
1974*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_MOREINPUT);
1975*6b445a62SJohn Marino
1976*6b445a62SJohn Marino if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
1977*6b445a62SJohn Marino {
1978*6b445a62SJohn Marino rl_ding ();
1979*6b445a62SJohn Marino return -1;
1980*6b445a62SJohn Marino }
1981*6b445a62SJohn Marino ch -= 'a';
1982*6b445a62SJohn Marino vi_mark_chars[ch] = rl_point;
1983*6b445a62SJohn Marino return 0;
1984*6b445a62SJohn Marino }
1985*6b445a62SJohn Marino
1986*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
1987*6b445a62SJohn Marino static int
_rl_vi_callback_set_mark(data)1988*6b445a62SJohn Marino _rl_vi_callback_set_mark (data)
1989*6b445a62SJohn Marino _rl_callback_generic_arg *data;
1990*6b445a62SJohn Marino {
1991*6b445a62SJohn Marino _rl_callback_func = 0;
1992*6b445a62SJohn Marino _rl_want_redisplay = 1;
1993*6b445a62SJohn Marino
1994*6b445a62SJohn Marino return (_rl_vi_set_mark ());
1995*6b445a62SJohn Marino }
1996*6b445a62SJohn Marino #endif
1997*6b445a62SJohn Marino
1998*6b445a62SJohn Marino int
rl_vi_set_mark(count,key)1999*6b445a62SJohn Marino rl_vi_set_mark (count, key)
2000*6b445a62SJohn Marino int count, key;
2001*6b445a62SJohn Marino {
2002*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
2003*6b445a62SJohn Marino if (RL_ISSTATE (RL_STATE_CALLBACK))
2004*6b445a62SJohn Marino {
2005*6b445a62SJohn Marino _rl_callback_data = 0;
2006*6b445a62SJohn Marino _rl_callback_func = _rl_vi_callback_set_mark;
2007*6b445a62SJohn Marino return (0);
2008*6b445a62SJohn Marino }
2009*6b445a62SJohn Marino #endif
2010*6b445a62SJohn Marino
2011*6b445a62SJohn Marino return (_rl_vi_set_mark ());
2012*6b445a62SJohn Marino }
2013*6b445a62SJohn Marino
2014*6b445a62SJohn Marino static int
_rl_vi_goto_mark()2015*6b445a62SJohn Marino _rl_vi_goto_mark ()
2016*6b445a62SJohn Marino {
2017*6b445a62SJohn Marino int ch;
2018*6b445a62SJohn Marino
2019*6b445a62SJohn Marino RL_SETSTATE(RL_STATE_MOREINPUT);
2020*6b445a62SJohn Marino ch = rl_read_key ();
2021*6b445a62SJohn Marino RL_UNSETSTATE(RL_STATE_MOREINPUT);
2022*6b445a62SJohn Marino
2023*6b445a62SJohn Marino if (ch == '`')
2024*6b445a62SJohn Marino {
2025*6b445a62SJohn Marino rl_point = rl_mark;
2026*6b445a62SJohn Marino return 0;
2027*6b445a62SJohn Marino }
2028*6b445a62SJohn Marino else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
2029*6b445a62SJohn Marino {
2030*6b445a62SJohn Marino rl_ding ();
2031*6b445a62SJohn Marino return -1;
2032*6b445a62SJohn Marino }
2033*6b445a62SJohn Marino
2034*6b445a62SJohn Marino ch -= 'a';
2035*6b445a62SJohn Marino if (vi_mark_chars[ch] == -1)
2036*6b445a62SJohn Marino {
2037*6b445a62SJohn Marino rl_ding ();
2038*6b445a62SJohn Marino return -1;
2039*6b445a62SJohn Marino }
2040*6b445a62SJohn Marino rl_point = vi_mark_chars[ch];
2041*6b445a62SJohn Marino return 0;
2042*6b445a62SJohn Marino }
2043*6b445a62SJohn Marino
2044*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
2045*6b445a62SJohn Marino static int
_rl_vi_callback_goto_mark(data)2046*6b445a62SJohn Marino _rl_vi_callback_goto_mark (data)
2047*6b445a62SJohn Marino _rl_callback_generic_arg *data;
2048*6b445a62SJohn Marino {
2049*6b445a62SJohn Marino _rl_callback_func = 0;
2050*6b445a62SJohn Marino _rl_want_redisplay = 1;
2051*6b445a62SJohn Marino
2052*6b445a62SJohn Marino return (_rl_vi_goto_mark ());
2053*6b445a62SJohn Marino }
2054*6b445a62SJohn Marino #endif
2055*6b445a62SJohn Marino
2056*6b445a62SJohn Marino int
rl_vi_goto_mark(count,key)2057*6b445a62SJohn Marino rl_vi_goto_mark (count, key)
2058*6b445a62SJohn Marino int count, key;
2059*6b445a62SJohn Marino {
2060*6b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
2061*6b445a62SJohn Marino if (RL_ISSTATE (RL_STATE_CALLBACK))
2062*6b445a62SJohn Marino {
2063*6b445a62SJohn Marino _rl_callback_data = 0;
2064*6b445a62SJohn Marino _rl_callback_func = _rl_vi_callback_goto_mark;
2065*6b445a62SJohn Marino return (0);
2066*6b445a62SJohn Marino }
2067*6b445a62SJohn Marino #endif
2068*6b445a62SJohn Marino
2069*6b445a62SJohn Marino return (_rl_vi_goto_mark ());
2070*6b445a62SJohn Marino }
2071*6b445a62SJohn Marino #endif /* VI_MODE */
2072