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, 1989, 1992 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. */
57 #include "rlprivate.h"
61 #define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
64 #ifndef _rl_digit_value
65 #define _rl_digit_value(c) ((c) - '0')
69 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
73 #define isident(c) ((_rl_pure_alphabetic (c) || _rl_digit_p (c) || c == '_'))
77 #define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
80 /* Non-zero means enter insertion mode. */
81 static int _rl_vi_doing_insert;
83 /* Command keys which do movement for xxx_to commands. */
84 static const char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
86 /* Keymap used for vi replace characters. Created dynamically since
88 static Keymap vi_replace_map;
90 /* The number of characters inserted in the last replace operation. */
91 static int vi_replace_count;
93 /* If non-zero, we have text inserted after a c[motion] command that put
94 us implicitly into insert mode. Some people want this text to be
95 attached to the command so that it is `redoable' with `.'. */
96 static int vi_continued_command;
97 static char *vi_insert_buffer;
98 static int vi_insert_buffer_size;
100 static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
101 static int _rl_vi_last_repeat = 1;
102 static int _rl_vi_last_arg_sign = 1;
103 static int _rl_vi_last_motion;
104 static int _rl_vi_last_search_char;
105 static int _rl_vi_last_replacement;
107 static int _rl_vi_last_key_before_insert;
109 static int vi_redoing;
111 /* Text modification commands. These are the `redoable' commands. */
112 static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
114 /* Arrays for the saved marks. */
115 static int vi_mark_chars[27];
117 static int rl_digit_loop1 __P((void));
120 _rl_vi_initialize_line ()
124 for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
125 vi_mark_chars[i] = -1;
131 _rl_vi_last_command = 'i';
132 _rl_vi_last_repeat = 1;
133 _rl_vi_last_arg_sign = 1;
134 _rl_vi_last_motion = 0;
138 _rl_vi_set_last (key, repeat, sign)
139 int key, repeat, sign;
141 _rl_vi_last_command = key;
142 _rl_vi_last_repeat = repeat;
143 _rl_vi_last_arg_sign = sign;
146 /* Is the command C a VI mode text modification command? */
148 _rl_vi_textmod_command (c)
151 return (member (c, vi_textmod));
155 _rl_vi_stuff_insert (count)
158 rl_begin_undo_group ();
160 rl_insert_text (vi_insert_buffer);
161 rl_end_undo_group ();
164 /* Bound to `.'. Called from command mode, so we know that we have to
165 redo a text modification command. The default for _rl_vi_last_command
166 puts you back into insert mode. */
168 rl_vi_redo (count, c)
171 if (!rl_explicit_arg)
173 rl_numeric_arg = _rl_vi_last_repeat;
174 rl_arg_sign = _rl_vi_last_arg_sign;
178 /* If we're redoing an insert with `i', stuff in the inserted text
179 and do not go into insertion mode. */
180 if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
182 _rl_vi_stuff_insert (count);
183 /* And back up point over the last character inserted. */
188 _rl_dispatch (_rl_vi_last_command, _rl_keymap);
194 /* A placeholder for further expansion. */
196 rl_vi_undo (count, key)
199 return (rl_undo_command (count, key));
202 /* Yank the nth arg from the previous line into this line at point. */
204 rl_vi_yank_arg (count, key)
207 /* Readline thinks that the first word on a line is the 0th, while vi
208 thinks the first word on a line is the 1st. Compensate. */
210 rl_yank_nth_arg (count - 1, 0);
212 rl_yank_nth_arg ('$', 0);
217 /* With an argument, move back that many history lines, else move to the
218 beginning of history. */
220 rl_vi_fetch_history (count, c)
225 /* Giving an argument of n means we want the nth command in the history
226 file. The command number is interpreted the same way that the bash
227 `history' command does it -- that is, giving an argument count of 450
228 to this command would get the command listed as number 450 in the
229 output of `history'. */
232 wanted = history_base + where_history () - count;
234 rl_beginning_of_history (0, 0);
236 rl_get_previous_history (wanted, c);
239 rl_beginning_of_history (count, 0);
243 /* Search again for the last thing searched for. */
245 rl_vi_search_again (count, key)
251 rl_noninc_reverse_search_again (count, key);
255 rl_noninc_forward_search_again (count, key);
261 /* Do a vi style search. */
263 rl_vi_search (count, key)
269 rl_noninc_forward_search (count, key);
273 rl_noninc_reverse_search (count, key);
283 /* Completion, from vi's point of view. */
285 rl_vi_complete (ignore, key)
288 if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
290 if (!whitespace (rl_line_buffer[rl_point + 1]))
291 rl_vi_end_word (1, 'E');
296 rl_complete_internal ('*'); /* Expansion and replacement. */
298 rl_complete_internal ('?'); /* List possible completions. */
299 else if (key == '\\')
300 rl_complete_internal (TAB); /* Standard Readline completion. */
302 rl_complete (0, key);
304 if (key == '*' || key == '\\')
306 _rl_vi_set_last (key, 1, rl_arg_sign);
307 rl_vi_insertion_mode (1, key);
312 /* Tilde expansion for vi mode. */
314 rl_vi_tilde_expand (ignore, key)
317 rl_tilde_expand (0, key);
318 _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
319 rl_vi_insertion_mode (1, key);
323 /* Previous word in vi mode. */
325 rl_vi_prev_word (count, key)
329 return (rl_vi_next_word (-count, key));
337 if (_rl_uppercase_p (key))
338 rl_vi_bWord (count, key);
340 rl_vi_bword (count, key);
345 /* Next word in vi mode. */
347 rl_vi_next_word (count, key)
351 return (rl_vi_prev_word (-count, key));
353 if (rl_point >= (rl_end - 1))
359 if (_rl_uppercase_p (key))
360 rl_vi_fWord (count, key);
362 rl_vi_fword (count, key);
366 /* Move to the end of the ?next? word. */
368 rl_vi_end_word (count, key)
377 if (_rl_uppercase_p (key))
378 rl_vi_eWord (count, key);
380 rl_vi_eword (count, key);
384 /* Move forward a word the way that 'W' does. */
386 rl_vi_fWord (count, ignore)
389 while (count-- && rl_point < (rl_end - 1))
391 /* Skip until whitespace. */
392 while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
395 /* Now skip whitespace. */
396 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
403 rl_vi_bWord (count, ignore)
406 while (count-- && rl_point > 0)
408 /* If we are at the start of a word, move back to whitespace so
409 we will go back to the start of the previous word. */
410 if (!whitespace (rl_line_buffer[rl_point]) &&
411 whitespace (rl_line_buffer[rl_point - 1]))
414 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
419 while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
427 rl_vi_eWord (count, ignore)
430 while (count-- && rl_point < (rl_end - 1))
432 if (!whitespace (rl_line_buffer[rl_point]))
435 /* Move to the next non-whitespace character (to the start of the
437 while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
439 if (rl_point && rl_point < rl_end)
441 /* Skip whitespace. */
442 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
445 /* Skip until whitespace. */
446 while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
449 /* Move back to the last character of the word. */
457 rl_vi_fword (count, ignore)
460 while (count-- && rl_point < (rl_end - 1))
462 /* Move to white space (really non-identifer). */
463 if (isident (rl_line_buffer[rl_point]))
465 while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
468 else /* if (!whitespace (rl_line_buffer[rl_point])) */
470 while (!isident (rl_line_buffer[rl_point]) &&
471 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
475 /* Move past whitespace. */
476 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
483 rl_vi_bword (count, ignore)
486 while (count-- && rl_point > 0)
490 /* If we are at the start of a word, move back to whitespace
491 so we will go back to the start of the previous word. */
492 if (!whitespace (rl_line_buffer[rl_point]) &&
493 whitespace (rl_line_buffer[rl_point - 1]))
496 /* If this character and the previous character are `opposite', move
497 back so we don't get messed up by the rl_point++ down there in
498 the while loop. Without this code, words like `l;' screw up the
500 last_is_ident = isident (rl_line_buffer[rl_point - 1]);
501 if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
502 (!isident (rl_line_buffer[rl_point]) && last_is_ident))
505 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
510 if (isident (rl_line_buffer[rl_point]))
511 while (--rl_point >= 0 && isident (rl_line_buffer[rl_point]));
513 while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) &&
514 !whitespace (rl_line_buffer[rl_point]));
522 rl_vi_eword (count, ignore)
525 while (count-- && rl_point < rl_end - 1)
527 if (!whitespace (rl_line_buffer[rl_point]))
530 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
533 if (rl_point < rl_end)
535 if (isident (rl_line_buffer[rl_point]))
536 while (++rl_point < rl_end && isident (rl_line_buffer[rl_point]));
538 while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point])
539 && !whitespace (rl_line_buffer[rl_point]));
547 rl_vi_insert_beg (count, key)
550 rl_beg_of_line (1, key);
551 rl_vi_insertion_mode (1, key);
556 rl_vi_append_mode (count, key)
559 if (rl_point < rl_end)
561 rl_vi_insertion_mode (1, key);
566 rl_vi_append_eol (count, key)
569 rl_end_of_line (1, key);
570 rl_vi_append_mode (1, key);
574 /* What to do in the case of C-d. */
576 rl_vi_eof_maybe (count, c)
579 return (rl_newline (1, '\n'));
582 /* Insertion mode stuff. */
584 /* Switching from one mode to the other really just involves
585 switching keymaps. */
587 rl_vi_insertion_mode (count, key)
590 _rl_keymap = vi_insertion_keymap;
591 _rl_vi_last_key_before_insert = key;
596 _rl_vi_save_insert (up)
603 if (vi_insert_buffer_size >= 1)
604 vi_insert_buffer[0] = '\0';
610 len = end - start + 1;
611 if (len >= vi_insert_buffer_size)
613 vi_insert_buffer_size += (len + 32) - (len % 32);
614 vi_insert_buffer = xrealloc (vi_insert_buffer, vi_insert_buffer_size);
616 strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
617 vi_insert_buffer[len-1] = '\0';
621 _rl_vi_done_inserting ()
623 if (_rl_vi_doing_insert)
625 rl_end_undo_group ();
626 /* Now, the text between rl_undo_list->next->start and
627 rl_undo_list->next->end is what was inserted while in insert
628 mode. It gets copied to VI_INSERT_BUFFER because it depends
629 on absolute indices into the line which may change (though they
630 probably will not). */
631 _rl_vi_doing_insert = 0;
632 _rl_vi_save_insert (rl_undo_list->next);
633 vi_continued_command = 1;
637 if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
638 _rl_vi_save_insert (rl_undo_list);
639 /* XXX - Other keys probably need to be checked. */
640 else if (_rl_vi_last_key_before_insert == 'C')
641 rl_end_undo_group ();
642 while (_rl_undo_group_level > 0)
643 rl_end_undo_group ();
644 vi_continued_command = 0;
649 rl_vi_movement_mode (count, key)
653 rl_backward (1, key);
655 _rl_keymap = vi_movement_keymap;
656 _rl_vi_done_inserting ();
661 rl_vi_arg_digit (count, c)
664 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
665 return (rl_beg_of_line (1, c));
667 return (rl_digit_argument (count, c));
671 rl_vi_change_case (count, ignore)
676 /* Don't try this on an empty line. */
677 if (rl_point >= rl_end)
680 while (count-- && rl_point < rl_end)
682 if (_rl_uppercase_p (rl_line_buffer[rl_point]))
683 c = _rl_to_lower (rl_line_buffer[rl_point]);
684 else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
685 c = _rl_to_upper (rl_line_buffer[rl_point]);
688 /* Just skip over characters neither upper nor lower case. */
693 /* Vi is kind of strange here. */
696 rl_begin_undo_group ();
699 rl_end_undo_group ();
709 rl_vi_put (count, key)
712 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
716 rl_backward (1, key);
723 if (rl_point && rl_point == rl_end)
729 rl_vi_column (count, key)
733 rl_end_of_line (1, key);
735 rl_point = count - 1;
740 rl_vi_domove (key, nextkey)
747 RL_SETSTATE(RL_STATE_MOREINPUT);
749 RL_UNSETSTATE(RL_STATE_MOREINPUT);
752 if (!member (c, vi_motion))
756 save = rl_numeric_arg;
757 rl_numeric_arg = _rl_digit_value (c);
759 rl_numeric_arg *= save;
760 RL_SETSTATE(RL_STATE_MOREINPUT);
761 c = rl_read_key (); /* real command */
762 RL_UNSETSTATE(RL_STATE_MOREINPUT);
765 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
768 rl_beg_of_line (1, c);
769 _rl_vi_last_motion = c;
776 _rl_vi_last_motion = c;
778 /* Append a blank character temporarily so that the motion routines
779 work right at the end of the line. */
781 rl_line_buffer[rl_end++] = ' ';
782 rl_line_buffer[rl_end] = '\0';
784 _rl_dispatch (c, _rl_keymap);
786 /* Remove the blank that we added. */
788 rl_line_buffer[rl_end] = '\0';
789 if (rl_point > rl_end)
792 /* No change in position means the command failed. */
793 if (rl_mark == rl_point)
796 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
797 word. If we are not at the end of the line, and we are on a
798 non-whitespace character, move back one (presumably to whitespace). */
799 if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
800 !whitespace (rl_line_buffer[rl_point]))
803 /* If cw or cW, back up to the end of a word, so the behaviour of ce
804 or cE is the actual result. Brute-force, no subtlety. */
805 if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
807 /* Don't move farther back than where we started. */
808 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
811 /* Posix.2 says that if cw or cW moves the cursor towards the end of
812 the line, the character under the cursor should be deleted. */
813 if (rl_point == rl_mark)
817 /* Move past the end of the word so that the kill doesn't
818 remove the last letter of the previous word. Only do this
819 if we are not at the end of the line. */
820 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
825 if (rl_mark < rl_point)
826 exchange (rl_point, rl_mark);
831 /* A simplified loop for vi. Don't dispatch key at end.
832 Don't recognize minus sign?
833 Should this do rl_save_prompt/rl_restore_prompt? */
839 RL_SETSTATE(RL_STATE_NUMERICARG);
842 if (rl_numeric_arg > 1000000)
844 rl_explicit_arg = rl_numeric_arg = 0;
847 RL_UNSETSTATE(RL_STATE_NUMERICARG);
850 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
851 RL_SETSTATE(RL_STATE_MOREINPUT);
852 key = c = rl_read_key ();
853 RL_UNSETSTATE(RL_STATE_MOREINPUT);
855 if (_rl_keymap[c].type == ISFUNC &&
856 _rl_keymap[c].function == rl_universal_argument)
866 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
868 rl_numeric_arg = _rl_digit_value (c);
879 RL_UNSETSTATE(RL_STATE_NUMERICARG);
884 rl_vi_delete_to (count, key)
889 if (_rl_uppercase_p (key))
892 rl_stuff_char (_rl_vi_last_motion);
894 if (rl_vi_domove (key, &c))
900 /* These are the motion commands that do not require adjusting the
902 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
905 rl_kill_text (rl_point, rl_mark);
910 rl_vi_change_to (count, key)
915 if (_rl_uppercase_p (key))
918 rl_stuff_char (_rl_vi_last_motion);
920 start_pos = rl_point;
922 if (rl_vi_domove (key, &c))
928 /* These are the motion commands that do not require adjusting the
929 mark. c[wW] are handled by special-case code in rl_vi_domove(),
930 and already leave the mark at the correct location. */
931 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
934 /* The cursor never moves with c[wW]. */
935 if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
936 rl_point = start_pos;
940 if (vi_insert_buffer && *vi_insert_buffer)
941 rl_begin_undo_group ();
942 rl_delete_text (rl_point, rl_mark);
943 if (vi_insert_buffer && *vi_insert_buffer)
945 rl_insert_text (vi_insert_buffer);
946 rl_end_undo_group ();
951 rl_begin_undo_group (); /* to make the `u' command work */
952 rl_kill_text (rl_point, rl_mark);
953 /* `C' does not save the text inserted for undoing or redoing. */
954 if (_rl_uppercase_p (key) == 0)
955 _rl_vi_doing_insert = 1;
956 _rl_vi_set_last (key, count, rl_arg_sign);
957 rl_vi_insertion_mode (1, key);
964 rl_vi_yank_to (count, key)
967 int c, save = rl_point;
969 if (_rl_uppercase_p (key))
972 if (rl_vi_domove (key, &c))
978 /* These are the motion commands that do not require adjusting the
980 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
983 rl_begin_undo_group ();
984 rl_kill_text (rl_point, rl_mark);
985 rl_end_undo_group ();
993 rl_vi_delete (count, key)
1004 end = rl_point + count;
1009 rl_kill_text (rl_point, end);
1011 if (rl_point > 0 && rl_point == rl_end)
1012 rl_backward (1, key);
1017 rl_vi_back_to_indent (count, key)
1020 rl_beg_of_line (1, key);
1021 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1027 rl_vi_first_print (count, key)
1030 return (rl_vi_back_to_indent (1, key));
1034 rl_vi_char_search (count, key)
1038 static int orig_dir, dir;
1040 if (key == ';' || key == ',')
1041 dir = key == ';' ? orig_dir : -orig_dir;
1045 target = _rl_vi_last_search_char;
1048 RL_SETSTATE(RL_STATE_MOREINPUT);
1049 _rl_vi_last_search_char = target = rl_read_key ();
1050 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1056 orig_dir = dir = FTO;
1060 orig_dir = dir = BTO;
1064 orig_dir = dir = FFIND;
1068 orig_dir = dir = BFIND;
1073 return (_rl_char_search_internal (count, dir, target));
1076 /* Match brackets */
1078 rl_vi_match (ignore, key)
1081 int count = 1, brack, pos;
1084 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1086 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1087 rl_point < rl_end - 1)
1088 rl_forward (1, key);
1106 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1109 else if (b == brack)
1125 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1128 else if (b == brack)
1149 case ')': return -1;
1151 case ']': return -2;
1153 case '}': return -3;
1159 rl_vi_change_char (count, key)
1165 c = _rl_vi_last_replacement;
1168 RL_SETSTATE(RL_STATE_MOREINPUT);
1169 _rl_vi_last_replacement = c = rl_read_key ();
1170 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1173 if (c == '\033' || c == CTRL ('C'))
1176 while (count-- && rl_point < rl_end)
1178 rl_begin_undo_group ();
1185 rl_end_undo_group ();
1191 rl_vi_subst (count, key)
1194 rl_begin_undo_group ();
1196 if (_rl_uppercase_p (key))
1198 rl_beg_of_line (1, key);
1199 rl_kill_line (1, key);
1202 rl_delete_text (rl_point, rl_point+count);
1204 rl_end_undo_group ();
1206 _rl_vi_set_last (key, count, rl_arg_sign);
1210 int o = _rl_doing_an_undo;
1212 _rl_doing_an_undo = 1;
1213 if (vi_insert_buffer && *vi_insert_buffer)
1214 rl_insert_text (vi_insert_buffer);
1215 _rl_doing_an_undo = o;
1219 rl_begin_undo_group ();
1220 _rl_vi_doing_insert = 1;
1221 rl_vi_insertion_mode (1, key);
1228 rl_vi_overstrike (count, key)
1233 if (_rl_vi_doing_insert == 0)
1235 _rl_vi_doing_insert = 1;
1236 rl_begin_undo_group ();
1239 for (i = 0; i < count; i++)
1242 rl_begin_undo_group ();
1244 if (rl_point < rl_end)
1252 rl_end_undo_group ();
1258 rl_vi_overstrike_delete (count, key)
1263 for (i = 0; i < count; i++)
1265 if (vi_replace_count == 0)
1276 rl_backward (1, key);
1279 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1281 rl_end_undo_group ();
1283 _rl_vi_doing_insert = 0;
1289 rl_vi_replace (count, key)
1294 vi_replace_count = 0;
1296 if (!vi_replace_map)
1298 vi_replace_map = rl_make_bare_keymap ();
1300 for (i = ' '; i < KEYMAP_SIZE; i++)
1301 vi_replace_map[i].function = rl_vi_overstrike;
1303 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1304 vi_replace_map[ESC].function = rl_vi_movement_mode;
1305 vi_replace_map[RETURN].function = rl_newline;
1306 vi_replace_map[NEWLINE].function = rl_newline;
1308 /* If the normal vi insertion keymap has ^H bound to erase, do the
1309 same here. Probably should remove the assignment to RUBOUT up
1310 there, but I don't think it will make a difference in real life. */
1311 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1312 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1313 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1316 _rl_keymap = vi_replace_map;
1321 /* Try to complete the word we are standing on or the word that ends with
1322 the previous character. A space matches everything. Word delimiters are
1325 rl_vi_possible_completions()
1327 int save_pos = rl_point;
1329 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1331 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1332 rl_line_buffer[rl_point] != ';')
1335 else if (rl_line_buffer[rl_point - 1] == ';')
1341 rl_possible_completions ();
1342 rl_point = save_pos;
1348 /* Functions to save and restore marks. */
1350 rl_vi_set_mark (count, key)
1355 RL_SETSTATE(RL_STATE_MOREINPUT);
1356 ch = rl_read_key ();
1357 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1359 if (_rl_lowercase_p (ch) == 0)
1365 vi_mark_chars[ch] = rl_point;
1370 rl_vi_goto_mark (count, key)
1375 RL_SETSTATE(RL_STATE_MOREINPUT);
1376 ch = rl_read_key ();
1377 RL_UNSETSTATE(RL_STATE_MOREINPUT);
1384 else if (_rl_lowercase_p (ch) == 0)
1391 if (vi_mark_chars[ch] == -1)
1396 rl_point = vi_mark_chars[ch];
1400 #endif /* VI_MODE */