I am playing with a script that, among other things, list a selection-list. As in:
1) Item 1 # (highlighted) 2) Item 2 3) Item 3 # (selected) 4) Item 4
- When user press
down-arrow
next items is highlighted - When user press
up-arrow
previous items is highlighted - etc.
- When user press
tab
item is selected - When user press
shift+tab
all items are selected / deselected - When user press
ctrl+a
all items are selected - ...
This works fine as of current use, which is my personal use where input is filtered by my own setup.
Question is how to make this reliable across various terminals.
I use a somewhat hackish solution to read input:
while read -rsn1 k # Read one key (first byte in key press)
do
case "$k" in
[[:graph:]])
# Normal input handling
;;
$'\x09') # TAB
# Routine for selecting current item
;;
$'\x7f') # Back-Space
# Routine for back-space
;;
$'\x01') # Ctrl+A
# Routine for ctrl+a
;;
...
$'\x1b') # ESC
read -rsn1 k
[ "$k" == "" ] && return # Esc-Key
[ "$k" == "[" ] && read -rsn1 k
[ "$k" == "O" ] && read -rsn1 k
case "$k" in
A) # Up
# Routine for handling arrow-up-key
;;
B) # Down
# Routine for handling arrow-down-key
;;
...
esac
read -rsn4 -t .1 # Try to flush out other sequences ...
esac
done
And so on.
As mentioned, question is how to make this reliable across various terminals: i.e. what byte sequences define a specific key. Is it even feasible in bash?
One thought was to use either tput
or infocmp
and filter by the result given by that. I am however in a snag there as both tput
and infocmp
differ from what I actually read when actually pressing keys. Same goes for example using C over bash.
for t in $(find /lib/terminfo -type f -printf "%f\n"); {
printf "%s\n" "$t:";
infocmp -L1 $t | grep -E 'key_(left|right|up|down|home|end)';
}
Yield sequences read as defined for for example linux
, but not xterm
, which is what is set by TERM
.
E.g. arrow left:
tput
/infocmp
:\x1 O D
read
:\x1 [ D
What am I missing?
dialog
variants, or use a language with decentncurses
support (perl or python for example, if you want to stick with "scripting" languages). – cas Jul 10 '16 at 4:50zsh
has builtin curses support (in the zsh/curses module) in addition to basic terminfo querying with itsechoti
builtin and$terminfo
associative array. – Stéphane Chazelas Jul 16 '16 at 6:25