Currently, if I press C-h c, then trice press ESC key on keyboard I get result
ESC ESC ESC (translated from <escape> <escape> <escape>) runs the command keyboard-escape-quit
What the difference between ESC and <escape> and how can I use this difference to make more keybindings?
Found solution in emacs mailing list archive:
The escape key usually is linked to the escape char, but the two
are different. Under a tty, Emacs receives the exact same byte-sequence
from the terminal if you type the escape key or if you type C-[ (both
send the escape char).
Under a GUI, on the other hand, Emacs can distinguish the two, so under
a GUI, the escape key doesn't send ?\e (aka ESC for kbd) but escape
(aka <escape> for kbd) which is usually turned into a ?\e via
function-key-map (i.e. only if there's no corresponding binding for the
key sequence with escape).
Same thing happens with tab (i.e. TAB (aka C-i) vs tab) and return
(i.e. RET (aka C-m) vs return).
Related
How to send ctrl+D into Emacs' Eshell? It looks like Emacs intercepts all my attempts to send any control key + a letter to shell and tries to interpret it as it's own command. How to send that combination to Emacs' EShell?
For the specific case of C-d, you can use C-c C-d, which is bound to eshell-send-eof-to-process. Otherwise, use C-q for quoted-insert, to force the following character to be inserted into the buffer even if it has a key binding in Emacs.
I always had this strange problem with Emacs that I really want to find a solution but unable to find any. By default key map ESC ESC ESC (three escapes) are mapped to keyboard-escape-quit, which works fine but, if I press ESC only two types and then press an arrow key, it inserts special characters into my text that I always have to redo of delete to get rid of. In other words I get this behavior:
ESC ESC up -> OA
ESC ESC down -> OB
ESC ESC right -> OC
ESC ESC left -> OD
When I use \C-H K to find which functions these keys have been mapped to it shows me ESC ESC ESC which is mapped to keyboad-escape-quit.
Does anyone have any solution how to get rid of this annoying key-binding? Note that I use Emacs in terminal.
Thank you
The arrow keys generate escape sequences.
E.g., if you start cat and hit the up arrow, you will see on your screen something like this:
$ cat
^[[A
i.e., escape, open bracket, A (it will be different depending on the terminal).
This means that if you hit ESC ESC up, Emacs sees ESC ESC ESC [ A and reacts accordingly (keyboard quit, then insert [A).
So, the Emacs behaves as per the docs.
If you want to disable the key binding, you can do
(define-key esc-map (kbd "<ESC><ESC>") nil)
This is not a very good solution, IMO, but not a disaster since you can always use C-g instead.
Sam has described the problem, but as for a general solution, you basically need to teach Emacs to distinguish the ESC received in response to you hitting the "escape key" from the ESC received as part of an "escape sequence". Of course, in general it can't be done, but in practice, you can check the timing: if ESC is followed by a bit of idle time, then it's probably an "escape key", and otherwise it's probably part of an "escape sequence".
This trick is used in VI emulators such as Viper or Evil:
(defvar viper-fast-keyseq-timeout 200)
(defun viper--tty-ESC-filter (map)
(if (and (equal (this-single-command-keys) [?\e])
(sit-for (/ viper-fast-keyseq-timeout 1000.0)))
[escape] map))
(defun viper--lookup-key (map key)
(catch 'found
(map-keymap (lambda (k b) (if (equal key k) (throw 'found b))) map)))
(defun viper-catch-tty-ESC ()
"Setup key mappings of current terminal to turn a tty's ESC into `escape'."
(when (memq (terminal-live-p (frame-terminal)) '(t pc))
(let ((esc-binding (viper--lookup-key input-decode-map ?\e)))
(define-key input-decode-map
[?\e] `(menu-item "" ,esc-binding :filter viper--tty-ESC-filter)))))
If you call viper-catch-tty-ESC, it will setup the decoding such that hitting the escape key should now generate an escape event (instead of an ESC event). This will automatically be mapped back to ESC if there is no binding for escape, thanks to a binding in function-key-map (this is used in GUI mode where the escape key indeed sends to escape event).
Note that this will not fix your problem: "ESC ESC up" will still insert "OA". The problem there is that Emacs's keyboard translation will still see "ESC ESC ESC O A" (tho the first two appeared in a round-about way going through escape and back). So to finally fix the problem, you additionally need to remove the "ESC ESC ESC" binding and replace it with a binding that will only be triggered with the new escape event:
(global-unset-key [?\e ?\e ?\e])
(global-set-key [?\e ?\e escape] 'keyboard-escape-quit)
Note: This is all tricky business. I'm intimately familiar with the corresponding code, yet my first two attempts while writing this answer failed because of some interaction I did not anticipate.
I'm trying to map C-[ in Emacs to do the same as C-g. I tried this:
(global-set-key "\C-[" 'keyboard-escape-quit)
But Emacs behaves strangely after remapping C-[. For example, M-x stops working and if I try to remap M-x I get the following error:
error: Key sequence M-x starts with non-prefix key ESC
Why does this happen? Is there a workaround?
C-[ is the same as ESC, the Escape key. You probably do not want to rebind ESC, since it is used in many, many, many keybindings, as a prefix key. It implements the Meta key modifier in many cases, which is probably why you say that "Emacs behaves strangely" after you rebound it (removing its prefix-key behavior). See the Emacs manual, node User Input.
As to "Is there a workaround?" -- pick another key (leave ESC alone).
And wrt ESC and C-g: See the Emacs manual, node Quitting (also node Menu Bar).
I found big distinction in standard emacs-nox and emacs-gtk.
I know that emacs console version (emacs-nox) has problem with some keys (eg Shift-Tab - ), but not with PageDown.
When I have empty .emacs file, and try to recognize command name run by PageDown key (by C-h c), emacs-nox emacs-gtk works normally - pushing PageDown makes scroll-up, and C-h c PageDown print scroll-up in minibuffer.
The problem arise when i try to bind "M-[" key.
In .emacs i has only one statement:
(global-set-key (kbd "M-[") 'hippie-expand)
emacs-nox does not recognize command name run by key - it does'nt print in minibuffer anything when C-h c PageDown, insted wriets to buffer "~6".
When I try
C-h k PageDown
I get: M-[ runs the command hippie-expand
emacs-gtk works normally - pushing PageDown makes scroll-up, and C-h c PageDown print scroll-up in minibuffer.
So I guess emacs nox treats PageDown as M-[ and add something extra.
Any idea how to fix this in emacs-nox?
I use emacs v23.2
EDIT:
I tested other case: In .emacs I have only:
(global-set-key (kbd "") 'hippie-expand)
and both C-h c PageDown and C-h k PageDown works properly (prints hippie-expand), and when in buffer I push PageDown also works good.
The problem has to do with the escape sequence the terminal sends to Emacs. You can check the escape sequence by typing C-v in a terminal window, followed by the key combination. So, for instance, if you type
C-v M-[
you should see something like this in the terminal window:
^[[
If you type
C-v PageDown
you should see
^[[6~
And that explains the problem: the key sequence generated by M-[ is a prefix of the key sequence generated by PageDown. Thus when you bind that prefix to a function (e.g., by globally setting M-[ to 'hippie-expand), you get the following effect when hitting PageDown:
The first two characters (^[[) of PageDown's escape sequence are interpreted as the prefix and thus 'hippie-expand is called. Then the remaining two characters are interpreters like ordinary key strokes, and are thus inserted into the buffer. That's why you see "6~" when you press PageDown.
I think the only way to change this is to convince the terminal to send different sequences for those keys. But the more painless way is just to use a different shortcut than M-[. (I would suggest M-/.)
This has to do with the terminal emulation and how Emacs-nox interprets the escape sequences sent to it by the terminal whenever you hit a key.
It thus depends on your terminal, but you could try to put the following lines in your .emacs file:
(unless window-system
(define-key input-decode-map "" [next])
(define-key input-decode-map "" [prior]))
Then move the cursor between the first two "" characters and type C-q PageDown, then move it between the "" in the row underneath and type C-q PageUp. The result should look like this:
(unless window-system
(define-key input-decode-map "^[[6~" [next])
(define-key input-decode-map "^[[5~" [prior]))
but note that the ^[ is only a single character (escape) - that's why you cannot simply copy & paste it from this answer.
Do the keys work after restarting emacs-nox?
Normally keyboard-escape-quit is bound to EscEscEsc. Is it possible to rebind it to a single Esc? I never use Escape as a prefix key.
I'm running Emacs 23.0.60.1 on Windows XP.
Rehashing other's answer, I have
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
in my .emacs file, and it works on my emacs 22 on WinXP. I also hate typing 3 ESC in a row; and from years of (windows) habits my finger goes so naturally to the escape key for getting out of anything unpleasant.
Not to say this is right for you, but when I had this problem I taught myself to press Ctrl-g instead, which is also bound to keyboard-escape-quit by default. For me, this has the advantage of keeping my left hand pretty close to the home position, as well as leaving my Esc prefix intact.
Edit: After reading through the linked page, it's not bound to exactly the same function, and on Windows Ctrl-g can't forcibly interrupt a running command, but Ctrl-g covers 99% of what I would use Esc Esc Esc for --- aborting a command that I screwed up entering.
You can do it, but at the expense of killing the Esc prefix key map
The code to do this is
(global-set-key "" 'keyboard-escape-quit)
where the funny char is is escape (use ^Q esc to type it in)
it will map esc for you but the rest of the keymap is gone
after that