Скасувати завершення, але лише завершення, в 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
}

0

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


1
Ctrl + S і Ctrl + Q - команди управління потоком. Вони впливають лише на вихід на термінал, що тут не має значення. Передбачувано, що Ctrl + S не має ефекту під час завершення (zsh все одно відключає налаштування терміналу, він захоплює комбінацію клавіш). Натискання клавіш Ctrl + Z (яке надсилає SIGTOP) також не робить ефекту.
Жил "ТАК - перестань бути злим"

Спасибі! Я не був повністю впевнений, що відбувається на задньому плані. Все, що я побачив, це те, що я отримав контроль над терміналом назад.
Аарон Окано
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.