noctuid / general.el Goto Github PK
View Code? Open in Web Editor NEWMore convenient key definitions in emacs
License: GNU General Public License v3.0
More convenient key definitions in emacs
License: GNU General Public License v3.0
Like bind-key, provide a keymap that will take precedence over minor modes. This just involves creating a keymap in emulation-mode-map-alists
, which has precedence just below text property maps and just above minor mode maps. This would only be used for keys that the user would never want to rebind in a minor mode.
I'm having some difficulty getting pink hydras to work with general-define-key
(i've posted this in the hydra repo as well, but the problem doesn't seem to be hydra related)
I have a SPC
prefix setup so that a subsequent press of z
will activate a hydra body:
(general-define-key
:states '(normal visual emacs)
:prefix "SPC"
:non-normal-prefix "C-SPC"
"SPC" 'helm-M-x
"z" '(hydra-zoom/body :which-key "zoom")
)
I'd like to create a pink hydra so the hydra doesn't exit when I press an unbound key:
(defhydra hydra-zoom (:color pink)
"
Zoom
----
_+_ in
_-_ out
_r_eset
"
("+" text-scale-increase)
("-" text-scale-decrease)
("r" (text-scale-adjust 0) :color blue)
)
However, when I try to activate the hydra (SPC z
) I get the following error:
Wrong type argument: commandp, hydra-zoom/body
This works fine when I use a normal red (or blue) hydra, but pink is causing some issues. I'm not sure what the implementation differences are (in either hydra or general) that is causing this colour type to behave differently to the others
I'm wondering if theres a specific way I should be setting up general keybindings to work with that colour type?
Hey noctuid! You might remember me as a user of your link-hint.el package. I just now realized you have other great packages such as this one.
It would be pretty cool if you created use-package integration, so that we could use a keyword like the existing :bind
, but I guess named differently like :general
or something preferably not too long.
I'd definitely use it because it makes things more organized and clean, I've found. The one problem I had with the :bind
keyword in use-package, which uses the bind-key package, was that it didn't seem to wait for the keymaps to exist, so I'd sometimes have to break from the norm of using :bind
to actually explicitly creating the bind in the :config
section or something. So even in that specific use case general would be of great help! It's very nice to be able to have the binds grouped up in one place for each use-package.
With respect to what its arguments should be, notice how :bind
has a variety of different features, from the readme:
(use-package color-moccur
:commands (isearch-moccur isearch-all)
:bind (
("M-s O" . moccur)
:map isearch-mode-map
("M-o" . isearch-moccur)
("M-O" . isearch-moccur-all)
)
:init
(setq isearch-lazy-highlight t)
:config
(use-package moccur-edit))
There you can see how it can take a :map
argument to specify the keymap on which to bind, so the subsequent list is bound to that map.
It would be cool if we could come up with a similar AST-ish thing for the various features that general supports.
One additional and crucial request would be the ability to interject an existing general wrapper (i.e. created with general-create-definer
), so that subsequent forms are based on it. So for example, something like:
(general-create-definer my-nmap :keymaps 'evil-normal-state-map)
:general (
;; as if general-define-key called with defaults
("C-c a" 'some-command
"C-c b" 'another-command)
;; general-define-key called with :prefix "C-x"
:prefix "C-x"
("j" 'jump
"p" 'paste)
;; using the my-nmap wrapper defined above, so those defaults are used
;; preferably this could be followed by "overrides" like I think is already possible
;; with normal wrappers, e.g. if this were followed by :keymaps 'evil-insert-state-map
;; to override the default defined in the wrapper. in this case it defeats the purpose
;; of using a wrapper since that was the only default it specified, but you get my point.
:defaults my-nmap
("o" 'thing
"a" 'other)
)
Separated out with whitespace to better convey what I mean.
So I guess each sub-list can be preceded by arguments that would go to general-define-key
, and the sublist that follows it are affected by those defaults. After the sublist, that can be repeated on a blank slate. So for example when it gets to :defaults my-nmap
, that's from a blank slate, the earlier :prefix "C-x"
no longer applies.
This would be absolutely amazing. Perhaps you can think of a better name than :defaults
, but my point is it would be great to have something like that. In the absolute worst case I guess you can just create a separate keyword for it, e.g. :general-with-defaults my-nmap
, but I would highly prefer and encourage a uniform :general
keyword, just like how use-package lately seems to be converging upon a single :bind
keyword based on recent commits I've seen.
Also like :bind
, the presence of a :general
form should imply :defer t
or whatever.
Do you think it would be usefull to add a way to override keys in all keymaps to avoid suprises?
I found this way of doing it: https://github.com/priyadarshan/bind-key/blob/master/bind-key.el#L78
Maybe a better way would be to detect collisions and warn the user.
evil-local-set-key
actually creates a keybinding for the current buffer. Unfortunately, local-set-key
creates a keybinding for the entire major mode.
In vim's clj-refactor, for example, (https://github.com/clojure-vim/clj-refactor.nvim) they have used the key space "cr" in normal mode to bind all the refactorings.
If I naively try something like
(nmap :keymaps 'clj-refactor-mode :prefix "c"
"r" 'cljr--all-helpers)
Obviously this doesn't work because "c" is bound to evil-change
or lispyville-change
. Is this something that emacs just isn't designed to handle very well? The only thing I can think of is that you'd have to add the case of pressing "r" to the definition of lispyville-change
to pass off to the other map. This sounds impossible to maintain for the variety of different configs out there. Is there a better way?
Consider something like this:
(bind*
"k e" 'save-buffers-kill-terminal
"k b" 'my-kill-this-buffer
"k f" 'delete-frame
"k o f" 'delete-other-frames
"k o w" 'delete-other-windows)
It requires repeating k
many times. Perhaps we can add some kind of convenience around this, perhaps if we have something like :append-prefix "k"
so that it's another prefix that gets appended to the existing :prefix
.
(bind* :append-prefix "k"
"e" 'save-buffers-kill-terminal
"b" 'my-kill-this-buffer
"f" 'delete-frame
"o f" 'delete-other-frames
"o w" 'delete-other-windows)
Perhaps an alternative wouldn't require making separate calls for separate prefixes, so e.g. they could nest multiple prefixes:
(bind*
"k" '(:nest
"e" 'save-buffers-kill-terminal
"b" 'my-kill-this-buffer
"f" 'delete-frame
"o" '(:nest
"f" 'delete-other-frames
"w" 'delete-other-windows
)
))
Although that seems to get more messy and probably more complex to handle, so I'm content enough with :append-prefix
or something like that, or perhaps you can come up with something better, perhaps you can keep specifying things like that, like:
(bind*
;; non-append prefix
"t" 'thing
;; C-c k e for example
:append-prefix "k"
"e" 'save-buffers-kill-terminal
"b" 'my-kill-this-buffer
"f" 'delete-frame
"o f" 'delete-other-frames
"o w" 'delete-other-windows
;; C-c j p for example
:append-prefix "j"
"p" 'whatever
)
That doesn't really support nesting but it supports multiple differently-prefixed keys.
Honestly though I think it'd be simpler and more consistent with the existing interface to just support one :append-prefix
and then we can make separate calls with different values for that as needed.
The latest general pkg from elpa is erroring out when a lambda function is bound to the keybinding.
Defined keybinding like this.
(general-define-key
"C-m" '(lambda () (interactive) (some-function))
)
Now C-m (just an example) errors out saying 'wrong type argument: commandp lambda'
It was working fine a week back.
general-default-keymaps
currently doesn't specify a :type
, and general-default-states
should also specify that it can be a single one of the choices (if there is some or construct).
This would allow defining keys for multiple states or keymaps at once (e.g. to bind keys in visual and normal mode at the same time).
I have to start by admitting that I haven't thought this through.
Here's an example of the problem (note the hydra-org-nav
, then look down for the next reference to that symbol):
https://github.com/AssailantLF/emacsconfig/blob/master/config.org#evil-org
The problem is that the key bindings (both keys and what they're bound to) have to be repeated, which is a shame. Maybe general.el could support hydra better, or replace it with something equivalent?
By the way I really appreciate general.el, my emacs config is much better for using it (together with use-package)!
(general-define-key :states '(normal motion insert emacs)
:keymaps 'emacs-lisp-mode-map
:prefix ","
:non-normal-prefix "M-m"
"/" 'swiper)
M-m , / We want M-m /
problem or you mean it ??
Did you hava a good idea?
I want a "M-m" can be used in normal motion insert emacs,etc.. not just in insert emacs mode.
like this:
(general-define-key :states '(normal motion insert emacs)
:keymaps 'emacs-lisp-mode-map
:prefix "," <<<normal motion ,this is working
:global-prefix "M-m" <<< normal motion insert emacs
"/" 'swiper)
Alll I mean : M-m / can be used in all , and ", /" in normal motion
Thanks..
Thank you for this excellent package! I'm having an issue that I'm trying to figure out how to handle.
I have Eshell key bindings defined with the use-package
keyword:
(use-package eshell
:commands eshell
:general
(:keymaps 'eshell-mode-map
"C-d" 'bury-buffer)
(:keymaps 'eshell-mode-map
:prefix "C-w"
"=" 'balance-windows
"h" 'windmove-left
"C-h" 'windmove-left
"l" 'windmove-right
"C-l" 'windmove-right
"j" 'windmove-down
"C-j" 'windmove-down
"k" 'windmove-up
"C-k" 'windmove-up
"C-o" 'delete-other-windows
"c" 'delete-window
"u" 'winner-undo)
:config
[...])
I start different Eshell instances for various projects via projectile
and projectile-run-eshell:
(defun projectile-run-eshell ()
"Invoke `eshell' in the project's root."
(interactive)
(let ((eshell-buffer-name (concat "*eshell " (projectile-project-name) "*")))
(projectile-with-default-dir (projectile-project-root)
(eshell))))
If I start Eshell for project foo
and another Eshell for project bar
then the key bindings I mentioned above will work in the first Eshell but not the second (or any subsequent Eshells).
How can I get the key bindings to work on all of my Eshells?
I've added some stuff to the help map like so:
(general-define-key :keymaps 'help-map
"A" '(nil :which-key "apropos"
"A D" 'apropos-documention
"A V" 'apropos-value)
But when I do C-h
then which-key
describes the A
option as +prefix
. As far as I can tell, it looks like general-define-key
is calling (which-key-add-key-based-replacements "A" "apropos")
, but that's never going to match the key sequence so far.
Your problem, or which-key's?
I'm still using Emacs 24.3 on certain machine.
Another issue is dependency on dash. I intend to use source code of general.el instead of elpa, as the way I use evil-leader. That's my strategy to manage critical packages. So critical package's dependency has to be also installed through source code. But I'm sure dash is also used by other packages installed through elpa,
Thus I could have two version's of dash which I want to avoid.
Currently if setting :keymaps
is the default, nmap
, for example, cannot be used as a wrapper for evil-define-key
(bind in a mode for a state) without wrapping the definer in a let and changing general-vim-definer-default
. A more ideal default would be to set :states
if the user manually used :keymaps
:
;; define key in evil-normal-state-map
(nmap "key" #'func)
;; define key in normal state for emacs-lisp-mode-map
(nmap :keymaps 'emacs-lisp-mode-map "key" #'func)
By setting general-vim-definer-default
to states
similar behavior can be achieved currently except without :keymaps
, the global keymap is used which is not the standard way of defining a generic normal state key binding.
When using :non-normal-prefix
with general-define-key
I get:
Wrong type argument: arrayp, :non-normal-prefix
Minimal init file:
(when (>= emacs-major-version 24)
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(package-initialize)
(defvar my-package-list
'(evil
general))
;; Install missing packages
(let ((refreshed nil))
(when (not package-archive-contents)
(package-refresh-contents)
(setq refreshed t))
(dolist (pkg my-package-list)
(when (and (not (package-installed-p pkg))
(assoc pkg package-archive-contents))
(unless refreshed
(package-refresh-contents)
(setq refreshed t))
(package-install pkg)))))
(require 'evil)
(evil-mode t)
(require 'general)
(setq general-default-states '(normal motion insert emacs))
(general-define-key :prefix ","
:non-normal-prefix "M-SPC"
"c" #'compile)
I don't run into any problems when I set general-default-non-normal-prefix
.
here:
Eager macro-expansion failure: (void-variable keymap)
Sorry for the long title, lemme explain in depth:
I have a large function/section in my evil init file for global mappings that I'd like available at all times in Evil normal state, which primarily remaps some default Evil keys, but also adds some shortcut keys. I used
(setq general-default-keymaps 'evil-normal-state-map)
to make things a little more clean, turning this:
(general-define-key :states 'normal "U" 'redo)
into this:
(general-define-key "U" 'redo)
However, upon making this change, I noticed that these bindings were now unavailable in all my mode-specific maps. For example, if I have custom bindings for dired, like so:
(general-evil-define-key 'normal 'dired-mode-map
<mappings>)
Then U
is undefined in dired. However, if I define :states 'normal
instead of using general-default-keymaps
, all my bindings are available like I want.
This is really only a minor issue for me, since it just makes some of my mappings require an extra 2 keywords, which isn't a big deal at all and is still way better than not using general.
Continuing our discussion from #22.
I just started creating spacemacs-like bindings where I have a prefix like SPC
and you can drill down from there, paired with which-key, and it's pretty cool but it kind of becomes a pain to have to call a different function to label the prefix keys that arise from this setup. It'd be great if we could have a way to label them via general.el, perhaps something like was discussed in #22, a more flexible form to which the current form is expanded:
(general-define-key :blah 'okay
"C-x k" '(:prefix t :which-key "some prefix")
"C-x k f" 'some-cmd
"C-x k b" '(:command other-cmd :which-key "kill buffer"))
So the first is a prefix, which I guess it can either detect from the :prefix t
(perhaps you can devise another way if you prefer). :which-key
can be applied to any binding though.
Note that the second style, the current style, would be rewritten to the third style, i.e. '(:command some-cmd)
, so that you can then handle them all uniformly. Or perhaps that's not necessary, just a suggestion.
This kind of provides some form of type hinting too considering the issue you were running into earlier, for example we can introduce :keymap helm-command-map
to bind a key to a keymap and so it knows that it has to wait for that keymap to load before actually creating the bind, or perhaps generating an autoload for it or whatever, and we can also use :package
so we can specify to which package that keymap belongs.
This would be more flexible and would allow for future functionality, all while not bothering current users or the general simple case.
This is slightly unrelated but I was wondering also that it feels like binding to nil
to unbind doesn't seem very intuitive. bind-key has unbind-key
for example. Rather than introducing yet another function though perhaps it would be cool if we could "bind" to :unbind
or :unset
or something, although that's such a minor cosmetic thing that's probably not worth the effort, but just something I was thinking about.
hi @noctuid,
I've just installed general.el with this setup (it's a snippet that is written on the readme page)
(general-evil-setup)
;; all keywords arguments are still supported
(general-nmap
:prefix "s"
"d" 'dired)
but when I restart emacs, I'm greeted with an error:
Warning (initialization): An error occurred while loading ‘/Users/ninrod/.emacs.d/init.el’:
error: Key sequence s s starts with non-prefix key s
Am I missing something here?
The syntax should be the same as evil-define-key
and define-key
. This would prevent the need to make changes when switching from evil-define-key
to general-evil-define-key
, for example.
This will require making general-define-key
a macro, but it would probably look cleaner this way anyway.
bind-keys
, used by use-package
, has a great deal of overlap with this package. Have you seen it?
When general-key-dispatch
is applied to c
, the cs
"change surround" operator is broken, but is easily fixed.
The fix: add evil-surround-change
as a sub-binding, just like evil-change-whole-line
.
(general-define-key :states 'normal
"c" (general-key-dispatch 'evil-change
;; other sub-bindings
"c" 'evil-change-whole-line
"s" 'evil-surround-change))
I figure that since evil-surround
is such a popular package, you may want to note this somewhere. Although the general-dispatch-key
section of the README already has quite a lot of info tacked on :P
When using evil features in combination with lexical-binding, general-define-key hangs.
Minimal repro: emacs -Q --load test.el
;;; -*- lexical-binding: t -*-
(require 'evil)
(evil-mode t)
(require 'general)
(general-define-key :states '(normal) "M-x" M-x)
I'm not sure if this would be inherently incompatible with the way you've set up general.el, but the bind-map package from which I migrated over to yours supports an arbitrary number of prefix keys. So for example in the readme it shows:
(bind-map my-elisp-map
:keys ("M-m m" "M-RET")
:evil-keys ("SPC m" ",")
:major-modes (emacs-lisp-mode
lisp-interaction-mode))
That means that in evil mode both SPC m
and ,
work as prefixes to the same map. I have a feeling this might seem like unnecessary functionality but I found myself missing when transitioning from one prefix to another.
If it is something that you can add, perhaps you can simply optionally take a list like you do with :keymaps
. I personally don't care that it's currently singular :prefix
instead of :prefixes
but perhaps for consistency you can add support for the other one as well, or only document the newer one from now on while continuing to support the singular form.
evil-leader
sets different leaders for emacs and insert state. This functionality may be useful if a user wants to bind the same keys in normal and insert state but with a different prefix. For example, the following would bind SPC /
in normal mode and M-SPC /
in insert mode to swiper
:
(setq general-default-prefix "SPC")
(setq general-default-non-normal-prefix "M-SPC")
(general-define-key :states '(normal insert) "/" 'swiper)
Hi!
After updating to latest version, I can't call (general-evil-setup)
(with or without t
). When using:
(use-package general
:ensure t
:config
(general-evil-setup))
... I get: Error (use-package): general :config: Wrong type argument: symbolp, (insert emacs)
.
The debugger backtraces it to general--evil-keymap-for-state((insert emacs))
, used with mapcar
from general-create-dual-vim-definer
, called from general-evil-setup
.
Thank you for this wonderful package.
One feature request I have is, to support :which-key
for general-key-dispatch
. Atleast for the top level command should be good.
Also support to add a docstring for the generated function would be good, it can be used to document sublevel bindings when using a :timeout
Here is a small example use case I have in mind, I would like , w
to show g
with
"Search google"
(general-define-key :prefix ","
"w g" (general-key-dispatch 'engine/search-google
:timeout 0.5
"i" 'engine/search-google-images
"m" 'engine/search-google-maps)
"w h" '(engine/search-github :which-key "Search Github")
"w y" '(engine/search-youtube :which-key "Search Youtube"))
Let's say I want to bind SPC s
to save-related stuff.
(general-define-key
:prefix "SPC"
:states '(normal)
"s" '(:ignore t :which-key "save")
"ss" 'save-buffer)
And now I want to bind SPC s
to avy-goto-char in operator map
(omap
:prefix "SPC"
"s" 'avy-goto-char)
I got a wrong result on my config when I press an operator. Say I press d
, SPC
, which-key indicates save
instead of avy-goto-char
.
Maybe it's a which-key related issue, but since I use the :which-key
keyword of your awesome package, I submitted an issue here.
Thanks !
This definitely doesn't work when using a prefix because of the fact that general--apply-prefix-and-kbd
looks for strings instead of acting on every other item (which I think it used to do when I as using dash). kbd
should still be applied to all strings when general-implicit-kbd
is non-nil, but the prefix should only be applied to the keys.
evil-define-key
uses evil-delay
to do this. Doing this for define-key
will require replicating this functionality without requiring evil. This might make things a little more messy since some-mode-map
can't be evaluated like it is currently.
Hello, I'm getting this error while trying to define keybindings that make use of the Meta
key:
error: Key sequence M-k starts with non-prefix key ESC
Perhaps I'm not understanding well how to use general along with evil
, I'm using the :general
keyword for use-package
like this:
(use-package general
:ensure t
:config
(setq general-default-states 'normal))
(use-package drag-stuff
:ensure t
:general
("M-k" #'drag-stuff-up
"M-j" #'drag-stuff-down))
What I want is that M-k
should be available globally without caring in which Evil mode I am.
I've tried some variants without success. Could you give me an intuition about why it's not working?
Thanks.
Hi @noctuid,
I want that when I'm in Info-mode, "DEL"
goes back in history, and "SPC"
invokes counsel-M-x
.
I'm trying this following snippet, to no success. Info-mode's keybinds remain the same! How would one go about setting up this keybind modification?
edit: if I specify :states 'normal
is does not make a difference, either
(general-define-key
:keymaps '(Info-edit-map
Info-edit-mode-map
Info-link-keymap
Info-merged-map
Info-mode-line-node-keymap
Info-mode-map
Info-speedbar-key-map
Info-tool-bar-map)
"SPC" nil
"DEL" nil
)
(general-define-key
:keymaps '(Info-edit-map
Info-edit-mode-map
Info-link-keymap
Info-merged-map
Info-mode-line-node-keymap
Info-mode-map
Info-speedbar-key-map
Info-tool-bar-map)
"DEL" 'Info-history-back
"SPC" 'counsel-M-x)
I expect both of the following to allow me to press -
inside a dired buffer while in normal state and jump to the upper directory. However, only the latter binding works. What am I doing incorrectly?
(setq general-vim-definer-default 'states)
(nmap :keymaps 'dired-mode-map
"-" 'dired-jump)
(general-define-key :keymaps 'dired-mode-map
"-" 'dired-jump)
.
to repeat in evil"Hell" is output as the repeat
"Hello" is output as the repeat
.emacs
down to minimal packages and this still happens, so doesn't appear to be caused by other packages.ESC
instead of the key combo will produce the correct result, so this doesn't appear to be caused by evil itself either.Config:
(use-package general
:config
(general-evil-setup t)
(general-imap "k" (general-key-dispatch 'self-insert-command :timeout 0.25 "j" 'evil-normal-state)))
Like with bind-key
there would be an optional :doc
keyword to support associating a string with a prefix sequence. There would also be a function that would display all keys bound with general.
Edit:
I'm initializing general with (general-evil-setup t)
. Calling other packages like this:
(use-package evil-commentary
:diminish evil-commentary-mode
:general (nmap "gc" 'evil-commentary
"gy" 'evil-commentary-yank))
Gives me Symbol's value as variable is void: key
error on startup.
This might fall under the category of feature request more than a bug. Perhaps I'm unaware of how to properly do this.
To elaborate: I'm using general.el with Evil and have SPC
as a prefix, and C-SPC
as a non-normal-prefix. I would like to be able to have :prefix
set to both SPC
and C-SPC
just to slightly simplify things.
I tried this (I left out the rest of my bindings besides the first):
(general-define-key
:states '(normal motion insert emacs)
:prefix "SPC" "C-SPC"
:non-normal-prefix "C-SPC"
"TAB" 'other-window)
and got this error: Wrong type argument: arrayp, other-window
I figure that this is either A: not supported yet, B: too difficult to implement, or C: can be done with different syntax. If it can be done, I think it'd be pretty convenient.
Thanks for the awesome package!
The first time the key bound to the "autoloaded" keymap is run, it works correctly, but the wrong which-key menu may be displayed. For example, if an "autoload" for projectile-command-map
is bound to SPC p
, then only SPC-
will be displayed in the echo area and the keys under SPC
will be shown in which-key. This problem was discovered in #26.
Apologies if there's a solution to this that I've just overlooked, but I'm unable to get a working binding to evil-commentary, which ports commentary.vim to evil.
evil-commentary provides a gc
comment operator (e.g. g c a p
to comment the current paragraph, g c c
for the current line) by default, which I'd like to bind to SPC ;
(so SPC ; a p
to comment the current paragraph, SPC ; ;
to comment the current line, etc.).
I was previously using evil-leader to accomplish this:
(evil-leader/set-leader "<SPC>")
(global-evil-leader-mode)
(evil-leader/set-key ";" 'evil-commentary)
My best attempt to do the same using general.el is:
(general-define-key :states '(normal visual)
:keymaps 'evil-commentary-mode-map
:prefix "SPC"
";" 'evil-commentary)
When I type SPC ;
, I get an error reporting, "No command bound to ;", which I've tracked down to evil-extract-count
in evil-common.el.
It looks like evil-extract-count
is called with the result of this-command-keys
as its KEYS argument from evil-operator-range
. So in this case, it's been passed SPC ;
(" ;").
My knowledge of Emacs keymaps is still pretty feeble. Any help you can provide would be much appreciated.
And thanks for the great plugin! Aside from this one issue, I've been really enjoying it.
hi @noctuid,
I have all my hydras organized to the SPC h
keybind. So for example, SPC hz
will execute my zooming hydra, and so on and so forth.
What I would like to do is this:
(general-create-definer spc-map
:states '(normal visual motion)
:prefix "SPC")
(spc-map
"h" 'here-would-go-my-zooming-hydra?) ; I wish that worked!
But is seems that hydra requires a premade keymap for the defhydra
macro. Does general.el creates a custom keymap when I call my custom spc-map
function so I could feed into the defhydra
macro like this?
(defhydra hydra-zoom (my-awesome-custom-spc-map "hz") ; here!
"zoom"
("i" text-scale-increase "in")
("o" text-scale-decrease "out"))
(which-key-declare-prefixes "SPC h" "hydras")
(which-key-add-key-based-replacements "SPC hz" "zooming hydra")
It would be great if we could either integrate with bind-key's describe-personal-keybindings
or replicate that behavior on our end. I really like being able to see all of the bindings that I've made, for every mode. It allows me to, for example, scan through them every once in a while to see if there are some I'm not really using. This is much faster and efficient than tracking down the specific configuration file and the binds for it etc.
It seems like all we'd have to do is add each binding made by general-define-key
to the personal-keybindings
list, see this. Perhaps this can be opt-in, and only if the bind-key package is present.
This and #22 are the only things I'm sorely missing from bind-key.
Because extra keys are recorded, keyboard macros won't work correctly. Ideally it would be nice to either be able to pause the keyboard macro or ignore certain events, but it should be possible to fix this by using cancel-kbd-macro-events
and then manually adding the correct keys with store-kbd-macro-event
.
As a last resort, I could have functions created with general-key-dispatch
and general-simulate-keys
behave differently when executing-kbd-macro
is non-nil.
Edit with notes to keep track of problems/progress:
This issue of duplicate key recording is caused when adding keys to unread-command-events
. If an incomplete key sequence is simulated and no command is simulated, keys will not be added to this-command-keys
as long as the events added are not in the form (t . event)
.
The issue now is that when both keys and a command are simulated (which is arguably the major use case; this is how general-key-dispatch
works when a fallback command is called), the simulated keys will be considered as the keys used to invoke the command (even though the command is called with call-interactively
). Using set--this-command-keys
is not a viable solution since simulated keys are still recorded in macros (and it's also new and marked as "internal use only"). clear-this-command-keys
does not work either (I, for example, tried advising the command that ends up being called in various ways without success).
The previous solution for evil repeating was to do complicated checking to find out what should actually be recorded. It broke with an evil update, and this is not possible for keyboard macros.
The previously mentioned "last resort" solution actually now seems to be the best and simplest. Since the simulated keys are duplicated, general--simulate-keys
can just check executing-kbd-macro
(which is also used by evil-repeat
) and not add any keys to unread-command-events
in this case. It also needs to normally force the keys to be added to this-command-keys
with (t . event)
because otherwise only the first simulated key will be recorded with evil-repeat
(this doesn't matter for macro recording).
All major issues seem to be fixed using this solution, but the current problem is finding a way to write tests for these cases that actually works (general--simulate-keys
and I'm not sure if I want to add some extra check to general--simulate-keys
to determine whether evil-execute-macro
is actually intended emulate an interactive keypress in the testing environment instead of an evil-repeat
call; I could alternatively just add the extra extra keys to be simulated (e.g. if "a" will simulated #'evil-delete then "iw", it could be written as "aiw" instead), but that is less than ideal).
Still to test:
I dunno how I didn't notice earlier, but if you set general-key-dispatch
to an operator and then attempt to repeat it, strange behavior occurs.
It's somewhat difficult to explain. For c
(the only thing I tried/used), motion-based changes will add extra letters in, like cw
would add an extra w
to the beginning of your repeated change. Still for c
, when text objects are used like ciw
, it gives an error: After 0 kbd macro iterations: Quit
.
It seems to be quite a fickle feature. :P
Sorry for the confusing title, couldn't figure out how to write it properly. Anyways, I'm currently using this with Evil and really like it, and am currently using <SPC>
as my main prefix key with a few commands mapped to keys with it. I wanted to map a few git commands to all have to start with <SPC>g
, so for example magit-status
would be <SPC>g s
, but whenever I try to add two keys to it throws this error message: Error (use-package): general :config: Key sequence SPC g s starts with non-prefix key SPC g
. I was wondering if this was possible with general.el
? Thanks for the great plugin! 😄
Wrong type argument: symbolp, (evil-normal-state-map evil-visual-state-map)
This would allow general-nmap
to be used to define in the global map for a state instead of in evil-normal-state-map
. See #16.
Trying out the general-key-dispatch
, if I use the example given by the readme:
(general-evil-setup)
(general-nmap "c"
(general-key-dispatch 'evil-change
"ow" 'toggle-word-wrap
"c" 'evil-change-whole-line))
I'm able to use cow
and cc
, but any normal c*
bindings (like cw
, cf
, etc.) give the error: Key sequence contains no complete binding.
It may be related to a separate setting or package on my end.
I would like the following, if possible:
Using the leader "," I would like to use it in every every state (normal visual emacs insert)
When in a :non-normal-prefix
I would like to have a short timeout where it will insert "," if I don't follow it up with a defined key.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.