Я знаю оpreexec()Хуки для zsh и способ, которым этого можно добиться в bash. (связь)
Но могу ли я получитьтекущий входпродолжая печатать?
Идея этого вопроса следующая:
Чтобы ускорить изучение команд, аргументов и сочетаний клавиш, я хочу найти вводимую команду в «базе данных», предоставляющей подсказки «помощь / полезно знать / сочетания клавиш» и показать их в другом сеансе с screen/tmux во время ввода в другом сеансе.
Можно ли проверить текущую набираемую команду? Если это не работает при каждом нажатии клавиши, то цикл таймера может сработать.
решение1
Я могу ответить только за то zsh
, где это можно сделать, да.
Во-первых, уже есть некоторые виджеты дляпостепенное завершение. Первый, по-видимому, принадлежит Y. Fujii. Хотяего сайтна японском языке, вы легко поймете, не зная этого языка, как он работает и как им пользоваться. Авто-фуявляется расширением оригинального сценария.
Пока что ссылки. zsh
Вредактор строк zsh( zle
) отвечает за интерактивное использование командной строки. Помимо множества других переменных, предоставляемых виджетам (см. man zshzle
), они представляют для вас интерес, поскольку вы хотите захватитьтекущая командная строка:
$БУФЕР: Все содержимое буфера редактирования.
$LBUFFER: Часть буфера, которая находится слева от позиции курсора.
$RBUFFER: Часть буфера, которая находится справа от позиции курсора.
Эти переменные доступны для записи, что изменит текущую командную строку!
Чтобы захватить каждое нажатие клавиши, вы можете изменить виджет self-insert
, который выполняется (по умолчанию) для каждого нажатия клавиши, кроме LF
или CR
. Вот пример, который не делает ничего полезного, но добавляет для каждого нажатия клавиши точку $RBUFFER
— просто для иллюстрации того, как это работает:
function self-insert() {
RBUFFER+="."
# execute some other command, but ensure they don't produce any output.
zle .self-insert
}
zle -N self-insert
.self-insert
— это встроенный виджет, поэтому мы не попадаем в бесконечный цикл.
Итак, вы можете либо начать с нуля, либо начать со скрипта Fujii и модифицировать его. Одним из преимуществ последнего является то, что он также выполняет некоторую обработку удаления нажатий клавиш, которую я здесь проигнорировал.
решение2
Для Bash вы можете создать следующий test.sh
скрипт:
#!/usr/bin/env bash
ARRAY=('1' '2' '3' '4' '5' '6' '7' '8' '9' '0' '-' '=' 'BACKSPACE' ''
'q' 'w' 'e' 'r' 't' 'y' 'u' 'i' 'o' 'p' '[' ']' 'NEWLINE' ''
'a' 's' 'd' 'f' 'g' 'h' 'j' 'k' 'l' ';' "'" '' '' '' 'z' 'x' 'c'
'v' 'b' 'n' 'm' '0' ',' '.' '/' '' '' 'SPACE')
while read row
do
if [[ "$row" == *press* ]]
then
index=$((${row/key press /}-10))
if [[ "${ARRAY[$index]}" == 'NEWLINE' ]]
then
printf "\n"
elif [[ "${ARRAY[$index]}" == 'BACKSPACE' ]]
then
echo -ne "\b \b"
elif [[ "${ARRAY[$index]}" == 'SPACE' ]]
then
printf " "
else
printf "%s" "${ARRAY[$index]}"
fi
fi
done
Это простой скрипт, который получает некоторые коды клавиатуры и выводит их на экран. Теперь передайте ему коды клавиатуры:
$ stdbuf -o0 xinput test 'AT Translated Set 2 keyboard' | bash test.sh
Теперь, если вы введете в другом терминале, он должен получить значения клавиш. Я не знаю, есть ли какой-нибудь умный способ сопоставить коды клавиш с их значениями ASCII, поэтому я просто делаю простое сопоставление. Вы можете улучшить этот код, чтобы он реагировал и на другие клавиши. Однако обратите внимание, что скрипт будет получать весь ввод с клавиатуры, а не только передаваться на один заданный терминал.
Что касается самой задачи (проверки текущей набираемой команды), то вы можете использовать ее compgen -c
для генерации списка возможных завершений на основе переданного аргумента:
$ compgen -c 'ls' | head -1
ls
$ compgen -c 'lsp' | head -1
lspci