#190350: vi mode glitch Whenever you do some non-inserting edit command, like 'x' or 'd', that becomes the command-to-repeat and no further insertions may be repeated. 1. Start a new bash shell 2. 'set -o vi' 2. Type 'kekepophxi\.' 3. You end up with 'kekepp' instead of 'kekep\\p'. This patch fixes it and tries to fix redoing the 'I' command as well. I'm not sure about 'c', though. Signed-off-by: Tomas Janousek --- lib/readline/misc.c | 2 +- lib/readline/readline.c | 2 +- lib/readline/readline.h | 1 + lib/readline/vi_keymap.c | 2 +- lib/readline/vi_mode.c | 21 +++++++++++++++++++-- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/lib/readline/misc.c b/lib/readline/misc.c index e9c72c5..35d6348 100644 --- a/lib/readline/misc.c +++ b/lib/readline/misc.c @@ -560,7 +560,7 @@ rl_vi_editing_mode (count, key) #if defined (VI_MODE) _rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */ rl_editing_mode = vi_mode; - rl_vi_insertion_mode (1, key); + rl_vi_insert_mode (1, key); #endif /* VI_MODE */ return 0; diff --git a/lib/readline/readline.c b/lib/readline/readline.c index bd4d263..4b3d91b 100644 --- a/lib/readline/readline.c +++ b/lib/readline/readline.c @@ -370,7 +370,7 @@ readline_internal_setup () #if defined (VI_MODE) if (rl_editing_mode == vi_mode) - rl_vi_insertion_mode (1, 'i'); + rl_vi_insert_mode (1, 'i'); #endif /* VI_MODE */ if (rl_pre_input_hook) diff --git a/lib/readline/readline.h b/lib/readline/readline.h index b71bf98..8527ebf 100644 --- a/lib/readline/readline.h +++ b/lib/readline/readline.h @@ -230,6 +230,7 @@ extern int rl_vi_next_word PARAMS((int, int)); extern int rl_vi_end_word PARAMS((int, int)); extern int rl_vi_insert_beg PARAMS((int, int)); extern int rl_vi_append_mode PARAMS((int, int)); +extern int rl_vi_insert_mode PARAMS((int, int)); extern int rl_vi_append_eol PARAMS((int, int)); extern int rl_vi_eof_maybe PARAMS((int, int)); extern int rl_vi_insertion_mode PARAMS((int, int)); diff --git a/lib/readline/vi_keymap.c b/lib/readline/vi_keymap.c index 4b48c75..3a017cc 100644 --- a/lib/readline/vi_keymap.c +++ b/lib/readline/vi_keymap.c @@ -151,7 +151,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = { { ISFUNC, rl_vi_char_search }, /* f */ { ISFUNC, (rl_command_func_t *)0x0 }, /* g */ { ISFUNC, rl_backward_char }, /* h */ - { ISFUNC, rl_vi_insertion_mode }, /* i */ + { ISFUNC, rl_vi_insert_mode }, /* i */ { ISFUNC, rl_get_next_history }, /* j */ { ISFUNC, rl_get_previous_history }, /* k */ { ISFUNC, rl_forward_char }, /* l */ diff --git a/lib/readline/vi_mode.c b/lib/readline/vi_mode.c index b0da0ab..e859062 100644 --- a/lib/readline/vi_mode.c +++ b/lib/readline/vi_mode.c @@ -220,6 +220,15 @@ rl_vi_redo (count, c) if (rl_point > 0) _rl_vi_backup (); } + /* Ditto for redoing an insert with `I', but move to the beginning of line + like the `I' command does. */ + else if (_rl_vi_last_command == 'I' && vi_insert_buffer && *vi_insert_buffer) + { + rl_beg_of_line (1, 'I'); + _rl_vi_stuff_insert (count); + if (rl_point > 0) + _rl_vi_backup (); + } else r = _rl_dispatch (_rl_vi_last_command, _rl_keymap); vi_redoing = 0; @@ -584,7 +593,7 @@ rl_vi_insert_beg (count, key) int count, key; { rl_beg_of_line (1, key); - rl_vi_insertion_mode (1, key); + rl_vi_insert_mode (1, key); return (0); } @@ -618,6 +627,14 @@ rl_vi_append_mode (count, key) } int +rl_vi_insert_mode (count, key) + int count, key; +{ + rl_vi_start_inserting (key, 1, rl_arg_sign); + return (0); +} + +int rl_vi_append_eol (count, key) int count, key; { @@ -690,7 +707,7 @@ _rl_vi_done_inserting () } else { - if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list) + if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a' || _rl_vi_last_key_before_insert == 'I') && rl_undo_list) _rl_vi_save_insert (rl_undo_list); /* XXX - Other keys probably need to be checked. */ else if (_rl_vi_last_key_before_insert == 'C') -- 1.5.3.7 -- Tomas Janousek, SW Engineer, Red Hat, Inc.