1 /* vi_mode.c -- A vi emulation mode for Bash.
2 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
4 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
6 This file is part of the GNU Readline Library, a library for
7 reading lines of text with interactive input and history editing.
9 The GNU Readline Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2, or
12 (at your option) any later version.
14 The GNU Readline Library is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
25 /* **************************************************************** */
27 /* VI Emulation Mode */
29 /* **************************************************************** */
34 #if defined (HAVE_CONFIG_H)
38 #include <sys/types.h>
40 #if defined (HAVE_STDLIB_H)
43 # include "ansi_stdlib.h"
44 #endif /* HAVE_STDLIB_H */
46 #if defined (HAVE_UNISTD_H)
52 /* Some standard library routines. */
59 #include "rlprivate.h"
63 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
66 int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
68 /* Non-zero means enter insertion mode. */
69 static int _rl_vi_doing_insert;
71 /* Command keys which do movement for xxx_to commands. */
72 static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
74 /* Keymap used for vi replace characters. Created dynamically since
76 static Keymap vi_replace_map;
78 /* The number of characters inserted in the last replace operation. */
79 static int vi_replace_count;
81 /* If non-zero, we have text inserted after a c[motion] command that put
82 us implicitly into insert mode. Some people want this text to be
83 attached to the command so that it is `redoable' with `.'. */
84 static int vi_continued_command;
85 static char *vi_insert_buffer;
86 static int vi_insert_buffer_size;
88 static int _rl_vi_last_repeat = 1;
89 static int _rl_vi_last_arg_sign = 1;
90 static int _rl_vi_last_motion;
91 #if defined (HANDLE_MULTIBYTE)
92 static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
93 static int _rl_vi_last_search_mblen;
95 static int _rl_vi_last_search_char;
97 static int _rl_vi_last_replacement;
99 static int _rl_vi_last_key_before_insert;
101 static int vi_redoing;
103 /* Text modification commands. These are the `redoable' commands. */
104 static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
106 /* Arrays for the saved marks. */
107 static int vi_mark_chars['z' - 'a' + 1];
109 static void _rl_vi_stuff_insert PARAMS((int));
110 static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
112 static void _rl_vi_backup PARAMS((void));
114 static int _rl_vi_arg_dispatch PARAMS((int));
115 static int rl_digit_loop1 PARAMS((void));
117 static int _rl_vi_set_mark PARAMS((void));
118 static int _rl_vi_goto_mark PARAMS((void));
120 static void _rl_vi_append_forward PARAMS((int));
122 static int _rl_vi_callback_getchar PARAMS((char *, int));
124 #if defined (READLINE_CALLBACKS)
125 static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
126 static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
127 static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
128 static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
132 _rl_vi_initialize_line ()
136 for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
137 vi_mark_chars[i] = -1;
139 RL_UNSETSTATE(RL_STATE_VICMDONCE);
145 _rl_vi_last_command = 'i';
146 _rl_vi_last_repeat = 1;
147 _rl_vi_last_arg_sign = 1;
148 _rl_vi_last_motion = 0;
152 _rl_vi_set_last (key, repeat, sign)
153 int key, repeat, sign;
155 _rl_vi_last_command = key;
156 _rl_vi_last_repeat = repeat;
157 _rl_vi_last_arg_sign = sign;
160 /* A convenience function that calls _rl_vi_set_last to save the last command
161 information and enters insertion mode. */
163 rl_vi_start_inserting (key, repeat, sign)
164 int key, repeat, sign;
166 _rl_vi_set_last (key, repeat, sign);
167 rl_vi_insertion_mode (1, key);
170 /* Is the command C a VI mode text modification command? */
172 _rl_vi_textmod_command (c)
175 return (member (c, vi_textmod));
179 _rl_vi_stuff_insert (count)
182 rl_begin_undo_group ();
184 rl_insert_text (vi_insert_buffer);
185 rl_end_undo_group ();
188 /* Bound to `.'. Called from command mode, so we know that we have to
189 redo a text modification command. The default for _rl_vi_last_command
190 puts you back into insert mode. */
192 rl_vi_redo (count, c)
197 if (!rl_explicit_arg)
199 rl_numeric_arg = _rl_vi_last_repeat;
200 rl_arg_sign = _rl_vi_last_arg_sign;
205 /* If we're redoing an insert with `i', stuff in the inserted text
206 and do not go into insertion mode. */
207 if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
209 _rl_vi_stuff_insert (count);
210 /* And back up point over the last character inserted. */
214 /* Ditto for redoing an insert with `a', but move forward a character first
215 like the `a' command does. */
216 else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer)
218 _rl_vi_append_forward ('a');
219 _rl_vi_stuff_insert (count);
224 r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
230 /* A placeholder for further expansion. */
232 rl_vi_undo (count, key)
235 return (rl_undo_command (count, key));
238 /* Yank the nth arg from the previous line into this line at point. */
240 rl_vi_yank_arg (count, key)
243 /* Readline thinks that the first word on a line is the 0th, while vi
244 thinks the first word on a line is the 1st. Compensate. */
246 rl_yank_nth_arg (count - 1, 0);
248 rl_yank_nth_arg ('$', 0);
253 /* With an argument, move back that many history lines, else move to the
254 beginning of history. */
256 rl_vi_fetch_history (count, c)
261 /* Giving an argument of n means we want the nth command in the history
262 file. The command number is interpreted the same way that the bash
263 `history' command does it -- that is, giving an argument count of 450
264 to this command would get the command listed as number 450 in the
265 output of `history'. */
268 wanted = history_base + where_history () - count;
270 rl_beginning_of_history (0, 0);
272 rl_get_previous_history (wanted, c);
275 rl_beginning_of_history (count, 0);
279 /* Search again for the last thing searched for. */
281 rl_vi_search_again (count, key)
287 rl_noninc_reverse_search_again (count, key);
291 rl_noninc_forward_search_again (count, key);
297 /* Do a vi style search. */
299 rl_vi_search (count, key)
305 _rl_free_saved_history_line ();
306 rl_noninc_forward_search (count, key);
310 _rl_free_saved_history_line ();
311 rl_noninc_reverse_search (count, key);
321 /* Completion, from vi's point of view. */
323 rl_vi_complete (ignore, key)
326 if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
328 if (!whitespace (rl_line_buffer[rl_point + 1]))
329 rl_vi_end_word (1, 'E');
334 rl_complete_internal ('*'); /* Expansion and replacement. */
336 rl_complete_internal ('?'); /* List possible completions. */
337 else if (key == '\\')
338 rl_complete_internal (TAB); /* Standard Readline completion. */
340 rl_complete (0, key);
342 if (key == '*' || key == '\\')
343 rl_vi_start_inserting (key, 1, rl_arg_sign);
348 /* Tilde expansion for vi mode. */
350 rl_vi_tilde_expand (ignore, key)
353 rl_tilde_expand (0, key);
354 rl_vi_start_inserting (key, 1, rl_arg_sign);
358 /* Previous word in vi mode. */
360 rl_vi_prev_word (count, key)
364 return (rl_vi_next_word (-count, key));
372 if (_rl_uppercase_p (key))
373 rl_vi_bWord (count, key);
375 rl_vi_bword (count, key);
380 /* Next word in vi mode. */
382 rl_vi_next_word (count, key)
386 return (rl_vi_prev_word (-count, key));
388 if (rl_point >= (rl_end - 1))
394 if (_rl_uppercase_p (key))
395 rl_vi_fWord (count, key);
397 rl_vi_fword (count, key);
401 /* Move to the end of the ?next? word. */
403 rl_vi_end_word (count, key)
412 if (_rl_uppercase_p (key))
413 rl_vi_eWord (count, key);
415 rl_vi_eword (count, key);
419 /* Move forward a word the way that 'W' does. */
421 rl_vi_fWord (count, ignore)
424 while (count-- && rl_point < (rl_end - 1))
426 /* Skip until whitespace. */
427 while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
430 /* Now skip whitespace. */
431 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
438 rl_vi_bWord (count, ignore)
441 while (count-- && rl_point > 0)
443 /* If we are at the start of a word, move back to whitespace so
444 we will go back to the start of the previous word. */
445 if (!whitespace (rl_line_buffer[rl_point]) &&
446 whitespace (rl_line_buffer[rl_point - 1]))
449 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
454 while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
462 rl_vi_eWord (count, ignore)
465 while (count-- && rl_point < (rl_end - 1))
467 if (!whitespace (rl_line_buffer[rl_point]))
470 /* Move to the next non-whitespace character (to the start of the
472 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
475 if (rl_point && rl_point < rl_end)
477 /* Skip whitespace. */
478 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
481 /* Skip until whitespace. */
482 while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
485 /* Move back to the last character of the word. */
493 rl_vi_fword (count, ignore)
496 while (count-- && rl_point < (rl_end - 1))
498 /* Move to white space (really non-identifer). */
499 if (_rl_isident (rl_line_buffer[rl_point]))
501 while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
504 else /* if (!whitespace (rl_line_buffer[rl_point])) */
506 while (!_rl_isident (rl_line_buffer[rl_point]) &&
507 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
511 /* Move past whitespace. */
512 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
519 rl_vi_bword (count, ignore)
522 while (count-- && rl_point > 0)
526 /* If we are at the start of a word, move back to whitespace
527 so we will go back to the start of the previous word. */
528 if (!whitespace (rl_line_buffer[rl_point]) &&
529 whitespace (rl_line_buffer[rl_point - 1]))
532 /* If this character and the previous character are `opposite', move
533 back so we don't get messed up by the rl_point++ down there in
534 the while loop. Without this code, words like `l;' screw up the
536 last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
537 if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
538 (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
541 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
546 if (_rl_isident (rl_line_buffer[rl_point]))
547 while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
549 while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
550 !whitespace (rl_line_buffer[rl_point]));
558 rl_vi_eword (count, ignore)
561 while (count-- && rl_point < rl_end - 1)
563 if (!whitespace (rl_line_buffer[rl_point]))
566 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
569 if (rl_point < rl_end)
571 if (_rl_isident (rl_line_buffer[rl_point]))
572 while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
574 while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
575 && !whitespace (rl_line_buffer[rl_point]));
583 rl_vi_insert_beg (count, key)
586 rl_beg_of_line (1, key);
587 rl_vi_insertion_mode (1, key);
592 _rl_vi_append_forward (key)
597 if (rl_point < rl_end)
599 if (MB_CUR_MAX == 1 || rl_byte_oriented)
604 rl_forward_char (1, key);
605 if (point == rl_point)
612 rl_vi_append_mode (count, key)
615 _rl_vi_append_forward (key);
616 rl_vi_start_inserting (key, 1, rl_arg_sign);
621 rl_vi_append_eol (count, key)
624 rl_end_of_line (1, key);
625 rl_vi_append_mode (1, key);
629 /* What to do in the case of C-d. */
631 rl_vi_eof_maybe (count, c)
634 return (rl_newline (1, '\n'));
637 /* Insertion mode stuff. */
639 /* Switching from one mode to the other really just involves
640 switching keymaps. */
642 rl_vi_insertion_mode (count, key)
645 _rl_keymap = vi_insertion_keymap;
646 _rl_vi_last_key_before_insert = key;
651 _rl_vi_save_insert (up)
656 if (up == 0 || up->what != UNDO_INSERT)
658 if (vi_insert_buffer_size >= 1)
659 vi_insert_buffer[0] = '\0';
665 len = end - start + 1;
666 if (len >= vi_insert_buffer_size)
668 vi_insert_buffer_size += (len + 32) - (len % 32);
669 vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
671 strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
672 vi_insert_buffer[len-1] = '\0';
676 _rl_vi_done_inserting ()
678 if (_rl_vi_doing_insert)
680 /* The `C', `s', and `S' commands set this. */
681 rl_end_undo_group ();
682 /* Now, the text between rl_undo_list->next->start and
683 rl_undo_list->next->end is what was inserted while in insert
684 mode. It gets copied to VI_INSERT_BUFFER because it depends
685 on absolute indices into the line which may change (though they
686 probably will not). */
687 _rl_vi_doing_insert = 0;
688 _rl_vi_save_insert (rl_undo_list->next);
689 vi_continued_command = 1;
693 if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
694 _rl_vi_save_insert (rl_undo_list);
695 /* XXX - Other keys probably need to be checked. */
696 else if (_rl_vi_last_key_before_insert == 'C')
697 rl_end_undo_group ();
698 while (_rl_undo_group_level > 0)
699 rl_end_undo_group ();
700 vi_continued_command = 0;
705 rl_vi_movement_mode (count, key)
709 rl_backward_char (1, key);
711 _rl_keymap = vi_movement_keymap;
712 _rl_vi_done_inserting ();
714 /* This is how POSIX.2 says `U' should behave -- everything up until the
715 first time you go into command mode should not be undone. */
716 if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
717 rl_free_undo_list ();
719 RL_SETSTATE (RL_STATE_VICMDONCE);
724 rl_vi_arg_digit (count, c)
727 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
728 return (rl_beg_of_line (1, c));
730 return (rl_digit_argument (count, c));
733 /* Change the case of the next COUNT characters. */
734 #if defined (HANDLE_MULTIBYTE)
736 _rl_vi_change_mbchar_case (count)
740 char mb[MB_LEN_MAX+1];
744 memset (&ps, 0, sizeof (mbstate_t));
745 if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
747 while (count-- && rl_point < rl_end)
749 mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
752 else if (iswlower (wc))
756 /* Just skip over chars neither upper nor lower case */
757 rl_forward_char (1, 0);
761 /* Vi is kind of strange here. */
765 mlen = wcrtomb (mb, wc, &ps);
768 rl_begin_undo_group ();
770 if (rl_point < p) /* Did we retreat at EOL? */
771 rl_point++; /* XXX - should we advance more than 1 for mbchar? */
773 rl_end_undo_group ();
777 rl_forward_char (1, 0);
785 rl_vi_change_case (count, ignore)
790 /* Don't try this on an empty line. */
791 if (rl_point >= rl_end)
795 #if defined (HANDLE_MULTIBYTE)
796 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
797 return (_rl_vi_change_mbchar_case (count));
800 while (count-- && rl_point < rl_end)
802 if (_rl_uppercase_p (rl_line_buffer[rl_point]))
803 c = _rl_to_lower (rl_line_buffer[rl_point]);
804 else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
805 c = _rl_to_upper (rl_line_buffer[rl_point]);
808 /* Just skip over characters neither upper nor lower case. */
809 rl_forward_char (1, c);
813 /* Vi is kind of strange here. */
817 rl_begin_undo_group ();
819 if (rl_point < p) /* Did we retreat at EOL? */
821 _rl_insert_char (1, c);
822 rl_end_undo_group ();
826 rl_forward_char (1, c);
832 rl_vi_put (count, key)
835 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
836 rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
841 rl_backward_char (1, key);
848 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
849 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
857 if (rl_point && rl_point == rl_end)
859 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
860 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
868 rl_vi_column (count, key)
872 rl_end_of_line (1, key);
874 rl_point = count - 1;
879 rl_vi_domove (key, nextkey)
886 RL_SETSTATE(RL_STATE_MOREINPUT);
888 RL_UNSETSTATE(RL_STATE_MOREINPUT);
898 if (!member (c, vi_motion))
902 save = rl_numeric_arg;
903 rl_numeric_arg = _rl_digit_value (c);
905 RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
907 RL_UNSETSTATE (RL_STATE_VIMOTION);
908 rl_numeric_arg *= save;
909 RL_SETSTATE(RL_STATE_MOREINPUT);
910 c = rl_read_key (); /* real command */
911 RL_UNSETSTATE(RL_STATE_MOREINPUT);
919 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
922 rl_beg_of_line (1, c);
923 _rl_vi_last_motion = c;
930 _rl_vi_last_motion = c;
932 /* Append a blank character temporarily so that the motion routines
933 work right at the end of the line. */
935 rl_line_buffer[rl_end++] = ' ';
936 rl_line_buffer[rl_end] = '\0';
938 _rl_dispatch (c, _rl_keymap);
940 /* Remove the blank that we added. */
942 rl_line_buffer[rl_end] = '\0';
943 if (rl_point > rl_end)
946 /* No change in position means the command failed. */
947 if (rl_mark == rl_point)
950 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
951 word. If we are not at the end of the line, and we are on a
952 non-whitespace character, move back one (presumably to whitespace). */
953 if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
954 !whitespace (rl_line_buffer[rl_point]))
957 /* If cw or cW, back up to the end of a word, so the behaviour of ce
958 or cE is the actual result. Brute-force, no subtlety. */
959 if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
961 /* Don't move farther back than where we started. */
962 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
965 /* Posix.2 says that if cw or cW moves the cursor towards the end of
966 the line, the character under the cursor should be deleted. */
967 if (rl_point == rl_mark)
971 /* Move past the end of the word so that the kill doesn't
972 remove the last letter of the previous word. Only do this
973 if we are not at the end of the line. */
974 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
979 if (rl_mark < rl_point)
980 SWAP (rl_point, rl_mark);
985 /* Process C as part of the current numeric argument. Return -1 if the
986 argument should be aborted, 0 if we should not read any more chars, and
987 1 if we should continue to read chars. */
989 _rl_vi_arg_dispatch (c)
995 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
1003 if (_rl_digit_p (c))
1005 if (rl_explicit_arg)
1006 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
1008 rl_numeric_arg = _rl_digit_value (c);
1009 rl_explicit_arg = 1;
1014 rl_clear_message ();
1015 rl_stuff_char (key);
1020 /* A simplified loop for vi. Don't dispatch key at end.
1021 Don't recognize minus sign?
1022 Should this do rl_save_prompt/rl_restore_prompt? */
1030 if (_rl_arg_overflow ())
1033 c = _rl_arg_getchar ();
1035 r = _rl_vi_arg_dispatch (c);
1040 RL_UNSETSTATE(RL_STATE_NUMERICARG);
1045 rl_vi_delete_to (count, key)
1050 if (_rl_uppercase_p (key))
1051 rl_stuff_char ('$');
1052 else if (vi_redoing)
1053 rl_stuff_char (_rl_vi_last_motion);
1055 if (rl_vi_domove (key, &c))
1061 /* These are the motion commands that do not require adjusting the
1063 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
1066 rl_kill_text (rl_point, rl_mark);
1071 rl_vi_change_to (count, key)
1076 if (_rl_uppercase_p (key))
1077 rl_stuff_char ('$');
1078 else if (vi_redoing)
1079 rl_stuff_char (_rl_vi_last_motion);
1081 start_pos = rl_point;
1083 if (rl_vi_domove (key, &c))
1089 /* These are the motion commands that do not require adjusting the
1090 mark. c[wW] are handled by special-case code in rl_vi_domove(),
1091 and already leave the mark at the correct location. */
1092 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
1095 /* The cursor never moves with c[wW]. */
1096 if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
1097 rl_point = start_pos;
1101 if (vi_insert_buffer && *vi_insert_buffer)
1102 rl_begin_undo_group ();
1103 rl_delete_text (rl_point, rl_mark);
1104 if (vi_insert_buffer && *vi_insert_buffer)
1106 rl_insert_text (vi_insert_buffer);
1107 rl_end_undo_group ();
1112 rl_begin_undo_group (); /* to make the `u' command work */
1113 rl_kill_text (rl_point, rl_mark);
1114 /* `C' does not save the text inserted for undoing or redoing. */
1115 if (_rl_uppercase_p (key) == 0)
1116 _rl_vi_doing_insert = 1;
1117 rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
1124 rl_vi_yank_to (count, key)
1130 if (_rl_uppercase_p (key))
1131 rl_stuff_char ('$');
1133 if (rl_vi_domove (key, &c))
1139 /* These are the motion commands that do not require adjusting the
1141 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
1144 rl_begin_undo_group ();
1145 rl_kill_text (rl_point, rl_mark);
1146 rl_end_undo_group ();
1154 rl_vi_rubout (count, key)
1160 return (rl_vi_delete (-count, key));
1169 if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1170 rl_backward_char (count, key);
1171 else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1172 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1179 rl_kill_text (rl_point, opoint);
1185 rl_vi_delete (count, key)
1191 return (rl_vi_rubout (-count, key));
1199 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1200 end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1202 end = rl_point + count;
1207 rl_kill_text (rl_point, end);
1209 if (rl_point > 0 && rl_point == rl_end)
1210 rl_backward_char (1, key);
1216 rl_vi_back_to_indent (count, key)
1219 rl_beg_of_line (1, key);
1220 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1226 rl_vi_first_print (count, key)
1229 return (rl_vi_back_to_indent (1, key));
1232 static int _rl_cs_dir, _rl_cs_orig_dir;
1234 #if defined (READLINE_CALLBACKS)
1236 _rl_vi_callback_char_search (data)
1237 _rl_callback_generic_arg *data;
1240 #if defined (HANDLE_MULTIBYTE)
1241 c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1243 RL_SETSTATE(RL_STATE_MOREINPUT);
1245 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1251 #if !defined (HANDLE_MULTIBYTE)
1252 _rl_vi_last_search_char = c;
1255 _rl_callback_func = 0;
1256 _rl_want_redisplay = 1;
1258 #if defined (HANDLE_MULTIBYTE)
1259 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
1261 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
1267 rl_vi_char_search (count, key)
1271 #if defined (HANDLE_MULTIBYTE)
1272 static char *target;
1278 if (key == ';' || key == ',')
1279 _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
1285 _rl_cs_orig_dir = _rl_cs_dir = FTO;
1289 _rl_cs_orig_dir = _rl_cs_dir = BTO;
1293 _rl_cs_orig_dir = _rl_cs_dir = FFIND;
1297 _rl_cs_orig_dir = _rl_cs_dir = BFIND;
1303 /* set target and tlen below */
1305 #if defined (READLINE_CALLBACKS)
1306 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1308 _rl_callback_data = _rl_callback_data_alloc (count);
1309 _rl_callback_data->i1 = _rl_cs_dir;
1310 _rl_callback_func = _rl_vi_callback_char_search;
1316 #if defined (HANDLE_MULTIBYTE)
1317 c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1320 _rl_vi_last_search_mblen = c;
1322 RL_SETSTATE(RL_STATE_MOREINPUT);
1324 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1327 _rl_vi_last_search_char = c;
1332 #if defined (HANDLE_MULTIBYTE)
1333 target = _rl_vi_last_search_mbchar;
1334 tlen = _rl_vi_last_search_mblen;
1336 target = _rl_vi_last_search_char;
1339 #if defined (HANDLE_MULTIBYTE)
1340 return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
1342 return (_rl_char_search_internal (count, _rl_cs_dir, target));
1346 /* Match brackets */
1348 rl_vi_match (ignore, key)
1351 int count = 1, brack, pos, tmp, pre;
1354 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1356 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1358 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1361 rl_forward_char (1, key);
1362 if (pre == rl_point)
1367 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1368 rl_point < rl_end - 1)
1369 rl_forward_char (1, key);
1386 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1390 pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1396 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1399 else if (b == brack)
1413 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1416 pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
1420 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1423 else if (b == brack)
1444 case ')': return -1;
1446 case ']': return -2;
1448 case '}': return -3;
1454 _rl_vi_change_char (count, c, mb)
1460 if (c == '\033' || c == CTRL ('C'))
1463 rl_begin_undo_group ();
1464 while (count-- && rl_point < rl_end)
1467 rl_vi_delete (1, c);
1468 if (rl_point < p) /* Did we retreat at EOL? */
1470 #if defined (HANDLE_MULTIBYTE)
1471 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1472 rl_insert_text (mb);
1475 _rl_insert_char (1, c);
1478 /* The cursor shall be left on the last character changed. */
1479 rl_backward_char (1, c);
1481 rl_end_undo_group ();
1487 _rl_vi_callback_getchar (mb, mlen)
1493 RL_SETSTATE(RL_STATE_MOREINPUT);
1495 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1500 #if defined (HANDLE_MULTIBYTE)
1501 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1502 c = _rl_read_mbstring (c, mb, mlen);
1508 #if defined (READLINE_CALLBACKS)
1510 _rl_vi_callback_change_char (data)
1511 _rl_callback_generic_arg *data;
1514 char mb[MB_LEN_MAX];
1516 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1521 _rl_callback_func = 0;
1522 _rl_want_redisplay = 1;
1524 return (_rl_vi_change_char (data->count, c, mb));
1529 rl_vi_change_char (count, key)
1533 char mb[MB_LEN_MAX];
1537 c = _rl_vi_last_replacement;
1541 #if defined (READLINE_CALLBACKS)
1542 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1544 _rl_callback_data = _rl_callback_data_alloc (count);
1545 _rl_callback_func = _rl_vi_callback_change_char;
1550 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1555 return (_rl_vi_change_char (count, c, mb));
1559 rl_vi_subst (count, key)
1562 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1563 if (vi_redoing == 0)
1564 rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1566 return (rl_vi_change_to (count, 'c'));
1570 rl_vi_overstrike (count, key)
1573 if (_rl_vi_doing_insert == 0)
1575 _rl_vi_doing_insert = 1;
1576 rl_begin_undo_group ();
1581 _rl_overwrite_char (count, key);
1582 vi_replace_count += count;
1589 rl_vi_overstrike_delete (count, key)
1594 for (i = 0; i < count; i++)
1596 if (vi_replace_count == 0)
1607 rl_backward_char (1, key);
1610 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1612 rl_end_undo_group ();
1614 _rl_vi_doing_insert = 0;
1620 rl_vi_replace (count, key)
1625 vi_replace_count = 0;
1627 if (!vi_replace_map)
1629 vi_replace_map = rl_make_bare_keymap ();
1631 for (i = ' '; i < KEYMAP_SIZE; i++)
1632 vi_replace_map[i].function = rl_vi_overstrike;
1634 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1635 vi_replace_map[ESC].function = rl_vi_movement_mode;
1636 vi_replace_map[RETURN].function = rl_newline;
1637 vi_replace_map[NEWLINE].function = rl_newline;
1639 /* If the normal vi insertion keymap has ^H bound to erase, do the
1640 same here. Probably should remove the assignment to RUBOUT up
1641 there, but I don't think it will make a difference in real life. */
1642 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1643 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1644 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1647 _rl_keymap = vi_replace_map;
1652 /* Try to complete the word we are standing on or the word that ends with
1653 the previous character. A space matches everything. Word delimiters are
1656 rl_vi_possible_completions()
1658 int save_pos = rl_point;
1660 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1662 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1663 rl_line_buffer[rl_point] != ';')
1666 else if (rl_line_buffer[rl_point - 1] == ';')
1672 rl_possible_completions ();
1673 rl_point = save_pos;
1679 /* Functions to save and restore marks. */
1685 RL_SETSTATE(RL_STATE_MOREINPUT);
1686 ch = rl_read_key ();
1687 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1689 if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
1695 vi_mark_chars[ch] = rl_point;
1699 #if defined (READLINE_CALLBACKS)
1701 _rl_vi_callback_set_mark (data)
1702 _rl_callback_generic_arg *data;
1704 _rl_callback_func = 0;
1705 _rl_want_redisplay = 1;
1707 return (_rl_vi_set_mark ());
1712 rl_vi_set_mark (count, key)
1715 #if defined (READLINE_CALLBACKS)
1716 if (RL_ISSTATE (RL_STATE_CALLBACK))
1718 _rl_callback_data = 0;
1719 _rl_callback_func = _rl_vi_callback_set_mark;
1724 return (_rl_vi_set_mark ());
1732 RL_SETSTATE(RL_STATE_MOREINPUT);
1733 ch = rl_read_key ();
1734 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1741 else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
1748 if (vi_mark_chars[ch] == -1)
1753 rl_point = vi_mark_chars[ch];
1757 #if defined (READLINE_CALLBACKS)
1759 _rl_vi_callback_goto_mark (data)
1760 _rl_callback_generic_arg *data;
1762 _rl_callback_func = 0;
1763 _rl_want_redisplay = 1;
1765 return (_rl_vi_goto_mark ());
1770 rl_vi_goto_mark (count, key)
1773 #if defined (READLINE_CALLBACKS)
1774 if (RL_ISSTATE (RL_STATE_CALLBACK))
1776 _rl_callback_data = 0;
1777 _rl_callback_func = _rl_vi_callback_goto_mark;
1782 return (_rl_vi_goto_mark ());
1784 #endif /* VI_MODE */