Annulla il completamento, ma solo il completamento, in zsh


13

Quando una funzione di completamento richiede molto tempo, posso interromperla premendo Ctrl+ C(tasto di interruzione del terminale, invia SIGINT) o Ctrl+ G(associato a send-break). Mi rimane quindi la parola incompleta.

Tuttavia, se mi capita di premere Ctrl+ Co Ctrl+ Gproprio quando termina la funzione di completamento, la mia pressione del tasto potrebbe annullare la riga di comando e darmi un nuovo prompt invece di annullare il completamento.

Come posso impostare zsh in modo che un determinato tasto annulli un completamento in corso ma non faccia nulla se nessuna funzione di completamento è attiva?

Risposte:


5

Ecco una soluzione che imposta un gestore SIGINT che fa Ctrl+ Cinterrompere solo quando il completamento è attivo.

# 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
}

0

Non so se questa sia una soluzione accettabile o meno, ma l'invio di un SIGSTOP ( Ctrl+ S) sembra avere l'effetto desiderato, con l'ulteriore vantaggio di poter avviare nuovamente il completamento automatico se si invia un SIGSTART ( Ctrl+ Q) prima di digitare qualunque altra cosa. Non sono un esperto di controllo del lavoro, quindi questo potrebbe lasciare qualche disordine aggiuntivo relativo al lavoro interrotto.


1
Ctrl + S e Ctrl + Q sono comandi di controllo del flusso. Interessano solo l'output al terminale, che qui è irrilevante. Com'era prevedibile, Ctrl + S non ha alcun effetto durante il completamento (zsh disabilita comunque l'impostazione del terminale, afferra la combinazione di tasti). La pressione di Ctrl + Z (che invia SIGTOP) non ha alcun effetto.
Gilles 'SO- smetti di essere malvagio' il

Grazie! Non ero del tutto sicuro di cosa stesse succedendo in background. Tutto quello che ho visto è che ho ripreso il controllo del terminale.
Aaron Okano,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.