1 /* vi_mode.c -- A vi emulation mode for Bash.
2 Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
4 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
6 This file is part of the GNU Readline Library, a library for
7 reading lines of text with interactive input and history editing.
9 The GNU Readline Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2, or
12 (at your option) any later version.
14 The GNU Readline Library is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
25 /* **************************************************************** */
27 /* VI Emulation Mode */
29 /* **************************************************************** */
34 #if defined (HAVE_CONFIG_H)
38 #include <sys/types.h>
40 #if defined (HAVE_STDLIB_H)
43 # include "ansi_stdlib.h"
44 #endif /* HAVE_STDLIB_H */
46 #if defined (HAVE_UNISTD_H)
52 /* Some standard library routines. */
59 #include "rlprivate.h"
63 #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
66 int _rl_vi_last_command
= 'i'; /* default `.' puts you in insert mode */
68 /* Non-zero means enter insertion mode. */
69 static int _rl_vi_doing_insert
;
71 /* Command keys which do movement for xxx_to commands. */
72 static const char *vi_motion
= " hl^$0ftFT;,%wbeWBE|";
74 /* Keymap used for vi replace characters. Created dynamically since
76 static Keymap vi_replace_map
;
78 /* The number of characters inserted in the last replace operation. */
79 static int vi_replace_count
;
81 /* If non-zero, we have text inserted after a c[motion] command that put
82 us implicitly into insert mode. Some people want this text to be
83 attached to the command so that it is `redoable' with `.'. */
84 static int vi_continued_command
;
85 static char *vi_insert_buffer
;
86 static int vi_insert_buffer_size
;
88 static int _rl_vi_last_repeat
= 1;
89 static int _rl_vi_last_arg_sign
= 1;
90 static int _rl_vi_last_motion
;
91 #if defined (HANDLE_MULTIBYTE)
92 static char _rl_vi_last_search_mbchar
[MB_LEN_MAX
];
93 static int _rl_vi_last_search_mblen
;
95 static int _rl_vi_last_search_char
;
97 static int _rl_vi_last_replacement
;
99 static int _rl_vi_last_key_before_insert
;
101 static int vi_redoing
;
103 /* Text modification commands. These are the `redoable' commands. */
104 static const char *vi_textmod
= "_*\\AaIiCcDdPpYyRrSsXx~";
106 /* Arrays for the saved marks. */
107 static int vi_mark_chars
['z' - 'a' + 1];
109 static void _rl_vi_stuff_insert
PARAMS((int));
110 static void _rl_vi_save_insert
PARAMS((UNDO_LIST
*));
112 static int _rl_vi_arg_dispatch
PARAMS((int));
113 static int rl_digit_loop1
PARAMS((void));
115 static int _rl_vi_set_mark
PARAMS((void));
116 static int _rl_vi_goto_mark
PARAMS((void));
118 static int _rl_vi_callback_getchar
PARAMS((char *, int));
120 #if defined (READLINE_CALLBACKS)
121 static int _rl_vi_callback_set_mark
PARAMS((_rl_callback_generic_arg
*));
122 static int _rl_vi_callback_goto_mark
PARAMS((_rl_callback_generic_arg
*));
123 static int _rl_vi_callback_change_char
PARAMS((_rl_callback_generic_arg
*));
124 static int _rl_vi_callback_char_search
PARAMS((_rl_callback_generic_arg
*));
128 _rl_vi_initialize_line ()
132 for (i
= 0; i
< sizeof (vi_mark_chars
) / sizeof (int); i
++)
133 vi_mark_chars
[i
] = -1;
135 RL_UNSETSTATE(RL_STATE_VICMDONCE
);
141 _rl_vi_last_command
= 'i';
142 _rl_vi_last_repeat
= 1;
143 _rl_vi_last_arg_sign
= 1;
144 _rl_vi_last_motion
= 0;
148 _rl_vi_set_last (key
, repeat
, sign
)
149 int key
, repeat
, sign
;
151 _rl_vi_last_command
= key
;
152 _rl_vi_last_repeat
= repeat
;
153 _rl_vi_last_arg_sign
= sign
;
156 /* A convenience function that calls _rl_vi_set_last to save the last command
157 information and enters insertion mode. */
159 rl_vi_start_inserting (key
, repeat
, sign
)
160 int key
, repeat
, sign
;
162 _rl_vi_set_last (key
, repeat
, sign
);
163 rl_vi_insertion_mode (1, key
);
166 /* Is the command C a VI mode text modification command? */
168 _rl_vi_textmod_command (c
)
171 return (member (c
, vi_textmod
));
175 _rl_vi_stuff_insert (count
)
178 rl_begin_undo_group ();
180 rl_insert_text (vi_insert_buffer
);
181 rl_end_undo_group ();
184 /* Bound to `.'. Called from command mode, so we know that we have to
185 redo a text modification command. The default for _rl_vi_last_command
186 puts you back into insert mode. */
188 rl_vi_redo (count
, c
)
193 if (!rl_explicit_arg
)
195 rl_numeric_arg
= _rl_vi_last_repeat
;
196 rl_arg_sign
= _rl_vi_last_arg_sign
;
201 /* If we're redoing an insert with `i', stuff in the inserted text
202 and do not go into insertion mode. */
203 if (_rl_vi_last_command
== 'i' && vi_insert_buffer
&& *vi_insert_buffer
)
205 _rl_vi_stuff_insert (count
);
206 /* And back up point over the last character inserted. */
211 r
= _rl_dispatch (_rl_vi_last_command
, _rl_keymap
);
217 /* A placeholder for further expansion. */
219 rl_vi_undo (count
, key
)
222 return (rl_undo_command (count
, key
));
225 /* Yank the nth arg from the previous line into this line at point. */
227 rl_vi_yank_arg (count
, key
)
230 /* Readline thinks that the first word on a line is the 0th, while vi
231 thinks the first word on a line is the 1st. Compensate. */
233 rl_yank_nth_arg (count
- 1, 0);
235 rl_yank_nth_arg ('$', 0);
240 /* With an argument, move back that many history lines, else move to the
241 beginning of history. */
243 rl_vi_fetch_history (count
, c
)
248 /* Giving an argument of n means we want the nth command in the history
249 file. The command number is interpreted the same way that the bash
250 `history' command does it -- that is, giving an argument count of 450
251 to this command would get the command listed as number 450 in the
252 output of `history'. */
255 wanted
= history_base
+ where_history () - count
;
257 rl_beginning_of_history (0, 0);
259 rl_get_previous_history (wanted
, c
);
262 rl_beginning_of_history (count
, 0);
266 /* Search again for the last thing searched for. */
268 rl_vi_search_again (count
, key
)
274 rl_noninc_reverse_search_again (count
, key
);
278 rl_noninc_forward_search_again (count
, key
);
284 /* Do a vi style search. */
286 rl_vi_search (count
, key
)
292 _rl_free_saved_history_line ();
293 rl_noninc_forward_search (count
, key
);
297 _rl_free_saved_history_line ();
298 rl_noninc_reverse_search (count
, key
);
308 /* Completion, from vi's point of view. */
310 rl_vi_complete (ignore
, key
)
313 if ((rl_point
< rl_end
) && (!whitespace (rl_line_buffer
[rl_point
])))
315 if (!whitespace (rl_line_buffer
[rl_point
+ 1]))
316 rl_vi_end_word (1, 'E');
321 rl_complete_internal ('*'); /* Expansion and replacement. */
323 rl_complete_internal ('?'); /* List possible completions. */
324 else if (key
== '\\')
325 rl_complete_internal (TAB
); /* Standard Readline completion. */
327 rl_complete (0, key
);
329 if (key
== '*' || key
== '\\')
330 rl_vi_start_inserting (key
, 1, rl_arg_sign
);
335 /* Tilde expansion for vi mode. */
337 rl_vi_tilde_expand (ignore
, key
)
340 rl_tilde_expand (0, key
);
341 rl_vi_start_inserting (key
, 1, rl_arg_sign
);
345 /* Previous word in vi mode. */
347 rl_vi_prev_word (count
, key
)
351 return (rl_vi_next_word (-count
, key
));
359 if (_rl_uppercase_p (key
))
360 rl_vi_bWord (count
, key
);
362 rl_vi_bword (count
, key
);
367 /* Next word in vi mode. */
369 rl_vi_next_word (count
, key
)
373 return (rl_vi_prev_word (-count
, key
));
375 if (rl_point
>= (rl_end
- 1))
381 if (_rl_uppercase_p (key
))
382 rl_vi_fWord (count
, key
);
384 rl_vi_fword (count
, key
);
388 /* Move to the end of the ?next? word. */
390 rl_vi_end_word (count
, key
)
399 if (_rl_uppercase_p (key
))
400 rl_vi_eWord (count
, key
);
402 rl_vi_eword (count
, key
);
406 /* Move forward a word the way that 'W' does. */
408 rl_vi_fWord (count
, ignore
)
411 while (count
-- && rl_point
< (rl_end
- 1))
413 /* Skip until whitespace. */
414 while (!whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
417 /* Now skip whitespace. */
418 while (whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
425 rl_vi_bWord (count
, ignore
)
428 while (count
-- && rl_point
> 0)
430 /* If we are at the start of a word, move back to whitespace so
431 we will go back to the start of the previous word. */
432 if (!whitespace (rl_line_buffer
[rl_point
]) &&
433 whitespace (rl_line_buffer
[rl_point
- 1]))
436 while (rl_point
> 0 && whitespace (rl_line_buffer
[rl_point
]))
441 while (--rl_point
>= 0 && !whitespace (rl_line_buffer
[rl_point
]));
449 rl_vi_eWord (count
, ignore
)
452 while (count
-- && rl_point
< (rl_end
- 1))
454 if (!whitespace (rl_line_buffer
[rl_point
]))
457 /* Move to the next non-whitespace character (to the start of the
459 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
462 if (rl_point
&& rl_point
< rl_end
)
464 /* Skip whitespace. */
465 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
468 /* Skip until whitespace. */
469 while (rl_point
< rl_end
&& !whitespace (rl_line_buffer
[rl_point
]))
472 /* Move back to the last character of the word. */
480 rl_vi_fword (count
, ignore
)
483 while (count
-- && rl_point
< (rl_end
- 1))
485 /* Move to white space (really non-identifer). */
486 if (_rl_isident (rl_line_buffer
[rl_point
]))
488 while (_rl_isident (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
491 else /* if (!whitespace (rl_line_buffer[rl_point])) */
493 while (!_rl_isident (rl_line_buffer
[rl_point
]) &&
494 !whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
498 /* Move past whitespace. */
499 while (whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
506 rl_vi_bword (count
, ignore
)
509 while (count
-- && rl_point
> 0)
513 /* If we are at the start of a word, move back to whitespace
514 so we will go back to the start of the previous word. */
515 if (!whitespace (rl_line_buffer
[rl_point
]) &&
516 whitespace (rl_line_buffer
[rl_point
- 1]))
519 /* If this character and the previous character are `opposite', move
520 back so we don't get messed up by the rl_point++ down there in
521 the while loop. Without this code, words like `l;' screw up the
523 last_is_ident
= _rl_isident (rl_line_buffer
[rl_point
- 1]);
524 if ((_rl_isident (rl_line_buffer
[rl_point
]) && !last_is_ident
) ||
525 (!_rl_isident (rl_line_buffer
[rl_point
]) && last_is_ident
))
528 while (rl_point
> 0 && whitespace (rl_line_buffer
[rl_point
]))
533 if (_rl_isident (rl_line_buffer
[rl_point
]))
534 while (--rl_point
>= 0 && _rl_isident (rl_line_buffer
[rl_point
]));
536 while (--rl_point
>= 0 && !_rl_isident (rl_line_buffer
[rl_point
]) &&
537 !whitespace (rl_line_buffer
[rl_point
]));
545 rl_vi_eword (count
, ignore
)
548 while (count
-- && rl_point
< rl_end
- 1)
550 if (!whitespace (rl_line_buffer
[rl_point
]))
553 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
556 if (rl_point
< rl_end
)
558 if (_rl_isident (rl_line_buffer
[rl_point
]))
559 while (++rl_point
< rl_end
&& _rl_isident (rl_line_buffer
[rl_point
]));
561 while (++rl_point
< rl_end
&& !_rl_isident (rl_line_buffer
[rl_point
])
562 && !whitespace (rl_line_buffer
[rl_point
]));
570 rl_vi_insert_beg (count
, key
)
573 rl_beg_of_line (1, key
);
574 rl_vi_insertion_mode (1, key
);
579 rl_vi_append_mode (count
, key
)
582 if (rl_point
< rl_end
)
584 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
588 int point
= rl_point
;
589 rl_forward_char (1, key
);
590 if (point
== rl_point
)
594 rl_vi_insertion_mode (1, key
);
599 rl_vi_append_eol (count
, key
)
602 rl_end_of_line (1, key
);
603 rl_vi_append_mode (1, key
);
607 /* What to do in the case of C-d. */
609 rl_vi_eof_maybe (count
, c
)
612 return (rl_newline (1, '\n'));
615 /* Insertion mode stuff. */
617 /* Switching from one mode to the other really just involves
618 switching keymaps. */
620 rl_vi_insertion_mode (count
, key
)
623 _rl_keymap
= vi_insertion_keymap
;
624 _rl_vi_last_key_before_insert
= key
;
629 _rl_vi_save_insert (up
)
636 if (vi_insert_buffer_size
>= 1)
637 vi_insert_buffer
[0] = '\0';
643 len
= end
- start
+ 1;
644 if (len
>= vi_insert_buffer_size
)
646 vi_insert_buffer_size
+= (len
+ 32) - (len
% 32);
647 vi_insert_buffer
= (char *)xrealloc (vi_insert_buffer
, vi_insert_buffer_size
);
649 strncpy (vi_insert_buffer
, rl_line_buffer
+ start
, len
- 1);
650 vi_insert_buffer
[len
-1] = '\0';
654 _rl_vi_done_inserting ()
656 if (_rl_vi_doing_insert
)
658 /* The `C', `s', and `S' commands set this. */
659 rl_end_undo_group ();
660 /* Now, the text between rl_undo_list->next->start and
661 rl_undo_list->next->end is what was inserted while in insert
662 mode. It gets copied to VI_INSERT_BUFFER because it depends
663 on absolute indices into the line which may change (though they
664 probably will not). */
665 _rl_vi_doing_insert
= 0;
666 _rl_vi_save_insert (rl_undo_list
->next
);
667 vi_continued_command
= 1;
671 if ((_rl_vi_last_key_before_insert
== 'i' || _rl_vi_last_key_before_insert
== 'a') && rl_undo_list
)
672 _rl_vi_save_insert (rl_undo_list
);
673 /* XXX - Other keys probably need to be checked. */
674 else if (_rl_vi_last_key_before_insert
== 'C')
675 rl_end_undo_group ();
676 while (_rl_undo_group_level
> 0)
677 rl_end_undo_group ();
678 vi_continued_command
= 0;
683 rl_vi_movement_mode (count
, key
)
687 rl_backward_char (1, key
);
689 _rl_keymap
= vi_movement_keymap
;
690 _rl_vi_done_inserting ();
692 /* This is how POSIX.2 says `U' should behave -- everything up until the
693 first time you go into command mode should not be undone. */
694 if (RL_ISSTATE (RL_STATE_VICMDONCE
) == 0)
695 rl_free_undo_list ();
697 RL_SETSTATE (RL_STATE_VICMDONCE
);
702 rl_vi_arg_digit (count
, c
)
705 if (c
== '0' && rl_numeric_arg
== 1 && !rl_explicit_arg
)
706 return (rl_beg_of_line (1, c
));
708 return (rl_digit_argument (count
, c
));
711 /* Change the case of the next COUNT characters. */
712 #if defined (HANDLE_MULTIBYTE)
714 _rl_vi_change_mbchar_case (count
)
718 char mb
[MB_LEN_MAX
+1];
722 memset (&ps
, 0, sizeof (mbstate_t));
723 if (_rl_adjust_point (rl_line_buffer
, rl_point
, &ps
) > 0)
725 while (count
-- && rl_point
< rl_end
)
727 mbrtowc (&wc
, rl_line_buffer
+ rl_point
, rl_end
- rl_point
, &ps
);
730 else if (iswlower (wc
))
734 /* Just skip over chars neither upper nor lower case */
735 rl_forward_char (1, 0);
739 /* Vi is kind of strange here. */
743 mblen
= wcrtomb (mb
, wc
, &ps
);
746 rl_begin_undo_group ();
748 if (rl_point
< p
) /* Did we retreat at EOL? */
749 rl_point
++; /* XXX - should we advance more than 1 for mbchar? */
751 rl_end_undo_group ();
755 rl_forward_char (1, 0);
763 rl_vi_change_case (count
, ignore
)
768 /* Don't try this on an empty line. */
769 if (rl_point
>= rl_end
)
773 #if defined (HANDLE_MULTIBYTE)
774 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
775 return (_rl_vi_change_mbchar_case (count
));
778 while (count
-- && rl_point
< rl_end
)
780 if (_rl_uppercase_p (rl_line_buffer
[rl_point
]))
781 c
= _rl_to_lower (rl_line_buffer
[rl_point
]);
782 else if (_rl_lowercase_p (rl_line_buffer
[rl_point
]))
783 c
= _rl_to_upper (rl_line_buffer
[rl_point
]);
786 /* Just skip over characters neither upper nor lower case. */
787 rl_forward_char (1, c
);
791 /* Vi is kind of strange here. */
795 rl_begin_undo_group ();
797 if (rl_point
< p
) /* Did we retreat at EOL? */
799 _rl_insert_char (1, c
);
800 rl_end_undo_group ();
804 rl_forward_char (1, c
);
810 rl_vi_put (count
, key
)
813 if (!_rl_uppercase_p (key
) && (rl_point
+ 1 <= rl_end
))
814 rl_point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
819 rl_backward_char (1, key
);
826 if (rl_point
&& rl_point
== rl_end
)
828 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
829 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
837 rl_vi_column (count
, key
)
841 rl_end_of_line (1, key
);
843 rl_point
= count
- 1;
848 rl_vi_domove (key
, nextkey
)
855 RL_SETSTATE(RL_STATE_MOREINPUT
);
857 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
860 if (!member (c
, vi_motion
))
864 save
= rl_numeric_arg
;
865 rl_numeric_arg
= _rl_digit_value (c
);
867 RL_SETSTATE (RL_STATE_NUMERICARG
|RL_STATE_VIMOTION
);
869 RL_UNSETSTATE (RL_STATE_VIMOTION
);
870 rl_numeric_arg
*= save
;
871 RL_SETSTATE(RL_STATE_MOREINPUT
);
872 c
= rl_read_key (); /* real command */
873 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
876 else if (key
== c
&& (key
== 'd' || key
== 'y' || key
== 'c'))
879 rl_beg_of_line (1, c
);
880 _rl_vi_last_motion
= c
;
887 _rl_vi_last_motion
= c
;
889 /* Append a blank character temporarily so that the motion routines
890 work right at the end of the line. */
892 rl_line_buffer
[rl_end
++] = ' ';
893 rl_line_buffer
[rl_end
] = '\0';
895 _rl_dispatch (c
, _rl_keymap
);
897 /* Remove the blank that we added. */
899 rl_line_buffer
[rl_end
] = '\0';
900 if (rl_point
> rl_end
)
903 /* No change in position means the command failed. */
904 if (rl_mark
== rl_point
)
907 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
908 word. If we are not at the end of the line, and we are on a
909 non-whitespace character, move back one (presumably to whitespace). */
910 if ((_rl_to_upper (c
) == 'W') && rl_point
< rl_end
&& rl_point
> rl_mark
&&
911 !whitespace (rl_line_buffer
[rl_point
]))
914 /* If cw or cW, back up to the end of a word, so the behaviour of ce
915 or cE is the actual result. Brute-force, no subtlety. */
916 if (key
== 'c' && rl_point
>= rl_mark
&& (_rl_to_upper (c
) == 'W'))
918 /* Don't move farther back than where we started. */
919 while (rl_point
> rl_mark
&& whitespace (rl_line_buffer
[rl_point
]))
922 /* Posix.2 says that if cw or cW moves the cursor towards the end of
923 the line, the character under the cursor should be deleted. */
924 if (rl_point
== rl_mark
)
928 /* Move past the end of the word so that the kill doesn't
929 remove the last letter of the previous word. Only do this
930 if we are not at the end of the line. */
931 if (rl_point
>= 0 && rl_point
< (rl_end
- 1) && !whitespace (rl_line_buffer
[rl_point
]))
936 if (rl_mark
< rl_point
)
937 SWAP (rl_point
, rl_mark
);
942 /* Process C as part of the current numeric argument. Return -1 if the
943 argument should be aborted, 0 if we should not read any more chars, and
944 1 if we should continue to read chars. */
946 _rl_vi_arg_dispatch (c
)
952 if (c
>= 0 && _rl_keymap
[c
].type
== ISFUNC
&& _rl_keymap
[c
].function
== rl_universal_argument
)
963 rl_numeric_arg
= (rl_numeric_arg
* 10) + _rl_digit_value (c
);
965 rl_numeric_arg
= _rl_digit_value (c
);
977 /* A simplified loop for vi. Don't dispatch key at end.
978 Don't recognize minus sign?
979 Should this do rl_save_prompt/rl_restore_prompt? */
987 if (_rl_arg_overflow ())
990 c
= _rl_arg_getchar ();
992 r
= _rl_vi_arg_dispatch (c
);
997 RL_UNSETSTATE(RL_STATE_NUMERICARG
);
1002 rl_vi_delete_to (count
, key
)
1007 if (_rl_uppercase_p (key
))
1008 rl_stuff_char ('$');
1009 else if (vi_redoing
)
1010 rl_stuff_char (_rl_vi_last_motion
);
1012 if (rl_vi_domove (key
, &c
))
1018 /* These are the motion commands that do not require adjusting the
1020 if ((strchr (" l|h^0bB", c
) == 0) && (rl_mark
< rl_end
))
1023 rl_kill_text (rl_point
, rl_mark
);
1028 rl_vi_change_to (count
, key
)
1033 if (_rl_uppercase_p (key
))
1034 rl_stuff_char ('$');
1035 else if (vi_redoing
)
1036 rl_stuff_char (_rl_vi_last_motion
);
1038 start_pos
= rl_point
;
1040 if (rl_vi_domove (key
, &c
))
1046 /* These are the motion commands that do not require adjusting the
1047 mark. c[wW] are handled by special-case code in rl_vi_domove(),
1048 and already leave the mark at the correct location. */
1049 if ((strchr (" l|hwW^0bB", c
) == 0) && (rl_mark
< rl_end
))
1052 /* The cursor never moves with c[wW]. */
1053 if ((_rl_to_upper (c
) == 'W') && rl_point
< start_pos
)
1054 rl_point
= start_pos
;
1058 if (vi_insert_buffer
&& *vi_insert_buffer
)
1059 rl_begin_undo_group ();
1060 rl_delete_text (rl_point
, rl_mark
);
1061 if (vi_insert_buffer
&& *vi_insert_buffer
)
1063 rl_insert_text (vi_insert_buffer
);
1064 rl_end_undo_group ();
1069 rl_begin_undo_group (); /* to make the `u' command work */
1070 rl_kill_text (rl_point
, rl_mark
);
1071 /* `C' does not save the text inserted for undoing or redoing. */
1072 if (_rl_uppercase_p (key
) == 0)
1073 _rl_vi_doing_insert
= 1;
1074 rl_vi_start_inserting (key
, rl_numeric_arg
, rl_arg_sign
);
1081 rl_vi_yank_to (count
, key
)
1087 if (_rl_uppercase_p (key
))
1088 rl_stuff_char ('$');
1090 if (rl_vi_domove (key
, &c
))
1096 /* These are the motion commands that do not require adjusting the
1098 if ((strchr (" l|h^0%bB", c
) == 0) && (rl_mark
< rl_end
))
1101 rl_begin_undo_group ();
1102 rl_kill_text (rl_point
, rl_mark
);
1103 rl_end_undo_group ();
1111 rl_vi_rubout (count
, key
)
1117 return (rl_vi_delete (-count
, key
));
1126 if (count
> 1 && MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1127 rl_backward_char (count
, key
);
1128 else if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1129 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1136 rl_kill_text (rl_point
, opoint
);
1142 rl_vi_delete (count
, key
)
1148 return (rl_vi_rubout (-count
, key
));
1156 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1157 end
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, count
, MB_FIND_NONZERO
);
1159 end
= rl_point
+ count
;
1164 rl_kill_text (rl_point
, end
);
1166 if (rl_point
> 0 && rl_point
== rl_end
)
1167 rl_backward_char (1, key
);
1173 rl_vi_back_to_indent (count
, key
)
1176 rl_beg_of_line (1, key
);
1177 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
1183 rl_vi_first_print (count
, key
)
1186 return (rl_vi_back_to_indent (1, key
));
1189 static int _rl_cs_dir
, _rl_cs_orig_dir
;
1191 #if defined (READLINE_CALLBACKS)
1193 _rl_vi_callback_char_search (data
)
1194 _rl_callback_generic_arg
*data
;
1196 #if defined (HANDLE_MULTIBYTE)
1197 _rl_vi_last_search_mblen
= _rl_read_mbchar (_rl_vi_last_search_mbchar
, MB_LEN_MAX
);
1199 RL_SETSTATE(RL_STATE_MOREINPUT
);
1200 _rl_vi_last_search_char
= rl_read_key ();
1201 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1204 _rl_callback_func
= 0;
1205 _rl_want_redisplay
= 1;
1207 #if defined (HANDLE_MULTIBYTE)
1208 return (_rl_char_search_internal (data
->count
, _rl_cs_dir
, _rl_vi_last_search_mbchar
, _rl_vi_last_search_mblen
));
1210 return (_rl_char_search_internal (data
->count
, _rl_cs_dir
, _rl_vi_last_search_char
));
1216 rl_vi_char_search (count
, key
)
1219 #if defined (HANDLE_MULTIBYTE)
1220 static char *target
;
1226 if (key
== ';' || key
== ',')
1227 _rl_cs_dir
= (key
== ';') ? _rl_cs_orig_dir
: -_rl_cs_orig_dir
;
1233 _rl_cs_orig_dir
= _rl_cs_dir
= FTO
;
1237 _rl_cs_orig_dir
= _rl_cs_dir
= BTO
;
1241 _rl_cs_orig_dir
= _rl_cs_dir
= FFIND
;
1245 _rl_cs_orig_dir
= _rl_cs_dir
= BFIND
;
1251 /* set target and tlen below */
1253 #if defined (READLINE_CALLBACKS)
1254 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1256 _rl_callback_data
= _rl_callback_data_alloc (count
);
1257 _rl_callback_data
->i1
= _rl_cs_dir
;
1258 _rl_callback_func
= _rl_vi_callback_char_search
;
1264 #if defined (HANDLE_MULTIBYTE)
1265 _rl_vi_last_search_mblen
= _rl_read_mbchar (_rl_vi_last_search_mbchar
, MB_LEN_MAX
);
1267 RL_SETSTATE(RL_STATE_MOREINPUT
);
1268 _rl_vi_last_search_char
= rl_read_key ();
1269 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1274 #if defined (HANDLE_MULTIBYTE)
1275 target
= _rl_vi_last_search_mbchar
;
1276 tlen
= _rl_vi_last_search_mblen
;
1278 target
= _rl_vi_last_search_char
;
1281 #if defined (HANDLE_MULTIBYTE)
1282 return (_rl_char_search_internal (count
, _rl_cs_dir
, target
, tlen
));
1284 return (_rl_char_search_internal (count
, _rl_cs_dir
, target
));
1288 /* Match brackets */
1290 rl_vi_match (ignore
, key
)
1293 int count
= 1, brack
, pos
, tmp
, pre
;
1296 if ((brack
= rl_vi_bracktype (rl_line_buffer
[rl_point
])) == 0)
1298 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1300 while ((brack
= rl_vi_bracktype (rl_line_buffer
[rl_point
])) == 0)
1303 rl_forward_char (1, key
);
1304 if (pre
== rl_point
)
1309 while ((brack
= rl_vi_bracktype (rl_line_buffer
[rl_point
])) == 0 &&
1310 rl_point
< rl_end
- 1)
1311 rl_forward_char (1, key
);
1328 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1332 pos
= _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
);
1338 int b
= rl_vi_bracktype (rl_line_buffer
[pos
]);
1341 else if (b
== brack
)
1355 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1358 pos
= _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
);
1362 int b
= rl_vi_bracktype (rl_line_buffer
[pos
]);
1365 else if (b
== brack
)
1386 case ')': return -1;
1388 case ']': return -2;
1390 case '}': return -3;
1396 _rl_vi_change_char (count
, c
, mb
)
1402 if (c
== '\033' || c
== CTRL ('C'))
1405 rl_begin_undo_group ();
1406 while (count
-- && rl_point
< rl_end
)
1409 rl_vi_delete (1, c
);
1410 if (rl_point
< p
) /* Did we retreat at EOL? */
1412 #if defined (HANDLE_MULTIBYTE)
1413 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1414 rl_insert_text (mb
);
1417 _rl_insert_char (1, c
);
1420 /* The cursor shall be left on the last character changed. */
1421 rl_backward_char (1, c
);
1423 rl_end_undo_group ();
1429 _rl_vi_callback_getchar (mb
, mblen
)
1435 RL_SETSTATE(RL_STATE_MOREINPUT
);
1437 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1439 #if defined (HANDLE_MULTIBYTE)
1440 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1441 c
= _rl_read_mbstring (c
, mb
, mblen
);
1447 #if defined (READLINE_CALLBACKS)
1449 _rl_vi_callback_change_char (data
)
1450 _rl_callback_generic_arg
*data
;
1453 char mb
[MB_LEN_MAX
];
1455 _rl_vi_last_replacement
= c
= _rl_vi_callback_getchar (mb
, MB_LEN_MAX
);
1457 _rl_callback_func
= 0;
1458 _rl_want_redisplay
= 1;
1460 return (_rl_vi_change_char (data
->count
, c
, mb
));
1465 rl_vi_change_char (count
, key
)
1469 char mb
[MB_LEN_MAX
];
1473 c
= _rl_vi_last_replacement
;
1477 #if defined (READLINE_CALLBACKS)
1478 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1480 _rl_callback_data
= _rl_callback_data_alloc (count
);
1481 _rl_callback_func
= _rl_vi_callback_change_char
;
1486 _rl_vi_last_replacement
= c
= _rl_vi_callback_getchar (mb
, MB_LEN_MAX
);
1488 return (_rl_vi_change_char (count
, c
, mb
));
1492 rl_vi_subst (count
, key
)
1495 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1496 if (vi_redoing
== 0)
1497 rl_stuff_char ((key
== 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1499 return (rl_vi_change_to (count
, 'c'));
1503 rl_vi_overstrike (count
, key
)
1506 if (_rl_vi_doing_insert
== 0)
1508 _rl_vi_doing_insert
= 1;
1509 rl_begin_undo_group ();
1514 _rl_overwrite_char (count
, key
);
1515 vi_replace_count
+= count
;
1522 rl_vi_overstrike_delete (count
, key
)
1527 for (i
= 0; i
< count
; i
++)
1529 if (vi_replace_count
== 0)
1540 rl_backward_char (1, key
);
1543 if (vi_replace_count
== 0 && _rl_vi_doing_insert
)
1545 rl_end_undo_group ();
1547 _rl_vi_doing_insert
= 0;
1553 rl_vi_replace (count
, key
)
1558 vi_replace_count
= 0;
1560 if (!vi_replace_map
)
1562 vi_replace_map
= rl_make_bare_keymap ();
1564 for (i
= ' '; i
< KEYMAP_SIZE
; i
++)
1565 vi_replace_map
[i
].function
= rl_vi_overstrike
;
1567 vi_replace_map
[RUBOUT
].function
= rl_vi_overstrike_delete
;
1568 vi_replace_map
[ESC
].function
= rl_vi_movement_mode
;
1569 vi_replace_map
[RETURN
].function
= rl_newline
;
1570 vi_replace_map
[NEWLINE
].function
= rl_newline
;
1572 /* If the normal vi insertion keymap has ^H bound to erase, do the
1573 same here. Probably should remove the assignment to RUBOUT up
1574 there, but I don't think it will make a difference in real life. */
1575 if (vi_insertion_keymap
[CTRL ('H')].type
== ISFUNC
&&
1576 vi_insertion_keymap
[CTRL ('H')].function
== rl_rubout
)
1577 vi_replace_map
[CTRL ('H')].function
= rl_vi_overstrike_delete
;
1580 _rl_keymap
= vi_replace_map
;
1585 /* Try to complete the word we are standing on or the word that ends with
1586 the previous character. A space matches everything. Word delimiters are
1589 rl_vi_possible_completions()
1591 int save_pos
= rl_point
;
1593 if (rl_line_buffer
[rl_point
] != ' ' && rl_line_buffer
[rl_point
] != ';')
1595 while (rl_point
< rl_end
&& rl_line_buffer
[rl_point
] != ' ' &&
1596 rl_line_buffer
[rl_point
] != ';')
1599 else if (rl_line_buffer
[rl_point
- 1] == ';')
1605 rl_possible_completions ();
1606 rl_point
= save_pos
;
1612 /* Functions to save and restore marks. */
1618 RL_SETSTATE(RL_STATE_MOREINPUT
);
1619 ch
= rl_read_key ();
1620 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1622 if (ch
< 'a' || ch
> 'z')
1628 vi_mark_chars
[ch
] = rl_point
;
1632 #if defined (READLINE_CALLBACKS)
1634 _rl_vi_callback_set_mark (data
)
1635 _rl_callback_generic_arg
*data
;
1637 _rl_callback_func
= 0;
1638 _rl_want_redisplay
= 1;
1640 return (_rl_vi_set_mark ());
1645 rl_vi_set_mark (count
, key
)
1648 #if defined (READLINE_CALLBACKS)
1649 if (RL_ISSTATE (RL_STATE_CALLBACK
))
1651 _rl_callback_data
= 0;
1652 _rl_callback_func
= _rl_vi_callback_set_mark
;
1657 return (_rl_vi_set_mark ());
1665 RL_SETSTATE(RL_STATE_MOREINPUT
);
1666 ch
= rl_read_key ();
1667 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1674 else if (ch
< 'a' || ch
> 'z')
1681 if (vi_mark_chars
[ch
] == -1)
1686 rl_point
= vi_mark_chars
[ch
];
1690 #if defined (READLINE_CALLBACKS)
1692 _rl_vi_callback_goto_mark (data
)
1693 _rl_callback_generic_arg
*data
;
1695 _rl_callback_func
= 0;
1696 _rl_want_redisplay
= 1;
1698 return (_rl_vi_goto_mark ());
1703 rl_vi_goto_mark (count
, key
)
1706 #if defined (READLINE_CALLBACKS)
1707 if (RL_ISSTATE (RL_STATE_CALLBACK
))
1709 _rl_callback_data
= 0;
1710 _rl_callback_func
= _rl_vi_callback_goto_mark
;
1715 return (_rl_vi_goto_mark ());
1717 #endif /* VI_MODE */