2 /* vi_mode.c -- A vi emulation mode for Bash.
3 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
5 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
7 This file is part of the GNU Readline Library, a library for
8 reading lines of text with interactive input and history editing.
10 The GNU Readline Library is free software; you can redistribute it
11 and/or modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2, or
13 (at your option) any later version.
15 The GNU Readline Library is distributed in the hope that it will be
16 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 The GNU General Public License is often shipped with GNU software, and
21 is generally kept in a file called COPYING or LICENSE. If you do not
22 have a copy of the license, write to the Free Software Foundation,
23 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24 #define READLINE_LIBRARY
26 /* **************************************************************** */
28 /* VI Emulation Mode */
30 /* **************************************************************** */
35 #if defined (HAVE_CONFIG_H)
39 #include <sys/types.h>
41 #if defined (HAVE_STDLIB_H)
44 # include "ansi_stdlib.h"
45 #endif /* HAVE_STDLIB_H */
47 #if defined (HAVE_UNISTD_H)
53 /* Some standard library routines. */
60 #include "rlprivate.h"
64 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
67 int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
69 /* Non-zero means enter insertion mode. */
70 static int _rl_vi_doing_insert;
72 /* Command keys which do movement for xxx_to commands. */
73 static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
75 /* Keymap used for vi replace characters. Created dynamically since
77 static Keymap vi_replace_map;
79 /* The number of characters inserted in the last replace operation. */
80 static int vi_replace_count;
82 /* If non-zero, we have text inserted after a c[motion] command that put
83 us implicitly into insert mode. Some people want this text to be
84 attached to the command so that it is `redoable' with `.'. */
85 static int vi_continued_command;
86 static char *vi_insert_buffer;
87 static int vi_insert_buffer_size;
89 static int _rl_vi_last_repeat = 1;
90 static int _rl_vi_last_arg_sign = 1;
91 static int _rl_vi_last_motion;
92 #if defined (HANDLE_MULTIBYTE)
93 static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
94 static int _rl_vi_last_search_mblen;
96 static int _rl_vi_last_search_char;
98 static int _rl_vi_last_replacement;
100 static int _rl_vi_last_key_before_insert;
102 static int vi_redoing;
104 /* Text modification commands. These are the `redoable' commands. */
105 static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
107 /* Arrays for the saved marks. */
108 static int vi_mark_chars['z' - 'a' + 1];
110 static void _rl_vi_stuff_insert PARAMS((int));
111 static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
113 static void _rl_vi_backup PARAMS((void));
115 static int _rl_vi_arg_dispatch PARAMS((int));
116 static int rl_digit_loop1 PARAMS((void));
118 static int _rl_vi_set_mark PARAMS((void));
119 static int _rl_vi_goto_mark PARAMS((void));
121 static void _rl_vi_append_forward PARAMS((int));
123 static int _rl_vi_callback_getchar PARAMS((char *, int));
125 #if defined (READLINE_CALLBACKS)
126 static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
127 static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
128 static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
129 static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
133 _rl_vi_initialize_line ()
137 for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
138 vi_mark_chars[i] = -1;
140 RL_UNSETSTATE(RL_STATE_VICMDONCE);
146 _rl_vi_last_command = 'i';
147 _rl_vi_last_repeat = 1;
148 _rl_vi_last_arg_sign = 1;
149 _rl_vi_last_motion = 0;
153 _rl_vi_set_last (key, repeat, sign)
154 int key, repeat, sign;
156 _rl_vi_last_command = key;
157 _rl_vi_last_repeat = repeat;
158 _rl_vi_last_arg_sign = sign;
161 /* A convenience function that calls _rl_vi_set_last to save the last command
162 information and enters insertion mode. */
164 rl_vi_start_inserting (key, repeat, sign)
165 int key, repeat, sign;
167 _rl_vi_set_last (key, repeat, sign);
168 rl_vi_insertion_mode (1, key);
171 /* Is the command C a VI mode text modification command? */
173 _rl_vi_textmod_command (c)
176 return (member (c, vi_textmod));
180 _rl_vi_stuff_insert (count)
183 rl_begin_undo_group ();
185 rl_insert_text (vi_insert_buffer);
186 rl_end_undo_group ();
189 /* Bound to `.'. Called from command mode, so we know that we have to
190 redo a text modification command. The default for _rl_vi_last_command
191 puts you back into insert mode. */
193 rl_vi_redo (count, c)
198 if (!rl_explicit_arg)
200 rl_numeric_arg = _rl_vi_last_repeat;
201 rl_arg_sign = _rl_vi_last_arg_sign;
206 /* If we're redoing an insert with `i', stuff in the inserted text
207 and do not go into insertion mode. */
208 if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
210 _rl_vi_stuff_insert (count);
211 /* And back up point over the last character inserted. */
215 /* Ditto for redoing an insert with `a', but move forward a character first
216 like the `a' command does. */
217 else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer)
219 _rl_vi_append_forward ('a');
220 _rl_vi_stuff_insert (count);
225 r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
231 /* A placeholder for further expansion. */
233 rl_vi_undo (count, key)
236 return (rl_undo_command (count, key));
239 /* Yank the nth arg from the previous line into this line at point. */
241 rl_vi_yank_arg (count, key)
244 /* Readline thinks that the first word on a line is the 0th, while vi
245 thinks the first word on a line is the 1st. Compensate. */
247 rl_yank_nth_arg (count - 1, 0);
249 rl_yank_nth_arg ('$', 0);
254 /* With an argument, move back that many history lines, else move to the
255 beginning of history. */
257 rl_vi_fetch_history (count, c)
262 /* Giving an argument of n means we want the nth command in the history
263 file. The command number is interpreted the same way that the bash
264 `history' command does it -- that is, giving an argument count of 450
265 to this command would get the command listed as number 450 in the
266 output of `history'. */
269 wanted = history_base + where_history () - count;
271 rl_beginning_of_history (0, 0);
273 rl_get_previous_history (wanted, c);
276 rl_beginning_of_history (count, 0);
280 /* Search again for the last thing searched for. */
282 rl_vi_search_again (count, key)
288 rl_noninc_reverse_search_again (count, key);
292 rl_noninc_forward_search_again (count, key);
298 /* Do a vi style search. */
300 rl_vi_search (count, key)
306 _rl_free_saved_history_line ();
307 rl_noninc_forward_search (count, key);
311 _rl_free_saved_history_line ();
312 rl_noninc_reverse_search (count, key);
322 /* Completion, from vi's point of view. */
324 rl_vi_complete (ignore, key)
327 if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
329 if (!whitespace (rl_line_buffer[rl_point + 1]))
330 rl_vi_end_word (1, 'E');
335 rl_complete_internal ('*'); /* Expansion and replacement. */
337 rl_complete_internal ('?'); /* List possible completions. */
338 else if (key == '\\')
339 rl_complete_internal (TAB); /* Standard Readline completion. */
341 rl_complete (0, key);
343 if (key == '*' || key == '\\')
344 rl_vi_start_inserting (key, 1, rl_arg_sign);
349 /* Tilde expansion for vi mode. */
351 rl_vi_tilde_expand (ignore, key)
354 rl_tilde_expand (0, key);
355 rl_vi_start_inserting (key, 1, rl_arg_sign);
359 /* Previous word in vi mode. */
361 rl_vi_prev_word (count, key)
365 return (rl_vi_next_word (-count, key));
373 if (_rl_uppercase_p (key))
374 rl_vi_bWord (count, key);
376 rl_vi_bword (count, key);
381 /* Next word in vi mode. */
383 rl_vi_next_word (count, key)
387 return (rl_vi_prev_word (-count, key));
389 if (rl_point >= (rl_end - 1))
395 if (_rl_uppercase_p (key))
396 rl_vi_fWord (count, key);
398 rl_vi_fword (count, key);
402 /* Move to the end of the ?next? word. */
404 rl_vi_end_word (count, key)
413 if (_rl_uppercase_p (key))
414 rl_vi_eWord (count, key);
416 rl_vi_eword (count, key);
420 /* Move forward a word the way that 'W' does. */
422 rl_vi_fWord (count, ignore)
425 while (count-- && rl_point < (rl_end - 1))
427 /* Skip until whitespace. */
428 while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
431 /* Now skip whitespace. */
432 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
439 rl_vi_bWord (count, ignore)
442 while (count-- && rl_point > 0)
444 /* If we are at the start of a word, move back to whitespace so
445 we will go back to the start of the previous word. */
446 if (!whitespace (rl_line_buffer[rl_point]) &&
447 whitespace (rl_line_buffer[rl_point - 1]))
450 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
455 while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
463 rl_vi_eWord (count, ignore)
466 while (count-- && rl_point < (rl_end - 1))
468 if (!whitespace (rl_line_buffer[rl_point]))
471 /* Move to the next non-whitespace character (to the start of the
473 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
476 if (rl_point && rl_point < rl_end)
478 /* Skip whitespace. */
479 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
482 /* Skip until whitespace. */
483 while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
486 /* Move back to the last character of the word. */
494 rl_vi_fword (count, ignore)
497 while (count-- && rl_point < (rl_end - 1))
499 /* Move to white space (really non-identifer). */
500 if (_rl_isident (rl_line_buffer[rl_point]))
502 while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
505 else /* if (!whitespace (rl_line_buffer[rl_point])) */
507 while (!_rl_isident (rl_line_buffer[rl_point]) &&
508 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
512 /* Move past whitespace. */
513 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
520 rl_vi_bword (count, ignore)
523 while (count-- && rl_point > 0)
527 /* If we are at the start of a word, move back to whitespace
528 so we will go back to the start of the previous word. */
529 if (!whitespace (rl_line_buffer[rl_point]) &&
530 whitespace (rl_line_buffer[rl_point - 1]))
533 /* If this character and the previous character are `opposite', move
534 back so we don't get messed up by the rl_point++ down there in
535 the while loop. Without this code, words like `l;' screw up the
537 last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
538 if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
539 (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
542 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
547 if (_rl_isident (rl_line_buffer[rl_point]))
548 while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
550 while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
551 !whitespace (rl_line_buffer[rl_point]));
559 rl_vi_eword (count, ignore)
562 while (count-- && rl_point < rl_end - 1)
564 if (!whitespace (rl_line_buffer[rl_point]))
567 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
570 if (rl_point < rl_end)
572 if (_rl_isident (rl_line_buffer[rl_point]))
573 while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
575 while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
576 && !whitespace (rl_line_buffer[rl_point]));
584 rl_vi_insert_beg (count, key)
587 rl_beg_of_line (1, key);
588 rl_vi_insertion_mode (1, key);
593 _rl_vi_append_forward (key)
598 if (rl_point < rl_end)
600 if (MB_CUR_MAX == 1 || rl_byte_oriented)
605 rl_forward_char (1, key);
606 if (point == rl_point)
613 rl_vi_append_mode (count, key)
616 _rl_vi_append_forward (key);
617 rl_vi_start_inserting (key, 1, rl_arg_sign);
622 rl_vi_append_eol (count, key)
625 rl_end_of_line (1, key);
626 rl_vi_append_mode (1, key);
630 /* What to do in the case of C-d. */
632 rl_vi_eof_maybe (count, c)
635 return (rl_newline (1, '\n'));
638 /* Insertion mode stuff. */
640 /* Switching from one mode to the other really just involves
641 switching keymaps. */
643 rl_vi_insertion_mode (count, key)
646 _rl_keymap = vi_insertion_keymap;
647 _rl_vi_last_key_before_insert = key;
652 _rl_vi_save_insert (up)
657 if (up == 0 || up->what != UNDO_INSERT)
659 if (vi_insert_buffer_size >= 1)
660 vi_insert_buffer[0] = '\0';
666 len = end - start + 1;
667 if (len >= vi_insert_buffer_size)
669 vi_insert_buffer_size += (len + 32) - (len % 32);
670 vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
672 strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
673 vi_insert_buffer[len-1] = '\0';
677 _rl_vi_done_inserting ()
679 if (_rl_vi_doing_insert)
681 /* The `C', `s', and `S' commands set this. */
682 rl_end_undo_group ();
683 /* Now, the text between rl_undo_list->next->start and
684 rl_undo_list->next->end is what was inserted while in insert
685 mode. It gets copied to VI_INSERT_BUFFER because it depends
686 on absolute indices into the line which may change (though they
687 probably will not). */
688 _rl_vi_doing_insert = 0;
689 _rl_vi_save_insert (rl_undo_list->next);
690 vi_continued_command = 1;
694 if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
695 _rl_vi_save_insert (rl_undo_list);
696 /* XXX - Other keys probably need to be checked. */
697 else if (_rl_vi_last_key_before_insert == 'C')
698 rl_end_undo_group ();
699 while (_rl_undo_group_level > 0)
700 rl_end_undo_group ();
701 vi_continued_command = 0;
706 rl_vi_movement_mode (count, key)
710 rl_backward_char (1, key);
712 _rl_keymap = vi_movement_keymap;
713 _rl_vi_done_inserting ();
715 /* This is how POSIX.2 says `U' should behave -- everything up until the
716 first time you go into command mode should not be undone. */
717 if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
718 rl_free_undo_list ();
720 RL_SETSTATE (RL_STATE_VICMDONCE);
725 rl_vi_arg_digit (count, c)
728 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
729 return (rl_beg_of_line (1, c));
731 return (rl_digit_argument (count, c));
734 /* Change the case of the next COUNT characters. */
735 #if defined (HANDLE_MULTIBYTE)
737 _rl_vi_change_mbchar_case (count)
741 char mb[MB_LEN_MAX+1];
745 memset (&ps, 0, sizeof (mbstate_t));
746 if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
748 while (count-- && rl_point < rl_end)
750 mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
753 else if (iswlower (wc))
757 /* Just skip over chars neither upper nor lower case */
758 rl_forward_char (1, 0);
762 /* Vi is kind of strange here. */
766 mlen = wcrtomb (mb, wc, &ps);
769 rl_begin_undo_group ();
771 if (rl_point < p) /* Did we retreat at EOL? */
772 rl_point++; /* XXX - should we advance more than 1 for mbchar? */
774 rl_end_undo_group ();
778 rl_forward_char (1, 0);
786 rl_vi_change_case (count, ignore)
791 /* Don't try this on an empty line. */
792 if (rl_point >= rl_end)
796 #if defined (HANDLE_MULTIBYTE)
797 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
798 return (_rl_vi_change_mbchar_case (count));
801 while (count-- && rl_point < rl_end)
803 if (_rl_uppercase_p (rl_line_buffer[rl_point]))
804 c = _rl_to_lower (rl_line_buffer[rl_point]);
805 else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
806 c = _rl_to_upper (rl_line_buffer[rl_point]);
809 /* Just skip over characters neither upper nor lower case. */
810 rl_forward_char (1, c);
814 /* Vi is kind of strange here. */
818 rl_begin_undo_group ();
820 if (rl_point < p) /* Did we retreat at EOL? */
822 _rl_insert_char (1, c);
823 rl_end_undo_group ();
827 rl_forward_char (1, c);
833 rl_vi_put (count, key)
836 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
837 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
842 rl_backward_char (1, key);
849 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
850 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
858 if (rl_point && rl_point == rl_end)
860 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
861 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
869 rl_vi_column (count, key)
873 rl_end_of_line (1, key);
875 rl_point = count - 1;
880 rl_vi_domove (key, nextkey)
887 RL_SETSTATE(RL_STATE_MOREINPUT);
889 RL_UNSETSTATE(RL_STATE_MOREINPUT);
892 if (!member (c, vi_motion))
896 save = rl_numeric_arg;
897 rl_numeric_arg = _rl_digit_value (c);
899 RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
901 RL_UNSETSTATE (RL_STATE_VIMOTION);
902 rl_numeric_arg *= save;
903 RL_SETSTATE(RL_STATE_MOREINPUT);
904 c = rl_read_key (); /* real command */
905 RL_UNSETSTATE(RL_STATE_MOREINPUT);
908 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
911 rl_beg_of_line (1, c);
912 _rl_vi_last_motion = c;
919 _rl_vi_last_motion = c;
921 /* Append a blank character temporarily so that the motion routines
922 work right at the end of the line. */
924 rl_line_buffer[rl_end++] = ' ';
925 rl_line_buffer[rl_end] = '\0';
927 _rl_dispatch (c, _rl_keymap);
929 /* Remove the blank that we added. */
931 rl_line_buffer[rl_end] = '\0';
932 if (rl_point > rl_end)
935 /* No change in position means the command failed. */
936 if (rl_mark == rl_point)
939 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
940 word. If we are not at the end of the line, and we are on a
941 non-whitespace character, move back one (presumably to whitespace). */
942 if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
943 !whitespace (rl_line_buffer[rl_point]))
946 /* If cw or cW, back up to the end of a word, so the behaviour of ce
947 or cE is the actual result. Brute-force, no subtlety. */
948 if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
950 /* Don't move farther back than where we started. */
951 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
954 /* Posix.2 says that if cw or cW moves the cursor towards the end of
955 the line, the character under the cursor should be deleted. */
956 if (rl_point == rl_mark)
960 /* Move past the end of the word so that the kill doesn't
961 remove the last letter of the previous word. Only do this
962 if we are not at the end of the line. */
963 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
968 if (rl_mark < rl_point)
969 SWAP (rl_point, rl_mark);
974 /* Process C as part of the current numeric argument. Return -1 if the
975 argument should be aborted, 0 if we should not read any more chars, and
976 1 if we should continue to read chars. */
978 _rl_vi_arg_dispatch (c)
984 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
995 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
997 rl_numeric_arg = _rl_digit_value (c);
1003 rl_clear_message ();
1004 rl_stuff_char (key);
1009 /* A simplified loop for vi. Don't dispatch key at end.
1010 Don't recognize minus sign?
1011 Should this do rl_save_prompt/rl_restore_prompt? */
1019 if (_rl_arg_overflow ())
1022 c = _rl_arg_getchar ();
1024 r = _rl_vi_arg_dispatch (c);
1029 RL_UNSETSTATE(RL_STATE_NUMERICARG);
1034 rl_vi_delete_to (count, key)
1039 if (_rl_uppercase_p (key))
1040 rl_stuff_char ('$');
1041 else if (vi_redoing)
1042 rl_stuff_char (_rl_vi_last_motion);
1044 if (rl_vi_domove (key, &c))
1050 /* These are the motion commands that do not require adjusting the
1052 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
1055 rl_kill_text (rl_point, rl_mark);
1060 rl_vi_change_to (count, key)
1065 if (_rl_uppercase_p (key))
1066 rl_stuff_char ('$');
1067 else if (vi_redoing)
1068 rl_stuff_char (_rl_vi_last_motion);
1070 start_pos = rl_point;
1072 if (rl_vi_domove (key, &c))
1078 /* These are the motion commands that do not require adjusting the
1079 mark. c[wW] are handled by special-case code in rl_vi_domove(),
1080 and already leave the mark at the correct location. */
1081 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
1084 /* The cursor never moves with c[wW]. */
1085 if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
1086 rl_point = start_pos;
1090 if (vi_insert_buffer && *vi_insert_buffer)
1091 rl_begin_undo_group ();
1092 rl_delete_text (rl_point, rl_mark);
1093 if (vi_insert_buffer && *vi_insert_buffer)
1095 rl_insert_text (vi_insert_buffer);
1096 rl_end_undo_group ();
1101 rl_begin_undo_group (); /* to make the `u' command work */
1102 rl_kill_text (rl_point, rl_mark);
1103 /* `C' does not save the text inserted for undoing or redoing. */
1104 if (_rl_uppercase_p (key) == 0)
1105 _rl_vi_doing_insert = 1;
1106 rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
1113 rl_vi_yank_to (count, key)
1119 if (_rl_uppercase_p (key))
1120 rl_stuff_char ('$');
1122 if (rl_vi_domove (key, &c))
1128 /* These are the motion commands that do not require adjusting the
1130 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
1133 rl_begin_undo_group ();
1134 rl_kill_text (rl_point, rl_mark);
1135 rl_end_undo_group ();
1143 rl_vi_rubout (count, key)
1149 return (rl_vi_delete (-count, key));
1158 if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1159 rl_backward_char (count, key);
1160 else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1161 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1168 rl_kill_text (rl_point, opoint);
1174 rl_vi_delete (count, key)
1180 return (rl_vi_rubout (-count, key));
1188 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1189 end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1191 end = rl_point + count;
1196 rl_kill_text (rl_point, end);
1198 if (rl_point > 0 && rl_point == rl_end)
1199 rl_backward_char (1, key);
1205 rl_vi_back_to_indent (count, key)
1208 rl_beg_of_line (1, key);
1209 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1215 rl_vi_first_print (count, key)
1218 return (rl_vi_back_to_indent (1, key));
1221 static int _rl_cs_dir, _rl_cs_orig_dir;
1223 #if defined (READLINE_CALLBACKS)
1225 _rl_vi_callback_char_search (data)
1226 _rl_callback_generic_arg *data;
1228 #if defined (HANDLE_MULTIBYTE)
1229 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1231 RL_SETSTATE(RL_STATE_MOREINPUT);
1232 _rl_vi_last_search_char = rl_read_key ();
1233 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1236 _rl_callback_func = 0;
1237 _rl_want_redisplay = 1;
1239 #if defined (HANDLE_MULTIBYTE)
1240 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
1242 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
1248 rl_vi_char_search (count, key)
1251 #if defined (HANDLE_MULTIBYTE)
1252 static char *target;
1258 if (key == ';' || key == ',')
1259 _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
1265 _rl_cs_orig_dir = _rl_cs_dir = FTO;
1269 _rl_cs_orig_dir = _rl_cs_dir = BTO;
1273 _rl_cs_orig_dir = _rl_cs_dir = FFIND;
1277 _rl_cs_orig_dir = _rl_cs_dir = BFIND;
1283 /* set target and tlen below */
1285 #if defined (READLINE_CALLBACKS)
1286 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1288 _rl_callback_data = _rl_callback_data_alloc (count);
1289 _rl_callback_data->i1 = _rl_cs_dir;
1290 _rl_callback_func = _rl_vi_callback_char_search;
1296 #if defined (HANDLE_MULTIBYTE)
1297 _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1299 RL_SETSTATE(RL_STATE_MOREINPUT);
1300 _rl_vi_last_search_char = rl_read_key ();
1301 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1306 #if defined (HANDLE_MULTIBYTE)
1307 target = _rl_vi_last_search_mbchar;
1308 tlen = _rl_vi_last_search_mblen;
1310 target = _rl_vi_last_search_char;
1313 #if defined (HANDLE_MULTIBYTE)
1314 return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
1316 return (_rl_char_search_internal (count, _rl_cs_dir, target));
1320 /* Match brackets */
1322 rl_vi_match (ignore, key)
1325 int count = 1, brack, pos, tmp, pre;
1328 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1330 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1332 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1335 rl_forward_char (1, key);
1336 if (pre == rl_point)
1341 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1342 rl_point < rl_end - 1)
1343 rl_forward_char (1, key);
1360 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1364 pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1370 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1373 else if (b == brack)
1387 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1390 pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
1394 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1397 else if (b == brack)
1418 case ')': return -1;
1420 case ']': return -2;
1422 case '}': return -3;
1428 _rl_vi_change_char (count, c, mb)
1434 if (c == '\033' || c == CTRL ('C'))
1437 rl_begin_undo_group ();
1438 while (count-- && rl_point < rl_end)
1441 rl_vi_delete (1, c);
1442 if (rl_point < p) /* Did we retreat at EOL? */
1444 #if defined (HANDLE_MULTIBYTE)
1445 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1446 rl_insert_text (mb);
1449 _rl_insert_char (1, c);
1452 /* The cursor shall be left on the last character changed. */
1453 rl_backward_char (1, c);
1455 rl_end_undo_group ();
1461 _rl_vi_callback_getchar (mb, mlen)
1467 RL_SETSTATE(RL_STATE_MOREINPUT);
1469 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1471 #if defined (HANDLE_MULTIBYTE)
1472 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1473 c = _rl_read_mbstring (c, mb, mlen);
1479 #if defined (READLINE_CALLBACKS)
1481 _rl_vi_callback_change_char (data)
1482 _rl_callback_generic_arg *data;
1485 char mb[MB_LEN_MAX];
1487 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1489 _rl_callback_func = 0;
1490 _rl_want_redisplay = 1;
1492 return (_rl_vi_change_char (data->count, c, mb));
1497 rl_vi_change_char (count, key)
1501 char mb[MB_LEN_MAX];
1505 c = _rl_vi_last_replacement;
1509 #if defined (READLINE_CALLBACKS)
1510 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1512 _rl_callback_data = _rl_callback_data_alloc (count);
1513 _rl_callback_func = _rl_vi_callback_change_char;
1518 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1520 return (_rl_vi_change_char (count, c, mb));
1524 rl_vi_subst (count, key)
1527 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1528 if (vi_redoing == 0)
1529 rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1531 return (rl_vi_change_to (count, 'c'));
1535 rl_vi_overstrike (count, key)
1538 if (_rl_vi_doing_insert == 0)
1540 _rl_vi_doing_insert = 1;
1541 rl_begin_undo_group ();
1546 _rl_overwrite_char (count, key);
1547 vi_replace_count += count;
1554 rl_vi_overstrike_delete (count, key)
1559 for (i = 0; i < count; i++)
1561 if (vi_replace_count == 0)
1572 rl_backward_char (1, key);
1575 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1577 rl_end_undo_group ();
1579 _rl_vi_doing_insert = 0;
1585 rl_vi_replace (count, key)
1590 vi_replace_count = 0;
1592 if (!vi_replace_map)
1594 vi_replace_map = rl_make_bare_keymap ();
1596 for (i = ' '; i < KEYMAP_SIZE; i++)
1597 vi_replace_map[i].function = rl_vi_overstrike;
1599 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1600 vi_replace_map[ESC].function = rl_vi_movement_mode;
1601 vi_replace_map[RETURN].function = rl_newline;
1602 vi_replace_map[NEWLINE].function = rl_newline;
1604 /* If the normal vi insertion keymap has ^H bound to erase, do the
1605 same here. Probably should remove the assignment to RUBOUT up
1606 there, but I don't think it will make a difference in real life. */
1607 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1608 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1609 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1612 _rl_keymap = vi_replace_map;
1617 /* Try to complete the word we are standing on or the word that ends with
1618 the previous character. A space matches everything. Word delimiters are
1621 rl_vi_possible_completions()
1623 int save_pos = rl_point;
1625 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1627 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1628 rl_line_buffer[rl_point] != ';')
1631 else if (rl_line_buffer[rl_point - 1] == ';')
1637 rl_possible_completions ();
1638 rl_point = save_pos;
1644 /* Functions to save and restore marks. */
1650 RL_SETSTATE(RL_STATE_MOREINPUT);
1651 ch = rl_read_key ();
1652 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1654 if (ch < 'a' || ch > 'z')
1660 vi_mark_chars[ch] = rl_point;
1664 #if defined (READLINE_CALLBACKS)
1666 _rl_vi_callback_set_mark (data)
1667 _rl_callback_generic_arg *data;
1669 _rl_callback_func = 0;
1670 _rl_want_redisplay = 1;
1672 return (_rl_vi_set_mark ());
1677 rl_vi_set_mark (count, key)
1680 #if defined (READLINE_CALLBACKS)
1681 if (RL_ISSTATE (RL_STATE_CALLBACK))
1683 _rl_callback_data = 0;
1684 _rl_callback_func = _rl_vi_callback_set_mark;
1689 return (_rl_vi_set_mark ());
1697 RL_SETSTATE(RL_STATE_MOREINPUT);
1698 ch = rl_read_key ();
1699 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1706 else if (ch < 'a' || ch > 'z')
1713 if (vi_mark_chars[ch] == -1)
1718 rl_point = vi_mark_chars[ch];
1722 #if defined (READLINE_CALLBACKS)
1724 _rl_vi_callback_goto_mark (data)
1725 _rl_callback_generic_arg *data;
1727 _rl_callback_func = 0;
1728 _rl_want_redisplay = 1;
1730 return (_rl_vi_goto_mark ());
1735 rl_vi_goto_mark (count, key)
1738 #if defined (READLINE_CALLBACKS)
1739 if (RL_ISSTATE (RL_STATE_CALLBACK))
1741 _rl_callback_data = 0;
1742 _rl_callback_func = _rl_vi_callback_goto_mark;
1747 return (_rl_vi_goto_mark ());
1749 #endif /* VI_MODE */