bug-readline
[Top][All Lists]
Advanced

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

[Bug-readline] vi motion command glitches


From: Wolfgang Jenkner
Subject: [Bug-readline] vi motion command glitches
Date: Wed, 27 Dec 2006 16:49:04 +0100
User-agent: Heirloom mailx 12.1 6/15/06

(I use readline-5.2 with readline52-001 on Linux 2.6.13.2 i686.)

In vi mode, the text regions affected by some of the motion commands
seem to be off-by-one (though the cursor positions are correct).

E.g., type xyz, escape to vi command mode, which moves the cursor over
the z; now typing dFx deletes the whole word.

However, Nvi [1] and Traditional vi [2] do not delete z (despite their
online availability I dare not refer to the Open Group Base Specifications
since the legal implications are not clear to me; instead I use these
implementations for reference).

[1] http://www.bostic.com/vi/
[2] http://ex-vi.sourceforge.net

Similarly, each of "`FT" or backwards moving ";," obeys the standard rule,
here cited from the vi.ref which comes with Nvi, that

        (...) the  region  affected by the command is from the starting
        or stopping cursor position which comes  first in  the  file,
        to  immediately  before the starting or stopping cursor position
        which comes later in the file.

On the other hand, the region affected by '%' always includes both of
the matching characters (though the stopping cursor position is over
one of those matching characters).

I suggest the following patch, which (in the first hunk) also makes sure
that the backquote is recognised as a motion command in combination with
c,d or y (e.g., type xyz, escape to vi command mode; typing mabd`a should
delete xy and leave z).

diff -cpr ../readline-5.2/vi_mode.c ./vi_mode.c
*** ../readline-5.2/vi_mode.c   Sat Jul 29 22:42:28 2006
--- ./vi_mode.c Wed Dec 27 00:52:49 2006
*************** int _rl_vi_last_command = 'i';  /* defaul
*** 69,75 ****
  static int _rl_vi_doing_insert;
  
  /* Command keys which do movement for xxx_to commands. */
! static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
  
  /* Keymap used for vi replace characters.  Created dynamically since
     rarely used. */
--- 69,75 ----
  static int _rl_vi_doing_insert;
  
  /* Command keys which do movement for xxx_to commands. */
! static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|`";
  
  /* Keymap used for vi replace characters.  Created dynamically since
     rarely used. */
*************** int
*** 1033,1045 ****
  rl_vi_delete_to (count, key)
       int count, key;
  {
!   int c;
  
    if (_rl_uppercase_p (key))
      rl_stuff_char ('$');
    else if (vi_redoing)
      rl_stuff_char (_rl_vi_last_motion);
  
    if (rl_vi_domove (key, &c))
      {
        rl_ding ();
--- 1033,1047 ----
  rl_vi_delete_to (count, key)
       int count, key;
  {
!   int c, start_pos;
  
    if (_rl_uppercase_p (key))
      rl_stuff_char ('$');
    else if (vi_redoing)
      rl_stuff_char (_rl_vi_last_motion);
  
+   start_pos = rl_point;
+ 
    if (rl_vi_domove (key, &c))
      {
        rl_ding ();
*************** rl_vi_delete_to (count, key)
*** 1048,1054 ****
  
    /* These are the motion commands that do not require adjusting the
       mark. */
!   if ((strchr (" l|h^0bB", c) == 0) && (rl_mark < rl_end))
      rl_mark++;
  
    rl_kill_text (rl_point, rl_mark);
--- 1050,1058 ----
  
    /* These are the motion commands that do not require adjusting the
       mark. */
!   if (!(strchr (" l|h^0bBFT`", c) ||
!       ((c == ';' || c == ',') && rl_point < start_pos)) &&
!       (rl_mark < rl_end))
      rl_mark++;
  
    rl_kill_text (rl_point, rl_mark);
*************** rl_vi_change_to (count, key)
*** 1077,1083 ****
    /* These are the motion commands that do not require adjusting the
       mark.  c[wW] are handled by special-case code in rl_vi_domove(),
       and already leave the mark at the correct location. */
!   if ((strchr (" l|hwW^0bB", c) == 0) && (rl_mark < rl_end))
      rl_mark++;
  
    /* The cursor never moves with c[wW]. */
--- 1081,1089 ----
    /* These are the motion commands that do not require adjusting the
       mark.  c[wW] are handled by special-case code in rl_vi_domove(),
       and already leave the mark at the correct location. */
!   if (!(strchr (" l|hwW^0bBFT`", c) ||
!       ((c == ';' || c == ',') && rl_point < start_pos)) &&
!       (rl_mark < rl_end))
      rl_mark++;
  
    /* The cursor never moves with c[wW]. */
*************** rl_vi_yank_to (count, key)
*** 1126,1132 ****
  
    /* These are the motion commands that do not require adjusting the
       mark. */
!   if ((strchr (" l|h^0%bB", c) == 0) && (rl_mark < rl_end))
      rl_mark++;
  
    rl_begin_undo_group ();
--- 1132,1140 ----
  
    /* These are the motion commands that do not require adjusting the
       mark. */
!   if (!(strchr (" l|h^0bBFT`", c) ||
!       ((c == ';' || c == ',') && rl_point < save)) &&
!       (rl_mark < rl_end))
      rl_mark++;
  
    rl_begin_undo_group ();




reply via email to

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