bug-readline
[Top][All Lists]
Advanced

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

[Bug-readline] (arg: x) prompt shifts the line


From: Richard Todd
Subject: [Bug-readline] (arg: x) prompt shifts the line
Date: Sun, 30 Sep 2018 07:19:24 +0000

Especially when using vi-mode, I use numeric arguments a lot, and it's
jarring to see the line I'm trying to work on shift around as I type:

    /usr/local/bin $ line I'm working on
    (arg: 1) line I'm working on
    (arg: 10) line I'm working on
    /usr/local/bin $ line I'm working on

If I type something like '10l' really fast, the line jumping arround 
just looks wrong.

I'm not used to having visual feedback when I use numeric args in
vim, so I wonder if a setting to stop calling rl_message() for numeric
args would be useful specifically for vi-mode?  Has anyone else ever
complained about this?

Here's an alternate idea I played with tonight. The following patch attacks
the issue in two ways:

  1) Changes the format string to (args %3d), so that at least you only get
     one shift of the line for up to 3-digits, which is pretty much every
     case.
  2) Pads the rl_message() prompt with spaces if it is shorter than the 
     `saved_visible_length' from the original prompt.

So if your prompt is short you still have to see it shift once, but if it
is long enough it will look like this:

    /usr/local/bin $ line I'm working on
    (arg:   1)       line I'm working on
    (arg:  10)       line I'm working on
    /usr/local/bin $ line I'm working on

Maybe a silent setting for vi-mode is would be my favorite, but I thought 
I'd throw this out in case it was interesting.  (the patch makes the 
change look more significant than it really is because I had to move the 
prompt saving logic up in the function a little, and also have to
change various paths depending on VA_ARGS and VSNPRINTF #ifdefs).


diff --git a/display.c b/display.c
index b2ed115..5ab32f4 100644
--- a/display.c
+++ b/display.c
@@ -2625,6 +2625,20 @@ rl_message (va_alist)
 #if defined (HAVE_VSNPRINTF)
   int bneed;
 #endif
+  int msg_buf_len;
+  int msg_target_len;
+
+  if (saved_local_prompt == 0)
+    {
+      rl_save_prompt ();
+      msg_saved_prompt = 1;
+    }
+  else if (local_prompt != saved_local_prompt)
+    {
+      FREE (local_prompt);
+      FREE (local_prompt_prefix);
+      local_prompt = (char *)NULL;
+    }
 
 #if defined (PREFER_STDARG)
   va_start (args, format);
@@ -2637,7 +2651,9 @@ rl_message (va_alist)
     msg_buf = xmalloc (msg_bufsiz = 128);
 
 #if defined (HAVE_VSNPRINTF)
-  bneed = vsnprintf (msg_buf, msg_bufsiz, format, args);
+  bneed = msg_buf_len = vsnprintf (msg_buf, msg_bufsiz, format, args);
+  if (bneed < saved_visible_length)
+    bneed = saved_visible_length;
   if (bneed >= msg_bufsiz - 1)
     {
       msg_bufsiz = bneed + 1;
@@ -2653,22 +2669,18 @@ rl_message (va_alist)
       vsnprintf (msg_buf, msg_bufsiz - 1, format, args);
     }
 #else
-  vsprintf (msg_buf, format, args);
+  msg_buf_len = vsprintf (msg_buf, format, args);
   msg_buf[msg_bufsiz - 1] = '\0';      /* overflow? */
 #endif
   va_end (args);
 
-  if (saved_local_prompt == 0)
-    {
-      rl_save_prompt ();
-      msg_saved_prompt = 1;
-    }
-  else if (local_prompt != saved_local_prompt)
-    {
-      FREE (local_prompt);
-      FREE (local_prompt_prefix);
-      local_prompt = (char *)NULL;
-    }
+  msg_target_len = (saved_visible_length < msg_bufsiz)
+                 ? saved_visible_length : msg_bufsiz - 1;
+
+  while (msg_buf_len < msg_target_len)
+    msg_buf[msg_buf_len++] = ' ';
+  msg_buf[msg_buf_len] = '\0'; /* overflow? */
+
   rl_display_prompt = msg_buf;
   local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
                                            &prompt_last_invisible,
@@ -2685,13 +2697,9 @@ int
 rl_message (format, arg1, arg2)
      char *format;
 {
-  if (msg_buf == 0)
-    msg_buf = xmalloc (msg_bufsiz = 128);
-
-  sprintf (msg_buf, format, arg1, arg2);
-  msg_buf[msg_bufsiz - 1] = '\0';      /* overflow? */
+  int msg_buf_len;
+  int msg_target_len;
 
-  rl_display_prompt = msg_buf;
   if (saved_local_prompt == 0)
     {
       rl_save_prompt ();
@@ -2703,6 +2711,19 @@ rl_message (format, arg1, arg2)
       FREE (local_prompt_prefix);
       local_prompt = (char *)NULL;
     }
+
+  if (msg_buf == 0)
+    msg_buf = xmalloc (msg_bufsiz = 128);
+
+  msg_target_len = (saved_visible_length < msg_bufsiz)
+                 ? saved_visible_length : msg_bufsiz - 1;
+
+  msg_buf_len = sprintf (msg_buf, format, arg1, arg2);
+  while (msg_buf_len < msg_target_len)
+    msg_buf[msg_buf_len++] = ' ';
+  msg_buf[msg_buf_len] = '\0'; /* overflow? */
+
+  rl_display_prompt = msg_buf;
   local_prompt = expand_prompt (msg_buf, 0, &prompt_visible_length,
                                            &prompt_last_invisible,
                                            &prompt_invis_chars_first_line,
diff --git a/misc.c b/misc.c
index 64b1457..6dda61d 100644
--- a/misc.c
+++ b/misc.c
@@ -53,6 +53,8 @@
 #include "rlshell.h"
 #include "xmalloc.h"
 
+#define ARG_FMT "(arg: %3d) "
+
 static int rl_digit_loop PARAMS((void));
 static void _rl_history_set_point PARAMS((void));
 
@@ -104,7 +106,7 @@ _rl_arg_getchar (void)
 {
   int c;
 
-  rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
+  rl_message (ARG_FMT, rl_arg_sign * rl_numeric_arg);
   RL_SETSTATE(RL_STATE_MOREINPUT);
   c = rl_read_key ();
   RL_UNSETSTATE(RL_STATE_MOREINPUT);
@@ -233,7 +235,7 @@ rl_digit_argument (int ignore, int key)
   if (RL_ISSTATE (RL_STATE_CALLBACK))
     {
       _rl_arg_dispatch (_rl_argcxt, key);
-      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
+      rl_message (ARG_FMT, rl_arg_sign * rl_numeric_arg);
       return 0;
     }
   else
@@ -276,7 +278,7 @@ _rl_arg_callback (_rl_arg_cxt cxt)
 
   r = _rl_arg_dispatch (cxt, c);
   if (r > 0)
-    rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
+    rl_message (ARG_FMT, rl_arg_sign * rl_numeric_arg);
   return (r != 1);
 }
 




reply via email to

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