Hi all. Is there a way to insert one symbol without entering into insert mode? I find it unconvenient to push "i <symbol> C-[" to insert one letter. Thanks. Petro.
On Mon, May 28 2012 (15:22), Petro <[email protected]> wrote:
Is there a way to insert one symbol without entering into insert mode? I find it unconvenient to push "i <symbol> C-[" to insert one letter.
\ <symbol> \ is bound to evil-execute-in-emacs-state that executes the following key chord in emacs state. That's not insert state so be aware of changed keybindings. But it's quite easy to derive an `execute-in-insert-state` from its code. Michael
On 2012-05-28 15:22 +0200, Petro wrote:
Is there a way to insert one symbol without entering into insert mode? I find it unconvenient to push "i <symbol> C-[" to insert one letter.
As Michael pointed out, you can use "\" to escape to Emacs state for the duration of one command. Thus, "\e" inserts the letter "e" and then returns to Normal state. The following Vim tip suggests to bind a character-insertion command to "SPC": http://vim.wikia.com/wiki/Insert_a_single_character If you would rather type "SPC <symbol>" instead of "\ <symbol>", then you can rebind "SPC". By typing "C-h k \", we see that "\" is bound to the command `evil-execute-in-emacs-state'. Thus, the following binds it to "SPC": (define-key evil-normal-state-map " " 'evil-execute-in-emacs-state) Then you can follow the Vim tip to set up similar behavior in Vim, if you use both editors. -- Vegard
"\ <char>" is a good tip for inputing one char without entering insert mode, however, it is not dot repeatable. I used to have my own function bound to SPC to insert one char and was repeatable, but I'm now binding SPC to ace-jump which I found to be even more useful. Is it possible to make "\<command>" repeatable? Thanks, York
You guys always find strange situations I've never thought off ... ;) On Tue, May 29, 2012 at 11:41:32AM -0400, York Zhao wrote:
"\ <char>" is a good tip for inputing one char without entering insert mode, however, it is not dot repeatable. I used to have my own function bound to SPC to insert one char and was repeatable, but I'm now binding SPC to ace-jump which I found to be even more useful. Is it possible to make "\<command>" repeatable?
No, not easily. There are two reasons for this. The first one is that Emacs state is not repeatable by intention. When Evil switches to Emacs state, then evil is essentially turned off (as far as it could be). This means the repeat system ignores all commands in Emacs state completely. That's because Emacs state is, well, plain Emacs, and it is very difficult to do repeat-recording right if there is no distinction between different states like normal state and insert state. Furthermore almost all commands active in Emacs state are non-Evil commands, which makes it even more difficult (they usually do not carry appropriate :repeat attributes). Furthermore the one-shot Emacs state, i.e., the command `evil-execute-in-emacs-state', essentially simply switches to Emacs state and installs a post-command-hook that returns to the previous state after the next command. So there is no easy way for the repeat system to distinguish the one-shot emacs state from the "real" emacs state. The second problem is that the repeat system relies on post-command-hook, too, in this interferes easily with the post-command-hook of `evil-execute-in-emacs-state'. A compromise could be to use insert-state instead of emacs-state. Both states are almost equivalent except for the repeat-recording and a few key-bindings (especially the ESC key) in `evil-insert-state-map' (In fact, in almost all situations insert state could be used whenever emacs state is desired). Still, the post-command-problem needs to be respected. The following command can be used (highly untested!!!) to execute a single command in insert state (it's almost equivalent to `evil-execute-in-emacs-state' except for the two lines dealing with the repeat system). (evil-define-command evil-execute-in-insert-state (&optional arg) "Execute the next command in Insert state." (cond ((called-interactively-p 'any) (add-hook 'post-command-hook #'evil-execute-in-insert-state t) (evil-insert 1) (evil-echo "Switched to Insert state for the next command ...")) ((not (eq this-command #'evil-execute-in-insert-state)) (remove-hook 'post-command-hook 'evil-execute-in-insert-state) (evil-change-to-previous-state) ;; ensure the command is recorded if we return to normal state (when (evil-normal-state-p) (evil-repeat-stop))))) (define-key evil-normal-state-map "\\" 'evil-execute-in-insert-state) One could also clear `evil-insert-state-map' temporarily to make insert-state in this special situation even more like emacs state. An alternative could be to implement `evil-execute-in-insert-state' or `evil-execute-in-emacs-state' by directly reading the next command with `read-key-sequence' and to call the appropriate binding directly, i.e., something like (evil-define-command evil-execute-in-emacs state () (let (evil-local-mode) (let ((key (read-key-sequence ""))) ... (call-interactively (key-binding key)) ... ))) This could probably be much more robust (no post-command-hook magic necessary), but I've never thought of this (there are certainly a lot of other problems with this approach). Frank
Thanks for the extremely detailed explanation Frank. I actually didn't think too much about this but I was sure it wouldn't be easy. And thanks for your creative ideas.
participants (5)
-
Frank Fischer -
Michael Markert -
Petro -
Vegard Øye -
York Zhao