私はとりわけ、選択リストをリストするスクリプトで遊んでいます。のように:
1)アイテム1 #(強調表示) 2)アイテム2 3)アイテム3#(選択) 4)アイテム4
- ユーザーが
down-arrow
次のアイテムを押すとハイライトされます - ユーザーが
up-arrow
前のアイテムを押すとハイライトされます - 等
- ユーザーが
tab
アイテムを押すと選択されたとき - ユーザーが押すと、
shift+tab
すべてのアイテムが選択/選択解除されます - ユーザーが
ctrl+a
すべてのアイテムを選択すると、選択されます - ...
これは、現在の使用状況では正常に機能します。これは、入力が自分のセットアップによってフィルターされる私の個人的な使用です。
問題は、さまざまな端末間でこれを信頼できる方法にすることです。
私は入力を読み取るためにややハックなソリューションを使用します:
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
等々。
述べたように、問題はさまざまな端末でこれをどのように信頼できるようにするかです。つまり、どのバイトシーケンスが特定のキーを定義するかです。bashでさえ実現可能ですか?
1つは、tput
orまたはinfocmp
and を使用して、それによって与えられた結果でフィルタリングすることでした。しかし、私は両方に障害があり、実際にキーを押したときに実際に読んだものtput
とはinfocmp
異なります。同じことが、例えばbashでCを使用する場合にも当てはまります。
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)';
}
たとえばlinux
、定義どおりに読み取られた歩留まりシーケンスはxterm
、によって設定されTERM
ますが、そうではありません。
たとえば、左矢印:
tput
/infocmp
:\x1 O D
read
:\x1 [ D
何が欠けていますか?
zsh
使用した基本的なterminfoクエリに加えて、組み込みのcursesサポート(zsh / cursesモジュール内)があることに注意してください。echoti
$terminfo
dialog
バリアントの1つを使用するか、まともなncurses
サポートのある言語を使用してください(たとえば、「スクリプト」言語を使いたい場合は、perlまたはpython)。