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 #include <sys/types.h>
36 #if defined (HAVE_STDLIB_H)
39 # include "ansi_stdlib.h"
40 #endif /* HAVE_STDLIB_H */
42 #if defined (HAVE_UNISTD_H)
48 /* Some standard library routines. */
54 #define digit_p(c) ((c) >= '0' && (c) <= '9')
58 #define digit_value(c) ((c) - '0')
62 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
66 #define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_'))
70 #define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
73 #ifndef VI_COMMENT_BEGIN_DEFAULT
74 #define VI_COMMENT_BEGIN_DEFAULT "#"
77 #if defined (STATIC_MALLOC)
78 static char *xmalloc (), *xrealloc ();
80 extern char *xmalloc (), *xrealloc ();
81 #endif /* STATIC_MALLOC */
83 /* Variables imported from readline.c */
84 extern int rl_point, rl_end, rl_mark, rl_done;
85 extern FILE *rl_instream;
86 extern int rl_line_buffer_len, rl_explicit_arg, rl_numeric_arg;
87 extern Keymap _rl_keymap;
88 extern char *rl_prompt;
89 extern char *rl_line_buffer;
90 extern int rl_arg_sign;
92 extern void _rl_dispatch ();
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 = 0;
100 /* String inserted into the line by rl_vi_comment (). */
101 char *rl_vi_comment_begin = (char *)NULL;
103 /* *** UNCLEAN *** */
104 /* Command keys which do movement for xxx_to commands. */
105 static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
107 /* Keymap used for vi replace characters. Created dynamically since
109 static Keymap vi_replace_map = (Keymap)NULL;
111 /* The number of characters inserted in the last replace operation. */
112 static int vi_replace_count = 0;
114 /* If non-zero, we have text inserted after a c[motion] command that put
115 us implicitly into insert mode. Some people want this text to be
116 attached to the command so that it is `redoable' with `.'. */
117 static int vi_continued_command = 0;
119 static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
120 static int _rl_vi_last_repeat = 1;
121 static int _rl_vi_last_arg_sign = 1;
122 static int _rl_vi_last_motion = 0;
123 static int _rl_vi_last_search_char = 0;
124 static int _rl_vi_last_replacement = 0;
126 static int vi_redoing = 0;
128 /* Text modification commands. These are the `redoable' commands. */
129 static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
131 static int rl_digit_loop1 ();
136 _rl_vi_last_command = 'i';
137 _rl_vi_last_repeat = 1;
138 _rl_vi_last_arg_sign = 1;
139 _rl_vi_last_motion = 0;
143 _rl_vi_set_last (key, repeat, sign)
144 int key, repeat, sign;
146 _rl_vi_last_command = key;
147 _rl_vi_last_repeat = repeat;
148 _rl_vi_last_arg_sign = sign;
151 /* Is the command C a VI mode text modification command? */
153 rl_vi_textmod_command (c)
156 return (member (c, vi_textmod));
159 /* Bound to `.'. Called from command mode, so we know that we have to
160 redo a text modification command. The default for _rl_vi_last_command
161 puts you back into insert mode. */
162 rl_vi_redo (count, c)
165 if (!rl_explicit_arg)
167 rl_numeric_arg = _rl_vi_last_repeat;
168 rl_arg_sign = _rl_vi_last_arg_sign;
172 _rl_dispatch (_rl_vi_last_command, _rl_keymap);
178 /* Yank the nth arg from the previous line into this line at point. */
179 rl_vi_yank_arg (count, key)
182 /* Readline thinks that the first word on a line is the 0th, while vi
183 thinks the first word on a line is the 1st. Compensate. */
185 rl_yank_nth_arg (count - 1, 0);
187 rl_yank_nth_arg ('$', 0);
192 /* With an argument, move back that many history lines, else move to the
193 beginning of history. */
194 rl_vi_fetch_history (count, c)
197 int current = where_history ();
199 /* Giving an argument of n means we want the nth command in the history
200 file. The command number is interpreted the same way that the bash
201 `history' command does it -- that is, giving an argument count of 450
202 to this command would get the command listed as number 450 in the
203 output of `history'. */
206 int wanted = history_base + current - count;
208 rl_beginning_of_history (0, 0);
210 rl_get_previous_history (wanted);
213 rl_beginning_of_history (count, 0);
217 /* Search again for the last thing searched for. */
218 rl_vi_search_again (count, key)
224 rl_noninc_reverse_search_again (count, key);
228 rl_noninc_forward_search_again (count, key);
234 /* Do a vi style search. */
235 rl_vi_search (count, key)
241 rl_noninc_forward_search (count, key);
245 rl_noninc_reverse_search (count, key);
255 /* Completion, from vi's point of view. */
256 rl_vi_complete (ignore, key)
259 if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
261 if (!whitespace (rl_line_buffer[rl_point + 1]))
262 rl_vi_end_word (1, 'E');
267 rl_complete_internal ('*'); /* Expansion and replacement. */
269 rl_complete_internal ('?'); /* List possible completions. */
270 else if (key == '\\')
271 rl_complete_internal (TAB); /* Standard Readline completion. */
273 rl_complete (0, key);
275 if (key == '*' || key == '\\')
277 _rl_vi_set_last (key, 1, rl_arg_sign);
278 rl_vi_insertion_mode (1, key);
283 /* Tilde expansion for vi mode. */
284 rl_vi_tilde_expand (ignore, key)
287 rl_tilde_expand (0, key);
288 _rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
289 rl_vi_insertion_mode (1, key);
293 /* Previous word in vi mode. */
294 rl_vi_prev_word (count, key)
298 return (rl_vi_next_word (-count, key));
306 if (uppercase_p (key))
314 /* Next word in vi mode. */
315 rl_vi_next_word (count, key)
319 return (rl_vi_prev_word (-count, key));
321 if (rl_point >= (rl_end - 1))
327 if (uppercase_p (key))
334 /* Move to the end of the ?next? word. */
335 rl_vi_end_word (count, key)
344 if (uppercase_p (key))
351 /* Move forward a word the way that 'W' does. */
355 while (count-- && rl_point < (rl_end - 1))
357 /* Skip until whitespace. */
358 while (!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
361 /* Now skip whitespace. */
362 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
371 while (count-- && rl_point > 0)
373 /* If we are at the start of a word, move back to whitespace so
374 we will go back to the start of the previous word. */
375 if (!whitespace (rl_line_buffer[rl_point]) &&
376 whitespace (rl_line_buffer[rl_point - 1]))
379 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
384 while (--rl_point >= 0 && !whitespace (rl_line_buffer[rl_point]));
394 while (count-- && rl_point < (rl_end - 1))
396 if (!whitespace (rl_line_buffer[rl_point]))
399 /* Move to the next non-whitespace character (to the start of the
401 while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
403 if (rl_point && rl_point < rl_end)
405 /* Skip whitespace. */
406 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
409 /* Skip until whitespace. */
410 while (rl_point < rl_end && !whitespace (rl_line_buffer[rl_point]))
413 /* Move back to the last character of the word. */
423 while (count-- && rl_point < (rl_end - 1))
425 /* Move to white space (really non-identifer). */
426 if (isident (rl_line_buffer[rl_point]))
428 while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
431 else /* if (!whitespace (rl_line_buffer[rl_point])) */
433 while (!isident (rl_line_buffer[rl_point]) &&
434 !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
438 /* Move past whitespace. */
439 while (whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
448 while (count-- && rl_point > 0)
452 /* If we are at the start of a word, move back to whitespace
453 so we will go back to the start of the previous word. */
454 if (!whitespace (rl_line_buffer[rl_point]) &&
455 whitespace (rl_line_buffer[rl_point - 1]))
458 /* If this character and the previous character are `opposite', move
459 back so we don't get messed up by the rl_point++ down there in
460 the while loop. Without this code, words like `l;' screw up the
462 last_is_ident = isident (rl_line_buffer[rl_point - 1]);
463 if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
464 (!isident (rl_line_buffer[rl_point]) && last_is_ident))
467 while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
472 if (isident (rl_line_buffer[rl_point]))
473 while (--rl_point >= 0 && isident (rl_line_buffer[rl_point]));
475 while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) &&
476 !whitespace (rl_line_buffer[rl_point]));
486 while (count-- && rl_point < rl_end - 1)
488 if (!whitespace (rl_line_buffer[rl_point]))
491 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
494 if (rl_point < rl_end)
496 if (isident (rl_line_buffer[rl_point]))
497 while (++rl_point < rl_end && isident (rl_line_buffer[rl_point]));
499 while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point])
500 && !whitespace (rl_line_buffer[rl_point]));
507 rl_vi_insert_beg (count, key)
510 rl_beg_of_line (1, key);
511 rl_vi_insertion_mode (1, key);
515 rl_vi_append_mode (count, key)
518 if (rl_point < rl_end)
520 rl_vi_insertion_mode (1, key);
524 rl_vi_append_eol (count, key)
527 rl_end_of_line (1, key);
528 rl_vi_append_mode (1, key);
532 /* What to do in the case of C-d. */
533 rl_vi_eof_maybe (count, c)
536 return (rl_newline (1, '\n'));
539 /* Insertion mode stuff. */
541 /* Switching from one mode to the other really just involves
542 switching keymaps. */
543 rl_vi_insertion_mode (count, key)
546 _rl_keymap = vi_insertion_keymap;
551 _rl_vi_done_inserting ()
553 if (_rl_vi_doing_insert)
555 rl_end_undo_group ();
556 /* Now, the text between rl_undo_list->next->start and
557 rl_undo_list->next->end is what was inserted while in insert
559 _rl_vi_doing_insert = 0;
560 vi_continued_command = 1;
563 vi_continued_command = 0;
566 rl_vi_movement_mode (count, key)
573 _rl_vi_reset_last ();
576 _rl_keymap = vi_movement_keymap;
577 _rl_vi_done_inserting ();
581 rl_vi_arg_digit (count, c)
584 if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
585 return (rl_beg_of_line ());
587 return (rl_digit_argument (count, c));
590 rl_vi_change_case (count, ignore)
595 /* Don't try this on an empty line. */
596 if (rl_point >= rl_end)
599 while (count-- && rl_point < rl_end)
601 if (uppercase_p (rl_line_buffer[rl_point]))
602 c = to_lower (rl_line_buffer[rl_point]);
603 else if (lowercase_p (rl_line_buffer[rl_point]))
604 c = to_upper (rl_line_buffer[rl_point]);
607 /* Just skip over characters neither upper nor lower case. */
612 /* Vi is kind of strange here. */
615 rl_begin_undo_group ();
618 rl_end_undo_group ();
627 rl_vi_put (count, key)
630 if (!uppercase_p (key) && (rl_point + 1 <= rl_end))
640 if (rl_point && rl_point == rl_end)
645 rl_vi_column (count, key)
651 rl_point = count - 1;
656 rl_vi_domove (key, nextkey)
666 if (!member (c, vi_motion))
670 save = rl_numeric_arg;
671 rl_numeric_arg = digit_value (c);
673 rl_numeric_arg *= save;
674 c = rl_read_key (); /* real command */
677 else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
681 _rl_vi_last_motion = c;
688 _rl_vi_last_motion = c;
690 /* Append a blank character temporarily so that the motion routines
691 work right at the end of the line. */
693 rl_line_buffer[rl_end++] = ' ';
694 rl_line_buffer[rl_end] = '\0';
696 _rl_dispatch (c, _rl_keymap);
698 /* Remove the blank that we added. */
700 rl_line_buffer[rl_end] = '\0';
701 if (rl_point > rl_end)
704 /* No change in position means the command failed. */
705 if (rl_mark == rl_point)
708 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
709 word. If we are not at the end of the line, and we are on a
710 non-whitespace character, move back one (presumably to whitespace). */
711 if ((to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
712 !whitespace (rl_line_buffer[rl_point]))
715 /* If cw or cW, back up to the end of a word, so the behaviour of ce
716 or cE is the actual result. Brute-force, no subtlety. */
717 if (key == 'c' && rl_point >= rl_mark && (to_upper (c) == 'W'))
719 /* Don't move farther back than where we started. */
720 while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
723 /* Posix.2 says that if cw or cW moves the cursor towards the end of
724 the line, the character under the cursor should be deleted. */
725 if (rl_point == rl_mark)
729 /* Move past the end of the word so that the kill doesn't
730 remove the last letter of the previous word. Only do this
731 if we are not at the end of the line. */
732 if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
737 if (rl_mark < rl_point)
738 exchange (rl_point, rl_mark);
743 /* A simplified loop for vi. Don't dispatch key at end.
744 Don't recognize minus sign? */
752 rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
753 key = c = rl_read_key ();
755 if (_rl_keymap[c].type == ISFUNC &&
756 _rl_keymap[c].function == rl_universal_argument)
766 rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c);
768 rl_numeric_arg = digit_value (c);
781 rl_vi_delete_to (count, key)
786 if (uppercase_p (key))
789 rl_stuff_char (_rl_vi_last_motion);
791 if (rl_vi_domove (key, &c))
797 /* These are the motion commands that do not require adjusting the
799 if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
802 rl_kill_text (rl_point, rl_mark);
806 rl_vi_change_to (count, key)
811 if (uppercase_p (key))
814 rl_stuff_char (_rl_vi_last_motion);
816 start_pos = rl_point;
818 if (rl_vi_domove (key, &c))
824 /* These are the motion commands that do not require adjusting the
825 mark. c[wW] are handled by special-case code in rl_vi_domove(),
826 and already leave the mark at the correct location. */
827 if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
830 /* The cursor never moves with c[wW]. */
831 if ((to_upper (c) == 'W') && rl_point < start_pos)
832 rl_point = start_pos;
834 rl_kill_text (rl_point, rl_mark);
836 rl_begin_undo_group ();
837 _rl_vi_doing_insert = 1;
838 _rl_vi_set_last (key, count, rl_arg_sign);
839 rl_vi_insertion_mode (1, key);
844 rl_vi_yank_to (count, key)
847 int c, save = rl_point;
849 if (uppercase_p (key))
852 if (rl_vi_domove (key, &c))
858 /* These are the motion commands that do not require adjusting the
860 if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
863 rl_begin_undo_group ();
864 rl_kill_text (rl_point, rl_mark);
865 rl_end_undo_group ();
872 rl_vi_delete (count, key)
883 end = rl_point + count;
888 rl_kill_text (rl_point, end);
890 if (rl_point > 0 && rl_point == rl_end)
895 /* Turn the current line into a comment in shell history.
896 A K*rn shell style function. */
897 rl_vi_comment (count, key)
902 if (rl_vi_comment_begin != (char *)NULL)
903 rl_insert_text (rl_vi_comment_begin);
905 rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */
908 rl_newline (1, '\n');
912 rl_vi_first_print (count, key)
915 return (rl_back_to_indent ());
918 rl_back_to_indent (ignore1, ignore2)
919 int ignore1, ignore2;
922 while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
927 /* NOTE: it is necessary that opposite directions are inverses */
928 #define FTO 1 /* forward to */
929 #define BTO -1 /* backward to */
930 #define FFIND 2 /* forward find */
931 #define BFIND -2 /* backward find */
933 rl_vi_char_search (count, key)
937 static int orig_dir, dir;
940 if (key == ';' || key == ',')
941 dir = (key == ';' ? orig_dir : -orig_dir);
945 target = _rl_vi_last_search_char;
947 _rl_vi_last_search_char = target = rl_getc (rl_instream);
952 orig_dir = dir = FTO;
956 orig_dir = dir = BTO;
960 orig_dir = dir = FFIND;
964 orig_dir = dir = BFIND;
984 if (rl_line_buffer[pos] == target)
1012 if (rl_line_buffer[pos] == target)
1021 while (++pos < rl_end);
1023 if (pos >= (rl_end - 1))
1033 /* Match brackets */
1034 rl_vi_match (ignore, key)
1037 int count = 1, brack, pos;
1040 if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
1042 while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
1043 rl_point < rl_end - 1)
1062 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1065 else if (b == brack)
1081 int b = rl_vi_bracktype (rl_line_buffer[pos]);
1084 else if (b == brack)
1105 case ')': return -1;
1107 case ']': return -2;
1109 case '}': return -3;
1114 rl_vi_change_char (count, key)
1120 c = _rl_vi_last_replacement;
1122 _rl_vi_last_replacement = c = rl_getc (rl_instream);
1124 if (c == '\033' || c == CTRL ('C'))
1127 while (count-- && rl_point < rl_end)
1129 rl_begin_undo_group ();
1136 rl_end_undo_group ();
1141 rl_vi_subst (count, key)
1144 rl_begin_undo_group ();
1146 if (uppercase_p (key))
1152 rl_delete_text (rl_point, rl_point+count);
1154 rl_end_undo_group ();
1156 _rl_vi_set_last (key, count, rl_arg_sign);
1158 rl_begin_undo_group ();
1159 _rl_vi_doing_insert = 1;
1160 rl_vi_insertion_mode (1, key);
1165 rl_vi_overstrike (count, key)
1170 if (_rl_vi_doing_insert == 0)
1172 _rl_vi_doing_insert = 1;
1173 rl_begin_undo_group ();
1176 for (i = 0; i < count; i++)
1179 rl_begin_undo_group ();
1181 if (rl_point < rl_end)
1189 rl_end_undo_group ();
1194 rl_vi_overstrike_delete (count)
1199 for (i = 0; i < count; i++)
1201 if (vi_replace_count == 0)
1215 if (vi_replace_count == 0 && _rl_vi_doing_insert)
1217 rl_end_undo_group ();
1219 _rl_vi_doing_insert = 0;
1224 rl_vi_replace (count, key)
1229 vi_replace_count = 0;
1231 if (!vi_replace_map)
1233 vi_replace_map = rl_make_bare_keymap ();
1235 for (i = ' '; i < KEYMAP_SIZE; i++)
1236 vi_replace_map[i].function = rl_vi_overstrike;
1238 vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
1239 vi_replace_map[ESC].function = rl_vi_movement_mode;
1240 vi_replace_map[RETURN].function = rl_newline;
1241 vi_replace_map[NEWLINE].function = rl_newline;
1243 /* If the normal vi insertion keymap has ^H bound to erase, do the
1244 same here. Probably should remove the assignment to RUBOUT up
1245 there, but I don't think it will make a difference in real life. */
1246 if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
1247 vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
1248 vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;
1251 _rl_keymap = vi_replace_map;
1256 /* Try to complete the word we are standing on or the word that ends with
1257 the previous character. A space matches everything. Word delimiters are
1259 rl_vi_possible_completions()
1261 int save_pos = rl_point;
1263 if (rl_line_buffer[rl_point] != ' ' && rl_line_buffer[rl_point] != ';')
1265 while (rl_point < rl_end && rl_line_buffer[rl_point] != ' ' &&
1266 rl_line_buffer[rl_point] != ';')
1269 else if (rl_line_buffer[rl_point - 1] == ';')
1275 rl_possible_completions ();
1276 rl_point = save_pos;
1282 #if defined (STATIC_MALLOC)
1284 /* **************************************************************** */
1286 /* xmalloc and xrealloc () */
1288 /* **************************************************************** */
1290 static void memory_error_and_abort ();
1296 char *temp = (char *)malloc (bytes);
1299 memory_error_and_abort ();
1304 xrealloc (pointer, bytes)
1311 temp = (char *)xmalloc (bytes);
1313 temp = (char *)realloc (pointer, bytes);
1316 memory_error_and_abort ();
1322 memory_error_and_abort ()
1324 fprintf (stderr, "readline: Out of virtual memory!\n");
1327 #endif /* STATIC_MALLOC */
1329 #endif /* VI_MODE */