All of lore.kernel.org
 help / color / mirror / Atom feed
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.