[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
prompt with \[ \] corrupted by vi history search
From: |
Mike Stroyan |
Subject: |
prompt with \[ \] corrupted by vi history search |
Date: |
Fri, 3 Feb 2006 12:16:07 -0700 |
User-agent: |
Mutt/1.5.9i |
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../bash -I../bash/include -I../bash/lib -g -O2
uname output: Linux hpstryn6 2.6.12-1-amd64-k8-smp #1 SMP Wed Sep 28 02:57:49
CEST 2005 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 3.1
Patch Level: 0
Release Status: release
Description:
The prompt is corrupted when using the vi Esc/ history search.
This happens when the prompt contains non-printing characters
marked by the \[ \] delimiters.
Repeat-By:
Set the PS1 prompt to a string containing non-printing
characters marked by \[ and \]. Use "set -o vi".
Type Esc/ to start a history search. The prompt will
be partially overwritten or printed with junk characters
after the prompt. In this captured example there are
junk characters covered up by backspaces. Longer prompts
tend to leave visible junk characters.
bash-3.1$ LANG=C bash-3.1/build-bash/bash --norc^M$
bash-3.1$ PS1="\[$(tput setf 2)\]\$\[$(tput sgr0)\] "^M$
^[[32m$^[[m^[(B ^[[Kset -o vi^M$
^[[32m$^[[m^[(B echo sample^M$
sample^M$
^[[32m$^[[m^[(B /^@ho sampl^@s^H^H^H^H^H^H^H^H^H^H^Hec^H^H^H^[[3Pecho
sample^H^H^H^H^H^H^H^H^H^H^H^M$
sample^M$
^[[32m$^[[m^[(B exit^M$
exit^M$
bash-3.1$ LANG=C bash-3.1-fix/build-bash/bash --norc^M$
bash-3.1$ PS1="\[$(tput setf 2)\]\$\[$(tput sgr0)\] "^M$
^[[32m$^[[m^[(B ^[[Kset -o vi^M$
^[[32m$^[[m^[(B echo sample^M$
sample^M$
^[[32m$^[[m^[(B /ec^H^H^Hecho sample^H^H^H^H^H^H^H^H^H^H^H^M$
sample^M$
^[[32m$^[[m^[(B exit^M$
exit^M$
Fix:
The best fix seems to be in _rl_make_prompt_for_search in
bash/lib/readline/display.c
_rl_nsearch_init does
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message (p, 0, 0);
_rl_make_prompt_for_search calls rl_save_prompt and then tests for
a non-null saved_local_prompt, which rl_save_prompt just set.
_rl_make_prompt_for_search returns a string based on the value
of local_prompt which rl_save_prompt just copied.
When _rl_nsearch_init passes that string to rl_message it does
some formatting with it into msg_buf and does
local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
The result is that expand_prompt is done twice on the prompt.
The second time around the string is missing the \[ ]\ sequences
that mark non-printing characters. The printing and non-printing
character counts become bad.
Everything behaves better if _rl_make_prompt_for_search just uses the
unexpanded rl_prompt string for composing its result. Here is a patch
that comments out the troublesome code.
# fix display of history search prompt with non-printing chars in vi edit mode
--- bash/lib/readline/display.c~ 2005-09-16 23:35:04.000000000 -0600
+++ bash/lib/readline/display.c 2005-09-16 23:43:19.000000000 -0600
@@ -1950,7 +1950,14 @@
rl_save_prompt ();
+#if 0
+ /* The rl_prompt should always be used so it has the non-printing
+ * character sequence marks in it. The local_prompt does not have
+ * them. This string is passed into rl_message, which passes it
+ * into expand_prompt.
+ */
if (saved_local_prompt == 0)
+#endif
{
len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
pmt = (char *)xmalloc (len + 2);
@@ -1959,6 +1966,7 @@
pmt[len] = pchar;
pmt[len+1] = '\0';
}
+#if 0
else
{
len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
@@ -1971,6 +1979,7 @@
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length + 1;
}
+#endif
return pmt;
}
- prompt with \[ \] corrupted by vi history search,
Mike Stroyan <=