bug-readline
[Top][All Lists]
Advanced

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

[Bug-readline] make ';' after 't' work in vi-mode


From: Richard Todd
Subject: [Bug-readline] make ';' after 't' work in vi-mode
Date: Wed, 26 Sep 2018 20:36:48 +0000

Hi all,

I noticed in vi-mode, if you search with 't'/'T', then readline
gets stuck on ';' (because the next letter already matches).  So,
from the start of this paragraph, I would expect 'te;' to take me
to the 'd' in the word "vi-mode", rut readline gets stuck on the
'c' in "noticed" instead.

The following small patch (against git devel) addresses the
issue for me. Since I'm not familiar with readline source, I
tried to make it as local to the vi-mode char search as possible.
I defined a short function, _rl_vi_nextchar_is(), to tell if we
are looking at the character we are about to search for. Then,
I used it in rl_vi_char_search() to increment the count on ';' and
',' repeat searches when we are both FTO/BTO and already staring
at the character in question.

I think this (or something like it) improves vi-compatibility
slightly, and offer it as a suggestion.


diff --git a/vi_mode.c b/vi_mode.c
index d6fa38e..5ada7c8 100644
--- a/vi_mode.c
+++ b/vi_mode.c
@@ -1768,6 +1768,25 @@ _rl_vi_callback_char_search (_rl_callback_generic_arg 
*data)
 }
 #endif
 
+#if defined (HANDLE_MULTIBYTE)
+static int
+_rl_vi_nextchar_is(int dir, char *smbchar, int len)
+#else
+_rl_vi_nextchar_is(int dir, char schar)
+#endif
+{
+  int pos = rl_point;
+
+#if defined (HANDLE_MULTIBYTE)
+  pos = (dir > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
+                  : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
+  return _rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len);
+#else
+  pos += (dir < 0) ? -1 : 1;
+  return rl_line_buffer[pos] == schar;
+#endif
+}
+
 int
 rl_vi_char_search (int count, int key)
 {
@@ -1791,6 +1810,16 @@ rl_vi_char_search (int count, int key)
        return 1;
 #endif
       _rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
+
+#if defined (HANDLE_MULTIBYTE)
+      if ((_rl_cs_dir == FTO || _rl_cs_dir == BTO) &&
+          _rl_vi_nextchar_is (_rl_cs_dir, _rl_vi_last_search_mbchar, 
_rl_vi_last_search_mblen))
+       ++count;
+#else
+      if ((_rl_cs_dir == FTO || _rl_cs_dir == BTO) &&
+          rl_vi_nextchar_is (_rl_cs_dir, _rl_vi_last_search_char))
+       ++count;
+#endif
     }
   else
     {



reply via email to

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