Util-Linux package development
 help / color / mirror / Atom feed
* bug: column assumes tabs every 8 columns & ttywidth=80
@ 2016-05-31 22:36 Linda Walsh
  0 siblings, 0 replies; only message in thread
From: Linda Walsh @ 2016-05-31 22:36 UTC (permalink / raw)
  To: util-linux

[-- 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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-05-31 22:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-31 22:36 bug: column assumes tabs every 8 columns & ttywidth=80 Linda Walsh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox