Cancelar finalización, pero solo finalización, en zsh

13

Cuando una función de finalización lleva mucho tiempo, puedo interrumpirla presionando Ctrl+ C(tecla de interrupción de terminal, envía SIGINT) o Ctrl+ G(vinculado a send-break). Entonces me queda la palabra incompleta.

Sin embargo, si presiono Ctrl+ Co Ctrl+ Gjusto cuando finaliza la función de finalización, al presionar la tecla puede cancelar la línea de comando y darme un nuevo aviso en lugar de cancelar la finalización.

¿Cómo puedo configurar zsh para que una determinada tecla cancele una finalización continua pero no haga nada si no hay ninguna función de finalización activa?

Gilles 'SO- deja de ser malvado'
fuente

Respuestas:

5

Aquí hay una solución que configura un controlador SIGINT que hace que Ctrl+ Csolo interrumpa cuando la finalización está activa.

# 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
}
Mate
fuente
0

No sé si esta es una solución aceptable o no, pero enviar un SIGSTOP ( Ctrl+ S) parece tener el efecto deseado, con el beneficio adicional de que puede iniciar el autocompletado nuevamente si envía un SIGSTART ( Ctrl+ Q) antes de escribir Algo más. Sin embargo, no soy un experto en control de trabajo, por lo que esto puede dejar un desorden adicional relacionado con el trabajo detenido.

Aaron Okano
fuente
1
Ctrl + S y Ctrl + Q son comandos de control de flujo. Solo afectan la salida al terminal, lo cual es irrelevante aquí. Como era de esperar, Ctrl + S no tiene efecto durante la finalización (zsh desactiva la configuración del terminal de todos modos, toma la combinación de teclas). Presionar Ctrl + Z (que envía SIGTOP) tampoco tiene ningún efecto.
Gilles 'SO- deja de ser malvado'
¡Gracias! No estaba completamente seguro de lo que estaba sucediendo en el fondo. Todo lo que vi fue que recuperé el control de la terminal.
Aaron Okano