Greg Wooledge wrote: > On Tue, Apr 23, 2013 at 11:42:34PM -0700, Linda Walsh wrote: >> Was my elaboration clear enough -- ? >> >> It's a display issue not a content issue -- except when you cut/paste >> from the terminal to another buffer under X. > > You forgot to copy the mailing list. Also, X has nothing to do with > this. This is solely between bash and the terminal. ----- No... It's about what *I* see, **AND**, when I copy/paste from the terminal to another application, -- what "X" sees.
> Pasting has nothing to do with bash. Pasting is between X and the > terminal. Totally separate issue. --- My terminal is displayed via 'X' --- X pics up the actual characters that were echoed to the screen. If TABS are used, it put's TABS in the copy/paste-buffer. If some lame application substitutes some other character for tabs, it will pic up the wrong value. For the general case, I submit that it should echo HW tabs when it encounters such. > >> However I can think of no good reason why bash should not pay attention >> to terminal settings and use the TAB char -- at least, as an option. > > How would bash KNOW what the terminal's tabstops are set to? It can't. ---- It uses the curses library. The code has references through-out that look to see what column it is in. Bash has builtin features in the prompt-build feature, to help it determine the correct column so it knows when to wrap your cursor -- and it knows when to wrap output. The same library it uses to keep track of that can tell it what the tabs stops are -- either directly or indirectly. > I am reluctant to speculate on this matter, but you appear to be grasping > at straws, so I will proffer some guesswork. Everything from here > downward is totally guesswork and may be completely wrong. > > Imagine that you're writing bash and that you want to include a feature > that lets people edit their commands. Some of these commands may include > a literal tab character, even as difficult as it is to do such a thing. ---- Imagine that you have a terminal where people paste intput from X. Ok.. not hard at all to image where the TABS come from. Imagine that they can invoke a full-screen oriented editor like emacs or vim to edit a line -- and that they are used to tabbing over when indenting code. > When the command editor is invoked, bash must reconstruct the command > on the terminal, bearing in mind that bash knows very little *about* > the terminal beyond the contents of $TERM and whatever it can glean > from the system's termcap/terminfo database. --- Yup..BINGO... > > If the command to be edited contains a literal tab, bash must present > the command on the screen in an editable format. ---- So If a users terminal uses "." -- it would be ok for bash to display "dot", instead of the actual character? > The user must be able > to move the cursor to any part of the command, and the cursor's position > must make sense to the user, and bash must always know where the cursor > is in the REAL command in memory. --- Right -- sans-unicode, 1 char/byte -- user moves 1 char, internal edit buffer moves 1 char...but on the screen bash expands it to 1-8 chars? > > Suppose bash wrote a literal tab to the terminal when in this mode. > The terminal may do anything with it. The terminal may move the cursor > to the 8th column, or the 5th column, or the 13th column, or anything. > Bash wouldn't know where the cursor went. --- Uh... yeah.. it shouldn't care. it knows that in it's internal buffer it put out 1 character for that position. > > So instead, bash does its own expansion of the tab using the standard > 8-space tabstops that 99.9999% of the people in the world use. --- Most people don't type in 8 spaces for a tab. Only hard-coded, broken computer programs. People use variable tabs in real life -- long before computers existed -- They put the columns where they wanted them. You don't see tabs expanded to 8 spaces in a word processor. Tabs are expanded by the hardware -- or hardware emulation. Then software started evolving to match the hardware -- but that was a hack. Hardware for years has had variable tab support -- vt102 -- it's not just linux consoles... it's emulating a much older standard. As for how hard it would be to find out the current tab setting? 1) allow the user to specify a tab settting in the ENV... like "duh? -- you mean allow the user to have input into what tabs expand to? SHOCK...if they don't have a preference, default to 8. 2), it talks to the curses library -- through it it can find how tabs are expanded. Finding out the data and setting it -- can all be set in BASH SCRIPT -- But getting BASH to reproduce tabs the way the terminal does --- has to be fixed in BASH. Here's a prog to read the tabs from the terminal and allow setting them (only uniform-unidistant tabs at this point, but that's all I need -- if someone else wants to improve on the prog -- I hereby release it to the public commons)... -------------------------- #!/bin/bash #console_codes(4) man page... shopt -s expand_aliases alias int='declare -i' alias sub='function' alias array='declare -a' alias intArray='declare -ia' printf -v clrallts "\x1b[3g" printf -v sts "\033H" printf -v cr "\013" printf -v cpr "\x1b[6n" function getpos () { local wanted=${1:-xy} local ans x y ( (sleep .01 && echo -en "\x1b[6n" >/dev/tty) & 2>/dev/null ) read -sd R -r -t 2 ans </dev/tty; declare ans=${ans:2}; x=${ans#*;}; y=${ans%;*} ; declare -g out="" [[ $wanted =~ x ]] && out="$x" [[ $wanted =~ y ]] && out="${out:+$x }$y" [[ $out ]] && echo "$out" } declare -iga tabs sub get_tabs () { printf $cr int pos=0 oldpos=0-1 while ((oldpos!=pos));do oldpos=pos printf "\t" pos=$(getpos x) tabs+=($pos) done return 0 } prompt="tty_tabs:" int newcol=${#prompt}+1 echo -n "$prompt" mycol=$(getpos x) if [[ $mycol != $newcol ]]; then echo " Term tabset ability not detected (out=$out mycol=$mycol, promptlen=$newcol)" exit -1 fi if (($#==0)) ; then echo -en " <n> - set tab stop to N\r" get_tabs && { printf "\r (cur tabs (from 1): " printf "%s " "${tabs[@]}" printf "\n" } exit 1 fi declare -i tab=$1; str="" declare -i pos=1 printf $clrallts while ((++pos<80)) ;do if ((pos%tab)); then str+=" " else str+="$sts" fi done #echo -e "\033c" echo -n "$str$cr" # vim: ts=2