Cancelar conclusão, mas somente conclusão, em zsh

13

Quando uma função de conclusão demora muito tempo, posso interrompê-la pressionando Ctrl+ C(tecla de interrupção do terminal, envia SIGINT) ou Ctrl+ G(ligado a send-break). Fico então com a palavra incompleta.

No entanto, se eu pressionar Ctrl+ Cou Ctrl+ Gassim que a função de conclusão for concluída, minha tecla pressionada poderá cancelar a linha de comando e fornecer um novo prompt em vez de cancelar a conclusão.

Como posso configurar o zsh para que uma determinada chave cancele uma conclusão em andamento, mas não faça nada se nenhuma função de conclusão estiver ativa?

Gilles 'SO- parar de ser mau'
fonte

Respostas:

5

Aqui está uma solução que configura um manipulador SIGINT que Ctrl+ Cinterrompe apenas quando a conclusão está ativa.

# 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
fonte
0

Não sei se essa é uma solução aceitável ou não, mas o envio de um SIGSTOP ( Ctrl+ S) parece ter o efeito desejado, com o benefício adicional de poder iniciar o preenchimento automático novamente se enviar um SIGSTART ( Ctrl+ Q) antes de digitar algo mais. No entanto, eu não sou especialista em controle de tarefas, portanto, isso pode deixar uma desordem adicional relacionada ao trabalho interrompido.

Aaron Okano
fonte
1
Ctrl + S e Ctrl + Q são comandos de controle de fluxo. Eles afetam apenas a saída do terminal, o que é irrelevante aqui. Previsivelmente, Ctrl + S não tem efeito durante a conclusão (o zsh desativa a configuração do terminal de qualquer maneira, ele pega a combinação de teclas). Pressionar Ctrl + Z (que envia SIGTOP) também não tem efeito.
Gilles 'SO- stop be evil'
Obrigado! Eu não tinha certeza do que estava acontecendo em segundo plano. Tudo o que vi foi que recuperei o controle do terminal.
Aaron Okano 26/09