Saya memiliki fungsi yang secara otomatis berjalan setelah pengguna melakukan beberapa tindakan. Namun, fungsi ini membutuhkan waktu lama untuk diselesaikan. Ini berarti Emacs menjadi tidak responsif untuk waktu yang singkat setelah setiap input. Untuk memperbaikinya, saya ingin memeriksa apakah pengguna telah memasukkan input baru dan jika demikian, batalkan eksekusi fungsi ini dan lanjutkan dengan input pengguna.
Apakah ada variabel yang menyimpan input keyboard yang antri? Jika tidak, apakah ada cara lain untuk memeriksa apakah pengguna telah menekan tombol sejak fungsi mulai berjalan?
while-no-input
makro. Tampaknya melakukan apa yang Anda inginkan: yaitu membatalkan eksekusi tubuhnya ketika input baru muncul.Jawaban:
OK, saya akan mencoba jawaban yang diperluas. Masalahnya, Emacs Lisp adalah single-threaded. Anda dapat memutar lebih banyak proses, tetapi tidak di dalam interpreter Emacs Lisp. Namun, input keyboard yang perlu Anda baca dari pengguna untuk mengganggu fungsi Anda perlu diproses oleh penerjemah Emacs Lisp yang sama. Ini berarti bahwa jika juru bahasa Anda macet menafsirkan beberapa kode Lisp mungkin tidak ada cara bagi Anda untuk menyela dari dalam. Inilah tempat di manual yang menggambarkan situasi ini:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html
Jadi, bagaimana Emacs masih memiliki fungsi C-g/ pembatalan? - Ada penghitung waktu dan fungsi yang dilakukan I / O (tunggu acara di loop perintah). Pengatur waktu dapat mengatur agar perhitungan Anda dilakukan dalam potongan, sehingga Anda memiliki poin dalam perhitungan Anda di mana Anda dapat melihat-lihat dan, jika perlu, mencegah semua perhitungan lebih lanjut. Fungsi I / O dapat mengirim
quit
sinyal. Makrowith-keyboard-quit
menunggu sinyal ini dan setelah diterima akan keluar dengan anggun. Namun, fungsi Anda perlu tahu untuk mengirim sinyal ini. Ini berarti bahwa jika fungsi Anda mencegah pengguna mengirim input keyboard, maka Anda tidak akan dapat memanfaatkan interupsi keyboard.Intinya: coba masukkan kode fungsi Anda
while-no-input
. Jika ini tidak berhasil, cobalah menulis ulang fungsi Anda dengan cara yang memungkinkan Emacs memproses acara papan ketik.sumber
C-g
selalu dapat menginterupsi kode lisp,while-no-input
hanya perluas ini ke input keyboard lain.(while t)
. (Tetapi sebelum Anda melakukannya, pastikan Anda telah menyimpan semua perubahan Anda).(while t)
ke dalam*scratch*
dan memukulC-x C-e
kemudianC-g
; Saya mendapatQuit
pesan, Emacs tidak macet.*scratch*
bisa dipercaya karena setiap evaluasi yang Anda lakukan ada dalam fungsi pembantu.(while t (condition-case _ (while t) (quit nil)))
, saya pikir dalam teori yang interruptible jika Anda bisa menekanC-g
pada waktu yang tepat, tetapi dalam praktiknya Anda tidak bisa.Saya akan pergi dengan
input-pending-t
. Dari dokumen:Contoh cepat:
sumber