meow-edit / meow

Yet another modal editing on Emacs / 猫态编辑
GNU General Public License v3.0
1.07k stars 128 forks source link

`meow-*-define-key` functions could leverage builtin `(STRING . DEFN)` definitions #537

Open montchr opened 4 months ago

montchr commented 4 months ago

Both define-key and keymap-set accept the following forms as definitions (quoting from the docstring of keymap-set):

DEFINITION is anything that can be a key's definition:
 nil (means key is undefined in this keymap),
 a command (a Lisp function suitable for interactive calling),
 a string (treated as a keyboard macro or a sequence of input events),
 a keymap (to define a prefix key),
 a symbol (when the key is looked up, the symbol will stand for its
    function definition, which should at that time be one of the above,
    or another symbol whose function definition is used, etc.),
 a cons (STRING . DEFN), meaning that DEFN is the definition
    (DEFN should be a valid definition in its own right) and
    STRING is the menu item name (which is used only if the containing
    keymap has been created with a menu name, see make-keymap),
 or a cons (MAP . CHAR), meaning use definition of CHAR in keymap MAP,
 or an extended menu item definition.

For whatever reason, I can't find this documented in the manual even in the description for keymap-set, otherwise I would link there. The best resource I found is Simple Menu Items (GNU Emacs Lisp Reference Manual).

Although the docstring as quoted above says the STRING in (STRING . DEFN) is "used only if the containing keymap has been created with a menu name", which-key specifically supports and encourages the use of STRING as the overriding description for a definition.

Meow's custom which-key-like leader popup could leverage (STRING . DEFN) to replace the +prefix labels. FWIW, general.el also causes these +prefix labels to appear everywhere because it doesn't handle which-key properly.

I think which-key does that here in a let* binding:

https://github.com/justbur/emacs-which-key/blob/4d20bc852545a2e602f59084a630f888542052b1/which-key.el#L1823-L1838

Excerpt:

                    (binding
                     (cons key-desc
                           (cond
                            ((symbolp def) (which-key--compute-binding def))
                            ((keymapp def) "prefix")
                            ((eq 'lambda (car-safe def)) "lambda")
                            ((eq 'closure (car-safe def)) "closure")
                            ((stringp def) def)
                            ((vectorp def) (key-description def))
                            ((and (consp def)
                                  ;; looking for (STRING . DEFN)
                                  (stringp (car def)))
                             (concat (when (keymapp (cdr-safe def))
                                       "group:")
                                     (car def)))
                            (t "unknown")))))
DogLooksGood commented 4 months ago

Thanks for pointing this. The meow-*-define-key helpers are just wrappers on define-key.

(meow-leader-define-key '("y" . ("yas" . yas-keymap)))
montchr commented 4 months ago

@DogLooksGood Right, though my suggestion is that Meow could, like which-key, use the additional description text in the leader popup to replace the default +prefix text if the user specifies a description. Currently, the description doesn’t have any effect because AFAIK it would need to be explicitly supported in the code that generates the popup text. I know you’ve been suggesting that users who have issues with the popup behavior should use which-key instead, but if the meow popup is still a supported feature here, supporting some way of overriding the key descriptions would be nice to have.

If the issue I’m describing with the default text for keymaps cannot be reproduced, then it’s possible I am misunderstanding something about its usage.

FWIW I have seen the same exact behavior with which-key in any prefix-map keybindings made with general.el even without Meow (and thus, even some of Doom Emacs’s default bindings). The difference is that which-key output can be customized using the menu text description as described above.