- Remove legacy keymap spam
- Move keys that express ideas, such as
C-n
, coherently across multiple modes - See the current state of your preferred top-level sequences
- Introspect modal key bindings, for both package development & configuration
(use-package user-keys) ; vanilla
;; using elpaca's with explicit recipe
(use-package user-keys
:elpaca (user-keys :host github :repo "positron-solutions/user-keys"))
;; straight with explicit recipe
(use-package user-keys
:straight (user-keys :type git :host github :repo "positron-solutions/user-keys"))
;; or use manual load-path & require, you brave yak shaver
;; Show the state of your preferred sequences in the current major
;; mode. Use this to find out which sequences you might want to bind
;; next.
(user-keys-report-preferred)
;; See a report of all "stupid" bindings and the maps that bind them.
(user-keys-report-stupid)
;; Check for shadows for a common sequence so you can move all of it's bindings
;; around at once.
(user-keys-report-shadows)
;; Open the output buffer and use the transient interface
(user-keys-start)
- Other Packages
- Motivation
- Long-Term Goal
- Correctly Communicating About Commands and Sequences
- The C-c Convention is Terrible
- What We Should Do
- Contributing
- Acknowledgments
Absolutely check out the newer modal packages such as Meow. They don’t have a lot of pre-configured bindings, and this opens up room to do crazy things.
- Completions frameworks alleviate the need for complex bindings because it’s just faster to complete the command name
- Transient bindings (transient package) are a good way to present context specific bindings such as for applications like magit
- Helpful presents bindings in a much better format when looking at keymap variables
- Which-key is definitely more useful after cleaning out some bindings
- Tree sitter is making more and more editing commands able to use the structure of text you are working on
- General provides lots of support for defining bindings more succinctly and differentiating user-defined bindings
Not all of these packages have a clear best choice, so be sure to research Emacs awesome and Reddit etc before adopting a recommendation here.
There are too many bindings. Everywhere. It gets in the way of progress. It gets in the way of use. We need tools to take back control and move forward.
- Empower users to modify & develop new schemes
Built-in ways to look at bindings are not appropriate for designing new bindings schemes or looking at bindings systematically. There’s not a good built-in way to see sets of bindings across multiple maps or the state of map activation across different buffers, information that is essential for designing and developing bindings schemes (such as new modal schemes).
- Give the keyboard back to the user
Having so many bindings in the way or being surprised by shadows from major & minor modes leads to user intimidation and calcification of things that were not intended to become standards. Whether you start with Evil or defaults, the mass proliferation of bad bindings gets in the way and adds risk and complexity to any attempt to go your own way. This package is developed with the belief that the keyboard belongs to the user, and that extra effort should be made to get out of the way.
- Manage Ad-hoc conventions
There is no configuration option for certain conventions, such as
C-n
usually selecting the next item in a list. Because these conventions exist but are not first class, changing the binding for an idea found in multiple keymaps usually requires modifying each keymap. By viewing all shadows in all maps at once, the user can modify and maintain their own conventions with more awareness and ease. - Support Tree Sitter Migration
The timing of development was partly motivated by tree-sitter adoption. Because of tree-sitter, editing commands that are aware of syntax boundaries will become common. The old keymaps based on heuristic editing commands will need to evolve. We need tools that make it easy to open up space and move old conventions.
It is possible that this package may become similar to a no-littering, but for key bindings. Maybe it should be the Magit of key bindings. Maybe it will become an editing interface for a new set of modal bindings. A lot depends on user demand. Be sure to support the project and help steer the direction.
We need to fix something culturally. Other users might say things such as,
“The C-x C-f command.” This is wrong. There is no “C-x C-f” command. There
is a “C-x f” key sequence that is bound, by default, to the command
find-file
. This is a binding.
Why you should always prefer command names when communicating:
- Command names point to source code and can be used as fuel for hacking new commands.
- Command names are named using frequent concepts from the glossary
- Command names do not change when users rebind keys. You can communicate about commands no matter what bindings system another user has.
- Command names tell users more about what package they came from.
Unfortunately there seems to be no mechanism to find out what a key was bound to in the default settings. We can all use commands. We cannot all know what a binding means.
Command names make you and other users more successful. Communicate by saying command names, not key sequences.
The elisp manual states that only the C-c
prefix and only with a
single letter should be respected by all major and minor
modes. This means the user is expected to bind all of their
preferred global commands behind just one prefix sequence.
Don’t define C-c letter as a key in Lisp programs. Sequences consisting of C-c and a letter (either upper or lower case; ASCII or non-ASCII) are reserved for users; they are the only sequences reserved for users, so do not block them.
Meanwhile countless packages add bindings to high-value short key sequences just because the package author felt like it or because they wanted to shadow an ad-hoc convention without knowing if the user reconfigured it.
Being forced to sort through massive lists of bindings with many ad-hoc conventions leads to user intimidation and a calcification of things that never should have been allowed to become standards.
C-c
was never a good idea. It is the kind of choice that occurred
after far too much spam was protected by being legacy, a legacy that
emerged from mixed contributions and exhausting bike shed mailing
list threads that reach conclusions like a ouija board.
Commands do not deserve bindings. They are not entitled to them. At the very most, a package author should provide a keymap and then tell the user how to bind that to a prefix. We have absolutely amazing command discovery these days. The user doesn’t need your bindings. Publish a list of commands in your package usage documentation. Put them into a context-specific application interface like transient. Avoid bad key sequences and ad-hoc conventions unless it’s the purpose of your package to shadow the defaults.
In addition to innovation in modal bindings that seek to sidestep the entire problem altogether…
- Reserve short sequences for the user
Meta and control keys, especially on the home row, should be considered sacred real-estate only available to the user. Opening up space will lower the friction for change, speeding up evolution, eventually leading us to discover new things we actually want to bind.
- Lean on M-x
In the modern era of awesome M-x completions, there’s almost no use to bind functions beyond a certain level of rarity. It only makes sense to have short sequences bound when no M-x sequences are actually very long.
- RISC, stateful commands with composition
In the global bindings, we should try to do more with a smaller set of commands, similar to a RISC style of compressing the possible input values but increasing the meaning of strings of values, which can be composed more easily than long sequences.
- Use modal interfaces for context-specific commands
For bindings that are very context-specific, they should be moved into more transient-like interfaces. If you won’t use a command often, it doesn’t make sense to try to use it from memory or to use it non-modally.
- Remove crufty applications from Emacs
Many bindings and the applications that they are tied to should just be removed from Emacs altogether and treated as independent packages on the GNU ELPA. This will lower the weight of the manual and other deep integrations, making more room to grow.
- Put legacy choices into a package
It needs to be easier to remove default bindings without disrupting legacy users, and that means using a compat package like every other platform out there. Users who want modern Emacs don’t need to care. Users who rely on the old ways should be served by a compat package, not by carrying forward the same old legacy defaults forever.
CONTRIBUTING contains instructions on using this repository’s functionality. A DCO and GPL3 license are included with this project.
Check the hacking NOTES document for some help getting started hacking on keymaps and bindings. The keymap data structures themselves are a little bit unwieldy.
Github Sponsors is configured. If you want features & support, organize an international coalition of backers and each donate a comfortable amount, while delegating the authority to pick priorities to those who either demonstrate competence or are willing to pay for what they want.
Thanks to Tarsius for publishing the keymap-utils package to MELPA.
Some of the built-in functions for exploring keymaps in Emacs were
not immediately appropriate for implementing all of the ideas in
user-keys. keymap-map-keys
seemed to provide a buffet of data
types and structures. kmu-map-keymap
was very helpful.