general.el
general.el copied to clipboard
How to define prefix keys for both case when evil-mode is enabled and disabled?
What I want to achieve:
- when
evil-mode
is disabled: S-SPC is prefix key - when
evil-mode
is enabled: SPC is prefix key fornormal
andvisual
state, S-SPC is prefix key forinsert
state.
I have tried
(general-create-definer default-leader
:states '(normal visual insert emacs jpnb)
:keymaps 'override
:prefix "SPC"
:non-normal-prefix "S-SPC")
and
(general-create-definer default-leader
:states '(normal visual insert emacs jpnb)
:keymaps 'override
:prefix "SPC"
:global-prefix "S-SPC")
What troubles me is that, when evil-mode
is disabled, S-SPC has no effect.
You're only defining keys in evil keymaps in your example. You could make non-evil keybindings with something like (general-define-key :prefix "prefix" "key" 'def ...)
. You could create a wrapper that calls your custom definer and one that has :prefix "S-SPC"
.
Thanks. For anyone with the same question:
(general-create-definer moon--default-leader
:states '(normal visual insert emacs jpnb)
:keymaps 'override
:prefix "SPC")
(general-create-definer moon-global-leader
:prefix "S-SPC"
:keymaps 'override)
(defmacro moon-default-leader (&rest args)
"Define for both default leader and global leader."
(declare (indent defun))
`(progn
(moon--default-leader
,@args)
(moon-global-leader
,@args)))
I replaced the original definer with a macro, the definer is renamed from moon-default-leader
to moon--default-leader
.
The same effect can be achieved without defining a macro:
(general-create-definer moon-global-leader
:prefix "S-SPC"
:keymaps 'override)
(general-def '(normal visual) "SPC" (general-simulate-key "S-SPC"))
But this and your code snippet both makes S-SPC
also the leader key in normal and visual state, which doesn't meet your needs in the description.
That's good to know. Thanks.
I don't like the solution of using general-simulate-key
for this. It should be avoided when it isn't necessary (and it isn't necessary here). To make this a little easier, I could either provide a helper to combine multiple definers or I could allow something like this:
(general-create-definer my-leader
;; can include nil to also define in just `general-override-mode-map'
:states '(normal visual insert emacs nil)
:keymaps 'override
:global-prefix "S-SPC"
:prefix "SPC")
This would complicate the code a bit more since I'd have to add some check to determine whether a keymap is an evil state keymap (and I don't think evil stores the defined states anywhere, so I'd have to do something like assume that evil-<name>-state-map
is a state keymap).
I would say a helper is simple and reliable, and can meet a variety of user needs that can or cannot be thought of now, so I prefer this.
@noctuid Hi. I think it's better to show you the whole scheme used by me, maybe it can be a reference.
(defconst toki-leader-key "C-j")
(defconst toki-normal-state-leader-key "SPC")
(defconst toki-app-key "a")
(defconst toki-window-key "w")
(defconst toki-emacs-key "e")
(defconst toki-search-key "s")
(defconst toki-code-key "d")
(defconst toki-file-key "f")
(defconst toki-help-key "h")
(defconst toki-navigate-key "n")
(defconst toki-ui-key "u")
(defconst toki-buffer-key "j")
(defconst toki-manage-key "m")
(defconst toki-text-key "k")
(use-package general
:config
(general-create-definer toki-leader-def
:prefix toki-leader-key
:keymaps 'override)
(general-def 'normal
:start-maps t
:keymaps 'override
toki-normal-state-leader-key (eval `(general-simulate-keys ,toki-leader-key)))
(general-create-definer toki-app-def
:prefix (concat toki-leader-key " " toki-app-key)
:keymaps 'override)
(general-create-definer toki-window-def
:prefix (concat toki-leader-key " " toki-window-key)
:keymaps 'override)
(general-create-definer toki-search-def
:prefix (concat toki-leader-key " " toki-search-key)
:keymaps 'override)
(general-create-definer toki-emacs-def
:prefix (concat toki-leader-key " " toki-emacs-key)
:keymaps 'override)
(general-create-definer toki-code-def
:prefix (concat toki-leader-key " " toki-code-key)
:keymaps 'override)
(general-create-definer toki-file-def
:prefix (concat toki-leader-key " " toki-file-key)
:keymaps 'override)
(general-create-definer toki-help-def
:prefix (concat toki-leader-key " " toki-help-key)
:keymaps 'override)
(general-create-definer toki-navigate-def
:prefix (concat toki-leader-key " " toki-navigate-key)
:keymaps 'override)
(general-create-definer toki-ui-def
:prefix (concat toki-leader-key " " toki-ui-key)
:keymaps 'override)
(general-create-definer toki-buffer-def
:prefix (concat toki-leader-key " " toki-buffer-key)
:keymaps 'override)
(general-create-definer toki-manage-def
:prefix (concat toki-leader-key " " toki-manage-key)
:keymaps 'override)
(general-create-definer toki-text-def
:prefix (concat toki-leader-key " " toki-text-key)
:keymaps 'override)
(toki-leader-def
:start-maps t
toki-window-key '(:wk "window")
toki-emacs-key '(:wk "emacs")
toki-search-key '(:wk "search-and-replace")
toki-code-key '(:wk "code")
toki-file-key '(:wk "file")
toki-help-key '(:wk "help")
toki-navigate-key '(:wk "navigate")
toki-ui-key '(:wk "UI")
toki-buffer-key '(:wk "buffer")
toki-manage-key '(:wk "manage")
toki-text-key '(:wk "text")))
So basically C-j
is the start menu, and there are many sub menus under it. Specific keybindings are set in each modules in my config. general-simulate-keys
is used since it seems to be the simplest way. The improvement should make this easier, not harder (e.g. having to create 10+ more definers).