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-2010 Free Software Foundation, Inc.
6 This file is part of the GNU Readline Library (Readline), a library
7 for reading lines of text with interactive input and history editing.
9 Readline is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Readline is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Readline. If not, see <http://www.gnu.org/licenses/>.
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 _rl_vimotion_cxt
*_rl_vimvcxt
= 0;
70 /* Non-zero means enter insertion mode. */
71 static int _rl_vi_doing_insert
;
73 /* Command keys which do movement for xxx_to commands. */
74 static const char * const vi_motion
= " hl^$0ftFT;,%wbeWBE|`";
76 /* Keymap used for vi replace characters. Created dynamically since
78 static Keymap vi_replace_map
;
80 /* The number of characters inserted in the last replace operation. */
81 static int vi_replace_count
;
83 /* If non-zero, we have text inserted after a c[motion] command that put
84 us implicitly into insert mode. Some people want this text to be
85 attached to the command so that it is `redoable' with `.'. */
86 static int vi_continued_command
;
87 static char *vi_insert_buffer
;
88 static int vi_insert_buffer_size
;
90 static int _rl_vi_last_repeat
= 1;
91 static int _rl_vi_last_arg_sign
= 1;
92 static int _rl_vi_last_motion
;
93 #if defined (HANDLE_MULTIBYTE)
94 static char _rl_vi_last_search_mbchar
[MB_LEN_MAX
];
95 static int _rl_vi_last_search_mblen
;
97 static int _rl_vi_last_search_char
;
99 static int _rl_vi_last_replacement
;
101 static int _rl_vi_last_key_before_insert
;
103 static int vi_redoing
;
105 /* Text modification commands. These are the `redoable' commands. */
106 static const char * const vi_textmod
= "_*\\AaIiCcDdPpYyRrSsXx~";
108 /* Arrays for the saved marks. */
109 static int vi_mark_chars
['z' - 'a' + 1];
111 static void _rl_vi_stuff_insert
PARAMS((int));
112 static void _rl_vi_save_insert
PARAMS((UNDO_LIST
*));
114 static void _rl_vi_backup
PARAMS((void));
116 static int _rl_vi_arg_dispatch
PARAMS((int));
117 static int rl_digit_loop1
PARAMS((void));
119 static int _rl_vi_set_mark
PARAMS((void));
120 static int _rl_vi_goto_mark
PARAMS((void));
122 static void _rl_vi_append_forward
PARAMS((int));
124 static int _rl_vi_callback_getchar
PARAMS((char *, int));
126 #if defined (READLINE_CALLBACKS)
127 static int _rl_vi_callback_set_mark
PARAMS((_rl_callback_generic_arg
*));
128 static int _rl_vi_callback_goto_mark
PARAMS((_rl_callback_generic_arg
*));
129 static int _rl_vi_callback_change_char
PARAMS((_rl_callback_generic_arg
*));
130 static int _rl_vi_callback_char_search
PARAMS((_rl_callback_generic_arg
*));
133 static int rl_domove_read_callback
PARAMS((_rl_vimotion_cxt
*));
134 static int rl_domove_motion_callback
PARAMS((_rl_vimotion_cxt
*));
135 static int rl_vi_domove_getchar
PARAMS((_rl_vimotion_cxt
*));
137 static int vi_change_dispatch
PARAMS((_rl_vimotion_cxt
*));
138 static int vi_delete_dispatch
PARAMS((_rl_vimotion_cxt
*));
139 static int vi_yank_dispatch
PARAMS((_rl_vimotion_cxt
*));
141 static int vidomove_dispatch
PARAMS((_rl_vimotion_cxt
*));
144 _rl_vi_initialize_line ()
148 n
= sizeof (vi_mark_chars
) / sizeof (vi_mark_chars
[0]);
149 for (i
= 0; i
< n
; i
++)
150 vi_mark_chars
[i
] = -1;
152 RL_UNSETSTATE(RL_STATE_VICMDONCE
);
158 _rl_vi_last_command
= 'i';
159 _rl_vi_last_repeat
= 1;
160 _rl_vi_last_arg_sign
= 1;
161 _rl_vi_last_motion
= 0;
165 _rl_vi_set_last (key
, repeat
, sign
)
166 int key
, repeat
, sign
;
168 _rl_vi_last_command
= key
;
169 _rl_vi_last_repeat
= repeat
;
170 _rl_vi_last_arg_sign
= sign
;
173 /* A convenience function that calls _rl_vi_set_last to save the last command
174 information and enters insertion mode. */
176 rl_vi_start_inserting (key
, repeat
, sign
)
177 int key
, repeat
, sign
;
179 _rl_vi_set_last (key
, repeat
, sign
);
180 rl_vi_insertion_mode (1, key
);
183 /* Is the command C a VI mode text modification command? */
185 _rl_vi_textmod_command (c
)
188 return (member (c
, vi_textmod
));
192 _rl_vi_stuff_insert (count
)
195 rl_begin_undo_group ();
197 rl_insert_text (vi_insert_buffer
);
198 rl_end_undo_group ();
201 /* Bound to `.'. Called from command mode, so we know that we have to
202 redo a text modification command. The default for _rl_vi_last_command
203 puts you back into insert mode. */
205 rl_vi_redo (count
, c
)
210 if (!rl_explicit_arg
)
212 rl_numeric_arg
= _rl_vi_last_repeat
;
213 rl_arg_sign
= _rl_vi_last_arg_sign
;
218 /* If we're redoing an insert with `i', stuff in the inserted text
219 and do not go into insertion mode. */
220 if (_rl_vi_last_command
== 'i' && vi_insert_buffer
&& *vi_insert_buffer
)
222 _rl_vi_stuff_insert (count
);
223 /* And back up point over the last character inserted. */
227 /* Ditto for redoing an insert with `I', but move to the beginning of the
228 line like the `I' command does. */
229 else if (_rl_vi_last_command
== 'I' && vi_insert_buffer
&& *vi_insert_buffer
)
231 rl_beg_of_line (1, 'I');
232 _rl_vi_stuff_insert (count
);
236 /* Ditto for redoing an insert with `a', but move forward a character first
237 like the `a' command does. */
238 else if (_rl_vi_last_command
== 'a' && vi_insert_buffer
&& *vi_insert_buffer
)
240 _rl_vi_append_forward ('a');
241 _rl_vi_stuff_insert (count
);
245 /* Ditto for redoing an insert with `A', but move to the end of the line
246 like the `A' command does. */
247 else if (_rl_vi_last_command
== 'A' && vi_insert_buffer
&& *vi_insert_buffer
)
249 rl_end_of_line (1, 'A');
250 _rl_vi_stuff_insert (count
);
255 r
= _rl_dispatch (_rl_vi_last_command
, _rl_keymap
);
261 /* A placeholder for further expansion. */
263 rl_vi_undo (count
, key
)
266 return (rl_undo_command (count
, key
));
269 /* Yank the nth arg from the previous line into this line at point. */
271 rl_vi_yank_arg (count
, key
)
274 /* Readline thinks that the first word on a line is the 0th, while vi
275 thinks the first word on a line is the 1st. Compensate. */
277 rl_yank_nth_arg (count
- 1, 0);
279 rl_yank_nth_arg ('$', 0);
284 /* With an argument, move back that many history lines, else move to the
285 beginning of history. */
287 rl_vi_fetch_history (count
, c
)
292 /* Giving an argument of n means we want the nth command in the history
293 file. The command number is interpreted the same way that the bash
294 `history' command does it -- that is, giving an argument count of 450
295 to this command would get the command listed as number 450 in the
296 output of `history'. */
299 wanted
= history_base
+ where_history () - count
;
301 rl_beginning_of_history (0, 0);
303 rl_get_previous_history (wanted
, c
);
306 rl_beginning_of_history (count
, 0);
310 /* Search again for the last thing searched for. */
312 rl_vi_search_again (count
, key
)
318 rl_noninc_reverse_search_again (count
, key
);
322 rl_noninc_forward_search_again (count
, key
);
328 /* Do a vi style search. */
330 rl_vi_search (count
, key
)
336 _rl_free_saved_history_line ();
337 rl_noninc_forward_search (count
, key
);
341 _rl_free_saved_history_line ();
342 rl_noninc_reverse_search (count
, key
);
352 /* Completion, from vi's point of view. */
354 rl_vi_complete (ignore
, key
)
357 if ((rl_point
< rl_end
) && (!whitespace (rl_line_buffer
[rl_point
])))
359 if (!whitespace (rl_line_buffer
[rl_point
+ 1]))
360 rl_vi_end_word (1, 'E');
365 rl_complete_internal ('*'); /* Expansion and replacement. */
367 rl_complete_internal ('?'); /* List possible completions. */
368 else if (key
== '\\')
369 rl_complete_internal (TAB
); /* Standard Readline completion. */
371 rl_complete (0, key
);
373 if (key
== '*' || key
== '\\')
374 rl_vi_start_inserting (key
, 1, rl_arg_sign
);
379 /* Tilde expansion for vi mode. */
381 rl_vi_tilde_expand (ignore
, key
)
384 rl_tilde_expand (0, key
);
385 rl_vi_start_inserting (key
, 1, rl_arg_sign
);
389 /* Previous word in vi mode. */
391 rl_vi_prev_word (count
, key
)
395 return (rl_vi_next_word (-count
, key
));
403 if (_rl_uppercase_p (key
))
404 rl_vi_bWord (count
, key
);
406 rl_vi_bword (count
, key
);
411 /* Next word in vi mode. */
413 rl_vi_next_word (count
, key
)
417 return (rl_vi_prev_word (-count
, key
));
419 if (rl_point
>= (rl_end
- 1))
425 if (_rl_uppercase_p (key
))
426 rl_vi_fWord (count
, key
);
428 rl_vi_fword (count
, key
);
432 /* Move to the end of the ?next? word. */
434 rl_vi_end_word (count
, key
)
443 if (_rl_uppercase_p (key
))
444 rl_vi_eWord (count
, key
);
446 rl_vi_eword (count
, key
);
450 /* Move forward a word the way that 'W' does. */
452 rl_vi_fWord (count
, ignore
)
455 while (count
-- && rl_point
< (rl_end
- 1))
457 /* Skip until whitespace. */
458 while (!whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
461 /* Now skip whitespace. */
462 while (whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
469 rl_vi_bWord (count
, ignore
)
472 while (count
-- && rl_point
> 0)
474 /* If we are at the start of a word, move back to whitespace so
475 we will go back to the start of the previous word. */
476 if (!whitespace (rl_line_buffer
[rl_point
]) &&
477 whitespace (rl_line_buffer
[rl_point
- 1]))
480 while (rl_point
> 0 && whitespace (rl_line_buffer
[rl_point
]))
485 while (--rl_point
>= 0 && !whitespace (rl_line_buffer
[rl_point
]));
493 rl_vi_eWord (count
, ignore
)
496 while (count
-- && rl_point
< (rl_end
- 1))
498 if (!whitespace (rl_line_buffer
[rl_point
]))
501 /* Move to the next non-whitespace character (to the start of the
503 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
506 if (rl_point
&& rl_point
< rl_end
)
508 /* Skip whitespace. */
509 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
512 /* Skip until whitespace. */
513 while (rl_point
< rl_end
&& !whitespace (rl_line_buffer
[rl_point
]))
516 /* Move back to the last character of the word. */
524 rl_vi_fword (count
, ignore
)
527 while (count
-- && rl_point
< (rl_end
- 1))
529 /* Move to white space (really non-identifer). */
530 if (_rl_isident (rl_line_buffer
[rl_point
]))
532 while (_rl_isident (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
535 else /* if (!whitespace (rl_line_buffer[rl_point])) */
537 while (!_rl_isident (rl_line_buffer
[rl_point
]) &&
538 !whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
542 /* Move past whitespace. */
543 while (whitespace (rl_line_buffer
[rl_point
]) && rl_point
< rl_end
)
550 rl_vi_bword (count
, ignore
)
553 while (count
-- && rl_point
> 0)
557 /* If we are at the start of a word, move back to whitespace
558 so we will go back to the start of the previous word. */
559 if (!whitespace (rl_line_buffer
[rl_point
]) &&
560 whitespace (rl_line_buffer
[rl_point
- 1]))
563 /* If this character and the previous character are `opposite', move
564 back so we don't get messed up by the rl_point++ down there in
565 the while loop. Without this code, words like `l;' screw up the
567 last_is_ident
= _rl_isident (rl_line_buffer
[rl_point
- 1]);
568 if ((_rl_isident (rl_line_buffer
[rl_point
]) && !last_is_ident
) ||
569 (!_rl_isident (rl_line_buffer
[rl_point
]) && last_is_ident
))
572 while (rl_point
> 0 && whitespace (rl_line_buffer
[rl_point
]))
577 if (_rl_isident (rl_line_buffer
[rl_point
]))
578 while (--rl_point
>= 0 && _rl_isident (rl_line_buffer
[rl_point
]));
580 while (--rl_point
>= 0 && !_rl_isident (rl_line_buffer
[rl_point
]) &&
581 !whitespace (rl_line_buffer
[rl_point
]));
589 rl_vi_eword (count
, ignore
)
592 while (count
-- && rl_point
< rl_end
- 1)
594 if (!whitespace (rl_line_buffer
[rl_point
]))
597 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
600 if (rl_point
< rl_end
)
602 if (_rl_isident (rl_line_buffer
[rl_point
]))
603 while (++rl_point
< rl_end
&& _rl_isident (rl_line_buffer
[rl_point
]));
605 while (++rl_point
< rl_end
&& !_rl_isident (rl_line_buffer
[rl_point
])
606 && !whitespace (rl_line_buffer
[rl_point
]));
614 rl_vi_insert_beg (count
, key
)
617 rl_beg_of_line (1, key
);
618 rl_vi_insert_mode (1, key
);
623 _rl_vi_append_forward (key
)
628 if (rl_point
< rl_end
)
630 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
636 rl_forward_char (1, key
);
638 rl_point
= _rl_forward_char_internal (1);
640 if (point
== rl_point
)
647 rl_vi_append_mode (count
, key
)
650 _rl_vi_append_forward (key
);
651 rl_vi_start_inserting (key
, 1, rl_arg_sign
);
656 rl_vi_append_eol (count
, key
)
659 rl_end_of_line (1, key
);
660 rl_vi_append_mode (1, key
);
664 /* What to do in the case of C-d. */
666 rl_vi_eof_maybe (count
, c
)
669 return (rl_newline (1, '\n'));
672 /* Insertion mode stuff. */
674 /* Switching from one mode to the other really just involves
675 switching keymaps. */
677 rl_vi_insertion_mode (count
, key
)
680 _rl_keymap
= vi_insertion_keymap
;
681 _rl_vi_last_key_before_insert
= key
;
686 rl_vi_insert_mode (count
, key
)
689 rl_vi_start_inserting (key
, 1, rl_arg_sign
);
694 _rl_vi_save_insert (up
)
699 if (up
== 0 || up
->what
!= UNDO_INSERT
)
701 if (vi_insert_buffer_size
>= 1)
702 vi_insert_buffer
[0] = '\0';
708 len
= end
- start
+ 1;
709 if (len
>= vi_insert_buffer_size
)
711 vi_insert_buffer_size
+= (len
+ 32) - (len
% 32);
712 vi_insert_buffer
= (char *)xrealloc (vi_insert_buffer
, vi_insert_buffer_size
);
714 strncpy (vi_insert_buffer
, rl_line_buffer
+ start
, len
- 1);
715 vi_insert_buffer
[len
-1] = '\0';
719 _rl_vi_done_inserting ()
721 if (_rl_vi_doing_insert
)
723 /* The `C', `s', and `S' commands set this. */
724 rl_end_undo_group ();
725 /* Now, the text between rl_undo_list->next->start and
726 rl_undo_list->next->end is what was inserted while in insert
727 mode. It gets copied to VI_INSERT_BUFFER because it depends
728 on absolute indices into the line which may change (though they
729 probably will not). */
730 _rl_vi_doing_insert
= 0;
731 _rl_vi_save_insert (rl_undo_list
->next
);
732 vi_continued_command
= 1;
736 if (rl_undo_list
&& (_rl_vi_last_key_before_insert
== 'i' ||
737 _rl_vi_last_key_before_insert
== 'a' ||
738 _rl_vi_last_key_before_insert
== 'I' ||
739 _rl_vi_last_key_before_insert
== 'A'))
740 _rl_vi_save_insert (rl_undo_list
);
741 /* XXX - Other keys probably need to be checked. */
742 else if (_rl_vi_last_key_before_insert
== 'C')
743 rl_end_undo_group ();
744 while (_rl_undo_group_level
> 0)
745 rl_end_undo_group ();
746 vi_continued_command
= 0;
751 rl_vi_movement_mode (count
, key
)
755 rl_backward_char (1, key
);
757 _rl_keymap
= vi_movement_keymap
;
758 _rl_vi_done_inserting ();
760 /* This is how POSIX.2 says `U' should behave -- everything up until the
761 first time you go into command mode should not be undone. */
762 if (RL_ISSTATE (RL_STATE_VICMDONCE
) == 0)
763 rl_free_undo_list ();
765 RL_SETSTATE (RL_STATE_VICMDONCE
);
770 rl_vi_arg_digit (count
, c
)
773 if (c
== '0' && rl_numeric_arg
== 1 && !rl_explicit_arg
)
774 return (rl_beg_of_line (1, c
));
776 return (rl_digit_argument (count
, c
));
779 /* Change the case of the next COUNT characters. */
780 #if defined (HANDLE_MULTIBYTE)
782 _rl_vi_change_mbchar_case (count
)
786 char mb
[MB_LEN_MAX
+1];
791 memset (&ps
, 0, sizeof (mbstate_t));
792 if (_rl_adjust_point (rl_line_buffer
, rl_point
, &ps
) > 0)
794 while (count
-- && rl_point
< rl_end
)
796 m
= mbrtowc (&wc
, rl_line_buffer
+ rl_point
, rl_end
- rl_point
, &ps
);
797 if (MB_INVALIDCH (m
))
798 wc
= (wchar_t)rl_line_buffer
[rl_point
];
799 else if (MB_NULLWCH (m
))
803 else if (iswlower (wc
))
807 /* Just skip over chars neither upper nor lower case */
808 rl_forward_char (1, 0);
812 /* Vi is kind of strange here. */
816 mlen
= wcrtomb (mb
, wc
, &ps
);
819 rl_begin_undo_group ();
821 if (rl_point
< p
) /* Did we retreat at EOL? */
822 rl_point
++; /* XXX - should we advance more than 1 for mbchar? */
824 rl_end_undo_group ();
828 rl_forward_char (1, 0);
836 rl_vi_change_case (count
, ignore
)
841 /* Don't try this on an empty line. */
842 if (rl_point
>= rl_end
)
846 #if defined (HANDLE_MULTIBYTE)
847 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
848 return (_rl_vi_change_mbchar_case (count
));
851 while (count
-- && rl_point
< rl_end
)
853 if (_rl_uppercase_p (rl_line_buffer
[rl_point
]))
854 c
= _rl_to_lower (rl_line_buffer
[rl_point
]);
855 else if (_rl_lowercase_p (rl_line_buffer
[rl_point
]))
856 c
= _rl_to_upper (rl_line_buffer
[rl_point
]);
859 /* Just skip over characters neither upper nor lower case. */
860 rl_forward_char (1, c
);
864 /* Vi is kind of strange here. */
868 rl_begin_undo_group ();
870 if (rl_point
< p
) /* Did we retreat at EOL? */
872 _rl_insert_char (1, c
);
873 rl_end_undo_group ();
877 rl_forward_char (1, c
);
883 rl_vi_put (count
, key
)
886 if (!_rl_uppercase_p (key
) && (rl_point
+ 1 <= rl_end
))
887 rl_point
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, 1, MB_FIND_NONZERO
);
892 rl_backward_char (1, key
);
899 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
900 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
908 if (rl_point
&& rl_point
== rl_end
)
910 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
911 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
919 rl_vi_column (count
, key
)
923 rl_end_of_line (1, key
);
925 rl_point
= count
- 1;
929 /* Process C as part of the current numeric argument. Return -1 if the
930 argument should be aborted, 0 if we should not read any more chars, and
931 1 if we should continue to read chars. */
933 _rl_vi_arg_dispatch (c
)
939 if (c
>= 0 && _rl_keymap
[c
].type
== ISFUNC
&& _rl_keymap
[c
].function
== rl_universal_argument
)
950 rl_numeric_arg
= (rl_numeric_arg
* 10) + _rl_digit_value (c
);
952 rl_numeric_arg
= _rl_digit_value (c
);
954 return 1; /* keep going */
964 /* A simplified loop for vi. Don't dispatch key at end.
965 Don't recognize minus sign?
966 Should this do rl_save_prompt/rl_restore_prompt? */
974 if (_rl_arg_overflow ())
977 c
= _rl_arg_getchar ();
979 r
= _rl_vi_arg_dispatch (c
);
984 RL_UNSETSTATE(RL_STATE_NUMERICARG
);
989 _rl_mvcxt_init (m
, op
, key
)
994 m
->state
= m
->flags
= 0;
1003 static _rl_vimotion_cxt
*
1004 _rl_mvcxt_alloc (op
, key
)
1007 _rl_vimotion_cxt
*m
;
1009 m
= xmalloc (sizeof (_rl_vimotion_cxt
));
1010 _rl_mvcxt_init (m
, op
, key
);
1015 _rl_mvcxt_dispose (m
)
1016 _rl_vimotion_cxt
*m
;
1022 rl_domove_motion_callback (m
)
1023 _rl_vimotion_cxt
*m
;
1025 int c
, key
, save
, r
;
1028 _rl_vi_last_motion
= c
= m
->motion
;
1030 /* Append a blank character temporarily so that the motion routines
1031 work right at the end of the line. */
1033 rl_line_buffer
[rl_end
++] = ' ';
1034 rl_line_buffer
[rl_end
] = '\0';
1036 _rl_dispatch (c
, _rl_keymap
);
1038 /* Remove the blank that we added. */
1040 rl_line_buffer
[rl_end
] = '\0';
1041 if (rl_point
> rl_end
)
1044 /* No change in position means the command failed. */
1045 if (rl_mark
== rl_point
)
1048 /* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
1049 word. If we are not at the end of the line, and we are on a
1050 non-whitespace character, move back one (presumably to whitespace). */
1051 if ((_rl_to_upper (c
) == 'W') && rl_point
< rl_end
&& rl_point
> rl_mark
&&
1052 !whitespace (rl_line_buffer
[rl_point
]))
1055 /* If cw or cW, back up to the end of a word, so the behaviour of ce
1056 or cE is the actual result. Brute-force, no subtlety. */
1057 if (key
== 'c' && rl_point
>= rl_mark
&& (_rl_to_upper (c
) == 'W'))
1059 /* Don't move farther back than where we started. */
1060 while (rl_point
> rl_mark
&& whitespace (rl_line_buffer
[rl_point
]))
1063 /* Posix.2 says that if cw or cW moves the cursor towards the end of
1064 the line, the character under the cursor should be deleted. */
1065 if (rl_point
== rl_mark
)
1069 /* Move past the end of the word so that the kill doesn't
1070 remove the last letter of the previous word. Only do this
1071 if we are not at the end of the line. */
1072 if (rl_point
>= 0 && rl_point
< (rl_end
- 1) && !whitespace (rl_line_buffer
[rl_point
]))
1077 if (rl_mark
< rl_point
)
1078 SWAP (rl_point
, rl_mark
);
1080 #if defined (READLINE_CALLBACKS)
1081 if (RL_ISSTATE (RL_STATE_CALLBACK
))
1082 (*rl_redisplay_function
)(); /* make sure motion is displayed */
1085 r
= vidomove_dispatch (m
);
1090 #define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))
1093 rl_domove_read_callback (m
)
1094 _rl_vimotion_cxt
*m
;
1100 if (member (c
, vi_motion
))
1102 #if defined (READLINE_CALLBACKS)
1103 /* If we just read a vi-mode motion command numeric argument, turn off
1104 the `reading numeric arg' state */
1105 if (RL_ISSTATE (RL_STATE_CALLBACK
) && RL_VIMOVENUMARG())
1106 RL_UNSETSTATE (RL_STATE_NUMERICARG
);
1108 /* Should do everything, including turning off RL_STATE_VIMOTION */
1109 return (rl_domove_motion_callback (m
));
1111 else if (m
->key
== c
&& (m
->key
== 'd' || m
->key
== 'y' || m
->key
== 'c'))
1114 rl_beg_of_line (1, c
);
1115 _rl_vi_last_motion
= c
;
1116 RL_UNSETSTATE (RL_STATE_VIMOTION
);
1119 #if defined (READLINE_CALLBACKS)
1120 /* XXX - these need to handle rl_universal_argument bindings */
1121 /* Reading vi motion char continuing numeric argument */
1122 else if (_rl_digit_p (c
) && RL_ISSTATE (RL_STATE_CALLBACK
) && RL_VIMOVENUMARG())
1124 return (_rl_vi_arg_dispatch (c
));
1126 /* Readine vi motion char starting numeric argument */
1127 else if (_rl_digit_p (c
) && RL_ISSTATE (RL_STATE_CALLBACK
) && RL_ISSTATE (RL_STATE_VIMOTION
) && (RL_ISSTATE (RL_STATE_NUMERICARG
) == 0))
1129 RL_SETSTATE (RL_STATE_NUMERICARG
);
1130 return (_rl_vi_arg_dispatch (c
));
1133 else if (_rl_digit_p (c
))
1135 /* This code path taken when not in callback mode */
1136 save
= rl_numeric_arg
;
1137 rl_numeric_arg
= _rl_digit_value (c
);
1138 rl_explicit_arg
= 1;
1139 RL_SETSTATE (RL_STATE_NUMERICARG
);
1141 rl_numeric_arg
*= save
;
1142 c
= rl_vi_domove_getchar (m
);
1149 return (rl_domove_motion_callback (m
));
1153 RL_UNSETSTATE (RL_STATE_VIMOTION
);
1154 RL_UNSETSTATE (RL_STATE_NUMERICARG
);
1160 rl_vi_domove_getchar (m
)
1161 _rl_vimotion_cxt
*m
;
1165 RL_SETSTATE(RL_STATE_MOREINPUT
);
1167 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1172 #if defined (READLINE_CALLBACKS)
1174 _rl_vi_domove_callback (m
)
1175 _rl_vimotion_cxt
*m
;
1179 m
->motion
= c
= rl_vi_domove_getchar (m
);
1180 /* XXX - what to do if this returns -1? Should we return 1 for eof to
1182 r
= rl_domove_read_callback (m
);
1184 return ((r
== 0) ? r
: 1); /* normalize return values */
1188 /* This code path taken when not in callback mode. */
1190 rl_vi_domove (x
, ignore
)
1194 _rl_vimotion_cxt
*m
;
1196 *ignore
= m
->motion
= rl_vi_domove_getchar (m
= _rl_vimvcxt
);
1204 return (rl_domove_read_callback (m
));
1208 vi_delete_dispatch (m
)
1209 _rl_vimotion_cxt
*m
;
1211 /* These are the motion commands that do not require adjusting the
1213 if (((strchr (" l|h^0bBFT`", m
->motion
) == 0) && (rl_point
>= m
->start
)) &&
1217 rl_kill_text (rl_point
, rl_mark
);
1222 rl_vi_delete_to (count
, key
)
1227 _rl_vimvcxt
= _rl_mvcxt_alloc (VIM_DELETE
, key
);
1228 _rl_vimvcxt
->start
= rl_point
;
1231 if (_rl_uppercase_p (key
))
1233 _rl_vimvcxt
->motion
= '$';
1234 r
= rl_domove_motion_callback (_rl_vimvcxt
);
1236 else if (vi_redoing
)
1238 _rl_vimvcxt
->motion
= _rl_vi_last_motion
;
1239 r
= rl_domove_motion_callback (_rl_vimvcxt
);
1241 #if defined (READLINE_CALLBACKS)
1242 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1244 RL_SETSTATE (RL_STATE_VIMOTION
);
1249 r
= rl_vi_domove (key
, &c
);
1257 _rl_mvcxt_dispose (_rl_vimvcxt
);
1264 vi_change_dispatch (m
)
1265 _rl_vimotion_cxt
*m
;
1267 /* These are the motion commands that do not require adjusting the
1268 mark. c[wW] are handled by special-case code in rl_vi_domove(),
1269 and already leave the mark at the correct location. */
1270 if (((strchr (" l|hwW^0bBFT`", m
->motion
) == 0) && (rl_point
>= m
->start
)) &&
1274 /* The cursor never moves with c[wW]. */
1275 if ((_rl_to_upper (m
->motion
) == 'W') && rl_point
< m
->start
)
1276 rl_point
= m
->start
;
1280 if (vi_insert_buffer
&& *vi_insert_buffer
)
1281 rl_begin_undo_group ();
1282 rl_delete_text (rl_point
, rl_mark
);
1283 if (vi_insert_buffer
&& *vi_insert_buffer
)
1285 rl_insert_text (vi_insert_buffer
);
1286 rl_end_undo_group ();
1291 rl_begin_undo_group (); /* to make the `u' command work */
1292 rl_kill_text (rl_point
, rl_mark
);
1293 /* `C' does not save the text inserted for undoing or redoing. */
1294 if (_rl_uppercase_p (m
->key
) == 0)
1295 _rl_vi_doing_insert
= 1;
1296 /* XXX -- TODO -- use m->numericarg? */
1297 rl_vi_start_inserting (m
->key
, rl_numeric_arg
, rl_arg_sign
);
1304 rl_vi_change_to (count
, key
)
1309 _rl_vimvcxt
= _rl_mvcxt_alloc (VIM_CHANGE
, key
);
1310 _rl_vimvcxt
->start
= rl_point
;
1313 if (_rl_uppercase_p (key
))
1315 _rl_vimvcxt
->motion
= '$';
1316 r
= rl_domove_motion_callback (_rl_vimvcxt
);
1318 else if (vi_redoing
)
1320 _rl_vimvcxt
->motion
= _rl_vi_last_motion
;
1321 r
= rl_domove_motion_callback (_rl_vimvcxt
);
1323 #if defined (READLINE_CALLBACKS)
1324 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1326 RL_SETSTATE (RL_STATE_VIMOTION
);
1331 r
= rl_vi_domove (key
, &c
);
1336 r
= -1; /* normalize return value */
1339 _rl_mvcxt_dispose (_rl_vimvcxt
);
1346 vi_yank_dispatch (m
)
1347 _rl_vimotion_cxt
*m
;
1349 /* These are the motion commands that do not require adjusting the
1351 if (((strchr (" l|h^0%bBFT`", m
->motion
) == 0) && (rl_point
>= m
->start
)) &&
1355 rl_begin_undo_group ();
1356 rl_kill_text (rl_point
, rl_mark
);
1357 rl_end_undo_group ();
1359 rl_point
= m
->start
;
1365 rl_vi_yank_to (count
, key
)
1370 _rl_vimvcxt
= _rl_mvcxt_alloc (VIM_YANK
, key
);
1371 _rl_vimvcxt
->start
= rl_point
;
1374 if (_rl_uppercase_p (key
))
1376 _rl_vimvcxt
->motion
= '$';
1377 r
= rl_domove_motion_callback (_rl_vimvcxt
);
1379 #if defined (READLINE_CALLBACKS)
1380 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1382 RL_SETSTATE (RL_STATE_VIMOTION
);
1387 r
= rl_vi_domove (key
, &c
);
1395 _rl_mvcxt_dispose (_rl_vimvcxt
);
1402 vidomove_dispatch (m
)
1403 _rl_vimotion_cxt
*m
;
1410 r
= vi_delete_dispatch (m
);
1413 r
= vi_change_dispatch (m
);
1416 r
= vi_yank_dispatch (m
);
1419 _rl_errmsg ("vidomove_dispatch: unknown operator %d", m
->op
);
1424 RL_UNSETSTATE (RL_STATE_VIMOTION
);
1429 rl_vi_rubout (count
, key
)
1435 return (rl_vi_delete (-count
, key
));
1444 if (count
> 1 && MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1445 rl_backward_char (count
, key
);
1446 else if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1447 rl_point
= _rl_find_prev_mbchar (rl_line_buffer
, rl_point
, MB_FIND_NONZERO
);
1454 rl_kill_text (rl_point
, opoint
);
1460 rl_vi_delete (count
, key
)
1466 return (rl_vi_rubout (-count
, key
));
1474 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1475 end
= _rl_find_next_mbchar (rl_line_buffer
, rl_point
, count
, MB_FIND_NONZERO
);
1477 end
= rl_point
+ count
;
1482 rl_kill_text (rl_point
, end
);
1484 if (rl_point
> 0 && rl_point
== rl_end
)
1485 rl_backward_char (1, key
);
1491 rl_vi_back_to_indent (count
, key
)
1494 rl_beg_of_line (1, key
);
1495 while (rl_point
< rl_end
&& whitespace (rl_line_buffer
[rl_point
]))
1501 rl_vi_first_print (count
, key
)
1504 return (rl_vi_back_to_indent (1, key
));
1507 static int _rl_cs_dir
, _rl_cs_orig_dir
;
1509 #if defined (READLINE_CALLBACKS)
1511 _rl_vi_callback_char_search (data
)
1512 _rl_callback_generic_arg
*data
;
1515 #if defined (HANDLE_MULTIBYTE)
1516 c
= _rl_vi_last_search_mblen
= _rl_read_mbchar (_rl_vi_last_search_mbchar
, MB_LEN_MAX
);
1518 RL_SETSTATE(RL_STATE_MOREINPUT
);
1520 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1526 #if !defined (HANDLE_MULTIBYTE)
1527 _rl_vi_last_search_char
= c
;
1530 _rl_callback_func
= 0;
1531 _rl_want_redisplay
= 1;
1533 #if defined (HANDLE_MULTIBYTE)
1534 return (_rl_char_search_internal (data
->count
, _rl_cs_dir
, _rl_vi_last_search_mbchar
, _rl_vi_last_search_mblen
));
1536 return (_rl_char_search_internal (data
->count
, _rl_cs_dir
, _rl_vi_last_search_char
));
1542 rl_vi_char_search (count
, key
)
1546 #if defined (HANDLE_MULTIBYTE)
1547 static char *target
;
1553 if (key
== ';' || key
== ',')
1555 if (_rl_cs_orig_dir
== 0)
1557 #if defined (HANDLE_MULTIBYTE)
1558 if (_rl_vi_last_search_mblen
== 0)
1561 if (_rl_vi_last_search_char
== 0)
1564 _rl_cs_dir
= (key
== ';') ? _rl_cs_orig_dir
: -_rl_cs_orig_dir
;
1571 _rl_cs_orig_dir
= _rl_cs_dir
= FTO
;
1575 _rl_cs_orig_dir
= _rl_cs_dir
= BTO
;
1579 _rl_cs_orig_dir
= _rl_cs_dir
= FFIND
;
1583 _rl_cs_orig_dir
= _rl_cs_dir
= BFIND
;
1589 /* set target and tlen below */
1591 #if defined (READLINE_CALLBACKS)
1592 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1594 _rl_callback_data
= _rl_callback_data_alloc (count
);
1595 _rl_callback_data
->i1
= _rl_cs_dir
;
1596 _rl_callback_func
= _rl_vi_callback_char_search
;
1602 #if defined (HANDLE_MULTIBYTE)
1603 c
= _rl_read_mbchar (_rl_vi_last_search_mbchar
, MB_LEN_MAX
);
1606 _rl_vi_last_search_mblen
= c
;
1608 RL_SETSTATE(RL_STATE_MOREINPUT
);
1610 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1613 _rl_vi_last_search_char
= c
;
1618 #if defined (HANDLE_MULTIBYTE)
1619 target
= _rl_vi_last_search_mbchar
;
1620 tlen
= _rl_vi_last_search_mblen
;
1622 target
= _rl_vi_last_search_char
;
1625 #if defined (HANDLE_MULTIBYTE)
1626 return (_rl_char_search_internal (count
, _rl_cs_dir
, target
, tlen
));
1628 return (_rl_char_search_internal (count
, _rl_cs_dir
, target
));
1632 /* Match brackets */
1634 rl_vi_match (ignore
, key
)
1637 int count
= 1, brack
, pos
, tmp
, pre
;
1640 if ((brack
= rl_vi_bracktype (rl_line_buffer
[rl_point
])) == 0)
1642 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1644 while ((brack
= rl_vi_bracktype (rl_line_buffer
[rl_point
])) == 0)
1647 rl_forward_char (1, key
);
1648 if (pre
== rl_point
)
1653 while ((brack
= rl_vi_bracktype (rl_line_buffer
[rl_point
])) == 0 &&
1654 rl_point
< rl_end
- 1)
1655 rl_forward_char (1, key
);
1672 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1676 pos
= _rl_find_prev_mbchar (rl_line_buffer
, pos
, MB_FIND_ANY
);
1682 int b
= rl_vi_bracktype (rl_line_buffer
[pos
]);
1685 else if (b
== brack
)
1699 if (MB_CUR_MAX
== 1 || rl_byte_oriented
)
1702 pos
= _rl_find_next_mbchar (rl_line_buffer
, pos
, 1, MB_FIND_ANY
);
1706 int b
= rl_vi_bracktype (rl_line_buffer
[pos
]);
1709 else if (b
== brack
)
1730 case ')': return -1;
1732 case ']': return -2;
1734 case '}': return -3;
1740 _rl_vi_change_char (count
, c
, mb
)
1746 if (c
== '\033' || c
== CTRL ('C'))
1749 rl_begin_undo_group ();
1750 while (count
-- && rl_point
< rl_end
)
1753 rl_vi_delete (1, c
);
1754 if (rl_point
< p
) /* Did we retreat at EOL? */
1756 #if defined (HANDLE_MULTIBYTE)
1757 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1758 rl_insert_text (mb
);
1761 _rl_insert_char (1, c
);
1764 /* The cursor shall be left on the last character changed. */
1765 rl_backward_char (1, c
);
1767 rl_end_undo_group ();
1773 _rl_vi_callback_getchar (mb
, mlen
)
1779 RL_SETSTATE(RL_STATE_MOREINPUT
);
1781 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1786 #if defined (HANDLE_MULTIBYTE)
1787 if (MB_CUR_MAX
> 1 && rl_byte_oriented
== 0)
1788 c
= _rl_read_mbstring (c
, mb
, mlen
);
1794 #if defined (READLINE_CALLBACKS)
1796 _rl_vi_callback_change_char (data
)
1797 _rl_callback_generic_arg
*data
;
1800 char mb
[MB_LEN_MAX
];
1802 _rl_vi_last_replacement
= c
= _rl_vi_callback_getchar (mb
, MB_LEN_MAX
);
1807 _rl_callback_func
= 0;
1808 _rl_want_redisplay
= 1;
1810 return (_rl_vi_change_char (data
->count
, c
, mb
));
1815 rl_vi_change_char (count
, key
)
1819 char mb
[MB_LEN_MAX
];
1823 c
= _rl_vi_last_replacement
;
1827 #if defined (READLINE_CALLBACKS)
1828 else if (RL_ISSTATE (RL_STATE_CALLBACK
))
1830 _rl_callback_data
= _rl_callback_data_alloc (count
);
1831 _rl_callback_func
= _rl_vi_callback_change_char
;
1836 _rl_vi_last_replacement
= c
= _rl_vi_callback_getchar (mb
, MB_LEN_MAX
);
1841 return (_rl_vi_change_char (count
, c
, mb
));
1845 rl_vi_subst (count
, key
)
1848 /* If we are redoing, rl_vi_change_to will stuff the last motion char */
1849 if (vi_redoing
== 0)
1850 rl_stuff_char ((key
== 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
1852 return (rl_vi_change_to (count
, 'c'));
1856 rl_vi_overstrike (count
, key
)
1859 if (_rl_vi_doing_insert
== 0)
1861 _rl_vi_doing_insert
= 1;
1862 rl_begin_undo_group ();
1867 _rl_overwrite_char (count
, key
);
1868 vi_replace_count
+= count
;
1875 rl_vi_overstrike_delete (count
, key
)
1880 for (i
= 0; i
< count
; i
++)
1882 if (vi_replace_count
== 0)
1893 rl_backward_char (1, key
);
1896 if (vi_replace_count
== 0 && _rl_vi_doing_insert
)
1898 rl_end_undo_group ();
1900 _rl_vi_doing_insert
= 0;
1906 rl_vi_replace (count
, key
)
1911 vi_replace_count
= 0;
1913 if (!vi_replace_map
)
1915 vi_replace_map
= rl_make_bare_keymap ();
1917 for (i
= ' '; i
< KEYMAP_SIZE
; i
++)
1918 vi_replace_map
[i
].function
= rl_vi_overstrike
;
1920 vi_replace_map
[RUBOUT
].function
= rl_vi_overstrike_delete
;
1921 vi_replace_map
[ESC
].function
= rl_vi_movement_mode
;
1922 vi_replace_map
[RETURN
].function
= rl_newline
;
1923 vi_replace_map
[NEWLINE
].function
= rl_newline
;
1925 /* If the normal vi insertion keymap has ^H bound to erase, do the
1926 same here. Probably should remove the assignment to RUBOUT up
1927 there, but I don't think it will make a difference in real life. */
1928 if (vi_insertion_keymap
[CTRL ('H')].type
== ISFUNC
&&
1929 vi_insertion_keymap
[CTRL ('H')].function
== rl_rubout
)
1930 vi_replace_map
[CTRL ('H')].function
= rl_vi_overstrike_delete
;
1933 _rl_keymap
= vi_replace_map
;
1938 /* Try to complete the word we are standing on or the word that ends with
1939 the previous character. A space matches everything. Word delimiters are
1942 rl_vi_possible_completions()
1944 int save_pos
= rl_point
;
1946 if (rl_line_buffer
[rl_point
] != ' ' && rl_line_buffer
[rl_point
] != ';')
1948 while (rl_point
< rl_end
&& rl_line_buffer
[rl_point
] != ' ' &&
1949 rl_line_buffer
[rl_point
] != ';')
1952 else if (rl_line_buffer
[rl_point
- 1] == ';')
1958 rl_possible_completions ();
1959 rl_point
= save_pos
;
1965 /* Functions to save and restore marks. */
1971 RL_SETSTATE(RL_STATE_MOREINPUT
);
1972 ch
= rl_read_key ();
1973 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
1975 if (ch
< 0 || ch
< 'a' || ch
> 'z') /* make test against 0 explicit */
1981 vi_mark_chars
[ch
] = rl_point
;
1985 #if defined (READLINE_CALLBACKS)
1987 _rl_vi_callback_set_mark (data
)
1988 _rl_callback_generic_arg
*data
;
1990 _rl_callback_func
= 0;
1991 _rl_want_redisplay
= 1;
1993 return (_rl_vi_set_mark ());
1998 rl_vi_set_mark (count
, key
)
2001 #if defined (READLINE_CALLBACKS)
2002 if (RL_ISSTATE (RL_STATE_CALLBACK
))
2004 _rl_callback_data
= 0;
2005 _rl_callback_func
= _rl_vi_callback_set_mark
;
2010 return (_rl_vi_set_mark ());
2018 RL_SETSTATE(RL_STATE_MOREINPUT
);
2019 ch
= rl_read_key ();
2020 RL_UNSETSTATE(RL_STATE_MOREINPUT
);
2027 else if (ch
< 0 || ch
< 'a' || ch
> 'z') /* make test against 0 explicit */
2034 if (vi_mark_chars
[ch
] == -1)
2039 rl_point
= vi_mark_chars
[ch
];
2043 #if defined (READLINE_CALLBACKS)
2045 _rl_vi_callback_goto_mark (data
)
2046 _rl_callback_generic_arg
*data
;
2048 _rl_callback_func
= 0;
2049 _rl_want_redisplay
= 1;
2051 return (_rl_vi_goto_mark ());
2056 rl_vi_goto_mark (count
, key
)
2059 #if defined (READLINE_CALLBACKS)
2060 if (RL_ISSTATE (RL_STATE_CALLBACK
))
2062 _rl_callback_data
= 0;
2063 _rl_callback_func
= _rl_vi_callback_goto_mark
;
2068 return (_rl_vi_goto_mark ());
2070 #endif /* VI_MODE */