bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bash doesn't display tabs for tabs -- ignores tabstops.


From: Linda Walsh
Subject: Re: bash doesn't display tabs for tabs -- ignores tabstops.
Date: Thu, 25 Apr 2013 23:38:27 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.24) Gecko/20100228 Lightning/0.9 Thunderbird/2.0.0.24 Mnenhy/0.7.6.666


Greg Wooledge wrote:
> On Wed, Apr 24, 2013 at 08:02:29PM -0700, Linda Walsh wrote:
>>      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.
> 
> That is not how my terminal works.
> 
> imadev:~$ echo $'tab>\t<tab'
> tab>    <tab
> imadev:~$ od -t x1
> tab>    <tab
> 0000000   74  61  62  3e  20  20  20  20  3c  74  61  62   a
> 0000015
> 
> This is in rxvt (not rxvt-unicode), on HP-UX 10.20.  I triple-left-clicked
> the line that the shell produced, then typed the od command and pressed
> Enter, then pasted the line by pressing the middle mouse button, then
> pressed Ctrl-D.
----
Hmmm.... In my testing only 2 terminals correctly copied the tab
char -- lxterminal & "Terminal" (aka xfce4-terminal).

Terms that didn't: kterm, xterm, SecureCRT.

However.   What I do see now, is still, the inconsistency between
the output in something like "cat" on a tabbed file, vs. If I paste
it into bash -- OR, edit the current line, and then read in the file
w/tabs.

I generated the file w/this scriptlet:

(tabs=$(echo -en "\t\t\t\t\t\t\t\t\t\t\t") &&
for ((i=0;i<=10;++i)) { ((i%5==0)) && {
  for ((j=0;j<=69;++j)) { printf "%1.1s" "$((j%10))"; }
  printf "\n"; }
  ((i<10)) && printf "%s%s\n" "${tabs:0:$i}" "$i" ; }) >/tmp/file

---
Depending on how your tabs on your terminal are set, you will
get different expansions -- and when you cut/paste -- you get different
numbers of SPACES on each line -- so the terminal is moving things
over according to its programming -- which bash can read.  But the
cut/past function on 66% of the terminal emulators, doesn't
pick up the actual TAB char...

But they ALL have compatible, programmable tab functions.
Found a bug and did some cleanup of my tab display and set
script.  Sample output, first w/default tabs:

> tty_tabs
tty_tabs: <n> - set tab stop to N
(cur tabs (from 1): 9 17 25 33 41 49 57 65 73 80
Ishtar:/> tty_tabs 2

> tty_tabs
tty_tabs: <n> - set tab stop to N
(cur tabs (from 1): 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43
45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 80
> tty_tabs 8

> tty_tabs
tty_tabs: <n> - set tab stop to N
(cur tabs (from 1): 9 17 25 33 41 49 57 65 73 80


>> #console_codes(4) man page...
> 
> Is specific to ONE terminal emulator.  There are many others that do
> not work the same way.  Plus there are real hardware terminals, and most
> of them are VERY quirky.
----
        It's based on vt102, so all of the terminal emulators on
linux that I tested worked with the tab expansion.  Also my script
tests to see if it has a hope or prayer of working before it tries
to set anything.   Given that 100% of the half dozen terminal
emulators I tested support variable tabs, it seems odd that the
system shell that seems to be most in use on linux doesn't.



===============
tty_tabs
===============
#!/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
    ((pos)) && tabs+=($pos)
    oldpos=pos
    printf "\t"
    pos=$(getpos x)
  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"
  echo -en "\r"
  get_tabs  && {
    printf "\r(cur tabs (from 1): "
    printf "%s " "${tabs[@]}"
    echo -en "\n"
  }
  exit 1
fi
declare -i tab=$1;
str=""
declare -i pos=0
printf $clrallts

while ((++pos<80)) ;do
  str+=" "
  ((pos%tab)) || str+="$sts"
done
#echo -e "\033c"
echo  -en "\r$str$cr"

# vim: ts=2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]