Отменить завершение, но только завершение, в zsh

13

Когда функция завершения занимает много времени, я могу прервать ее , нажав Ctrl+ C(клавиша прерывания терминала, отправляет SIGINT) или Ctrl+ G(привязано к send-break). Затем я остался с незавершенным словом.

Тем не менее, если мне случится нажать Ctrl+ Cили Ctrl+, Gкак только завершится функция завершения, нажатие моей клавиши может отменить командную строку и дать мне новый запрос вместо отмены завершения.

Как я могу настроить zsh так, чтобы определенный ключ отменял текущее завершение, но ничего не делал, если никакая функция завершения не активна?

Жиль "ТАК - прекрати быть злым"
источник

Ответы:

5

Вот решение, которое устанавливает обработчик SIGINT, который делает Ctrl+ Cтолько прерывание, когда завершение активно.

# 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
источник
0

Я не знаю, является ли это приемлемым решением или нет, но отправка SIGSTOP ( Ctrl+ S), кажется, дает желаемый эффект, с дополнительным преимуществом, что вы можете снова запустить автозаполнение, если вы отправляете SIGSTART ( Ctrl+ Q) перед вводом что-нибудь еще. Я не эксперт по контролю за работой, хотя, так что это может оставить некоторый дополнительный беспорядок, связанный с остановленной работой.

Аарон Окано
источник
1
Ctrl + S и Ctrl + Q - команды управления потоком. Они влияют только на вывод на терминал, что здесь не имеет значения. Как и ожидалось, Ctrl + S не имеет никакого эффекта во время завершения (zsh отключает настройку терминала в любом случае, он захватывает комбинацию клавиш). Нажатие Ctrl + Z (которое отправляет SIGTOP) также не имеет никакого эффекта.
Жиль "ТАК - перестань быть злым"
Благодарность! Я не был полностью уверен, что происходит на заднем плане. Все, что я видел, было то, что я получил контроль над терминалом назад.
Аарон Окано