🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

4 total messages Started by john Sun, 06 Sep 1992 00:53
"Philosophical" bug: Bash needs an "invisiblity" sequence inside PS1
#873
Author: john
Date: Sun, 06 Sep 1992 00:53
285 lines
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
#881
Author: Dan R. Greening
Date: Tue, 08 Sep 1992 21:27
23 lines
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
#885
Author: Daniel S. Riley
Date: Thu, 10 Sep 1992 17:40
30 lines
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
#899
Author: Peter Funk
Date: Mon, 14 Sep 1992 08:24
38 lines
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