[Top][All Lists]

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

redraw-current-line fails with multiline prompts

From: Hugh Davenport
Subject: redraw-current-line fails with multiline prompts
Date: Fri, 12 Feb 2016 05:45:56 +0000


Not sure this got through from my laptop as I couldn't get it to send using the 
bashbug utility.



Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
-DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib  -D_FORTIFY_SOURCE=2 -g 
-O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall
uname output: Linux laptop 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u2 
(2016-01-02) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.3
Patch Level: 30
Release Status: release

        Assume I have a multiline prompt (`PS1="first\nsecond"`), and a bind to
        redraw-current-line (`bind '"\er": redraw-current-line'`). When I
        refresh the line with M-r, I get the following output:

        What is happening is that the redraw-current-line is assuming that I
        only have a single line prompt, and is just redrawing that current
        line. Two possible solutions to this are:
          1) Work out the last line of the prompt and only redraw that (makes
                sense with function name, or
          2) Work out number of lines in the prompt, and redraw entire prompt.

        Have a rc file with the following
        bind '"\er": redraw-current-line'

        Then start bash with that rc file, and hit M-r a few times, notice that
        the last line gets overwritten, but the first line doesn't. You can
        expand this by having PS="first\nsecond\nthird" and seeing that the
        third line gets overwritten, but not the first and the second. This
        leads to a lot of wasted vertical space if you are redrawing often.

        I've got a patch for option 2, which works well with existing methods,
        but makes the function name a bit misleading.

index f29adf8..183aea4 100644
--- a/lib/readline/text.c
+++ b/lib/readline/text.c
@@ -562,8 +562,14 @@ rl_refresh_line (ignore1, ignore2)
      int ignore1, ignore2;
   int curr_line;
+  int newlines;
+  char *s;
   curr_line = _rl_current_display_line ();
+  /* Detect any new lines on current prompt */
+  for (newlines = 0, s = rl_prompt; s[newlines]; s[newlines] == '\n' ? 
newlines++ : *s++);
+  /* Shift up current line by number of new lines */
+  curr_line -= newlines;
   _rl_move_vert (curr_line);
   _rl_move_cursor_relative (0, rl_line_buffer);   /* XXX is this right */

reply via email to

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