Batalkan penyelesaian, tetapi hanya penyelesaian, di zsh

13

Ketika fungsi penyelesaian membutuhkan waktu lama, saya dapat menghentikannya dengan menekan Ctrl+ C(kunci interupsi terminal, mengirim SIGINT) atau Ctrl+ G(terikat ke send-break). Saya kemudian ditinggalkan dengan kata-kata yang tidak lengkap.

Namun, jika saya menekan Ctrl+ Catau Ctrl+ Gsaat fungsi selesai, tekan tombol saya dapat membatalkan baris perintah dan memberi saya prompt baru alih-alih membatalkan penyelesaian.

Bagaimana saya mengatur zsh sehingga kunci tertentu akan membatalkan penyelesaian yang sedang berlangsung tetapi tidak melakukan apa-apa jika tidak ada fungsi penyelesaian yang aktif?

Gilles 'SANGAT berhenti menjadi jahat'
sumber

Jawaban:

5

Berikut adalah solusi yang mengatur penangan SIGINT yang membuat Ctrl+ Chanya mengganggu ketika penyelesaian aktif.

# 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
}
Mat
sumber
0

Saya tidak tahu apakah ini solusi yang dapat diterima atau tidak, tetapi mengirimkan SIGSTOP ( Ctrl+ S) tampaknya memiliki efek yang diinginkan, dengan manfaat tambahan bahwa Anda dapat memulai lagi pengisian otomatis jika Anda mengirim SIGSTART ( Ctrl+ Q) sebelum mengetik ada yang lain. Saya bukan ahli dalam kontrol pekerjaan, jadi ini mungkin meninggalkan beberapa kekacauan tambahan terkait dengan pekerjaan yang dihentikan.

Aaron Okano
sumber
1
Ctrl + S dan Ctrl + Q adalah perintah kontrol aliran. Mereka hanya memengaruhi keluaran ke terminal, yang tidak relevan di sini. Bisa ditebak, Ctrl + S tidak memiliki efek selama penyelesaian (zsh tetap menonaktifkan pengaturan terminal, itu meraih kombinasi tombol). Menekan Ctrl + Z (yang mengirim SIGTOP) juga tidak berpengaruh.
Gilles 'SANGAT berhenti menjadi jahat'
Terima kasih! Saya tidak sepenuhnya yakin apa yang sedang terjadi di latar belakang. Yang saya lihat adalah saya bisa mengendalikan terminal kembali.
Aaron Okano