मैं यह कैसे पता लगा सकता हूं कि किस कीम की चाबी बंधी है?


63

मेरे पास एक 'd' कुंजी है gnus-article-mode, लेकिन इसका पुराना व्यवहार तब भी सक्रिय है जब बिंदु एक अनुलग्नक पर होता है। मैं देख सकता हूं कि ऐसा करने से रिबॉन्डिंग का असर नहीं हुआ C-h k d, लेकिन यह मुझे यह नहीं बता रहा है कि उस बिंदु पर क्या कीमैप प्रभावी है, ताकि मैं इसे रिवाइंड कर सकूं।

क्या इसका पता लगाने का कोई तरीका है?

यहाँ एक सटीक उदाहरण है: मैं बुराई का उपयोग कर रहा हूं, और मैं चाहता हूं कि लेख गति में हो। मेरे कीबोर्ड लेआउट के लिए मेरे पास 'd' है जिसे ऊपर जाने की कुंजी के रूप में कॉन्फ़िगर किया गया है।

(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)

यह सुनिश्चित करने के लिए कि दुष्ट कुंजी को ध्यान में रखा गया है, मैं स्थानीय मानचित्र में gnus कुंजी को अनसेट करता हूं:

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

दुर्भाग्य से, जब बिंदु एक अनुलग्नक पर होता है, तो 'd' कुंजी अब ऊपर नहीं जाती है, लेकिन यह मुझे अनुलग्नक को हटाने की पेशकश करती है। मुझे लगता है कि एक और बाध्यकारी उस बिंदु पर सक्रिय है, इसलिए प्रश्न।

समाधान मैं keymaps-at-pointनीचे इस्तेमाल किया कीमैप का उपयोग करने के लिए एक पाठ संपत्ति से था। मैंने फिर कीम का नाम खोजने के लिए बाध्य फ़ंक्शन के कोड को देखा gnus-mime-button-map। निम्नलिखित कोड मैं क्या चाहता हूँ:

(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
इस छद्म कोड लिस्प का उपयोग करें और अपने उच्च-स्तरीय गाइड के रूप में वर्णन करें कि Emacs एक कुंजी कैसे दिखता है : Elisp मैन्युअल, नोडSearching Keymaps । नोड्स Functions for Key Lookupऔर भी देखें Active Keymaps
ड्रू

दूसरे समारोह में मेरे प्रारंभिक उत्तर के साथ एक बहुत बड़ा बग था। मैंने अभी इसे ठीक किया है, इसलिए इसे आपकी कीबाइंड का पता लगाने में सक्षम होना चाहिए। क्या आप फिर से कोशिश कर सकते हैं?
मालाबार 20

जवाबों:


61

इमैकस 25

जैसा कि टिप्पणी में @YoungFrog द्वारा उल्लेख किया गया है, 25.1 Emacs से शुरू होता है , C-h kकुंजी-बाइंड का वर्णन करने का अच्छा-पुराना तरीका भी आपको बताएगा कि कुंजी किस कुंजी में पाई गई थी।

25 Emacs से पहले

इस पर यहाँ कुछ कोड है , लेकिन यह अधूरा है क्योंकि यह सब कुछ कवर नहीं करता है। नीचे इसका एक बेहतर संस्करण है।

कीज़ को 9 (!) तरीकों से बांधा जा सकता है। धन्यवाद के लिए @Drew को इस लिंक (भी द्वारा पूरक इस ) पूरी सूची के साथ। पूर्वता के क्रम से, वे हैं:

  1. कुंजी का एक टर्मिनल-विशिष्ट सेट overriding-terminal-local-map,। यह set-transient-mapफ़ंक्शन द्वारा परिभाषित किया गया है।
  2. एक बफर-लोकल ओवरराइड मैप overriding-local-map,। यदि यह सेट हो जाता है, तो आइटम 3-8 छोड़ दिए जाते हैं (शायद आप इनमें से कई क्यों नहीं देखते हैं)।
  3. keymapपाठ-प्रसार के माध्यम से बिंदु पर (जो वास्तविक पाठ पर या ओवरले पर जा सकता है)।
  4. एक चर, जो अनिवार्य रूप सक्षम नाबालिग-मोड के विभिन्न संभव सेट simulates emulation-mode-map-alists
  5. एक चर जहां प्रमुख-मोड मामूली-मोड की कीबाइंड को ओवरराइड कर सकते हैं, और minor-mode-overriding-map-alist
  6. वास्तविक माइनर-मोड्स , जिनकी कीबाइंड को स्टोर किया जाता है minor-mode-map-alist
  7. बिंदु पर (फिर से), local-mapपाठ संपत्ति के माध्यम से । यदि यह मौजूद है, तो आइटम 8 छोड़ दिया जाता है।
  8. मानक बफर-स्थानीय कीमैप (जहां प्रमुख-मोड या बफर-स्थानीय कीबाइंड चलते हैं), फ़ंक्शन द्वारा लौटाए जाते हैं current-local-map
  9. वैश्विक कीमैप , द्वारा लौटाए गए current-global-map

एक अर्ध-आइटम भी है 10. उपरोक्त प्रक्रिया के माध्यम से जो भी आदेश मिला था, उसे भी हटा दिया गया होगा।

निम्न फ़ंक्शन इनमें से कुछ संभावनाओं (सबसे अधिक संभावना वाले) पर सवाल उठाता है , और परिणाम देता है या प्रिंट करता है।

(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))

इनमें से प्रत्येक के लिए अंतर्निहित कार्य पहले को छोड़कर हैं, इसलिए हमें एक (ऊपर लिंक किए गए कोड का एक बेहतर संस्करण) भी बनाना होगा।

(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))))))

चूंकि आप कह रहे हैं कि जब अटैचमेंट पर बिंदु सक्रिय होता है, तो यह अच्छा मौका होता है कि यह कीबाइंड ओवरले या टेक्स्ट-प्रॉपर्टी पर लगे।

यदि वह काम नहीं करता है , तो निम्न कमांड को भी आज़माएं। बस लगाव पर कर्सर रखें, और करें 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)))

यह मुझे बताएगा कि क्या कुंजी में एक स्थानीय बंधन है, और यह किस कमांड से जुड़ा हुआ है, लेकिन यह अभी भी मुझे उस कीपैड का नाम नहीं बताता है जो यह आया था।
nispio

@nispio अगर इसमें लोकल बाइंडिंग है, तो यह मेजर-मोड कीमैप से या लोकल-सेट-की के लिए कॉल से होना चाहिए। दुर्भाग्य से, दो मामलों को अलग-अलग बताने का कोई मूर्ख तरीका नहीं है।
मालाबार

1
@ मलबारबा क्या आपका मतलब है "दुर्भाग्य से, दो मामलों को अलग-अलग बताने का कोई आसान तरीका नहीं है ?" निश्चित रूप से जानकारी सभी मौजूद है। इसके अलावा, क्या हर प्रमुख मोड में एक मोड मैप होता है? यदि नहीं, तो क्या यह बताने का कोई तरीका है कि कौन सा प्रमुख मोड मैप सक्रिय है?
nispio

1
अभी तक जारी होने से 25 emacs, "Ch k" होगा, कुछ में (अच्छी तरह से, "अधिकांश" उम्मीद में) मामले आपको बताते हैं जिसमें कीमैप (अधिक सटीक: एक प्रतीक जो उस कीमैप को अपने मूल्य के रूप में रखता है) एक दिया कीबाइंडिंग है परिभाषित। उदाहरण आउटपुट:k runs the command gnus-summary-kill-same-subject-and-select (found in gnus-summary-mode-map), which is (...)
यंगफ्रॉग

2
रुचि रखने वाले किसी भी व्यक्ति के लिए, यह प्रासंगिक प्रतिबद्धता है जो emacs 25+ में कुंजी बाइंडिंग कीमैप प्रदर्शित करता है।
कौशल मोदी

2

इस बारे में:

(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))

उदाहरण के लिए (my-lookup-key (kbd "C-c v v"))मैं *Message*बफर में सूची प्राप्त करता हूं :

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

यह दृष्टिकोण उप-कीमैप को खोजने के लिए उपयोगी है जो उच्च स्तर के कीमैप में शामिल है, उदाहरण के लिए आउटपुट से:

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

है vc-prefix-mapमें शामिल किया गया है जो global-map:

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

यदि आप शामिल करने के लिए फ़िल्टरिंग स्थिति को संशोधित करते हैं keymapp- आप उपसर्गों के लिए कभी भी खोज कर पाएंगे:

(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))

तो rst-mode-mapदोनों पर मिल जाएगा:

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

1

मुझे पता है कि निम्नलिखित इस सवाल का जवाब नहीं देता है कि मैं यह कैसे पता लगा सकता हूं कि कौन सा कीमैप है , हालांकि यह इस मामले में अंतर्निहित समस्या से निपटता है कि कैसे dउपयोगकर्ता यह सुनिश्चित करता है कि उपयोगकर्ता क्या चाहता है उसके अनुसार व्यवहार करता है। यदि पसंद किया जाता है, तो मैं इस उत्तर को हटा सकता हूं और उस मुद्दे के संबंध में किसी अन्य प्रश्न + उत्तर में परिवर्तित कर सकता हूं।

text-property/overlayनक्शे को ओवरराइड करने की विधि के रूप में , आपको उपयोग करने में सक्षम होना चाहिए:

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

के अनुसार सक्रिय नक्शे को नियंत्रित करना , overriding-local-mapहर दूसरे सक्रिय अलावा अन्य मानचित्र पर पूर्वता लेता है overriding-terminal-local-map


यह सब कुछ तोड़ देता है: मैं अब सारांश मोड में एक संदेश नहीं खोल सकता हूं, और बुराई और प्रतिष्ठित काम करना बंद कर देते हैं।
18

यह सब कुछ तोड़ देता है: मैं अब सारांश मोड में एक संदेश नहीं खोल सकता हूं, और बुराई और प्रतिष्ठित काम करना बंद कर देते हैं।
एमिली हूवर

0

emacs- बटन प्रदान करता है buttons-display, जो एक उपसर्ग तर्क के साथ सभी वर्तमान बाइंडिंग के पुनरावर्ती दृश्य होता है।

(अस्वीकरण: मैं पैकेज का लेखक हूं)

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.