all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jim Porter <jporterbugs@gmail.com>
To: emacs-devel@gnu.org
Subject: [WIP PATCH] Adding keys to keymaps in alphabetical order (for use with `mode-line-mode-menu')
Date: Thu, 17 Jun 2021 20:39:42 -0700	[thread overview]
Message-ID: <CANh=_JHJpubzHU65=+SdHdDM1bpFr9meTsdUHDiU0N3F0N9tig@mail.gmail.com> (raw)

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

Currently, there's not a simple way of inserting a key binding into a
keymap in alphabetical order. This would be nice for
`mode-line-mode-menu'; to see the issue, you can run the following:

  emacs -Q
  <mouse-3> ;; on the mode name in the mode-line
  ;; See the nice alphabetical list
  M-x ruler-mode
  <mouse-3> ;; on the mode name in the mode-line again
  ;; "Ruler" is first(?!)

I believe `ruler-mode' is the only place in Emacs itself that has this
issue, but third-party packages (or user configs) might want to add to
`mode-line-mode-menu'. For example, I prefer to get rid of the
mode-line lighter for `company-mode' and put an item for it into
`mode-line-mode-menu' for the rare times I want to check/change its
status. Especially with packages that get loaded after startup, the
current behavior could be somewhat confusing since the order items are
added to the menu can vary.

I've attached a simple patch that fixes this by adding a
`define-key-sorted' function. I imagine it still needs some work to
handle more complex cases, but it works well enough for
`mode-line-mode-menu'.

- Jim

[-- Attachment #2: 0001-Add-define-key-sorted-to-simplify-entering-menu-item.patch --]
[-- Type: application/octet-stream, Size: 2260 bytes --]

From 880a83c661baff6890e0ba6fcb606d428a92b226 Mon Sep 17 00:00:00 2001
From: Jim Porter <jporterbugs@gmail.com>
Date: Thu, 17 Jun 2021 20:38:47 -0700
Subject: [PATCH] Add 'define-key-sorted' to simplify entering menu items in
 alphabetical order

* lisp/subr.el (define-key-sorted): New function.
* lisp/ruler-mode.el: Use 'define-key-sorted' instead of 'define-key'.
---
 lisp/ruler-mode.el |  2 +-
 lisp/subr.el       | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/lisp/ruler-mode.el b/lisp/ruler-mode.el
index a0d4f6e96c..aba27930db 100644
--- a/lisp/ruler-mode.el
+++ b/lisp/ruler-mode.el
@@ -586,7 +586,7 @@ ruler-mode
     (remove-hook 'post-command-hook 'force-mode-line-update t)))
 \f
 ;; Add ruler-mode to the minor mode menu in the mode line
-(define-key mode-line-mode-menu [ruler-mode]
+(define-key-sorted mode-line-mode-menu [ruler-mode]
   '(menu-item "Ruler" ruler-mode
               :button (:toggle . ruler-mode)))
 
diff --git a/lisp/subr.el b/lisp/subr.el
index e49c277335..120c120ddb 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1032,6 +1032,26 @@ define-key-after
 	    (setq inserted t)))
       (setq tail (cdr tail)))))
 
+(defun define-key-sorted (keymap key definition)
+  "Add binding in KEYMAP for KEY => DEFINITION, sorted in alphabetical order.
+This is like `define-key' except that the binding for KEY is placed
+in alphabetical order within the keymap.
+
+The order of bindings in a keymap matters only when it is used as
+a menu, so this function is not useful for non-menu keymaps."
+  (or (keymapp keymap)
+      (signal 'wrong-type-argument (list 'keymapp keymap)))
+  (let ((tail (cdr keymap)) prev found)
+    (while (and (not found) (listp (car tail)))
+      (let ((next (car tail)))
+        (setq found (string> (caddr next) (cadr definition)))
+        (unless found
+          (setq prev next
+                tail (cdr tail)))))
+    (if prev
+        (define-key-after keymap key definition (car prev))
+      (define-key keymap key definition))))
+
 (defun define-prefix-command (command &optional mapvar name)
   "Define COMMAND as a prefix command.  COMMAND should be a symbol.
 A new sparse keymap is stored as COMMAND's function definition and its
-- 
2.25.1


             reply	other threads:[~2021-06-18  3:39 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-18  3:39 Jim Porter [this message]
2021-06-19 12:31 ` [WIP PATCH] Adding keys to keymaps in alphabetical order (for use with `mode-line-mode-menu') Lars Ingebrigtsen
2021-06-21  5:31   ` Jim Porter
2021-06-21 12:31     ` Lars Ingebrigtsen
2021-06-23  5:17       ` Jim Porter
2021-06-23 13:06         ` Lars Ingebrigtsen
2021-06-23 13:58           ` Stefan Monnier
2021-06-23 14:10             ` Lars Ingebrigtsen
2021-06-23 16:50             ` [Updated Patch] " Jim Porter
2021-06-24 14:51               ` Lars Ingebrigtsen

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='CANh=_JHJpubzHU65=+SdHdDM1bpFr9meTsdUHDiU0N3F0N9tig@mail.gmail.com' \
    --to=jporterbugs@gmail.com \
    --cc=emacs-devel@gnu.org \
    /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.