Thread View: gnu.bash.bug
4 messages
4 total messages
Started by john
Sun, 06 Sep 1992 00:53
"Philosophical" bug: Bash needs an "invisiblity" sequence inside PS1
Author: john
Date: Sun, 06 Sep 1992 00:53
Date: Sun, 06 Sep 1992 00:53
285 lines
8580 bytes
8580 bytes
I use GNU Bash, version 1.12.9, and the terminal program I use is Stuart
2.4 on a NeXT, which has title-bar-setting escape sequences that are a
superset of those understood by Xterm. A problem I was experiencing was
that the Readline library used by Bash doesn't know what part of the prompt
is actually visible. So, if I have a big, nasty PS1 variable that puts
lots of things in the title bar, Readline decides I've hit the 80th column
and breaks the line way too early. (About the 15th character, with my
current PS1 setting.) Things just get worse when you start doing cursor
motion commands, redraws, etc.
Very bad.
I thought of a reasonably simple fix. Introduce two new sequences into
the PS[124] variables: "\i" to say that the following characters are
invisible and shouldn't get put into the prompt that Readline knows
about, and (naturally) "\I" to turn off invisibility for the following
characters. Now, a PS1 sequence to set the titlebar for an Xterm (or
a Stuart, in my case) might be
PS1="\i^[]0;\u@\h:\w^G\I% '
I had originally planned just to send in a whiney message complaining
about this and sit around and wait until somebody did something, but
I figured I'd like this feature right away, and besides, you probably
wouldn't stick this feature in future versions anyway ... :-) So, a
little diddling around produced the following apparently-operational
diff.
The code works like this: it introduces a global variable called
invisible_readline_prompt that is effectively a second return value
from decode_prompt_string(). When prompt_again() calls
decode_prompt_string(), it prints invisible_readline_prompt to stderr.
decode_prompt_string() was modified to have two states. One state is
the "invisible" state, and the other is the "visible" state. In the
visible state, operation is as it was before. The string result is
built up a little bit at a time. However, the sequences \i and \I
switch to/from the invisible state, and in the invisible state, the
little chunks get added to a new local variable called invisible_result
(use of invisible_result was a cut 'n' paste from the code that dealt
with result). When the function is done, it copies invisible_result
out to invisible_readline_prompt.
I wouldn't say this was the greatest implementation in the world, but
it was quick and easy, and I think the \i and \I are easy to use. (And
probably won't break existing code.) Feel free (of course) to throw
this code out and do it like it should have been done. But please --
put SOMETHING like this in the next Bash. The problem with invisible
prompt characters messing up the line breaking was terribly annoying.
Incidentally, to Brian Fox and whoever else has contributed code to
Bash: I'm extremely impressed with Bash, both from a user standpoint
and from a standpoint of a guy who just had to hack it to add a
little feature. The code is extremely readable and maintainable.
Good work.
--
john@arissoft.com (John Dawson)
Enclosure:
--------------------------------------------------------------------
*** parse.y.old Sat Sep 5 16:20:42 1992
--- parse.y Sat Sep 5 19:18:29 1992
***************
*** 601,606 ****
--- 601,607 ----
#if defined (READLINE)
char *current_readline_prompt = (char *)NULL;
+ char *invisible_readline_prompt = (char *)NULL;
char *current_readline_line = (char *)NULL;
int current_readline_line_index = 0;
***************
*** 2328,2334 ****
ps2_prompt = get_string_value ("PS2");
if (!prompt_string_pointer)
! prompt_string_pointer = &ps1_prompt;
if (*prompt_string_pointer)
temp_prompt = decode_prompt_string (*prompt_string_pointer);
--- 2329,2337 ----
ps2_prompt = get_string_value ("PS2");
if (!prompt_string_pointer)
! {
! prompt_string_pointer = &ps1_prompt;
! }
if (*prompt_string_pointer)
temp_prompt = decode_prompt_string (*prompt_string_pointer);
***************
*** 2335,2340 ****
--- 2338,2349 ----
else
temp_prompt = savestring ("");
+ if (invisible_readline_prompt)
+ {
+ fprintf(stderr, "%s", invisible_readline_prompt);
+ fflush(stderr);
+ }
+
current_prompt_string = *prompt_string_pointer;
prompt_string_pointer = &ps2_prompt;
***************
*** 2356,2361 ****
--- 2365,2371 ----
}
free (temp_prompt);
}
+
}
#include "maxpath.h"
***************
*** 2376,2381 ****
--- 2386,2393 ----
\$ a $ or a # if you are root
\<octal> character code in octal
\\ a backslash
+ \i mark beginning of invisible sequence
+ \I mark end of invisible sequence
*/
#include <sys/param.h>
#include <time.h>
***************
*** 2388,2397 ****
--- 2400,2414 ----
int result_size = PROMPT_GROWTH;
int result_index = 0;
char *result = (char *)xmalloc (PROMPT_GROWTH);
+ int invisible_result_size = PROMPT_GROWTH;
+ int invisible_result_index = 0;
+ char *invisible_result = (char *)xmalloc (PROMPT_GROWTH);
int c;
char *temp = (char *)NULL;
+ int invisible = 0;
result[0] = 0;
+ invisible_result[0] = 0;
while (c = *string++)
{
if (c == '\\')
***************
*** 2545,2573 ****
case '\\':
temp = savestring ("\\");
goto add_string;
default:
temp = savestring ("\\ ");
temp[1] = c;
add_string:
! if (c)
! string++;
! result =
! (char *)sub_append_string (temp, result,
! &result_index, &result_size);
! temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
! result[result_index] = '\0';
! break;
}
}
else
{
! while (3 + result_index > result_size)
! result = (char *)xrealloc (result, result_size += PROMPT_GROWTH);
! result[result_index++] = c;
! result[result_index] = '\0';
}
}
--- 2562,2628 ----
case '\\':
temp = savestring ("\\");
goto add_string;
+
+ case 'i':
+ invisible = 1;
+ temp = savestring ("");
+ goto add_string;
+ case 'I':
+ invisible = 0;
+ temp = savestring ("");
+ goto add_string;
+
default:
temp = savestring ("\\ ");
temp[1] = c;
add_string:
! if (invisible)
! {
! if (c)
! string++;
! invisible_result =
! (char *)sub_append_string (temp, invisible_result,
! &invisible_result_index,
! &invisible_result_size);
! temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
! invisible_result[invisible_result_index] = '\0';
! break;
! }
! else
! {
! if (c)
! string++;
! result =
! (char *)sub_append_string (temp, result,
! &result_index, &result_size);
! temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
! result[result_index] = '\0';
! break;
! }
}
}
else
{
! if (invisible)
! {
! while (3 + invisible_result_index > invisible_result_size)
! result = (char *)
! xrealloc(invisible_result,
! invisible_result_size += PROMPT_GROWTH);
! invisible_result[invisible_result_index++] = c;
! invisible_result[invisible_result_index] = '\0';
! }
! else
! {
! while (3 + result_index > result_size)
! result = (char *)xrealloc (result, result_size+=PROMPT_GROWTH);
!
! result[result_index++] = c;
! result[result_index] = '\0';
! }
}
}
***************
*** 2582,2587 ****
--- 2637,2646 ----
result = string_list (list);
dispose_words (list);
}
+
+ if (invisible_readline_prompt)
+ free(invisible_readline_prompt);
+ invisible_readline_prompt = invisible_result;
return (result);
}
--------------------------------------------------------------------
Re: "Philosophical" bug: Bash needs an "invisiblity" sequence inside PS1
Author: Dan R. Greening
Date: Tue, 08 Sep 1992 21:27
Date: Tue, 08 Sep 1992 21:27
23 lines
1575 bytes
1575 bytes
In article <9209060053.AA02428@arissoft.com> john@arissoft.COM writes: >I use GNU Bash, version 1.12.9, and the terminal program I use is Stuart >2.4 on a NeXT, which has title-bar-setting escape sequences that are a >superset of those understood by Xterm. A problem I was experiencing was >that the Readline library used by Bash doesn't know what part of the prompt >is actually visible. So, if I have a big, nasty PS1 variable that puts >lots of things in the title bar, Readline decides I've hit the 80th column >and breaks the line way too early. [ plus a patch ] I have seen at least 3 complaints here about bash's behavior with invisible character sequences. My prompt is underlined, and I have had similar problems. The complaints have been ongoing since bash version 1.05. I will incorporate this code into my version of bash, and I humbly request that the implementers of bash include it in their next release. Please. -- ____ \ /Dan Greening Software Transformation 1601 Saratoga-Sunnyvale Rd, #100 \/dgreen@sti.com (408) 973-8081 x313 Cupertino, CA 95014
Re: "Philosophical" bug: Bash needs an "invisiblity" sequence inside PS1
Author: Daniel S. Riley
Date: Thu, 10 Sep 1992 17:40
Date: Thu, 10 Sep 1992 17:40
30 lines
1585 bytes
1585 bytes
In article <9209060053.AA02428@arissoft.com> john@arissoft.COM writes:
>I use GNU Bash, version 1.12.9, and the terminal program I use is Stuart
>2.4 on a NeXT, which has title-bar-setting escape sequences that are a
>superset of those understood by Xterm. A problem I was experiencing was
>that the Readline library used by Bash doesn't know what part of the prompt
>is actually visible. So, if I have a big, nasty PS1 variable that puts
>lots of things in the title bar, Readline decides I've hit the 80th column
>and breaks the line way too early.
For title bar escape sequences, why not use PROMPT_COMMAND? For instance,
my .bashrc has
xtitle() {
if [ $# -gt 1 ]; then
echo -ne "\e]1;$1\a"
echo -ne "\e]2;$2\a"
else
echo -ne "\e]0;$1\a"
fi
}
cd_xtitle() {
xtitle "$USER@$HOST" "$USER@$HOST $PWD"
}
[ "$TERM" = "xterm" ] && PROMPT_COMMAND=cd_xtitle
--
-Dan Riley Internet: dsr@lns598.tn.cornell.edu
-Wilson Lab, Cornell University HEPNET/SPAN: lns598::dsr (44630::dsr)
Re: "Philosophical" bug: Bash needs an "invisiblity" sequence inside PS1
Author: Peter Funk
Date: Mon, 14 Sep 1992 08:24
Date: Mon, 14 Sep 1992 08:24
38 lines
2237 bytes
2237 bytes
In article <9209060053.AA02428@arissoft.com> john@arissoft.COM writes:
>I use GNU Bash, version 1.12.9, and the terminal program I use is Stuart
>2.4 on a NeXT, which has title-bar-setting escape sequences that are a
>superset of those understood by Xterm. A problem I was experiencing was
>that the Readline library used by Bash doesn't know what part of the prompt
>is actually visible. So, if I have a big, nasty PS1 variable that puts
>lots of things in the title bar, Readline decides I've hit the 80th column
>and breaks the line way too early.
In <1992Sep10.174049.2127@tc.cornell.edu> riley@theory.tc.cornell.edu (Daniel S. Riley) writes:
> For title bar escape sequences, why not use PROMPT_COMMAND? For instance,
> my .bashrc has
[...neat workaround deleted...]
Also this works for title strings, it is no solution for those of
us, who want to include escape sequences _INTO_ the prompt.
I like to have the host name included into the prompt string
and highlighted by inverse video. So my prompt is defined as:
ME=`logname`
if [ -w /etc/passwd ]
then PCH="#"
else PCH=">"
fi
SMSO=`tput smso`
RMSO=`tput rmso`
PS1="$ME@$SMSO\h$RMSO:$TERMLINE \w \!$PCH "
I have omitted the code to determine $TERMLINE (which will be
usually something like 'tty05'), because it is somewhat nasty
and has nothing to do with problem here.
Regards, Peter
Note: The usual "english_is_not_my_native_language"-disclaimer applies
to this "kraut"-babble.
-=-=-
Peter Funk \\ ArtCom GmbH, Schwachhauser Heerstr. 78, D-2800 Bremen 1
Work at home: Oldenburger Str.86, D-2875 Ganderkesee 1 / voice : top secret
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads