bug-readline
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-readline] vi-mode: allow [count] on i/I/a/A commands


From: Richard Todd
Subject: [Bug-readline] vi-mode: allow [count] on i/I/a/A commands
Date: Mon, 1 Oct 2018 05:55:12 +0000

Hi all, this is the last patch I intend to submit at present, as
vi-mode now works for my purposes.  If a `vi-extensions` option opens
up, I may code up some vim features and submit them.

POSIX vi lets you say:

    5ihello <esc> ==> hello hello hello hello hello  

... and similar for I, a, and A commands.  Giving the `.' command
after this will get me 5 more hello's.  Further, if I then issue

    3.

... it will insert 3 hello's instead of 5, and remember to insert
only three on future `.' commands.

The following patch adds this capability to readline.  I submit it for
your consideration.

(FYI The adjustments of the undo groups in this patch also fixes a
vi-mode bug:

    a1<esc>a2<esc>. ==> 122  (correct vi behavior)
    a1<esc>a2<esc>. ==> 1212 (current readline behavior)

... readline was concatenating the inputs for undo purposes, so that
the `.' adds 12 instead of just repeating the last `a' command as it
should.)


diff --git a/vi_mode.c b/vi_mode.c
index d6fa38e..56de25b 100644
--- a/vi_mode.c
+++ b/vi_mode.c
@@ -198,6 +198,7 @@ void
 rl_vi_start_inserting (int key, int repeat, int sign)
 {
   _rl_vi_set_last (key, repeat, sign);
+  rl_begin_undo_group ();
   rl_vi_insertion_mode (1, key);
 }
 
@@ -248,9 +249,14 @@ rl_vi_redo (int count, int c)
 
   if (rl_explicit_arg == 0)
     {
-      rl_numeric_arg = _rl_vi_last_repeat;
+      count = rl_numeric_arg = _rl_vi_last_repeat;
       rl_arg_sign = _rl_vi_last_arg_sign;
     }
+  else
+    {
+      rl_numeric_arg = _rl_vi_last_repeat = (count >= 0) ? count : -count;
+      rl_arg_sign = _rl_vi_last_arg_sign = (count >= 0) ? 1 : -1;
+    }
 
   r = 0;
   _rl_vi_redoing = 1;
@@ -749,7 +755,7 @@ int
 rl_vi_insert_beg (int count, int key)
 {
   rl_beg_of_line (1, key);
-  rl_vi_insert_mode (1, key);
+  rl_vi_insert_mode (count, key);
   return (0);
 }
 
@@ -763,7 +769,7 @@ int
 rl_vi_append_mode (int count, int key)
 {
   _rl_vi_append_forward (key);
-  rl_vi_start_inserting (key, 1, rl_arg_sign);
+  rl_vi_start_inserting (key, count, rl_arg_sign);
   return (0);
 }
 
@@ -771,7 +777,7 @@ int
 rl_vi_append_eol (int count, int key)
 {
   rl_end_of_line (1, key);
-  rl_vi_append_mode (1, key);
+  rl_vi_append_mode (count, key);
   return (0);
 }
 
@@ -799,7 +805,7 @@ rl_vi_insertion_mode (int count, int key)
 int
 rl_vi_insert_mode (int count, int key)
 {
-  rl_vi_start_inserting (key, 1, rl_arg_sign);
+  rl_vi_start_inserting (key, count, rl_arg_sign);
   return (0);
 }
 
@@ -883,7 +889,16 @@ _rl_vi_done_inserting (void)
                           _rl_vi_last_key_before_insert == 'a' ||
                           _rl_vi_last_key_before_insert == 'I' ||
                           _rl_vi_last_key_before_insert == 'A'))
-       _rl_vi_save_insert (rl_undo_list);
+       {
+         _rl_vi_save_insert (rl_undo_list);
+          if (_rl_vi_last_repeat > 1)
+           {
+             if (_rl_vi_last_key_before_insert == 'i')
+               _rl_vi_advance_point ();
+             rl_explicit_arg = 1;
+             rl_vi_redo (_rl_vi_last_repeat - 1, '.');
+           }
+       }
       /* XXX - Other keys probably need to be checked. */
       else if (_rl_vi_last_key_before_insert == 'C')
        rl_end_undo_group ();



reply via email to

[Prev in Thread] Current Thread [Next in Thread]