Mensimulasikan operasi mouse dengan keyboard

8

Adakah cara, melalui beberapa perintah yang dapat dipanggil oleh keyboard, membuat Emacs berpikir bahwa saya mengklik pada titik tertentu (sehingga melakukan apa pun yang akan dilakukan jika saya mengklik di sana, misalnya ikuti tautan atau pop up menu )? Atau saya mengarahkan mouse pada titik (sehingga ujung alat muncul)?

[Motivasi: Beberapa mode menghias buffer, mengubah beberapa teks menjadi tautan dan sebagainya. Saya mungkin tahu bagaimana melakukan sesuatu dengan mouse (mis. Klik di atasnya), tetapi bukan pintasan / perintah keyboard yang setara untuk memanggil. Tentu saja saya harus membaca dokumentasi untuk mode dan mempelajarinya, tetapi menganggapnya sebagai pertanyaan yang menarik.]

ShreevatsaR
sumber
2
Saya terutama tertarik pada apakah Anda dapat mensimulasikan hover dengan keyboard. Tidak jarang tip alat menjadi tempat termudah untuk menemukan informasi yang saya cari.
nispio
@nispio Anda dapat melihat pratinjau tooltip pada titik dengan bantuan tampilan lokal
Malabarba
@Malabarba: Terima kasih banyak; yang sepertinya berhasil!
ShreevatsaR

Jawaban:

5

Seringkali, menavigasi ke lokasi dan menekan beberapa tombol akan memiliki efek yang sama dengan mengklik di lokasi itu. Tidak ada mekanisme built-in yang memastikan ini, hanya saja mode biasanya ditulis seperti itu.

Anda dapat membuat acara mouse ( klik , dobel / tripel / ... klik , tombol turun / atas , seret , gerak ). Semua acara mouse memiliki bentuk di (TYPE POSITION . EXTRA-DATA)mana TYPE adalah simbol yang menyandikan tombol mouse, sifat tindakan (klik, seret, dll.), Dan pengubah. TYPE adalah mouse-movementuntuk acara gerak. Panggilan posn-at-pointuntuk menghasilkan POSISI untuk lokasi titik di buffer saat ini.

Berikut adalah beberapa kode bukti konsep yang mensimulasikan klik mouse pada posisi kursor ketika Anda menekan f11diikuti dengan angka. Pengubah diperhitungkan.

(defun make-mouse-event-at-point (base-event)
  (let ((posn (posn-at-point))
        (prefix "")
        (basic-type (event-basic-type base-event))
        (modifiers (event-modifiers base-event)))
    (cond
     ((and (integerp basic-type) (>= basic-type ?0) (<= basic-type ?9))
      ;; click
      (let* ((mouse-type (intern (format "%smouse-%d" prefix (- basic-type ?0))))
             (click-count 1)
             (type (event-convert-list (append modifiers (list mouse-type)))))
        (list type posn click-count)))
     (t
      (error "Unsupported key for mouse event: %s" (event-basic-type base-event))))))
(defun simulate-mouse-event-at-point ()
  (interactive)
  (let ((event (make-mouse-event-at-point last-input-event)))
    (setq unread-command-events (cons event unread-command-events))))

(defvar simulate-mouse-event-map (make-sparse-keymap))
(global-set-key [f11] simulate-mouse-event-map)
(define-key simulate-mouse-event-map [t] 'simulate-mouse-event-at-point)

Simulasi melayang-layang terlihat lebih sulit.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
Ini tidak mensimulasikan melayang, tetapi jika semua yang Anda inginkan adalah melihat tooltip, Anda dapat melihat pratinjau tooltip pada titik dengan bantuan tampilan lokal
Malabarba
Saya masih mencoba ini, tetapi sebagai tanggapan terhadap beberapa kalimat pertama: alasan saya mengajukan pertanyaan ini adalah bahwa saya bekerja dalam mode di mana "beberapa kunci" tidak jelas (kebetulan C-c C-, RET, tapi saya harus mencari dokumentasi mode untuk itu).
ShreevatsaR
Sebenarnya ini tidak cukup berhasil. Dalam mode yang sedang saya kerjakan, beberapa kode diubah menjadi tautan, dan mengklik dengan mouse akan membuka menu pada titik tersebut. Melakukan hal di atas dengan f11 1tidak melakukan itu (itu mencetak sesuatu di minibuffer tapi itu tidak setara dengan klik mouse pada tautan) meskipun f11 3tampaknya setara dengan <mouse-3>dan seterusnya.
ShreevatsaR
@ShreevatsaR Mungkin tindakan klik mouse yang Anda inginkan terikat down-mouse-1dan tidak mouse-1? Bagaimana saya bisa mengetahui di mana kunci tombol terikat? dapat membantu menyelidiki hal ini.
Gilles 'SANGAT berhenti menjadi jahat'