all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Nicolas Richard <theonewiththeevillook@yahoo.fr>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Nicolas Richard <theonewiththeevillook@yahoo.fr>,
	13948@debbugs.gnu.org, Brian Malehorn <bmalehorn@gmail.com>
Subject: bug#13948: no key-binding-locus
Date: Wed, 11 Jun 2014 13:23:17 +0200	[thread overview]
Message-ID: <87fvjbd716.fsf@geodiff-mac3.ulb.ac.be> (raw)
In-Reply-To: <jwvy4x4e7x4.fsf-monnier+emacsbugs@gnu.org> (Stefan Monnier's message of "Tue, 10 Jun 2014 18:24:50 -0400")

[-- Attachment #1: Type: text/plain, Size: 2229 bytes --]

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Here's another attempt. Like the previous patch, I define
>> key-binding-keymap which finds the keymap by mimicking key-binding, and
>> describe-key--binding-locus which matches the keymap to a symbol and
>> makes a description suitable for describe-key.
>
> Looks pretty good.  Feel free to install it into `trunk'.

I can send a patch, including a ChangeLog entry, but I don't have
permission to commit.

>> +      (when (integerp found)
>> +        ;; prefix was found but not the whole sequence
>> +        (setq found nil)))
>
> If key-binding returned a command, then we should never hit this case.
> It's OK to keep the code, but you might like to add a comment mentioning
> that we don't expect this case to happen.

We do hit the case, because we look in active keymaps one by one,
instead of using the keymap (cons 'keymap active-keymaps) like
key-binding does.

>> +         ;; look into these advertised symbols first
>> +         (while (and (not found) advertised-syms)
>> +           (let ((sym (pop advertised-syms)))
>> +             (setq found
>> +                   (when (and
>> +                          (boundp sym)
>> +                          (eq map (symbol-value sym)))
>> +                     sym))))
>> +         ;; only look in other symbols otherwise
>> +         (when (not found)
>> +           (mapatoms
>> +            (lambda (x)
>> +              (when (and (boundp x)
>> +                         ;; avoid let-bound symbols
>> +                         (special-variable-p x)
>> +                         (eq (symbol-value x) map))
>> +                (push x found))))
>> +           (when (and (consp found)
>> +                      (null (cdr found)))
>> +             (setq found (car found))))
>
> I think this code will be simpler if you use catch/throw (you can then
> use dolist over advertised-syms, for example and you don't need
> `found').

Shall I return only the first symbol that matches, also in the mapatoms
case ? I assume yes because of your next suggestion :

> I think it's better to make this function return the symbol rather than
> a string, and let the caller turn it into a string.

Ok.

Here's the patch.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-describe-key-mention-the-keymap-in-which-the-binding.patch --]
[-- Type: text/x-diff, Size: 7274 bytes --]

>From 685224012675c7b608ad67825cb7ff4d88ce8392 Mon Sep 17 00:00:00 2001
From: Nicolas Richard <theonewiththeevillook@yahoo.fr>
Date: Tue, 10 Jun 2014 20:06:27 +0200
Subject: [PATCH] describe-key: mention the keymap in which the binding was
 found.

* help.el (help--key-binding-keymap): New function.
(help--binding-locus): New function.
(describe-key): Mention the keymap in which the binding was found.
---
 lisp/ChangeLog |  6 ++++
 lisp/help.el   | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 2f40577..9912407 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-11  Nicolas Richard  <theonewiththeevillook@yahoo.fr>
+
+	* help.el (help--key-binding-keymap): New function.
+	(help--binding-locus): New function.
+	(describe-key): Mention the keymap in which the binding was found.
+
 2014-05-26  Paul Eggert  <eggert@cs.ucla.edu>
 
 	Include sources used to create macuvs.h.
diff --git a/lisp/help.el b/lisp/help.el
index 72a9524..0effdfa 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -647,6 +647,67 @@ temporarily enables it to allow getting help on disabled items and buttons."
 	(princ (format "%s%s is undefined" key-desc mouse-msg))
       (princ (format "%s%s runs the command %S" key-desc mouse-msg defn)))))
 
+(defun help--key-binding-keymap (key &optional accept-default no-remap position)
+  "Return a keymap holding a binding for KEY within current keymaps.
+The effect of the arguments KEY, ACCEPT-DEFAULT, NO-REMAP and
+POSITION is as documented in the function `key-binding'."
+  (let* ((active-maps (current-active-maps t position))
+         map found)
+    ;; We loop over active maps like key-binding does.
+    (while (and
+            (not found)
+            (setq map (pop active-maps)))
+      (setq found (lookup-key map key accept-default))
+      (when (integerp found)
+        ;; Prefix was found but not the whole sequence.
+        (setq found nil)))
+    (when found
+      (if (and (symbolp found)
+               (not no-remap)
+               (command-remapping found))
+          ;; The user might want to know in which map the binding is
+          ;; found, or in which map the remapping is found. The
+          ;; default is to show where the remapping is done.
+          (key-binding-keymap (vector 'remap found))
+        map))))
+
+(defun help--binding-locus (key position)
+  "Describe in which keymap KEY is defined.
+Return a symbol pointing to that keymap if one exists ; otherwise
+return nil."
+  (let ((map (key-binding-keymap key t nil position)))
+    (when map
+      (catch 'found
+        (let ((advertised-syms (nconc
+                                (list 'overriding-terminal-local-map
+                                      'overriding-local-map)
+                                (delq nil
+                                      (mapcar
+                                       (lambda (mode-and-map)
+                                         (let ((mode (car mode-and-map)))
+                                           (when (symbol-value mode)
+                                             (intern-soft
+                                              (format "%s-map" mode)))))
+                                       minor-mode-map-alist))
+                                (list 'global-map
+                                      (intern-soft (format "%s-map" major-mode)))))
+              found)
+          ;; Look into these advertised symbols first.
+          (dolist (sym advertised-syms)
+            (when (and
+                   (boundp sym)
+                   (eq map (symbol-value sym)))
+              (throw 'found sym)))
+          ;; Only look in other symbols otherwise.
+          (mapatoms
+           (lambda (x)
+             (when (and (boundp x)
+                        ;; Avoid let-bound symbols.
+                        (special-variable-p x)
+                        (eq (symbol-value x) map))
+               (throw 'found x))))
+          nil)))))
+
 (defun describe-key (&optional key untranslated up-event)
   "Display documentation of the function invoked by KEY.
 KEY can be any kind of a key sequence; it can include keyboard events,
@@ -709,6 +770,7 @@ temporarily enables it to allow getting help on disabled items and buttons."
 	 (mouse-msg (if (or (memq 'click modifiers) (memq 'down modifiers)
 			    (memq 'drag modifiers)) " at that spot" ""))
 	 (defn (key-binding key t))
+         key-locus key-locus-up key-locus-up-tricky
 	 defn-up defn-up-tricky ev-type
 	 mouse-1-remapped mouse-1-tricky)
 
@@ -747,15 +809,19 @@ temporarily enables it to allow getting help on disabled items and buttons."
 		   (setcar up-event (elt mouse-1-remapped 0)))
 		  (t (setcar up-event 'mouse-2))))
 	  (setq defn-up (key-binding sequence nil nil (event-start up-event)))
+          (setq key-locus-up (help--binding-locus sequence (event-start up-event)))
 	  (when mouse-1-tricky
 	    (setq sequence (vector up-event))
 	    (aset sequence 0 'mouse-1)
-	    (setq defn-up-tricky (key-binding sequence nil nil (event-start up-event))))))
+	    (setq defn-up-tricky (key-binding sequence nil nil (event-start up-event)))
+            (setq key-locus-up-tricky (help--binding-locus sequence (event-start up-event))))))
+      (setq key-locus (help--binding-locus key (event-start event)))
       (with-help-window (help-buffer)
 	(princ (help-key-description key untranslated))
-	(princ (format "\
-%s runs the command %S, which is "
-		       mouse-msg defn))
+	(princ (format "%s runs the command %S%s, which is "
+		       mouse-msg defn (if key-locus
+                                          (format " (found in %s)" key-locus)
+                                        "")))
 	(describe-function-1 defn)
 	(when up-event
 	  (unless (or (null defn-up)
@@ -765,13 +831,15 @@ temporarily enables it to allow getting help on disabled items and buttons."
 
 ----------------- up-event %s----------------
 
-%s%s%s runs the command %S, which is "
+%s%s%s runs the command %S%s, which is "
 			   (if mouse-1-tricky "(short click) " "")
 			   (key-description (vector up-event))
 			   mouse-msg
 			   (if mouse-1-remapped
                                " is remapped to <mouse-2>, which" "")
-			   defn-up))
+			   defn-up (if key-locus-up
+                                       (format " (found in %s)" key-locus-up)
+                                     "")))
 	    (describe-function-1 defn-up))
 	  (unless (or (null defn-up-tricky)
 		      (integerp defn-up-tricky)
@@ -781,10 +849,12 @@ temporarily enables it to allow getting help on disabled items and buttons."
 ----------------- up-event (long click) ----------------
 
 Pressing <%S>%s for longer than %d milli-seconds
-runs the command %S, which is "
+runs the command %S%s, which is "
 			   ev-type mouse-msg
 			   mouse-1-click-follows-link
-			   defn-up-tricky))
+			   defn-up-tricky (if key-locus-up-tricky
+                                              (format " (found in %s)" key-locus-up-tricky)
+                                            "")))
 	    (describe-function-1 defn-up-tricky)))))))
 \f
 (defun describe-mode (&optional buffer)
-- 
2.0.0



[-- Attachment #3: Type: text/plain, Size: 11 bytes --]


-- 
Nico.

  reply	other threads:[~2014-06-11 11:23 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-13 20:34 bug#13948: no key-binding-locus Brian Malehorn
2013-04-23 19:41 ` Josh
2014-06-02 10:15 ` Nicolas Richard
2014-06-02 13:55   ` Stefan Monnier
2014-06-04 10:51     ` Nicolas Richard
2014-06-04 13:50       ` Stefan Monnier
2014-06-04 14:00         ` Nicolas Richard
2014-06-04 14:20           ` Stefan Monnier
2014-06-06 17:57             ` Nicolas Richard
2014-06-06 18:27               ` Stefan Monnier
2014-06-10 19:46                 ` Nicolas Richard
2014-06-10 22:24                   ` Stefan Monnier
2014-06-11 11:23                     ` Nicolas Richard [this message]
2014-06-11 18:06                       ` Stefan Monnier
2014-06-11 20:20                         ` Nicolas Richard
2014-06-11 22:00                           ` Stefan Monnier
2014-06-12  8:16                           ` Nicolas Richard
2014-06-12 16:09                     ` Nicolas Richard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87fvjbd716.fsf@geodiff-mac3.ulb.ac.be \
    --to=theonewiththeevillook@yahoo.fr \
    --cc=13948@debbugs.gnu.org \
    --cc=bmalehorn@gmail.com \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.