Sorry for what is probably an easy question for an experienced emacs user, I'm having a really hard time figuring out how to switch the default bindings for the ESC and "`" keys.
This is what I have so far:
(defun set-my-key-bindings ()
;; This next line works, makes ` the escape key in insert node.
(define-key evil-insert-state-map (kbd "`") 'evil-normal-state))
;; This doesn't do anything, but I want it to insert a "`" character when the escape key is pressed while in insert mode.
(define-key evil-insert-state-map (kbd "ESC") (lambda () (interactive) (insert "`")))
Should I be approaching this differently? It seems everything I'm finding always binds a key to a emacs symbol, but the best I can find is the (self-insert-command) when I do C-H k "`" while in insert mode.
Any help greatly appreciated!!
Related
I want to type a single keystroke to insert unicode brackets #xab and #xbb.
This works (for a different unicode bracket):
(global-set-key (kbd "C-c [") "⟨")
But this doesn't work:
(global-set-key (kbd "C-c [") "«")
How do I coax emacs into inserting "«" with a single keystroke?
(I happen to be on MacOS, but intend to use ubuntu in Parallels)
I`m not sure what is expected, double ⟨ or one «, but hope this can help
check function and loop
(defun my-insert ()
"test something"
(interactive)
(dotimes (i 2)
(insert "⟨"))
)
(defun my-insert2 ()
"test something"
(interactive)
(insert "«")
)
(global-set-key (kbd "C-c [") 'my-insert)
(global-set-key (kbd "C-c ]") 'my-insert2)
There is a more general solution which works everywhere, making it more convenient (as you may not want to open an emacs instance each time you need a particular character), which is the compose key. Compose key is specific to Linux, but there is a way to install an equivalent solution on MacOS, and you can even convert existing Compose Key bindings, which is useful because there are a lot of predefined sequences out there in the wild, for instance the default ones.
E.g. on Ubuntu you probably just need to enable it in the settings, and then with the default configuration typing Compose < < will produce «.
In Evil, The default binding of ESC in insert mode is (evil-normal-state nil).
I want to rebind ESC in insert mode like this:
(define-key evil-insert-state-map (kbd "ESC")
(lambda () (interactive) (message "hello")))
However, when I try to do this I get unexpected behavior. First, the binding does not change. And for a reason I don't understand it also breaks M-x in insert mode.
Why does this happen?
This is likely related to the fact that ESC is an ASCII character which is used in all kinds of "escape sequences" and which Emacs normally considers as an alternative to the Meta modifier.
IIRC Evil handles this issue by mapping the ESC key not to the ESC character (code 27), as done by default in Emacs, but to the escape event. So you might like to try:
(define-key evil-insert-state-map [escape]
(lambda () (interactive) (message "hello")))
I don't like the insert-state, and so I want to replace it with emacs-state. But this setting does not work:
(add-hook 'evil-insert-state-entry-hook 'evil-emacs-state)
After press o or cw, I am still in insert-state.
How about this approach:
(setq evil-insert-state-map (make-sparse-keymap))
(define-key evil-insert-state-map (kbd "<escape>") 'evil-normal-state)
I use it and it seems to do the trick. And since you're not changing the state, you retain state-related configs like cursor-color, etc.
Surprised nobody posted this yet...
(defalias 'evil-insert-state 'evil-emacs-state)
Anything that tries to call evil-insert-state will just end up calling evil-emacs-state. Works for i, a, o, O, etc.
There is now a bulitin way for Evil to do this
(setq evil-disable-insert-state-bindings t)
before loading evil
Reference: https://github.com/noctuid/evil-guide#use-some-emacs-keybindings
Tell me how this works. It's a hack that basically replaces the function evil-insert-state with evil-emacs-state. The problem is figuring out how to exit emacs state with the escape key. For instance, this version works fine when I exit emacs state with the ESC key, but not when I try to do the same with C-[:
; redefine emacs state to intercept the escape key like insert-state does:
(evil-define-state emacs
"Emacs state that can be exited with the escape key."
:tag " <EE> "
:message "-- EMACS WITH ESCAPE --"
:input-method t
;; :intercept-esc nil)
)
(defadvice evil-insert-state (around emacs-state-instead-of-insert-state activate)
(evil-emacs-state))
If the point is that you want to use normal Emacs editing when doing the kind of tasks vi uses insert mode for, then wiping the insert mode dictionary accomplishes this. It is probably desirable that the ESC key gets you back into normal mode and have C-z get you into Emacs state; Leo Alekseyev posts a tiny bit of code that does this:
(setcdr evil-insert-state-map nil)
(define-key evil-insert-state-map
(read-kbd-macro evil-toggle-key) 'evil-emacs-state)
which I use and like. There are two potential disadvantages to being in insert mode rather than emacs mode:
You can't use the ESC key as another, prefixed way of ALT-keymapping; and
There is a risk (so I am told, though I haven't encountered this) if you are accessing Emacs through a tty, that Emacs will interpret ALT-modified keys as ESC followed by the character, which gives a difference in insert mode than in emacs mode.
I don't think either problem is serious.
How I became a unix chad:
;; unix chad setting
(defalias 'evil-insert-state 'evil-emacs-state)
(define-key evil-emacs-state-map (kbd "<escape>") 'evil-normal-state)
(setq evil-emacs-state-cursor '(bar . 1))
From the documentation about evil-emacs-state-entry-hook:
Hooks to run when entering Emacs state.
So the evil-emacs-state function is run when you enter emacs-state (with C-z).
You can, however, do this:
(define-key evil-normal-state-map (kbd "i") 'evil-emacs-state)
The problem now is exiting emacs state. I remember there were some problems binding ESC in emacs state, as ESC is used as META, and (IIRC) Evil uses some "special" code to intercept the ESC key.
EDIT: following your comment: this one should work:
(fset 'evil-insert-state 'evil-emacs-state)
I have taken the below code from emacs site for evil -
(defun my-esc (prompt)
"Functionality for escaping generally. Includes exiting Evil insert state and C-g binding. "
(cond
;; If we're in one of the Evil states that defines [escape] key, return [escape] so as
;; Key Lookup will use it.
((or (evil-insert-state-p) (evil-normal-state-p) (evil-replace-state-p) (evil-visual-state-p)) [escape])
;; This is the best way I could infer for now to have C-c work during evil-read-key.
;; Note: As long as I return [escape] in normal-state, I don't need this.
;;((eq overriding-terminal-local-map evil-read-key-map) (keyboard-quit) (kbd ""))
(t (kbd "C-g"))))
(define-key key-translation-map (kbd "C-c") 'my-esc)
;; Works around the fact that Evil uses read-event directly when in operator state, which
;; doesn't use the key-translation-map.
(define-key evil-operator-state-map (kbd "C-c") 'keyboard-quit)
;; Not sure what behavior this changes, but might as well set it, seeing the Elisp manual's
;; documentation of it.
(set-quit-char "C-c")
It sets up the C-c key for escaping from the insert mode. How do I change it to a more convenient keychord such as "tt" ?
I used the below -
(key-chord-define evil-insert-state-map "tt" 'evil-normal-state)
However when I press 'tt' in the insert mode, it gives the following msg in the mini buffer -
<key-chord> <escape> is undefined
I couldn't reproduce your error, works fine for me.
Make sure you have the key-chord package installed.
(require 'key-chord)(key-chord-mode 1) ; turn on key-chord-mode
(key-chord-define evil-insert-state-map "tt" 'evil-normal-state)
I'd like to have M-u to insert an underscore when I am in isearch (isearch-regexp and also the reverse variants).
Neither
(define-key isearch-mode-map (kbd "M-u") 'insert-underscore)
nor
(add-hook 'isearch-mode-hook
(lambda ()
(local-set-key (kbd "M-u") 'insert-underscore)
))
insert-underscore is my function that simply inserts "_". It works in the main frame and also in minibuffer, but I can't get it working in isearch...
Thank you!
Isearch doesn't use regular commands. (kbd "_") along with every other
printable character is bound to a special command in isearch-mode-map. It's
not obvious, but a lot of things happen in "isearch-mode" when you press a
key. Display is refreshed with new results, wrapping is a possibility, etc, etc,
You'd have to manipulate raw keyboard events to get this to work.
(defun underscore ()
(interactive)
(isearch-unread-key-sequence (list ?_)))
(define-key isearch-mode-map (kbd "M-u") 'underscore)
Note that this code is not robust; for example, numeric prefix does not work.
EDIT: After letting percolate in my mind for a while, it occured to me that this is the exact use-case for translation keymaps
(define-key key-translation-map (kbd "M-u") (kbd "_"))
Ain't Emacs grand?