Monday, June 3, 2013

variable tabstops on your tty (linux, vt100/102/200?... similar)?

Seeing the conversation on variable tabs in Vim, thought some might
find the attached script of use if they use certain text terms...

FWIW, the linux type terminal implements a large subset of the VT102 and
ECMA-48/ISO ANSI x4.64 terminal controls...

Within this feature set, is the abilty to set tabsptops at any column.

I wrote a short shell script that sets them to *regular* intervals as
specified on a command line.

I use an indent level of 2 in much of my program development, so I
wrote it to support that. As it is, the script only supports fixed
sized, but user-settable tabs.

In looking at the code, if someone wanted to build on this to have it
take variable tabs, that wouldn't be difficult (the difficulty comes in
doing it elegantly! ;-)).

The terminal protocol supports tab stops at any column.

So, depending on what terminal emulators/TTY windows you use, you could
have native tab expansion to your desired tab width. I think standard
xterms support this as well.

For coding, it's certainly more portable to use 1 tabstop / indent than
to use tabs+spaces, since tabs+spaces can't be converted to a different
size tab w/o changing the code. But if you use 1 tabstop/indent, another
programmer can set them to their preference and not have to modify the
code -- allowing people to have a preference in tab expansion w/o needing
to muck up 'diff's, and patches w/white space changes.

The bash shell script is below.. feel free to ignore it if it
isn't of interest! ;-)

----
tty_tab -- reports on current settings, and with a param, can set
tabs on compliant terminals.


--------------------------*
*#!/bin/bash -u
#console_codes(4) man page... vt100/2 et && EMCA-48 standard
# Original author la walsh (2013) -- free to use and modify for personal
use.

# 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 int='declare -i'
alias sub='function'
alias array='declare -a'
alias intArray='declare -ia'
alias P=printf

P -v clrallts "\x1b[3g"
P -v sts "\033H"
P -v cr "\013"
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
if [[ -z ${sttyout:-""} ]]; then
echo $default_cols; return 0;fi
int cols="${sttyout#*\ }"
echo $[cols<2?default_cols:cols]
return 0
}

sub 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 () {
P $cr
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
}


sub test_tabset_ability () {
prompt="tty_tab:"
int newcol=${#prompt}+1
P "\r$prompt"
mycol=$(getpos x)

if [[ $mycol != $newcol ]]; then
(
P " Term tabset ability not detected (out=$out mycol=$mycol,"
P " promptlen=$newcol)\n"
) >&2
exit -1
fi
}

sub do_help_n_display_curtabs () {
P " <n> - set tab stop to N"
P "\r"
intArray diffs;
int last=1
int cur i
local 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=-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 "\n"
}
}

sub set_tabs () {
int max_col=${1:-80} ## #columns on screen
int tabstop=${2:-"need a param for tabstop"}
int tab=$tabstop
str=""
int pos=0
P $clrallts ## reset old tabs
while ((++pos<cols)) ;do ## move across screen setting tabs
str+=" "
((pos%tab)) || str+="$sts"
done
#echo -e "\033c"
P "\r$str$cr"
P ""
}


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


-------------------------------------------

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

No comments: