sh
declare paridx=0;
declare -a OPT_p;
_ctrl ()
{
local char="${1:1:1}";
case $char in
A) asc=$'\x01' ;;
B) asc=$'\x02' ;;
C) asc=$'\x03' ;;
D) asc=$'\x04' ;;
E) asc=$'\x05' ;;
F) asc=$'\x06' ;;
G) asc=$'\x07' ;;
H) asc=$'\x08' ;;
I) asc=$'\x09' ;;
J) asc=$'\x0a' ;;
K) asc=$'\x0b' ;;
L) asc=$'\x0c' ;;
M) asc=$'\x0d' ;;
N) asc=$'\x0e' ;;
O) asc=$'\x0f' ;;
P) asc=$'\x10' ;;
Q) asc=$'\x11' ;;
R) asc=$'\x12' ;;
S) asc=$'\x13' ;;
T) asc=$'\x14' ;;
U) asc=$'\x15' ;;
V) asc=$'\x16' ;;
W) asc=$'\x17' ;;
X) asc=$'\x18' ;;
Y) asc=$'\x19' ;;
Z) asc=$'\x1a' ;;
[) asc=$'\x1b' ;;
\\) asc=$'\x1c' ;;
]) asc=$'\x1d' ;;
^) asc=$'\x1e' ;;
_) asc=$'\x1f' ;;
*) asc="$1" ;;
esac;
}
_decode ()
{
local \
asc="" \
symbol="" \
ctlbuf="" ;
ctlstr="";
for symbol in "$@";
do
case "$symbol" in
S7C1T) symbol="ESC SP F" ;; S8C1T) symbol="ESC SP G" ;; DECDHLU)symbol="ESC # 3" ;; DECDHLL)symbol="ESC # 4" ;; DECSWL) symbol="ESC # 5" ;; DECDWL) symbol="ESC # 6" ;; DECALN) symbol="ESC # 8" ;; DECSC) symbol="ESC 7" ;; DECRC) symbol="ESC 8" ;; DECPAM) symbol="ESC =" ;; DECPNM) symbol="ESC >" ;; RIS) symbol="ESC c" ;; ESC) symbol="^[" ;; IND) symbol="ESC D" ;; NEL) symbol="ESC E" ;; HTS) symbol="ESC H" ;; RI) symbol="ESC M" ;; SS2) symbol="ESC N" ;; SS3) symbol="ESC O" ;; DCS) symbol="ESC P" ;; SPA) symbol="ESC V" ;; EPA) symbol="ESC W" ;; SOS) symbol="ESC X" ;; DECID) symbol="ESC Z" ;; CSI) symbol="ESC [" ;; ST) symbol="ESC \\" ;; OSC) symbol="ESC ]" ;; PM) symbol="ESC ^" ;; APC) symbol="ESC _" ;; BEL) symbol="^G" ;; BS) symbol="^H" ;; CR) symbol="^M" ;; ENQ) symbol="^E" ;; FF) symbol="^L" ;; LF) symbol="^J" ;; SO) symbol="^N" ;; TAB) symbol="^I" ;; VT) symbol="^K" ;; SI) symbol="^O" ;; ^?) _ctrl "$symbol"; symbol="$asc" ;; SET_WTITLE) symbol="OSC 2 ; %p ST" ;;
SET_ITITLE) symbol="OSC 1 ; %p ST" ;;
SET_TITLES) symbol="OSC 0 ; %p ST" ;;
SET_XPROP) symbol="OSC 3 ; %p ST" ;;
GET_WTITLE) symbol="CSI 2 1 t" ;;
GET_ITITLE) symbol="CSI 2 0 t" ;;
esac;
ctlbuf="${ctlbuf}${ctlbuf:+ }${symbol}";
done;
ctlstr="${ctlbuf}";
}
usage ()
{
cat <<EOF | ${PAGER:-cat}
usage:
$0 [-r] [-R] [-p arg0 [-p arg1]...] <SYMBOLIC SEQUENCE...>
This tool translates a sequence of symbols and strings into a
corresponding terminal escape sequence, which it then prints
on stdout.
If the -r flag is supplied, then it sends the escape sequence
to the tty ( via '/dev/tty' ), reads the terminal's response,
trims some leading and trailing marker characters, and prints
the result on stdout instead (unless -R was specified, in which
case you get the raw response sequence).
Note that the raw response generally begins with a control string
that renders it invisible when printed, so it's a good idea to
capture it with a RSP=\$($0 -r -R SEQUENCE) type construct.
The sequence will have all the spaces stripped out of it, except
those explicitly passed as the 'SP' symbol.
$0 knows about the following symbols:
S7C1T 7 bit control sequences
S8C1T 8 bit control sequences
DECDHLU double height line, upper half
DECDHLL double height line, lower half
DECSWL single width
DECDWL double width
DECALN alignment test
DECSC save cursor
DECRC restore cursor
DECPAM app keypad
DECPNM normal keypad
RIS full reset
ESC esc
IND index
NEL next line
HTS set tab stop
RI Reverse Index
SS2 Single Shift G2 charset: next char only
SS3 Single Shift G3 charset: next char only
DCS Device Control String
SPA Start Protected Area
EPA End Protected Area
SOS Start Of String
DECID terminal id (obsolete: use CSI Ps c)
CSI Control Sequence Introduction
ST String Terminator
OSC Operating System Command
PM Privacy Message
APC Application Program Command
BEL beep
BS backspace
CR Carriage Return (beginning of line)
ENQ terminal status
FF Form Feed (clear/redraw screen)
LF Line Feed
SO Shift Out : G1 character set
SP space
TAB Tab
VT same as LF
SI Shift In : G0 (default) character set
^A ... ^_ control characters 0x01 through 0x1f
The following high-level sequences have been defined for convenience:
GET_WTITLE fetch the window title
GET_ITITLE fetch the icon title
Additionally, we support parametrised symbolic sequences:
Each '%p' in a sequence will be replaced with successive
values of the -p flag.
The following parametrised sequences are built in:
SET_WTITLE (1 arg) Set the window title
SET_ITITLE (1 arg) Set the icon title
SET_TITLES (1 arg) Set both the above
SET_XPROP (1 arg) Set (prop=value) or zap (prop) an X property
The escape sequences are detailed here:
http://rtfm.etla.org/xterm/ctlseq.html
Example:
# sets the title bar to "Xterm Title"
$0 OSC 0 \; Xterm SP Title ST
# or:
$0 -p "Xterm SP Title" SET_WTITLE
# stores the (sanitised) title response in \$TSTR
TSTR=\$($0 CSI 2 1 t)
# or:
TSTR=\$($0 GET_WTITLE)
EOF
}
_param ()
{
local curidx=0;
while [ 1 -eq 1 ];
do
if [ $paridx -eq $curidx ];
then
par=${OPT_p[$curidx]};
paridx=$(($paridx + 1));
break;
else
curidx=$(($curidx + 1));
fi;
done;
}
decode ()
{
local\
ctlstr="" \
sym="" \
seqbuf="" ;
for sym in "$@";
do
while [ "1" = "1" ];
do
_decode $sym;
if [ "X$ctlstr" = "X$sym" ]; then break; else sym="$ctlstr"; fi;
done;
sequence="${sequence}${sequence:+ }${sym}";
done;
for sym in $sequence;
do
if [ "X$sym" = "XSP" ]; then sym=" "; fi;
if [ "X$sym" = "X%p" ]; then _param ; sym="$par"; fi;
seqbuf="${seqbuf}${sym}";
done;
sequence="$seqbuf";
}
ctl_read ()
{
local \
old="" \
cseq="$*" \
response="" \
sequence="" ;
exec </dev/tty; old="$(stty -g)"; stty raw -echo min 0 time 1; echo -n "$cseq" > /dev/tty; IFS='' read -r response; stty "$old";
if [ -z "$OPT_R" ] && [ -n "$response" ];
then
local \
OSC="" \
CSI="" \
rlen=${#response} \
start=${response:0:2} ;
decode "OSC"; OSC="$sequence";
decode "CSI"; CSI="$sequence";
if [ "$start" = "$OSC" ]; then response=${response:3:$(($rlen-5))};
elif [ "$start" = "$CSI" ]; then response=${response:3:$(($rlen-4))};
fi;
fi;
echo -n "$response"; }
main ()
{
local \
name="" \
setarg="" ;
while getopts rRhp: n;
do
case $n in
p)
OPT_p[$paridx]="${OPTARG:-$paridx}";
paridx=$(($paridx + 1));
;;
*)
setarg="OPT_${n}=\"\${OPT_${n}}\${OPT_$n:+ }${OPTARG:-1}\"";
eval $setarg;
;;
esac;
done;
paridx=0;
shift $(($OPTIND-1));
if [ $# -eq 0 ] || [ -n "$OPT_h" ]; then usage; exit 0; fi;
decode "$@";
if [ -n "$OPT_r" ]; then ctl_read $sequence; else echo -n $sequence; fi;
}
main "$@";
|