evil-mode: How to automatically switch to insert mode after certain commands?
There are many emacs commands after which I almost always immediately want to insert text. This often requires entering insert mode after the initial command. Is there any way to instead enter insert mode automatically after certain commands? For example, in org-mode, a user will usually enter some text immediately after the commands org-insert-heading or org-capture. Though this only requires typing <i>, the situation arises so many times in a day that I find myself wishing I could eliminate that extra key press. What would be the recommended way to do this? Incidentally, I am also using evil-org-mode. Thanks, Max
max6166 <[email protected]> writes:
There are many emacs commands after which I almost always immediately want to insert text. This often requires entering insert mode after the initial command.
Is there any way to instead enter insert mode automatically after certain commands?
For example, in org-mode, a user will usually enter some text immediately after the commands org-insert-heading or org-capture.
Though this only requires typing <i>, the situation arises so many times in a day that I find myself wishing I could eliminate that extra key press.
What would be the recommended way to do this?
Incidentally, I am also using evil-org-mode.
I would try adding a function to `post-command-hook' that enters instert-mode when `insert-command' is in a list of symbols. Totally untested code: (defvar maybe-enter-insert-mode-commands '(org-insert-heading) "List of commands that trigger insert mode.") (defun maybe-enter-insert-mode () (when (memq last-command maybe-enter-insert-mode-commands) (evil-insert-state nil))) (add-hook post-command-hook 'maybe-enter-insert-mode)
Óscar Fuentes <[email protected]> writes:
I would try adding a function to `post-command-hook' that enters instert-mode when `insert-command' is in a list of symbols.
s/insert-command/last-command
Óscar Fuentes <ofv <at> wanadoo.es> writes:
I would try adding a function to `post-command-hook' that enters instert-mode when `insert-command' is in a list of symbols.
Totally untested code:
(defvar maybe-enter-insert-mode-commands '(org-insert-heading) "List of commands that trigger insert mode.")
(defun maybe-enter-insert-mode () (when (memq last-command maybe-enter-insert-mode-commands) (evil-insert-state nil)))
(add-hook post-command-hook 'maybe-enter-insert-mode)
Thank you very much, Oscar. The above code gives the error: add-hook: Wrong type argument: symbolp, (evil-visual-post-command linum-update-current t) [2 times] Unfortunately, I am new to elisp & emacs so I have no idea how to figure out the problem.
max6166 <[email protected]> writes:
Thank you very much, Oscar. The above code gives the error:
add-hook: Wrong type argument: symbolp, (evil-visual-post-command linum-update-current t) [2 times]
That's because there is a missing quote. The correct call to add-hook is: (add-hook 'post-command-hook 'maybe-enter-insert-mode)
Unfortunately, I am new to elisp & emacs so I have no idea how to figure out the problem.
The method does not work because post-command-hook is not called with the expected (by me) value in `last-command' (nor `this-command'). Another approach is to advice `call-interactively'. Again, untested code: (defvar maybe-enter-insert-mode-commands '(org-insert-heading) "List of commands that trigger insert mode.") (defun maybe-enter-insert-mode (command &rest args) (when (memq command maybe-enter-insert-mode-commands) (evil-insert-state nil))) (advice-add 'call-interactively :after 'maybe-enter-insert-mode) Be warned that this method is quite gross. If your Emacs starts behaving strangely, the code above can be the cause.
Óscar Fuentes <ofv <at> wanadoo.es> writes:
Another approach is to advice `call-interactively'. Again, untested code:
(defvar maybe-enter-insert-mode-commands '(org-insert-heading) "List of commands that trigger insert mode.")
(defun maybe-enter-insert-mode (command &rest args) (when (memq command maybe-enter-insert-mode-commands) (evil-insert-state nil)))
(advice-add 'call-interactively :after 'maybe-enter-insert-mode)
Be warned that this method is quite gross. If your Emacs starts behaving strangely, the code above can be the cause.
Thank you so much, Oscar. The above method is working great so far. I was thinking of adapting your code for other purposes, but I am concerned about your warning. What are the potential problems with this code? Thanks again. -- For other readers, I think the last line is missing a hash and should be: (advice-add 'call-interactively :after #'maybe-enter-insert-mode)
max6166 <[email protected]> writes:
Thank you so much, Oscar. The above method is working great so far.
You're welcome.
I was thinking of adapting your code for other purposes, but I am concerned about your warning. What are the potential problems with this code?
The problem with advising `call-interactively' is that it is a core function that invokes all other interactive commands. When we call `evil-insert-state' from the advice, we are introducing side effects that can collide with the state created by the command invoked by `call-interactively'. One dumb example of this interaction is to add `evil-normal-state' to `maybe-enter-insert-mode-commands': the advice would revert the effect of `evil-normal-state' by calling `evil-insert-state' just afterwards. I can't think of a realistic case that could cause a problem, but the method makes me feel a bit uneasy anyways. You can ask on emacs-help about the risks of adivind `call-interactively', if you feel concerned. The Elisp experts there can also suggest better methods for achieving what you want.
For other readers, I think the last line is missing a hash and should be:
(advice-add 'call-interactively :after #'maybe-enter-insert-mode)
The hash is "more correct" in the sense that AFAIK it allows some checks (the byte compiler will warn if `maybe-enter-insert-mode' is not defined, for example) but otherwise it is not strictly required.
participants (2)
-
max6166 -
Óscar Fuentes