From: Linda Walsh <lkml@tlinx.org>
To: util-linux@vger.kernel.org
Subject: bug: column assumes tabs every 8 columns & ttywidth=80
Date: Tue, 31 May 2016 15:36:11 -0700 [thread overview]
Message-ID: <574E11DB.2010501@tlinx.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]
In util-linux2.25, the "column" command isn't written for Linux using a
Linux-console (among others). It assumes 8-column
fixed-width tabs and screen width of 80).
The Linux-console (or any emulator) and terminals supporting
the EMCA-48 standard (vt-100-emulating terms, as well as "xterm")
can have tabs set to arbitrary spacing.
Attached is a bash-script that can show current tab settings
as well as set them to a new value.
It only supports setting tabs to fixed-width, but there is nothing
preventing tabs from being set to variable width expansions.
Ex:
> tty_tab 8
> tty_tab
(from 1, tabs skip to column: 9 17 25 33 41 49 57 65 73 80
> tty_tab 2
> tty_tab
(from 1, tabs skip to column: 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
Suggestions to fix column (or other progs that deal
w/the console and use tabs):
1) allow -i (-t is taken) to specify width of terminal tab expansion
-i 8 (default)
-i 4 (some like 4-column indents)
-i 2 (and some use 2 to keep down line length). I've seen "1" used
as a tabsize in javascript files...
1a) (low priority) -- have "-i" take a list of numbers, like
-i 18 36 44 54
(might be reasonable for /etc/fstab?) -- any tabs beyond the
last would use the last specified interval (in above case, "10")
2) --no-tabs
A "Don't use tabs" option for lining up columns, use spaces.
AFAIK, spaces are a fixed size on tty's.
----
There's a tab-set program in the ncurses-utils as well called 'tabs'.
[-- Attachment #2: tty_tab --]
[-- Type: text/plain, Size: 3364 bytes --]
#!/bin/bash -u
#console_codes(4) man page... vt100/2 et && EMCA-48 standard
# (c) la walsh (2013) -- free to use and modify for personal use.
# -- optionally licenced under Gnu v3 license.
# v0.0.3 - try to reduce tabcols to minimal set to reproduce.
# v0.0.2 - set tabs for full terminal width (try to get term width)
shopt -s expand_aliases extglob
alias my=declare sub=function
alias int='my -i' array='my -a' intArray='my -ia' string=my
my _Pt=$(type -t P)
[[ $_Pt && $_Pt == function ]] && unset -f P
alias P=printf
unset _Pt
P -v clrallts "\x1b[3g"
P -v sts "\033H"
P -v cpr "\x1b[6n"
sub getcols() {
local sttyout="$(stty size </dev/tty)"
int default_cols=80
if [[ -n ${COLUMNS:-""} && $COLUMNS =~ ^[0-9]+$ ]]; then
default_cols=$COLUMNS; fi
[[ -z ${sttyout:-""} ]] && { echo $default_cols; return 0; }
int cols="${sttyout#*\ }"
echo -n $[cols<2?default_cols:cols]
return 0
}
sub getpos () {
string ans wanted=${1:-xy}
int attempt=0 max_attempt=1 # in case of rare failure case
# use 'attempt' value as additional
# time to wait for response
while : ; do
( ( P "\x1b[6n" >/dev/tty) & 2>/dev/null )
read -sd R -r -t $[2 + attempt] ans </dev/tty;
ans=${ans:2};
int x=0-1 y=0-1
if ! x="${ans#*;}" y="${ans%;*}" 2>/dev/null ||
((x==-1||y==-1)); then
((attempt+=1 < max_attempt)) && continue
fi
break; done
string out=""
[[ $wanted =~ x ]] && out="$x"
[[ $wanted =~ y ]] && out="${out:+$x }$y"
[[ $out ]] && echo -n "$out"
}
declare -ia tabs
sub get_tabs () {
P "\r"
tabs=()
int pos=0 oldpos=0-1
while ((oldpos!=pos));do
((pos)) && tabs+=($pos)
oldpos=pos
P "\t"
pos=$(getpos x)
done
P "\r"
return 0
}
# Note: this sub uses ability to _read_ tabstops as _proxy_ for setting them
# (i.e. it makes no sense to be able to read them if you can't set them)
sub test_tabset_ability () {
string prompt="tty_tab:"
int newcol=${#prompt}+1
P "\r$prompt"
int mycol=$(getpos x)
((mycol && mycol==newcol)) && return 0 ## return OK
{ P " Term tabset ability not detected mycol=${mycol:-''},"
P " promptlen=$newcol)\n"; } >&2
exit -1
}
sub do_help_n_display_curtabs () {
P " <n> - set tab stop to N\r"
intArray diffs;
int last=1 cur i
string eol=""
get_tabs && {
for ((i=0; i<${#tabs[@]}; ++i)); do
cur=${tabs[i]}
diffs[i]=cur-last
last=cur
done
intArray reverse_tabs_set=()
int prevtab=0-1
for ((i=${#diffs[@]}-2; i>0; --i)); do
int thistab=${diffs[i]}
if ((thistab!= prevtab)) ;then
reverse_tabs_set+=($thistab)
prevtab=thistab
fi
done
P "current value: tty_tab "
for ((i=${#reverse_tabs_set[@]}-1; i>=0; --i)); do
P "%d " "${reverse_tabs_set[i]}"; done
P "\r";
}
get_tabs && {
P "(from 1, tabs skip to column: "
P "%s " "${tabs[@]}"
P "\r\n"
}
}
sub set_tabs () {
int max_col=${1:=0-80}
int tabstop=${2:-?"need a param for tabstop"}
int tab=$tabstop pos=0
string str=""
P $clrallts ## reset old tabs
while ((++pos<cols)) ;do ## move across screen setting tabs
str+=" "
((pos%tab)) || str+="$sts"
done
P "\r$str\r"
}
int cols=$(getcols)
test_tabset_ability ## exits if no ability
if (($#==0)) ; then
do_help_n_display_curtabs
exit 1
else
set_tabs "$cols" "$@"
fi
# vim: ts=2 sw=2
reply other threads:[~2016-05-31 22:45 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=574E11DB.2010501@tlinx.org \
--to=lkml@tlinx.org \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.