Bagaimana mendeteksi penekanan tombol yang tidak mengedit buffer?

8

Apa cara terbaik untuk mendeteksi penekanan tombol (misalnya melalui kail) yang tidak mengedit buffer? Maksud saya hal-hal seperti tombol panah untuk gerakan titik, panggilan ke beginning-of-buffer, dll.

Alasan untuk ini adalah bahwa saya sedang mengerjakan beberapa ycmdbinding untuk emacs, dan saya ingin dapat mendeteksi (setidaknya secara heuristik) ketika pengguna telah berhenti mengedit dan bergerak di sekitar buffer. Ini adalah saat yang tepat untuk mengirim konten buffer untuk parsing. Klien vim melakukan ini ketika pengguna keluar dari mode penyisipan, dan saya mencoba untuk meniru perilaku itu.

abingham
sumber
8
Anda mungkin tertarik pada pengatur waktu menganggur untuk hal-hal semacam ini: gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html
giordano
2
Gagasan lain (atau penyempurnaan gagasan dengan penghitung waktu idle): menyarankan self-insert-commanduntuk membatalkan dan menjadwal ulang penghitung waktu alih-alih menggunakan penghitung waktu idle. Dengan cara ini, bahkan jika pengguna melakukan sesuatu, penghitung waktu tidak diatur ulang kecuali "sesuatu" adalah penyisipan teks.
mbork
2
mbork: after-change-functionsadalah mekanisme umum untuk bereaksi terhadap perubahan teks.
phils
1
Gunakan a post-command-hook. Itu akan memicu semuanya, jadi Anda mungkin perlu memfilter apa yang memicu sebelum mengambil tindakan apa pun yang Anda inginkan.
Malabarba
1
Tidak yakin itu relevan untuk masalah khusus ini, tetapi buffer-chars-modified-tickfungsinya mungkin bermanfaat.
Jon O.

Jawaban:

2

Tambahkan kait berikut:

  • Untuk pre-command-hook, atur beberapa variabel sentinel ke t- ini menandakan perintah tidak berubah.
  • Untuk after-change-functions, setel nilai sentinel ini ke nil. (Ini adalah hook, itu tidak terdengar seperti itu; terima kasih kepada @phils untuk menunjukkan ini.)
  • Untuk post-command-hook, periksa nilai sentinel ini dan jalankan fungsi Anda.

Ini mungkin atau mungkin tidak berfungsi tergantung pada urutan eksekusi. Jika tidak, beri tahu saya di komentar di bawah.


Ketika saya pulang kerja, saya akan memposting contoh.

Sean Allred
sumber
Saya harus pergi bekerja sekarang ...
Sean Allred
2
Jangan menyarankan sisipan diri. Gunakan after-change-functions
Malabarba
Saya akan mencoba ini ketika ada kesempatan.
abingham
4
@abingham Sebagai aturan umum, kait lebih disukai daripada saran. Kait dirancang khusus untuk Anda melampirkan fungsi, sedangkan saran adalah cara untuk melampirkan sesuatu di tempat yang tak terduga. Dalam kasus khusus ini, juga tidak disarankan untuk menyarankan beberapa fungsi yang sangat mendasar, karena berinteraksi tidak dapat diandalkan dengan kompilasi byte.
Malabarba
2
Saya pikir Sean dimaksudkan untuk merujuk post-self-insert-hook(sedikit jawaban yang tampaknya membingungkan hook dengan menasihati self-insert-command). Bagaimanapun, saya pikir Anda umumnya akan lebih suka after-change-functionskarena itu benar-benar melakukan apa yang Anda inginkan (karena memasukkan sendiri bukan satu-satunya jenis stroke kunci yang memodifikasi buffer).
phils
0

Hanya pemikiran saja -

Ini seharusnya tidak benar-benar tentang "penekanan tombol", tetapi tentang perintah - tidak peduli bagaimana mereka dieksekusi, bukan ? Jika saya mengerti dengan benar, Anda benar-benar mencari cara untuk mengetahui apakah perintah yang diberikan dipanggil memodifikasi buffer.

Jika demikian, maka mungkin lakukan sesuatu seperti ini:

  • Letakkan fungsi pada pre-command-hookyang (1) mencatat nilai saat ini (buffer-modified-p)dan kemudian (2) menggunakan set-modified-puntuk membuat buffer tidak dimodifikasi.

  • Letakkan fungsi pada post-command-hookyang (1) memeriksa apakah perintah memodifikasi buffer (dengan membandingkan nilai yang direkam dengan nilai saat ini yang baru (buffer-modified-p)), kemudian bertindak sesuai, dan (2) jika nilai baru nilkemudian diatur ulang ke nilai pra-perubahan menggunakan set-modified-p.

Agak berat (memeriksa setiap perintah yang dipanggil), tetapi mungkin patut dicoba.

Jika bagian " bertindak sesuai " hanyalah no-op untuk semua perintah modifikasi buffer, dan jika itu juga no-op untuk banyak perintah yang tidak memodifikasi (misalnya karena Anda baru saja melakukannya pada perintah non-modifikasi sebelumnya), maka setidaknya Anda tidak akan melakukan tindakan " bertindak sesuai " lebih dari yang diperlukan. Tetapi bagian pengecekan saja mungkin mahal / berlebihan (memperlambat banyak hal) - coba lihat.

Drew
sumber