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 1, 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 675 Mass Ave, Cambridge, MA 02139, 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. */
58 #define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
61 #ifndef _rl_digit_value
62 #define _rl_digit_value(c) ((c) - '0')
66 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
70 #define isident(c) ((_rl_pure_alphabetic (c) || _rl_digit_p (c) || c == '_'))
74 #define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
77 extern char *xmalloc (), *xrealloc ();
79 /* Variables imported from readline.c */
80 extern int rl_point, rl_end, rl_mark, rl_done;
81 extern FILE *rl_instream;
82 extern int rl_line_buffer_len, rl_explicit_arg, rl_numeric_arg;
83 extern Keymap _rl_keymap;
84 extern char *rl_prompt;
85 extern char *rl_line_buffer;
86 extern int rl_arg_sign;
88 extern int _rl_doing_an_undo;
89 extern int _rl_undo_group_level;
91 extern void _rl_dispatch ();
92 extern int _rl_char_search_internal ();
94 extern void rl_extend_line_buffer ();
95 extern int rl_vi_check ();
97 /* Non-zero means enter insertion mode. */
98 static int _rl_vi_doing_insert;
100 /* Command keys which do movement for xxx_to commands. */
101 static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
103 /* Keymap used for vi replace characters. Created dynamically since
105 static Keymap vi_replace_map;
107 /* The number of characters inserted in the last replace operation. */
108 static int vi_replace_count;
110 /* If non-zero, we have text inserted after a c[motion] command that put
111 us implicitly into insert mode. Some people want this text to be
112 attached to the command so that it is `redoable' with `.'. */
113 static int vi_continued_command;
114 static char *vi_insert_buffer;
115 static int vi_insert_buffer_size;
117 static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
118 static int _rl_vi_last_repeat = 1;
119 static int _rl_vi_last_arg_sign = 1;
120 static int _rl_vi_last_motion;
121 static int _rl_vi_last_search_char;
122 static int _rl_vi_last_replacement;
124 static int _rl_vi_last_key_before_insert;
126 static int vi_redoing;
128 /* Text modification commands. These are the `redoable' commands. */
129 static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
131 /* Arrays for the saved marks. */
132 static int vi_mark_chars[27];
134 static int rl_digit_loop1 ();
137 _rl_vi_initialize_line ()
141 for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
142 vi_mark_chars[i] = -1;
148 _rl_vi_last_command = 'i';
149 _rl_vi_last_repeat = 1;
150 _rl_vi_last_arg_sign = 1;
151 _rl_vi_last_motion = 0;
155 _rl_vi_set_last (key, repeat, sign)
156 int key, repeat, sign;
158 _rl_vi_last_command = key;
159 _rl_vi_last_repeat = repeat;
160 _rl_vi_last_arg_sign = sign;
163 /* Is the command C a VI mode text modification command? */
165 _rl_vi_textmod_command (c)
168 return (member (c, vi_textmod));
172 _rl_vi_stuff_insert (count)
175 rl_begin_undo_group ();
177 rl_insert_text (vi_insert_buffer);
178 rl_end_undo_group ();
181 /* Bound to `.'. Called from command mode, so we know that we have to
182 redo a text modification command. The default for _rl_vi_last_command
183 puts you back into insert mode. */
185 rl_vi_redo (count, c)
188 if (!rl_explicit_arg)
190 rl_numeric_arg = _rl_vi_last_repeat;
191 rl_arg_sign = _rl_vi_last_arg_sign;
195 /* If we're redoing an insert with `i', stuff in the inserted text
196 and do not go into insertion mode. */
197 if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
199 _rl_vi_stuff_insert (count);
200 /* And back up point over the last character inserted. */
205 _rl_dispatch (_rl_vi_last_command, _rl_keymap);
211 /* A placeholder for further expansion. */
213 rl_vi_undo (count, key)
216 return (rl_undo_command (count, key));
219 /* Yank the nth arg from the previous line into this line at point. */
221 rl_vi_yank_arg (count, key)
224 /* Readline thinks that the first word on a line is the 0th, while vi
225 thinks the first word on a line is the 1st. Compensate. */
227 rl_yank_nth_arg (count - 1, 0);
229 rl_yank_nth_arg ('$', 0);
234 /* With an argument, move back that many history lines, else move to the
235 beginning of history. */
237 rl_vi_fetch_history (count, c)
242 /* Giving an argument of n means we want the nth command in the history
243 file. The command number is interpreted the same way that the bash
244 `history' command does it -- that is, giving an argument count of 450
245 to this command would get the command listed as number 450 in the
246 output of `history'. */
249 wanted = history_base + where_history () - count;
251 rl_beginning_of_history (0, 0);
253 rl_get_previous_history (wanted, c);
256 rl_beginning_of_history (count, 0);
260 /* Search again for the last thing searched for. */
262 rl_vi_search_again (count, key)
268 rl_noninc_reverse_search_again (count, key);
272 rl_noninc_forward_search_again (count, key);
278 /* Do a vi style search. */
280 rl_vi_search (count, key)
286 rl_noninc_forward_search (count, key);
290 rl_noninc_reverse_search (count, key);
300 /* Completion, from vi's point of view. */
302 rl_vi_complete (ignore, key)
305 if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
307 if (!whitespace (rl_line_buffer[rl_point + 1]))
308 rl_vi_end_word (1, 'E');
313 rl_complete_internal ('*'); /* Expansion and replacement. */
315 rl_complete_internal ('?'); /* List possible completions. */
316 else if (key == '\\')
317 rl_complete_internal (TAB); /* Standard Readline completion. */
319 rl_complete (0, key);
321 if (key == '*' || key == '\\')
323 _rl_vi_set_last (key, 1, rl_arg_sign);
324 rl_vi_insertion_mode (1, key);
329 /* Tilde expansion for vi mode. */
331 rl_vi_tilde_expand (ignore, key)
334 rl_tilde_expand (0, key);
335 _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
336 rl_vi_insertion_mode (1, key);
340 /* Previous word in vi mode. */
342 rl_vi_prev_word (count, key)
346 return (rl_vi_next_word (-count, key));
354 if (_rl_uppercase_p (key))
362 /* Next word in vi mode. */
364 rl_vi_next_word (count, key)
368 return (rl_vi_prev_word (-count, key));
370 if (rl_point >= (rl_end - 1))
376 if (_rl_uppercase_p (key))
383 /* Move to the end of the ?next? word. */
385 rl_vi_end_word (count, key)
394 if (_rl_uppercase_p (key))
401 /* Move forward a word the way that 'W' does. */
406 while (count-- && rl_point < (rl_end - 1))
408 /* Skip until whitespace. */
409 while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
412 /* Now skip whitespace. */
413 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
423 while (count-- && rl_point > 0)
425 /* If we are at the start of a word, move back to whitespace so
426 we will go back to the start of the previous word. */
427 if (!whitespace (rl_line_buffer[rl_point]) &&
428 whitespace (rl_line_buffer[rl_point - 1]))
431 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
436 while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
447 while (count-- && rl_point < (rl_end - 1))
449 if (!whitespace (rl_line_buffer[rl_point]))
452 /* Move to the next non-whitespace character (to the start of the
454 while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
456 if (rl_point && rl_point < rl_end)
458 /* Skip whitespace. */
459 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
462 /* Skip until whitespace. */
463 while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
466 /* Move back to the last character of the word. */
477 while (count-- && rl_point < (rl_end - 1))
479 /* Move to white space (really non-identifer). */
480 if (isident (rl_line_buffer[rl_point]))
482 while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
485 else /* if (!whitespace (rl_line_buffer[rl_point])) */
487 while (!isident (rl_line_buffer[rl_point]) &&
488 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
492 /* Move past whitespace. */
493 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
503 while (count-- && rl_point > 0)
507 /* If we are at the start of a word, move back to whitespace
508 so we will go back to the start of the previous word. */
509 if (!whitespace (rl_line_buffer[rl_point]) &&
510 whitespace (rl_line_buffer[rl_point - 1]))
513 /* If this character and the previous character are `opposite', move
514 back so we don't get messed up by the rl_point++ down there in
515 the while loop. Without this code, words like `l;' screw up the
517 last_is_ident = isident (rl_line_buffer[rl_point - 1]);
518 if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
519 (!isident (rl_line_buffer[rl_point]) && last_is_ident))
522 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
527 if (isident (rl_line_buffer[rl_point]))
528 while (--rl_point >= 0 && isident (rl_line_buffer[rl_point]));
530 while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) &&
531 !whitespace (rl_line_buffer[rl_point]));
542 while (count-- && rl_point < rl_end - 1)
544 if (!whitespace (rl_line_buffer[rl_point]))
547 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
550 if (rl_point < rl_end)
552 if (isident (rl_line_buffer[rl_point]))
553 while (++rl_point < rl_end && isident (rl_line_buffer[rl_point]));
555 while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point])
556 && !whitespace (rl_line_buffer[rl_point]));
564 rl_vi_insert_beg (count, key)
567 rl_beg_of_line (1, key);
568 rl_vi_insertion_mode (1, key);
573 rl_vi_append_mode (count, key)
576 if (rl_point < rl_end)
578 rl_vi_insertion_mode (1, key);
583 rl_vi_append_eol (count, key)
586 rl_end_of_line (1, key);
587 rl_vi_append_mode (1, key);
591 /* What to do in the case of C-d. */
593 rl_vi_eof_maybe (count, c)
596 return (rl_newline (1, '\n'));
599 /* Insertion mode stuff. */
601 /* Switching from one mode to the other really just involves
602 switching keymaps. */
604 rl_vi_insertion_mode (count, key)
607 _rl_keymap = vi_insertion_keymap;
608 _rl_vi_last_key_before_insert = key;
613 _rl_vi_save_insert (up)
620 if (vi_insert_buffer_size >= 1)
621 vi_insert_buffer[0] = '\0';
627 len = end - start + 1;
628 if (len >= vi_insert_buffer_size)
630 vi_insert_buffer_size += (len + 32) - (len % 32);
631 vi_insert_buffer = xrealloc (vi_insert_buffer, vi_insert_buffer_size);
633 strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
634 vi_insert_buffer[len-1] = '\0';
638 _rl_vi_done_inserting ()
640 if (_rl_vi_doing_insert)
642 rl_end_undo_group ();
643 /* Now, the text between rl_undo_list->next->start and
644 rl_undo_list->next->end is what was inserted while in insert
645 mode. It gets copied to VI_INSERT_BUFFER because it depends
646 on absolute indices into the line which may change (though they
647 probably will not). */
648 _rl_vi_doing_insert = 0;
649 _rl_vi_save_insert (rl_undo_list->next);
650 vi_continued_command = 1;
654 if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
655 _rl_vi_save_insert (rl_undo_list);
656 /* XXX - Other keys probably need to be checked. */
657 else if (_rl_vi_last_key_before_insert == 'C')
658 rl_end_undo_group ();
659 while (_rl_undo_group_level > 0)
660 rl_end_undo_group ();
661 vi_continued_command = 0;
666 rl_vi_movement_mode (count, key)
670 rl_backward (1, key);
672 _rl_keymap = vi_movement_keymap;
673 _rl_vi_done_inserting ();
678 rl_vi_arg_digit (count, c)
681 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
682 return (rl_beg_of_line (1, c));
684 return (rl_digit_argument (count, c));
688 rl_vi_change_case (count, ignore)
693 /* Don't try this on an empty line. */
694 if (rl_point >= rl_end)
697 while (count-- && rl_point < rl_end)
699 if (_rl_uppercase_p (rl_line_buffer[rl_point]))
700 c = _rl_to_lower (rl_line_buffer[rl_point]);
701 else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
702 c = _rl_to_upper (rl_line_buffer[rl_point]);
705 /* Just skip over characters neither upper nor lower case. */
710 /* Vi is kind of strange here. */
713 rl_begin_undo_group ();
716 rl_end_undo_group ();
726 rl_vi_put (count, key)
729 if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
733 rl_backward (1, key);
740 if (rl_point && rl_point == rl_end)
746 rl_vi_column (count, key)
750 rl_end_of_line (1, key);
752 rl_point = count - 1;
757 rl_vi_domove (key, nextkey)
767 if (!member (c, vi_motion))
771 save = rl_numeric_arg;
772 rl_numeric_arg = _rl_digit_value (c);
774 rl_numeric_arg *= save;
775 c = rl_read_key (); /* real command */
778 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
781 rl_beg_of_line (1, c);
782 _rl_vi_last_motion = c;
789 _rl_vi_last_motion = c;
791 /* Append a blank character temporarily so that the motion routines
792 work right at the end of the line. */
794 rl_line_buffer[rl_end++] = ' ';
795 rl_line_buffer[rl_end] = '\0';
797 _rl_dispatch (c, _rl_keymap);
799 /* Remove the blank that we added. */
801 rl_line_buffer[rl_end] = '\0';
802 if (rl_point > rl_end)
805 /* No change in position means the command failed. */
806 if (rl_mark == rl_point)
809 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
810 word. If we are not at the end of the line, and we are on a
811 non-whitespace character, move back one (presumably to whitespace). */
812 if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
813 !whitespace (rl_line_buffer[rl_point]))
816 /* If cw or cW, back up to the end of a word, so the behaviour of ce
817 or cE is the actual result. Brute-force, no subtlety. */
818 if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
820 /* Don't move farther back than where we started. */
821 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
824 /* Posix.2 says that if cw or cW moves the cursor towards the end of
825 the line, the character under the cursor should be deleted. */
826 if (rl_point == rl_mark)
830 /* Move past the end of the word so that the kill doesn't
831 remove the last letter of the previous word. Only do this
832 if we are not at the end of the line. */
833 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
838 if (rl_mark < rl_point)
839 exchange (rl_point, rl_mark);
844 /* A simplified loop for vi. Don't dispatch key at end.
845 Don't recognize minus sign? */
853 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
854 key = c = rl_read_key ();
856 if (_rl_keymap[c].type == ISFUNC &&
857 _rl_keymap[c].function == rl_universal_argument)
867 rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
869 rl_numeric_arg = _rl_digit_value (c);
883 rl_vi_delete_to (count, key)
888 if (_rl_uppercase_p (key))
891 rl_stuff_char (_rl_vi_last_motion);
893 if (rl_vi_domove (key, &c))
899 /* These are the motion commands that do not require adjusting the
901 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
904 rl_kill_text (rl_point, rl_mark);
909 rl_vi_change_to (count, key)
914 if (_rl_uppercase_p (key))
917 rl_stuff_char (_rl_vi_last_motion);
919 start_pos = rl_point;
921 if (rl_vi_domove (key, &c))
927 /* These are the motion commands that do not require adjusting the
928 mark. c[wW] are handled by special-case code in rl_vi_domove(),
929 and already leave the mark at the correct location. */
930 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
933 /* The cursor never moves with c[wW]. */
934 if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
935 rl_point = start_pos;
939 if (vi_insert_buffer && *vi_insert_buffer)
940 rl_begin_undo_group ();
941 rl_delete_text (rl_point, rl_mark);
942 if (vi_insert_buffer && *vi_insert_buffer)
944 rl_insert_text (vi_insert_buffer);
945 rl_end_undo_group ();
950 rl_begin_undo_group (); /* to make the `u' command work */
951 rl_kill_text (rl_point, rl_mark);
952 /* `C' does not save the text inserted for undoing or redoing. */
953 if (_rl_uppercase_p (key) == 0)
954 _rl_vi_doing_insert = 1;
955 _rl_vi_set_last (key, count, rl_arg_sign);
956 rl_vi_insertion_mode (1, key);
963 rl_vi_yank_to (count, key)
966 int c, save = rl_point;
968 if (_rl_uppercase_p (key))
971 if (rl_vi_domove (key, &c))
977 /* These are the motion commands that do not require adjusting the
979 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
982 rl_begin_undo_group ();
983 rl_kill_text (rl_point, rl_mark);
984 rl_end_undo_group ();
992 rl_vi_delete (count, key)
1003 end = rl_point + count;
1008 rl_kill_text (rl_point, end);
1010 if (rl_point > 0 && rl_point == rl_end)
1011 rl_backward (1, key);
1016 rl_vi_back_to_indent (count, key)
1019 rl_beg_of_line (1, key);
1020 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
1026 rl_vi_first_print (count, key)
1029 return (rl_vi_back_to_indent (1, key));
1033 rl_vi_char_search (count, key)
1037 static int orig_dir, dir;
1039 if (key == ';' || key == ',')
1040 dir = key == ';' ? orig_dir : -orig_dir;
1044 target = _rl_vi_last_search_char;
1046 _rl_vi_last_search_char = target = rl_getc (rl_instream);
1051 orig_dir = dir = FTO;
1055 orig_dir = dir = BTO;
1059 orig_dir = dir = FFIND;
1063 orig_dir = dir = BFIND;
1068 return (_rl_char_search_internal (count, dir, target));
1071 /* Match brackets */
1073 rl_vi_match (ignore, key)
1076 int count = 1, brack, pos;
1079 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1081 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1082 rl_point < rl_end - 1)
1083 rl_forward (1, key);
1101 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1104 else if (b == brack)
1120 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1123 else if (b == brack)
1144 case ')': return -1;
1146 case ']': return -2;
1148 case '}': return -3;
1154 rl_vi_change_char (count, key)
1160 c = _rl_vi_last_replacement;
1162 _rl_vi_last_replacement = c = rl_getc (rl_instream);
1164 if (c == '\033' || c == CTRL ('C'))
1167 while (count-- && rl_point < rl_end)
1169 rl_begin_undo_group ();
1176 rl_end_undo_group ();
1182 rl_vi_subst (count, key)
1185 rl_begin_undo_group ();
1187 if (_rl_uppercase_p (key))
1189 rl_beg_of_line (1, key);
1190 rl_kill_line (1, key);
1193 rl_delete_text (rl_point, rl_point+count);
1195 rl_end_undo_group ();
1197 _rl_vi_set_last (key, count, rl_arg_sign);
1201 int o = _rl_doing_an_undo;
1203 _rl_doing_an_undo = 1;
1204 if (vi_insert_buffer && *vi_insert_buffer)
1205 rl_insert_text (vi_insert_buffer);
1206 _rl_doing_an_undo = o;
1210 rl_begin_undo_group ();
1211 _rl_vi_doing_insert = 1;
1212 rl_vi_insertion_mode (1, key);
1219 rl_vi_overstrike (count, key)
1224 if (_rl_vi_doing_insert == 0)
1226 _rl_vi_doing_insert = 1;
1227 rl_begin_undo_group ();
1230 for (i = 0; i < count; i++)
1233 rl_begin_undo_group ();
1235 if (rl_point < rl_end)
1243 rl_end_undo_group ();
1249 rl_vi_overstrike_delete (count, key)
1254 for (i = 0; i < count; i++)
1256 if (vi_replace_count == 0)
1267 rl_backward (1, key);
1270 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1272 rl_end_undo_group ();
1274 _rl_vi_doing_insert = 0;
1280 rl_vi_replace (count, key)
1285 vi_replace_count = 0;
1287 if (!vi_replace_map)
1289 vi_replace_map = rl_make_bare_keymap ();
1291 for (i = ' '; i < KEYMAP_SIZE; i++)
1292 vi_replace_map[i].function = rl_vi_overstrike;
1294 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1295 vi_replace_map[ESC].function = rl_vi_movement_mode;
1296 vi_replace_map[RETURN].function = rl_newline;
1297 vi_replace_map[NEWLINE].function = rl_newline;
1299 /* If the normal vi insertion keymap has ^H bound to erase, do the
1300 same here. Probably should remove the assignment to RUBOUT up
1301 there, but I don't think it will make a difference in real life. */
1302 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1303 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1304 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1307 _rl_keymap = vi_replace_map;
1312 /* Try to complete the word we are standing on or the word that ends with
1313 the previous character. A space matches everything. Word delimiters are
1316 rl_vi_possible_completions()
1318 int save_pos = rl_point;
1320 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1322 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1323 rl_line_buffer[rl_point] != ';')
1326 else if (rl_line_buffer[rl_point - 1] == ';')
1332 rl_possible_completions ();
1333 rl_point = save_pos;
1339 /* Functions to save and restore marks. */
1341 rl_vi_set_mark (count, key)
1346 ch = rl_read_key ();
1347 if (_rl_lowercase_p (ch) == 0)
1353 vi_mark_chars[ch] = rl_point;
1358 rl_vi_goto_mark (count, key)
1363 ch = rl_read_key ();
1369 else if (_rl_lowercase_p (ch) == 0)
1376 if (vi_mark_chars[ch] == -1)
1381 rl_point = vi_mark_chars[ch];
1385 #endif /* VI_MODE */