Abschluss abbrechen, aber nur Abschluss in zsh

13

Wenn eine Abschlussfunktion lange dauert, kann ich sie durch Drücken von Ctrl+ C(Terminal-Interrupt-Taste, SIGINT senden) oder Ctrl+ G(gebunden an send-break) unterbrechen . Mir bleibt dann das unvollständige Wort.

Wenn ich jedoch zufällig Ctrl+ Coder Ctrl+ Gdrücke, sobald die Abschlussfunktion beendet ist, wird die Befehlszeile möglicherweise abgebrochen, und ich erhalte eine neue Aufforderung, anstatt den Abschluss abzubrechen.

Wie kann ich zsh so einrichten, dass eine bestimmte Taste einen laufenden Abschluss abbricht, aber nichts tut, wenn keine Abschlussfunktion aktiv ist?

Gilles 'SO - hör auf böse zu sein'
quelle

Antworten:

5

Hier ist eine Lösung, die einen SIGINT-Handler einrichtet, der Ctrl+ Cnur unterbricht, wenn der Abschluss aktiv ist.

# A completer widget that sets a flag for the duration of
# the completion so the SIGINT handler knows whether completion
# is active. It would be better if we could check some internal
# zsh parameter to determine if completion is running, but as 
# far as I'm aware that isn't possible.
function interruptible-expand-or-complete {
    COMPLETION_ACTIVE=1

    # Bonus feature: automatically interrupt completion
    # after a three second timeout.
    # ( sleep 3; kill -INT $$ ) &!

    zle expand-or-complete

    COMPLETION_ACTIVE=0
}

# Bind our completer widget to tab.
zle -N interruptible-expand-or-complete
bindkey '^I' interruptible-expand-or-complete

# Interrupt only if completion is active.
function TRAPINT {
    if [[ $COMPLETION_ACTIVE == 1 ]]; then
        COMPLETION_ACTIVE=0
        zle -M "Completion canceled."            

        # Returning non-zero tells zsh to handle SIGINT,
        # which will interrupt the completion function. 
        return 1
    else
        # Returning zero tells zsh that we handled SIGINT;
        # don't interrupt whatever is currently running.
        return 0
    fi
}
Matt
quelle
0

Ich weiß nicht, ob dies eine akzeptable Lösung ist oder nicht, aber das Senden eines SIGSTOP ( Ctrl+ S) scheint den gewünschten Effekt zu haben, mit dem zusätzlichen Vorteil, dass Sie die Autovervollständigung erneut starten können, wenn Sie ein SIGSTART ( Ctrl+ Q) vor dem Tippen senden noch etwas. Ich bin jedoch kein Experte für Job-Kontrolle, daher kann dies zusätzliche Unordnung in Bezug auf den abgebrochenen Job hinterlassen.

Aaron Okano
quelle
1
Strg + S und Strg + Q sind Befehle zur Flusssteuerung. Sie wirken sich nur auf die Ausgabe auf das Terminal aus, was hier irrelevant ist. Vorhersehbar hat Strg + S während des Abschlusses keine Auswirkung (zsh deaktiviert die Terminaleinstellung trotzdem und greift nach der Tastenkombination). Das Drücken von Strg + Z (das SIGTOP sendet) hat ebenfalls keine Auswirkung.
Gilles 'SO- hör auf böse zu sein'
Vielen Dank! Ich war mir nicht ganz sicher, was im Hintergrund vorging. Ich sah nur, dass ich die Kontrolle über das Terminal zurückerhielt.
Aaron Okano