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);
899 if (!member (c, vi_motion))
903 save = rl_numeric_arg;
904 rl_numeric_arg = _rl_digit_value (c);
906 RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
908 RL_UNSETSTATE (RL_STATE_VIMOTION);
909 rl_numeric_arg *= save;
910 RL_SETSTATE(RL_STATE_MOREINPUT);
911 c = rl_read_key (); /* real command */
912 RL_UNSETSTATE(RL_STATE_MOREINPUT);
920 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
923 rl_beg_of_line (1, c);
924 _rl_vi_last_motion = c;
931 _rl_vi_last_motion = c;
933 /* Append a blank character temporarily so that the motion routines
934 work right at the end of the line. */
936 rl_line_buffer[rl_end++] = ' ';
937 rl_line_buffer[rl_end] = '\0';
939 _rl_dispatch (c, _rl_keymap);
941 /* Remove the blank that we added. */
943 rl_line_buffer[rl_end] = '\0';
944 if (rl_point > rl_end)
947 /* No change in position means the command failed. */
948 if (rl_mark == rl_point)
951 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
952 word. If we are not at the end of the line, and we are on a
953 non-whitespace character, move back one (presumably to whitespace). */
954 if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
955 !whitespace (rl_line_buffer[rl_point]))
958 /* If cw or cW, back up to the end of a word, so the behaviour of ce
959 or cE is the actual result. Brute-force, no subtlety. */
960 if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
962 /* Don't move farther back than where we started. */
963 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
966 /* Posix.2 says that if cw or cW moves the cursor towards the end of
967 the line, the character under the cursor should be deleted. */
968 if (rl_point == rl_mark)
972 /* Move past the end of the word so that the kill doesn't
973 remove the last letter of the previous word. Only do this
974 if we are not at the end of the line. */
975 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
980 if (rl_mark < rl_point)
981 SWAP (rl_point, rl_mark);
986 /* Process C as part of the current numeric argument. Return -1 if the
987 argument should be aborted, 0 if we should not read any more chars, and
988 1 if we should continue to read chars. */
990 _rl_vi_arg_dispatch (c)
996 if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
1004 if (_rl_digit_p (c))
1006 if (rl_explicit_arg)
1007 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
1009 rl_numeric_arg = _rl_digit_value (c);
1010 rl_explicit_arg = 1;
1015 rl_clear_message ();
1016 rl_stuff_char (key);
1021 /* A simplified loop for vi. Don't dispatch key at end.
1022 Don't recognize minus sign?
1023 Should this do rl_save_prompt/rl_restore_prompt? */
1031 if (_rl_arg_overflow ())
1034 c = _rl_arg_getchar ();
1036 r = _rl_vi_arg_dispatch (c);
1041 RL_UNSETSTATE(RL_STATE_NUMERICARG);
1046 rl_vi_delete_to (count, key)
1051 if (_rl_uppercase_p (key))
1052 rl_stuff_char ('$');
1053 else if (vi_redoing)
1054 rl_stuff_char (_rl_vi_last_motion);
1056 if (rl_vi_domove (key, &c))
1062 /* These are the motion commands that do not require adjusting the
1064 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
1067 rl_kill_text (rl_point, rl_mark);
1072 rl_vi_change_to (count, key)
1077 if (_rl_uppercase_p (key))
1078 rl_stuff_char ('$');
1079 else if (vi_redoing)
1080 rl_stuff_char (_rl_vi_last_motion);
1082 start_pos = rl_point;
1084 if (rl_vi_domove (key, &c))
1090 /* These are the motion commands that do not require adjusting the
1091 mark. c[wW] are handled by special-case code in rl_vi_domove(),
1092 and already leave the mark at the correct location. */
1093 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
1096 /* The cursor never moves with c[wW]. */
1097 if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
1098 rl_point = start_pos;
1102 if (vi_insert_buffer && *vi_insert_buffer)
1103 rl_begin_undo_group ();
1104 rl_delete_text (rl_point, rl_mark);
1105 if (vi_insert_buffer && *vi_insert_buffer)
1107 rl_insert_text (vi_insert_buffer);
1108 rl_end_undo_group ();
1113 rl_begin_undo_group (); /* to make the `u' command work */
1114 rl_kill_text (rl_point, rl_mark);
1115 /* `C' does not save the text inserted for undoing or redoing. */
1116 if (_rl_uppercase_p (key) == 0)
1117 _rl_vi_doing_insert = 1;
1118 rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
1125 rl_vi_yank_to (count, key)
1131 if (_rl_uppercase_p (key))
1132 rl_stuff_char ('$');
1134 if (rl_vi_domove (key, &c))
1140 /* These are the motion commands that do not require adjusting the
1142 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
1145 rl_begin_undo_group ();
1146 rl_kill_text (rl_point, rl_mark);
1147 rl_end_undo_group ();
1155 rl_vi_rubout (count, key)
1161 return (rl_vi_delete (-count, key));
1170 if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1171 rl_backward_char (count, key);
1172 else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1173 rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
1180 rl_kill_text (rl_point, opoint);
1186 rl_vi_delete (count, key)
1192 return (rl_vi_rubout (-count, key));
1200 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1201 end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
1203 end = rl_point + count;
1208 rl_kill_text (rl_point, end);
1210 if (rl_point > 0 && rl_point == rl_end)
1211 rl_backward_char (1, key);
1217 rl_vi_back_to_indent (count, key)
1220 rl_beg_of_line (1, key);
1221 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1227 rl_vi_first_print (count, key)
1230 return (rl_vi_back_to_indent (1, key));
1233 static int _rl_cs_dir, _rl_cs_orig_dir;
1235 #if defined (READLINE_CALLBACKS)
1237 _rl_vi_callback_char_search (data)
1238 _rl_callback_generic_arg *data;
1241 #if defined (HANDLE_MULTIBYTE)
1242 c = _rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1244 RL_SETSTATE(RL_STATE_MOREINPUT);
1246 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1252 #if !defined (HANDLE_MULTIBYTE)
1253 _rl_vi_last_search_char = c;
1256 _rl_callback_func = 0;
1257 _rl_want_redisplay = 1;
1259 #if defined (HANDLE_MULTIBYTE)
1260 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
1262 return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
1268 rl_vi_char_search (count, key)
1272 #if defined (HANDLE_MULTIBYTE)
1273 static char *target;
1279 if (key == ';' || key == ',')
1280 _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
1286 _rl_cs_orig_dir = _rl_cs_dir = FTO;
1290 _rl_cs_orig_dir = _rl_cs_dir = BTO;
1294 _rl_cs_orig_dir = _rl_cs_dir = FFIND;
1298 _rl_cs_orig_dir = _rl_cs_dir = BFIND;
1304 /* set target and tlen below */
1306 #if defined (READLINE_CALLBACKS)
1307 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1309 _rl_callback_data = _rl_callback_data_alloc (count);
1310 _rl_callback_data->i1 = _rl_cs_dir;
1311 _rl_callback_func = _rl_vi_callback_char_search;
1317 #if defined (HANDLE_MULTIBYTE)
1318 c = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
1321 _rl_vi_last_search_mblen = c;
1323 RL_SETSTATE(RL_STATE_MOREINPUT);
1325 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1328 _rl_vi_last_search_char = c;
1333 #if defined (HANDLE_MULTIBYTE)
1334 target = _rl_vi_last_search_mbchar;
1335 tlen = _rl_vi_last_search_mblen;
1337 target = _rl_vi_last_search_char;
1340 #if defined (HANDLE_MULTIBYTE)
1341 return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
1343 return (_rl_char_search_internal (count, _rl_cs_dir, target));
1347 /* Match brackets */
1349 rl_vi_match (ignore, key)
1352 int count = 1, brack, pos, tmp, pre;
1355 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1357 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1359 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1362 rl_forward_char (1, key);
1363 if (pre == rl_point)
1368 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1369 rl_point < rl_end - 1)
1370 rl_forward_char (1, key);
1387 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1391 pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
1397 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1400 else if (b == brack)
1414 if (MB_CUR_MAX == 1 || rl_byte_oriented)
1417 pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
1421 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1424 else if (b == brack)
1445 case ')': return -1;
1447 case ']': return -2;
1449 case '}': return -3;
1455 _rl_vi_change_char (count, c, mb)
1461 if (c == '\033' || c == CTRL ('C'))
1464 rl_begin_undo_group ();
1465 while (count-- && rl_point < rl_end)
1468 rl_vi_delete (1, c);
1469 if (rl_point < p) /* Did we retreat at EOL? */
1471 #if defined (HANDLE_MULTIBYTE)
1472 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1473 rl_insert_text (mb);
1476 _rl_insert_char (1, c);
1479 /* The cursor shall be left on the last character changed. */
1480 rl_backward_char (1, c);
1482 rl_end_undo_group ();
1488 _rl_vi_callback_getchar (mb, mlen)
1494 RL_SETSTATE(RL_STATE_MOREINPUT);
1496 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1501 #if defined (HANDLE_MULTIBYTE)
1502 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
1503 c = _rl_read_mbstring (c, mb, mlen);
1509 #if defined (READLINE_CALLBACKS)
1511 _rl_vi_callback_change_char (data)
1512 _rl_callback_generic_arg *data;
1515 char mb[MB_LEN_MAX];
1517 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1522 _rl_callback_func = 0;
1523 _rl_want_redisplay = 1;
1525 return (_rl_vi_change_char (data->count, c, mb));
1530 rl_vi_change_char (count, key)
1534 char mb[MB_LEN_MAX];
1538 c = _rl_vi_last_replacement;
1542 #if defined (READLINE_CALLBACKS)
1543 else if (RL_ISSTATE (RL_STATE_CALLBACK))
1545 _rl_callback_data = _rl_callback_data_alloc (count);
1546 _rl_callback_func = _rl_vi_callback_change_char;
1551 _rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
1556 return (_rl_vi_change_char (count, c, mb));
1560 rl_vi_subst (count, key)
1563 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1564 if (vi_redoing == 0)
1565 rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1567 return (rl_vi_change_to (count, 'c'));
1571 rl_vi_overstrike (count, key)
1574 if (_rl_vi_doing_insert == 0)
1576 _rl_vi_doing_insert = 1;
1577 rl_begin_undo_group ();
1582 _rl_overwrite_char (count, key);
1583 vi_replace_count += count;
1590 rl_vi_overstrike_delete (count, key)
1595 for (i = 0; i < count; i++)
1597 if (vi_replace_count == 0)
1608 rl_backward_char (1, key);
1611 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1613 rl_end_undo_group ();
1615 _rl_vi_doing_insert = 0;
1621 rl_vi_replace (count, key)
1626 vi_replace_count = 0;
1628 if (!vi_replace_map)
1630 vi_replace_map = rl_make_bare_keymap ();
1632 for (i = ' '; i < KEYMAP_SIZE; i++)
1633 vi_replace_map[i].function = rl_vi_overstrike;
1635 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1636 vi_replace_map[ESC].function = rl_vi_movement_mode;
1637 vi_replace_map[RETURN].function = rl_newline;
1638 vi_replace_map[NEWLINE].function = rl_newline;
1640 /* If the normal vi insertion keymap has ^H bound to erase, do the
1641 same here. Probably should remove the assignment to RUBOUT up
1642 there, but I don't think it will make a difference in real life. */
1643 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1644 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1645 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1648 _rl_keymap = vi_replace_map;
1653 /* Try to complete the word we are standing on or the word that ends with
1654 the previous character. A space matches everything. Word delimiters are
1657 rl_vi_possible_completions()
1659 int save_pos = rl_point;
1661 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1663 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1664 rl_line_buffer[rl_point] != ';')
1667 else if (rl_line_buffer[rl_point - 1] == ';')
1673 rl_possible_completions ();
1674 rl_point = save_pos;
1680 /* Functions to save and restore marks. */
1686 RL_SETSTATE(RL_STATE_MOREINPUT);
1687 ch = rl_read_key ();
1688 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1690 if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
1696 vi_mark_chars[ch] = rl_point;
1700 #if defined (READLINE_CALLBACKS)
1702 _rl_vi_callback_set_mark (data)
1703 _rl_callback_generic_arg *data;
1705 _rl_callback_func = 0;
1706 _rl_want_redisplay = 1;
1708 return (_rl_vi_set_mark ());
1713 rl_vi_set_mark (count, key)
1716 #if defined (READLINE_CALLBACKS)
1717 if (RL_ISSTATE (RL_STATE_CALLBACK))
1719 _rl_callback_data = 0;
1720 _rl_callback_func = _rl_vi_callback_set_mark;
1725 return (_rl_vi_set_mark ());
1733 RL_SETSTATE(RL_STATE_MOREINPUT);
1734 ch = rl_read_key ();
1735 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1742 else if (ch < 0 || ch < 'a' || ch > 'z') /* make test against 0 explicit */
1749 if (vi_mark_chars[ch] == -1)
1754 rl_point = vi_mark_chars[ch];
1758 #if defined (READLINE_CALLBACKS)
1760 _rl_vi_callback_goto_mark (data)
1761 _rl_callback_generic_arg *data;
1763 _rl_callback_func = 0;
1764 _rl_want_redisplay = 1;
1766 return (_rl_vi_goto_mark ());
1771 rl_vi_goto_mark (count, key)
1774 #if defined (READLINE_CALLBACKS)
1775 if (RL_ISSTATE (RL_STATE_CALLBACK))
1777 _rl_callback_data = 0;
1778 _rl_callback_func = _rl_vi_callback_goto_mark;
1783 return (_rl_vi_goto_mark ());
1785 #endif /* VI_MODE */