This is second of three big naming convention changes. In this commit,
we change the naming conventions for hook functions and variable
functions:
1. Replace the bar | to indicate a hook function with a -h suffix, e.g.
doom|init-ui -> doom-init-ui-h
doom|run-local-var-hooks -> doom-run-local-var-hooks-h
2. And add a -fn suffix for functions meant to be set on variables,
e.g.
(setq magit-display-buffer-function #'+magit-display-buffer-fn)
See ccf327f8 for the reasoning behind these changes.
Each prefix now defines a doom-leader-DESC-map keymap, where DESC is the
which-key description for that prefix key. This should make it easier
for users to move leader prefixes. e.g.
To move SPC TAB (workspaces) to SPC l:
(map! :leader
"TAB" nil
"l" doom-leader-workspaces-map)
Creates a separate doom--define-leader-key macro for internal use (in
map!). define-leader-key! will continue to exist as a convenience macro
for users who want a general.el interface to defining leader keys.
Possibly relevant to: #1309
I don't want to litter config/default/+evil-bindings.el with conditions
for every keybind whose module may or may not be enabled. It impacts its
readability and is relatively expensive (due to the internals of map!
and general).
So instead, we no-op keybinds for commands that don't exist (and aren't
autoloaded), so you don't see missing function errors when using these
keys.
This will later be used for doom/describe-packages to list all locations
where a package is being configured (along with def-package! and after!
blocks).
Using general to bind leader keys was responsible for 40-50% of Doom's
startup time. This change reduces that significantly, but not entirely.
It may be better that the config/default module not use map!. It is a
convenient macro, but general is a huge bottleneck.
This changes how leader keys are bound, to fix an issue where the wrong
which-key label was assigned to the wrong keys, and cases where the
leader key was being shadowed by other minor mode mappings.
Unfortunately, this new method adds 10-20% to startup times. I'll
address this in a future patch. For now, correctness is more important.
Also fixes dashboard keybind detection.
The global leader keybind was conflicting with a global M-SPC keybind in
helm-map. This keybind should only be set in non-evil sessions, so we
unset it if evil is found.
Due to issues with preset prefixes in general definers and nested
:prefix's supplied from a map! call not cooperating, many localleader
keybinds were broken and causing errors. For :leader/:localleader keys,
we now use :infix for sub-prefixes.
However, with this change, the :alt-prefix property has been removed, as
there is no simple way to support this without some major state
gymnastics in map!.
Fixes#1059
This resolves issues with :leader/:localleader keys not working when
evil states are specified. Evil states are now ignored. Also, some of
map!'s internals have been optimized to yield a ~10% improvement in
macro expansion time.
The former approach was the cause for a huge increase in startup
time (adding ~0.4s) when :leader and :localleader were used. This is
because general-define-key was called for every key-def pair.
This new approach batches these calls, which has decreased the
performance impact by at least 80%.
+ Now uses an overriding keymap for leader keys, so that it is always
available, even outside of normal/visual states. In insert/emacs
states, or in sessions where evil is absent, an alternative prefix is
used for leader/localleader keys. See these variables:
+ doom-leader-prefix
+ doom-leader-alt-prefix
+ doom-localleader-prefix
+ doom-localleader-alt-prefix
+ Keybinds now support alternative prefixes through the new :alt-prefix
property. This is useful for non-evil users and non-normal evil
states. By default, this is M-SPC (leader) and M-SPC m (localleader).
+ Removed +evil-commands flag from config/default (moved to
feature/evil/+commands.el).
+ config/default/+bindings.el has been split into
config/default/+{evil,emacs}-bindings.el, which one is loaded depends
on whether evil is present or not. The latter is blank, but will soon
be populated with a keybinding scheme for non-evil users (perhaps
inspired by #641).
+ The define-key! macro has been replaced; it is now an alias for
general-def.
+ Added unmap! as an alias for general-unbind.
+ The following modifier key conventions are now enforced for
consistency, across all OSes:
alt/option = meta
windows/command = super
It used to be
alt/option = alt
windows/command = meta
Many of the default keybinds have been updated to reflect this switch,
but it is likely to affect personal meta/super keybinds!
The map! macro has also been rewritten to use general-define-key. Here
is what has been changed:
+ map! no longer works with characters, e.g. (map! ?x #'do-something) is
no longer supported. Keys must be kbd-able strings like "C-c x" or
vectors like [?C-c ?x].
+ The :map and :map* properties are now the same thing. If specified
keymaps aren't defined when binding keys, it is automatically
deferred.
+ The way you bind local keybinds has changed:
;; Don't do this
(map! :l "a" #'func-a
:l "b" #'func-b)
;; Do this
(map! :map 'local "a" #'func-a
"b" #'func-b)
+ map! now supports the following new blocks:
+ (:if COND THEN-FORM ELSE-FORM...)
+ (:alt-prefix PREFIX KEYS...) -- this prefix will be used for
non-normal evil states. Equivalent to :non-normal-prefix in general.
+ The way you declare a which-key label for a prefix key has changed:
;; before
(map! :desc "label" :prefix "a" ...)
;; now
(map! :prefix ("a" . "label") ...)
+ It used to be that map! supported binding a key to a key sequence,
like so:
(map! "a" [?x]) ; pressing a is like pressing x
This functionality was removed *temporarily* while I figure out the
implementation.
Addresses: #448, #814, #860
Mentioned in: #940