Bir anahtarın hangi tuş eşlemesinde bağlı olduğunu nasıl öğrenebilirim?


63

Bir 'd' anahtarını yeniden gnus-article-modebaşlattım, ancak nokta bir eklenti üzerindeyken eski davranışı hala etkin. Yeniden bağlama işleminin orada yapmanın etkili olmadığını görebiliyorum C-h k d, ancak bu noktada hangi anahtar eşlemin geçerli olduğunu söylemiyor, böylece yeniden adlandırabilirim.

Bunu öğrenmenin bir yolu var mı?

İşte kesin bir örnek: Kötülük kullanıyorum ve makalelerin hareket modunda olmasını istiyorum. Klavye düzenimde yukarı çıkmanın anahtarı olarak 'd' yapılandırdım.

(evil-mode 1)
(add-to-list 'evil-motion-state-modes 'gnus-article-mode)
(setq evil-emacs-state-modes (remove 'gnus-article-mode evil-emacs-state-modes))
(define-key evil-motion-state-map "d" 'evil-previous-line)

Kötü anahtarların dikkate alındığından emin olmak için, gnus anahtarını yerel haritada belirledim:

(defun as/alter-article-evil-map ()
  (local-unset-key "d"))
(add-hook 'gnus-article-mode-hook 'as/alter-article-evil-map)

Maalesef, nokta bir ek üzerindeyken, 'd' tuşu artık artmaz ancak eki silmemi önerir. Sanırım bu noktada başka bir bağ daha aktif, yani soru.

Çözüm Kullanılan keymaps-at-pointkeymap'i bir text özelliğinden bulmak için aşağıdakileri kullandım. Daha sonra keymap'in ismini bulmak için ilişkili fonksiyonun koduna baktım gnus-mime-button-map. Aşağıdaki kod istediğimi yapar:

(defun as/alter-article-evil-map ()
  (define-key gnus-mime-button-map "d" nil))
(add-hook 'gnus-article-mode-hook 'as/alter-article-evil-map)

3
Bu sözde kod Lisp'i ve açıklamayı Emacs'in bir anahtarın nasıl göründüğüne ilişkin üst düzey kılavuzunuz olarak kullanın : Elisp el kitabı, düğümSearching Keymaps . Ayrıca düğümlerin Bkz Functions for Key Lookupve Active Keymaps.
Drew

İkinci fonksiyondaki ilk cevabımla ilgili oldukça büyük bir hata vardı. Bunu şimdi düzelttim, bu yüzden anahtarlığınızı bulabiliyor olmalı. Tekrar deneyebilir misin
Malabarba

Yanıtlar:


61

Emacs 25

Yorumlarda @YoungFrog tarafından belirtildiği gibi, Emacs 25.1 ile başlayarak , anahtar bağları C-h ktanımlamanın eski usulü size anahtarın hangi anahtar eşlemede bulunduğunu da söyleyecektir.

Emacs öncesi 25

Bununla ilgili bazı kodlar var , ancak her şeyi kapsamadığı için eksik. Aşağıda bunun geliştirilmiş bir versiyonu var.

Anahtarlar 9 (!) Şekilde bağlanabilir. Teşekkür için @Drew için bu linke (ayrıca tarafından desteklenen bu tam listesi ile birlikte). Öncelik sırasına göre, bunlar:

  1. Bir terminale özgü tuş takımı overriding-terminal-local-map,. Bu set-transient-mapişlev tarafından tanımlanır .
  2. Tampon-yerel geçersiz kılma haritası overriding-local-map. Eğer bu ayarlanmışsa, 3-8 arasındaki öğeler atlanır (muhtemelen neden çoğunu görmüyorsunuz).
  3. Noktada aracılığıyla keymapmetin Mülkiyet (gerçek metin üzerinde ya da bindirmeleri gidebiliriz olan).
  4. Esasen etkin minör-modları farklı olası setleri taklit Bir değişken, emulation-mode-map-alists.
  5. Büyük modların küçük modların ana bağlarını geçersiz kılabileceği bir değişken minor-mode-overriding-map-alist,.
  6. Tuşları saklanan gerçek küçük modlarminor-mode-map-alist .
  7. Noktada (tekrar), local-maptext özelliği ile. Bu varsa, madde 8 atlanır.
  8. İşlev tarafından döndürülen standart arabellek yerel anahtar haritası (ana mod veya arabellek yerel tuşlarının gittiği yer) current-local-map.
  9. Küresel tuş eşleşmesi , döndürdüğü current-global-map.

Ayrıca yarı öğe 10 da var. Yukarıdaki prosedürde bulunan her ne olursa olsun, yine de yeniden gönderilmiş olabilir.

Aşağıdaki işlev , bu olasılıkların bazılarını (en muhtemel olanları) sorgular ve sonucu döndürür veya yazdırır.

(defun locate-key-binding (key)
  "Determine in which keymap KEY is defined."
  (interactive "kPress key: ")
  (let ((ret
         (list
          (key-binding-at-point key)
          (minor-mode-key-binding key)
          (local-key-binding key)
          (global-key-binding key))))
    (when (called-interactively-p 'any)
      (message "At Point: %s\nMinor-mode: %s\nLocal: %s\nGlobal: %s"
               (or (nth 0 ret) "") 
               (or (mapconcat (lambda (x) (format "%s: %s" (car x) (cdr x)))
                              (nth 1 ret) "\n             ")
                   "")
               (or (nth 2 ret) "")
               (or (nth 3 ret) "")))
    ret))

Bunların her biri için ilki hariç yerleşik işlevler vardır, o yüzden bir tane oluşturmalıyız (ayrıca yukarıda bağlanan kodun geliştirilmiş bir versiyonunu da).

(defun key-binding-at-point (key)
  (mapcar (lambda (keymap) (when (keymapp keymap)
                             (lookup-key keymap key)))
          (list
           ;; More likely
           (get-text-property (point) 'keymap)
           (mapcar (lambda (overlay)
                     (overlay-get overlay 'keymap))
                   (overlays-at (point)))
           ;; Less likely
           (get-text-property (point) 'local-map)
           (mapcar (lambda (overlay)
                     (overlay-get overlay 'local-map))
                   (overlays-at (point))))))

Nokta bir ek üzerindeyken davranışın etkin olduğunu söylediğiniz için, bu tuş bağlantısının bir bindirme veya metin özelliği üzerinde gerçekleşmesi iyi bir ihtimaldir.

Bu işe yaramazsa , aşağıdaki komutu da deneyin. Sadece imleci ekin üzerine getirin ve yapın M-x keymaps-at-point.

(defun keymaps-at-point ()
  "List entire keymaps present at point."
  (interactive)
  (let ((map-list
         (list
          (mapcar (lambda (overlay)
                    (overlay-get overlay 'keymap))
                  (overlays-at (point)))
          (mapcar (lambda (overlay)
                    (overlay-get overlay 'local-map))
                  (overlays-at (point)))
          (get-text-property (point) 'keymap)
          (get-text-property (point) 'local-map))))
    (apply #'message
           (concat 
            "Overlay keymap: %s\n"
            "Overlay local-map: %s\n"
            "Text-property keymap: %s\n"
            "Text-property local-map: %s")
           map-list)))

Bu bana, anahtarın yerel bir bağı olup olmadığını ve hangi komuta bağlı olduğunu söyleyecektir, ancak yine de bana gelen anahtar haritanın adını söylemiyor .
nispio

Yerel bir bağlayıcı varsa @ nispio, ana modun anahtar haritasından veya bir çağrıdan yerel set anahtarına kadar olması gerekir. Ne yazık ki, iki davayı birbirinden ayırmanın kusursuz bir yolu yok.
Malabarba

1
@ Malababa "Ne yazık ki, iki olayı birbirinden ayırmanın kolay yolu yok mu?" Elbette tüm bilgiler mevcut. Ayrıca, her ana modun tam olarak bir mod haritası var mı? Değilse, hangi ana mod haritasının aktif olduğunu söylemenin bir yolu var mı?
nispio

1
Henüz çıkarılmamış emacs 25'ten başlayarak, "Ch k" bazı (iyi, "umarım" da) bazı durumlarda hangi keymap'in (daha doğrusu: bu keymap değerini değeri olarak tutan bir sembol) belirli bir tuş takımının ne olduğunu söyleyecektir. tanımladı. örnek çıktı:k runs the command gnus-summary-kill-same-subject-and-select (found in gnus-summary-mode-map), which is (...)
YoungFrog

2
İlgilenen herkes için, işte emacs 25 + 'daki kilit bağlamanın anahtar haritasını gösteren ilgili taahhüt .
Kaushal Modi

2

Bu hakkında:

(defun my-lookup-key (key)
  "Search for KEY in all known keymaps."
  (mapatoms (lambda (ob) (when (and (boundp ob) (keymapp (symbol-value ob)))
                      (when (functionp (lookup-key (symbol-value ob) key))
                        (message "%S" ob))))
            obarray))

Örneğin (my-lookup-key (kbd "C-c v v")), *Message*tampondaki listeyi almak için :

global-map
term-pager-break-map
widget-global-map

Bu yaklaşım, örneğin aşağıdakilerden çıktı elde etmek için daha yüksek seviye anahtar haritaya dahil edilen alt anahtar eşlemesini aramak için kullanışlıdır:

(my-lookup-key (kbd "d"))

olduğu vc-prefix-mapiçine dahil edildiği global-map:

(eq (lookup-key global-map (kbd "C-x v")) 'vc-prefix-map)

Dahil etmek için filtreleme koşulunu değiştirirseniz keymapp- önekleri her zaman arayabileceksiniz:

(defun my-lookup-key-prefix (key)
  "Search for KEY as prefix in all known keymaps."
  (mapatoms (lambda (ob) (when (and (boundp ob) (keymapp (symbol-value ob)))
                      (when (let ((m (lookup-key (symbol-value ob) key)))
                              (and m (or (symbolp m) (keymapp m))))
                        (message "%S" ob))))
            obarray))

Yani rst-mode-mapher ikisinde de bulunacak:

(my-lookup-key-prefix (kbd "C-c C-t"))
(my-lookup-key-prefix (kbd "C-c C-t C-t"))

1

Aşağıdakilerin hangid anahtar haritayı nasıl bulabilirim sorusuna yanıt vermediğini biliyorum , ancak bu durumda anahtarın kullanıcının isteğine göre davranmasını sağlamak için nasıl bir temel sorun olduğunu ele alıyor . Tercih edilirse, bu cevabı kaldırabilir ve bu konuyla ilgili başka bir soruya + cevaba dönüştürebilirim.

text-property/overlayHaritayı geçersiz kılma yöntemi olarak kullanabilmeniz gerekir:

(let ((map (make-sparse-keymap)))
  (define-key map "d" 'evil-previous-line)
  (setq overriding-local-map map))

Gereğince Aktif Haritaların Kontrolü , overriding-local-mapbaşka her aktif harita önceliklidir overriding-terminal-local-map.


Bu her şeyi kırar: Artık özet modunda bir mesaj açamıyorum ve kötülük ve buz sarkıtları çalışmayı durduruyor.
bra kas

Bu her şeyi kırar: Artık özet modunda bir mesaj açamıyorum ve kötülük ve buz sarkıtları çalışmayı durduruyor.
Emily Hoover

0

emacs-buttons , buttons-displaybir önek argümanıyla tüm mevcut ciltlemelerin özyinelemeli bir görselleştirmesini gösterir.

(Feragatname: Ben paketin yazarıyım)

https://github.com/erjoalgo/emacs-buttons/blob/master/doc/img/sample-visualization.png

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.