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); } _______________________________________________ Bug-readline mailing list Bug-readline@gnu.org https://lists.gnu.org/mailman/listinfo/bug-readline