Estou brincando com um script que, entre outras coisas, lista uma lista de seleção. Como em:
1) Item 1 # (destacado) 2) Item 2 3) Item 3 # (selecionado) 4) Item 4
- Quando o usuário pressionar os
down-arrow
próximos itens, será destacado - Quando o usuário pressiona
up-arrow
os itens anteriores é destacado - etc.
- Quando o
tab
item pressionado pelo usuário é selecionado - Quando o usuário pressiona
shift+tab
todos os itens são selecionados / desmarcados - Quando o usuário pressiona
ctrl+a
todos os itens são selecionados - ...
Isso funciona bem como no uso atual, que é meu uso pessoal, onde as entradas são filtradas pela minha própria configuração.
A questão é como tornar isso confiável em vários terminais.
Eu uso uma solução um pouco hackish para ler a entrada:
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
E assim por diante.
Como mencionado, a questão é como tornar isso confiável em vários terminais: ou seja, quais seqüências de bytes definem uma chave específica. É mesmo possível no bash?
Um pensamento era usar um tput
ou infocmp
e filtrar pelo resultado dado por isso. Estou, no entanto, em uma senão lá como tanto tput
e infocmp
diferem do que eu realmente ler quando na verdade pressionando as teclas. O mesmo vale, por exemplo, usando C sobre 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)';
}
Sequências de rendimento lidas como definidas, por exemplo linux
, mas não xterm
, e é isso que é definido por TERM
.
Por exemplo, seta para a esquerda:
tput
/infocmp
:\x1 O D
read
:\x1 [ D
o que estou perdendo?
zsh
possui suporte a curses integrados (no módulo zsh / curses), além da consulta básica de terminfo com sua matriz incorporada echoti
e $terminfo
associativa.
dialog
variantes ou use uma linguagem comncurses
suporte decente (perl ou python, por exemplo, se você quiser usar as linguagens de "script").