home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / gnu / bash / bug / 594 < prev    next >
Encoding:
Text File  |  1992-09-08  |  8.1 KB  |  299 lines

  1. Newsgroups: gnu.bash.bug
  2. Path: sparky!uunet!cis.ohio-state.edu!arissoft.COM!john
  3. From: john@arissoft.COM
  4. Subject: "Philosophical" bug:  Bash needs an "invisiblity" sequence inside PS1
  5. Message-ID: <9209060053.AA02428@arissoft.com>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: GNUs Not Usenet
  8. Distribution: gnu
  9. Date: Sun, 6 Sep 1992 00:53:13 GMT
  10. Approved: bug-bash@prep.ai.mit.edu
  11. Lines: 286
  12.  
  13. I use GNU Bash, version 1.12.9, and the terminal program I use is Stuart
  14. 2.4 on a NeXT, which has title-bar-setting escape sequences that are a
  15. superset of those understood by Xterm.  A problem I was experiencing was
  16. that the Readline library used by Bash doesn't know what part of the prompt
  17. is actually visible.  So, if I have a big, nasty PS1 variable that puts
  18. lots of things in the title bar, Readline decides I've hit the 80th column
  19. and breaks the line way too early.  (About the 15th character, with my
  20. current PS1 setting.)  Things just get worse when you start doing cursor
  21. motion commands, redraws, etc.
  22.  
  23. Very bad.
  24.  
  25. I thought of a reasonably simple fix.  Introduce two new sequences into
  26. the PS[124] variables:  "\i" to say that the following characters are
  27. invisible and shouldn't get put into the prompt that Readline knows
  28. about, and (naturally) "\I" to turn off invisibility for the following
  29. characters.  Now, a PS1 sequence to set the titlebar for an Xterm (or
  30. a Stuart, in my case) might be
  31.  
  32.     PS1="\i^[]0;\u@\h:\w^G\I% '
  33.  
  34. I had originally planned just to send in a whiney message complaining
  35. about this and sit around and wait until somebody did something, but
  36. I figured I'd like this feature right away, and besides, you probably
  37. wouldn't stick this feature in future versions anyway ... :-)  So, a
  38. little diddling around produced the following apparently-operational
  39. diff.
  40.  
  41. The code works like this:  it introduces a global variable called
  42. invisible_readline_prompt that is effectively a second return value
  43. from decode_prompt_string().  When prompt_again() calls
  44. decode_prompt_string(), it prints invisible_readline_prompt to stderr.
  45.  
  46. decode_prompt_string() was modified to have two states.  One state is
  47. the "invisible" state, and the other is the "visible" state.  In the
  48. visible state, operation is as it was before.  The string result is
  49. built up a little bit at a time.  However, the sequences \i and \I
  50. switch to/from the invisible state, and in the invisible state, the
  51. little chunks get added to a new local variable called invisible_result
  52. (use of invisible_result was a cut 'n' paste from the code that dealt
  53. with result).  When the function is done, it copies invisible_result
  54. out to invisible_readline_prompt.
  55.  
  56. I wouldn't say this was the greatest implementation in the world, but
  57. it was quick and easy, and I think the \i and \I are easy to use.  (And
  58. probably won't break existing code.)  Feel free (of course) to throw
  59. this code out and do it like it should have been done.  But please --
  60. put SOMETHING like this in the next Bash.  The problem with invisible
  61. prompt characters messing up the line breaking was terribly annoying.
  62.  
  63. Incidentally, to Brian Fox and whoever else has contributed code to
  64. Bash:  I'm extremely impressed with Bash, both from a user standpoint
  65. and from a standpoint of a guy who just had to hack it to add a
  66. little feature.  The code is extremely readable and maintainable.
  67. Good work.
  68.  
  69. --
  70. john@arissoft.com (John Dawson)
  71.  
  72. Enclosure:
  73. --------------------------------------------------------------------
  74. *** parse.y.old    Sat Sep  5 16:20:42 1992
  75. --- parse.y    Sat Sep  5 19:18:29 1992
  76. ***************
  77. *** 601,606 ****
  78. --- 601,607 ----
  79.   
  80.  
  81.   #if defined (READLINE)
  82.   char *current_readline_prompt = (char *)NULL;
  83. + char *invisible_readline_prompt = (char *)NULL;
  84.   char *current_readline_line = (char *)NULL;
  85.   int current_readline_line_index = 0;
  86.   
  87.  
  88. ***************
  89. *** 2328,2334 ****
  90.     ps2_prompt = get_string_value ("PS2");
  91.   
  92.  
  93.     if (!prompt_string_pointer)
  94. !     prompt_string_pointer = &ps1_prompt;
  95.   
  96.  
  97.     if (*prompt_string_pointer)
  98.       temp_prompt = decode_prompt_string (*prompt_string_pointer);
  99. --- 2329,2337 ----
  100.     ps2_prompt = get_string_value ("PS2");
  101.   
  102.  
  103.     if (!prompt_string_pointer)
  104. !     {
  105. !       prompt_string_pointer = &ps1_prompt;
  106. !     }
  107.   
  108.  
  109.     if (*prompt_string_pointer)
  110.       temp_prompt = decode_prompt_string (*prompt_string_pointer);
  111. ***************
  112. *** 2335,2340 ****
  113. --- 2338,2349 ----
  114.     else
  115.       temp_prompt = savestring ("");
  116.   
  117.  
  118. +   if (invisible_readline_prompt)
  119. +     {
  120. +       fprintf(stderr, "%s", invisible_readline_prompt);
  121. +       fflush(stderr);
  122. +     }
  123.  
  124.     current_prompt_string = *prompt_string_pointer;
  125.     prompt_string_pointer = &ps2_prompt;
  126.   
  127.  
  128. ***************
  129. *** 2356,2361 ****
  130. --- 2365,2371 ----
  131.       }
  132.         free (temp_prompt);
  133.       }
  134.  
  135.   }
  136.   
  137.  
  138.   #include "maxpath.h"
  139. ***************
  140. *** 2376,2381 ****
  141. --- 2386,2393 ----
  142.       \$    a $ or a # if you are root
  143.       \<octal> character code in octal
  144.       \\    a backslash
  145. +     \i    mark beginning of invisible sequence
  146. +     \I    mark end of invisible sequence
  147.   */
  148.   #include <sys/param.h>
  149.   #include <time.h>
  150. ***************
  151. *** 2388,2397 ****
  152. --- 2400,2414 ----
  153.     int result_size = PROMPT_GROWTH;
  154.     int result_index = 0;
  155.     char *result = (char *)xmalloc (PROMPT_GROWTH);
  156. +   int invisible_result_size = PROMPT_GROWTH;
  157. +   int invisible_result_index = 0;
  158. +   char *invisible_result = (char *)xmalloc (PROMPT_GROWTH);
  159.     int c;
  160.     char *temp = (char *)NULL;
  161. +   int invisible = 0;
  162.   
  163.  
  164.     result[0] = 0;
  165. +   invisible_result[0] = 0;
  166.     while (c = *string++)
  167.       {
  168.         if (c == '\\')
  169. ***************
  170. *** 2545,2573 ****
  171.           case '\\':
  172.             temp = savestring ("\\");
  173.             goto add_string;
  174.   
  175.  
  176.           default:
  177.             temp = savestring ("\\ ");
  178.             temp[1] = c;
  179.   
  180.  
  181.           add_string:
  182. !           if (c)
  183. !         string++;
  184. !           result =
  185. !         (char *)sub_append_string (temp, result,
  186. !                        &result_index, &result_size);
  187. !           temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
  188. !           result[result_index] = '\0';
  189. !           break;
  190.           }
  191.       }
  192.         else
  193.       {
  194. !       while (3 + result_index > result_size)
  195. !         result = (char *)xrealloc (result, result_size += PROMPT_GROWTH);
  196.   
  197.  
  198. !       result[result_index++] = c;
  199. !       result[result_index] = '\0';
  200.       }
  201.       }
  202.   
  203.  
  204. --- 2562,2628 ----
  205.           case '\\':
  206.             temp = savestring ("\\");
  207.             goto add_string;
  208. +         
  209.  
  210. +         case 'i':
  211. +           invisible = 1;
  212. +           temp = savestring ("");
  213. +           goto add_string;
  214.   
  215.  
  216. +         case 'I':
  217. +           invisible = 0;
  218. +           temp = savestring ("");
  219. +           goto add_string;
  220.  
  221.           default:
  222.             temp = savestring ("\\ ");
  223.             temp[1] = c;
  224.   
  225.  
  226.           add_string:
  227. !           if (invisible) 
  228.  
  229. !         {
  230. !           if (c)
  231. !             string++;
  232. !           invisible_result =
  233. !             (char *)sub_append_string (temp, invisible_result,
  234. !                            &invisible_result_index,
  235. !                            &invisible_result_size);
  236. !           temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
  237. !           invisible_result[invisible_result_index] = '\0';
  238. !           break;
  239. !         }
  240. !           else
  241. !         {
  242. !           if (c)
  243. !             string++;
  244. !           result =
  245. !             (char *)sub_append_string (temp, result,
  246. !                            &result_index, &result_size);
  247. !           temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
  248. !           result[result_index] = '\0';
  249. !           break;
  250. !         }
  251.           }
  252.       }
  253.         else
  254.       {
  255. !       if (invisible)
  256. !         {
  257. !           while (3 + invisible_result_index > invisible_result_size)
  258. !         result = (char *)
  259. !             xrealloc(invisible_result,
  260. !                      invisible_result_size += PROMPT_GROWTH);
  261.   
  262.  
  263. !           invisible_result[invisible_result_index++] = c;
  264. !           invisible_result[invisible_result_index] = '\0';
  265. !         }
  266. !       else
  267. !         {
  268. !           while (3 + result_index > result_size)
  269. !         result = (char *)xrealloc (result, result_size+=PROMPT_GROWTH);
  270.  
  271. !           result[result_index++] = c;
  272. !           result[result_index] = '\0';
  273. !         }
  274.       }
  275.       }
  276.   
  277.  
  278. ***************
  279. *** 2582,2587 ****
  280. --- 2637,2646 ----
  281.         result = string_list (list);
  282.         dispose_words (list);
  283.       }
  284.  
  285. +   if (invisible_readline_prompt)
  286. +     free(invisible_readline_prompt);
  287. +   invisible_readline_prompt = invisible_result;
  288.   
  289.  
  290.     return (result);
  291.   }
  292. --------------------------------------------------------------------
  293.  
  294.