GNU Emacs, use-package, and key binding for mode specific keymaps
Over on the Fediverse, I said:
Current status: ELisp. So much ELisp. In so many little defuns.
Also, it has been '0' days since I had to use ':demand t' with use-package in order to get keymaps working. I think I should just assume any per-mode keymaps need ':demand t' for mysterious reasons I would probably understand if I knew enough and read the use-package documentation (such as it is) carefully enough.
Many GNU Emacs modes, such as MH-E, define mode specific keyboard mappings (keymaps), instead of putting their special keyboard commands into the global keymap that's normally used in every file (okay, buffer). This is especially common in Emacs modes that are basically implementing an application inside Emacs, like MH-E and magit, but they also appear for other things like lsp-mode and backward-forward. Often you may want to modify those mode-specific keymaps, like mh-folder-mode-map, backward-forward-mode-map, company-active-map, and lsp-ui-mode-map.
These days I try to do all of my management of Emacs configuration with use-package, which has become sufficiently popular that it's officially part of GNU Emacs now (justifying my decision to focus on it). Use-package has features for defining key bindings in mode-specific keymaps, for example:
(use-package mh-folder :bind (:map mh-folder-mode-map ("S-SPC" . mh-previous-page) ("s" . mh-alt-show)) )
However, as far as I can tell, this example does not work as is.
Instead, you must force use-package to load the mh-folder package
with the '
:demand' keyword. Before I do this, use-package reports
no errors but my key bindings are mysteriously missing; once I do
this, everything works.
(I would like to avoid loading large packages until I actually use them, but I suppose that in practice Emacs startup time hardly matters in these days of fairly fast machines. On the other hand, several MH-E packages take over a tenth of a second each to load. Sadly, I'm not sure use-package provides any good way for a non-expert to work out why it's immediately loading something, and the slow MH-E packages have innocuous looking use-package declarations and load even without mh-folder enabled.)
As covered in How and when use-package loads packages,
use-package sometimes already loads packages immediately and sometimes
doesn't. I'm not sure exactly when use-package decides that it must
load a package immediately and when it can be deferred (it's not
quite as simple as only having keywords from Deferring package
With appropriate use-package settings you can look at your
*Messages* buffer after starting Emacs to see what was loaded
already (at this point I may leave '
use-package-verbose' set to
debug). However, it is not as simple as everything that uses
:bind' to bind keys requires forced immediate loading, because
the following works:
(use-package magit :config (global-magit-file-mode) :bind ("C-x g" . magit-status) )
(I have tried some of the ways of expanding what use-package is doing that were mentioned here, but without enlightenment.)
(This is the kind of entry I write for my future self, and to gather various links in one place. Hopefully I will remember this the next time I'm beating my head against problems where a key binding is mysteriously missing.)