ich weiss Bescheidpreexec()Hooks für zsh und wie dies in Bash erreicht werden kann. (Verknüpfung)
Aber kann ich dieStromeingangwährend Sie noch tippen?
Die Idee hinter dieser Frage ist folgende:
Um ein schnelleres Erlernen von Befehlen, Argumenten und Tastenkombinationen zu ermöglichen, möchte ich den eingegebenen Befehl in einer „Datenbank“ mit Hinweisen zu „Hilfe“, „Gut zu wissen“ und „Tastenkombinationen“ suchen und diese in einer anderen Sitzung mit Screen/TMUX anzeigen, während ich die andere eintippe.
Ist es möglich, den aktuell eingegebenen Befehl zu überprüfen? Wenn dies nicht bei jedem Tastendruck funktioniert, könnte auch eine Zeitschleife funktionieren.
Antwort1
Ich kann nur für die Fälle antworten zsh
, in denen dies möglich ist: ja.
Erstens gibt es bereits einige Widgets fürinkrementelle Fertigstellung. Das erste ist offenbar das von Y. Fujii. Obwohlseine Websiteist auf Japanisch, Sie können also leicht herausfinden, wie es funktioniert und wie man es verwendet, auch ohne die Sprache zu sprechen. Auto-fuist eine Erweiterung des Originalskripts.
Soweit die Referenzen. In zsh
derzsh-Zeileneditor( zle
) ist für die interaktive Nutzung der Kommandozeile zuständig. Neben vielen anderen Variablen, die Widgets zur Verfügung stehen (siehe man zshzle
), sind diese für Sie von Interesse, da Sie dieaktuelle Befehlszeile:
$PUFFER: Der gesamte Inhalt des Bearbeitungspuffers.
$LBUFFER: Der Teil des Puffers, der links von der Cursorposition liegt.
$RBUFFER: Der Teil des Puffers, der rechts von der Cursorposition liegt.
Diese Variablen sind beschreibbar, was die aktuelle Befehlszeile ändert!
Um jeden Tastendruck zu erfassen, können Sie das Widget ändern self-insert
, das (standardmäßig) für jeden Tastendruck außer LF
oder ausgeführt wird CR
. Hier ist ein Beispiel, das nichts wirklich Nützliches tut, aber für jeden Tastendruck einen Punkt anfügt $RBUFFER
– nur um zu veranschaulichen, wie das funktioniert:
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
ist das integrierte Widget, sodass wir nicht in eine Endlosschleife geraten.
Sie können also entweder von vorne beginnen oder Fujiis Skript verwenden und es ändern. Ein Vorteil des letzteren ist, dass es auch einige Löschvorgänge für Tastenanschläge übernimmt, die ich hier vernachlässigt habe.
Antwort2
Für Bash können Sie folgendes test.sh
Skript erstellen:
#!/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
Es handelt sich um ein einfaches Skript, das einige Tastaturcodes empfängt und auf dem Bildschirm ausgibt. Übergeben Sie ihm nun die Tastaturcodes:
$ stdbuf -o0 xinput test 'AT Translated Set 2 keyboard' | bash test.sh
Wenn Sie jetzt in ein anderes Terminal tippen, sollte es Tastenwerte empfangen. Ich weiß nicht, ob es eine clevere Möglichkeit gibt, Tastencodes ihren ASCII-Werten zuzuordnen, also mache ich nur eine einfache Zuordnung. Sie können diesen Code verbessern, damit er auch auf andere Tasten reagiert. Beachten Sie jedoch, dass das Skript alle Tastatureingaben empfängt und nicht nur an ein bestimmtes Terminal weiterleitet.
Was die Aufgabe selbst betrifft (Überprüfung des aktuell eingegebenen Befehls), können Sie compgen -c
basierend auf dem übergebenen Argument eine Liste möglicher Vervollständigungen generieren:
$ compgen -c 'ls' | head -1
ls
$ compgen -c 'lsp' | head -1
lspci