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.
Related
I am fairly new to emacs, and I'm having a problem with the minibuffer remaining active when I don't think it should be. I have the following mapping for 'other-window:
(global-set-key (kbd "M-s M-s") 'other-window)
I know that this will cycle through the minibuffer if it is active, and I like that behavior. The problem is that my minibuffer keeps getting stuck in the following state:
Next element matching (regexp):
It gets in there sometimes when I am not even trying to do a regex search or even a search at all. When I hit C-g to kill it, I get the Quit message, but the minibuffer stays active and goes right back to
Next element matching (regexp):
Also, when it is in this state, I cannot use M-s M-s to get to the next window in my frame. C-x o still seems to work though.
I also seem to be able to run other minibuffer commnands (such as file search) just fine, even when I'm stuck like this.
Is there a way that I can do one of the following:
Kill the minibuffer when in that mode.
Set my custom 'other-window M-s M-s function to get out of the minibuffer and on to the next window?
Either solution would be fine, though the 1st might be better since getting the minibuffer stuck may have other unexpected consequences.
Just do this:
(define-key minibuffer-local-map "\M-s" nil)
The problem is that M-s is locally bound in the minibuffer (in minibuffer-local-must-match-map and other minibuffer keymaps) to next-matching-history-element, which gives you that prompt and lets you search the history.
What you need to do is unbind M-s in each of the minibuffer keymaps: i.e., bind it to nil. Some of those maps inherit from others; minibuffer-local-map should take care of it, but you might want to do the same thing for minibuffer-local-ns-map. M-x apropos-variable minibuffer map tells you about all of the maps.
[You can use C-h M-k to see the bindings of any keymap, e.g., minibuffer-local-must-match-map -- it is available in library help-fns+.el.]
Likely what is happening is that you're doing a search (thus the prompt Next element matching (regexp):), and using your M-s M-s to stop the search.
What this actually does is just switch to a different buffer, but leaves the search active.
One change you could do is change your behavior, and use C-g to quit out of the search, and return you to the buffer you were searching. This is good to know in case you're in an Emacs that doesn't have your customization. You can also use the M-s M-s to switch back into the minibuffer, and then quit out with C-g.
But, I think your binding could be updated by doing:
(global-set-key (kbd "M-s M-s") 'my-other-window)
(defun my-other-window (count)
(interactive "p")
(if (and (>= (recursion-depth) 1) (active-minibuffer-window))
(abort-recursive-edit)
(other-window count)))
Which will automatically quit the minibuffer if it is active (and implicitly switch back to the original buffer), otherwise it'll just switch windows as requested.
You've now heard where the problem is coming from. As for how to get out of it, use C-].
I did a ctrl h b to view all my bindings in emacs. Now I want to unbind a lot of keys, simply because I never use those functions of Emacs and I don't want to perform them when I accidently press the bound keys! This also frees up a lot of keys for other tasks (for use with Cedet for example). So apart from global-unset-key, is there any method to remove bindings in bulk?
C-a move-beginning-of-line
C-b backward-char
C-c mode-specific-command-prefix
C-d delete-char
C-e move-end-of-line
C-f forward-char
C-g keyboard-quit
C-h help-command
C-k kill-line
C-l recenter-top-bottom
C-n next-line
C-o open-line
C-p previous-line
C-q quoted-insert
C-t transpose-chars
C-u universal-argument
C-v scroll-up
C-x Control-X-prefix
C-z suspend-frame
ESC ESC-prefix
I want to remove most of these bindings which are absolutely useless for me.
There's no built-in way to unset a lot of keys, because it's easy to do it yourself:
(Edited for strict correctness:)
(dolist (key '("\C-a" "\C-b" "\C-c" "\C-d" "\C-e" "\C-f" "\C-g"
"\C-h" "\C-k" "\C-l" "\C-n" "\C-o" "\C-p" "\C-q"
"\C-t" "\C-u" "\C-v" "\C-x" "\C-z" "\e"))
(global-unset-key key))
Although I have to say that most of the commands you call "useless" I would call "essential."
(Edited to add:)
As for freeing up keys for other tasks, there's plenty of unused key real estate:
Key sequences consisting of C-c followed by a letter are by convention reserved for users.
If you have an extra modifier available, like Option on the Mac or the Windows key on a PC, you can associate it with an Emacs modifier like super. I have super-b bound to browse-url-at-point, for example.
If you're not on a plain terminal, the shift key becomes available to distinguish key sequences. For example, I have shift-meta-b bound to bury-buffer.
For commands that are useful but not run often enough to warrant a dedicated key sequence, you can use defalias to provide a shorter name. In my .emacs file, I have (defalias 'ru 'rename-uniquely) and (defalias 'c 'calendar) (among many others).
global-unset-key and local-unset-key are useful, but it's worth having an answer to this question that points out that the general way to unbind a key (for any keymap) is to define a binding of nil:
(define-key KEYMAP KEY nil)
If you follow the code for either of those other functions, you'll notice that this is exactly what they do.
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
Most emacs modes include some sort of prefix to activate their features. For example, when using GUD "next" is "C-c C-n". Of these modes, many provide special buffers where one can use a single key to activate some functionality (just 'n' or 'p' to read next/previous mail in GNUS for example).
Not all modes provide such a buffer, however, and repeatedly typing the prefix can be tiresome. Is there a well-known bit of elisp that will allow for ad-hoc specification of prefix keys to be perpended to all input for some time? (Until hitting ESC or some other sanctioned key, for example)
I agree with Joe Casadonte's answer that the way to go is to define your own minor (or major) mode.
That being said, your question is interesting.
Here's a solution that prompts you for a key sequence and it takes the prefix keystrokes and promotes that keymap to the top level.
e.g. Assume the following keymap:
M-g ESC Prefix Command
M-g g goto-line
M-g n next-error
M-g p previous-error
When you run M-x semi-modal-minor-mode, it will prompt you for some keystrokes. If you enter M-g n, then the following keybindings are set:
ESC Prefix Command (same as M-g ESC)
g goto-line
n next-error
p previous-error
So now n doesn't self-insert, but jumps to the next error. See the code below.
Note: when this minor mode is enabled, <f12> is bound to a command which disables the minor mode. This is because the keybindings might very well disable your Emacs (for instance, what if there was a new keybinding for M-x).
Edited to add these thoughts: the minor mode variable was originally made buffer local, but that doesn't work unless you also make the minor-mode-alist variable buffer local (duh). But, you also (probably) don't want these bindings in the minibuffer... So, I'm not going to test it b/c it really depends on what you want, but I've added a comment to the code reflecting this thought.
Without further ado:
(defvar semi-modal-minor-mode-keymap (make-sparse-keymap)
"keymap holding the prefix key's keymapping, not really used")
(defvar semi-modal-minor-mode-disable-key (kbd "<f12>")
"key to disable the minor mode")
(defun semi-modal-minor-mode-disable ()
"disable the minor mode"
(interactive)
(semi-modal-minor-mode 0))
(define-minor-mode semi-modal-minor-mode
"local minor mode that prompts for a prefix key and promotes that keymap to the toplevel
e.g. If there are bindings like the following:
M-g ESC Prefix Command
M-g g goto-line
M-g n next-error
M-g p previous-error
And you enter 'M-g n' when prompted,
then the minor mode keymap has the bindings
g -> goto-line
n -> next-error
p -> previous-error
ESC -> Prefix Command (same as M-g ESC)
The variable semi-modal-minor-mode-disable-key is bound to disable the minor mode map.
This is provided because often the mappings make the keyboard unusable.
Use at your own risk."
nil " Semi" semi-modal-minor-mode-keymap
(make-local-variable 'semi-modal-minor-mode)
(make-local-variable 'minor-mode-map-alist)
(let ((pair-holding-keymap-to-modify (assq 'semi-modal-minor-mode minor-mode-map-alist)))
(setcdr pair-holding-keymap-to-modify (make-sparse-keymap))
(if semi-modal-minor-mode
(let (key
keymap)
;; all but last (b/c we want a prefix
(setq key (substring (read-key-sequence "Enter a full key combination, the prefix will be used: ") 0 -1))
(if (and (not (equal "" key))
(not (equal (kbd "C-g") key))
(let ((semi-modal-minor-mode nil))
(keymapp (setq keymap (key-binding key)))))
(progn
(setcdr pair-holding-keymap-to-modify (copy-keymap keymap))
(when semi-modal-minor-mode-disable-key
(define-key (cdr pair-holding-keymap-to-modify)
semi-modal-minor-mode-disable-key 'semi-modal-minor-mode-disable)))
(semi-modal-minor-mode 0))))))
The mode-specific (modal?) part of key-bindings in Emacs is realized by the various local maps that overshadow the universal global-map. Most major and minor modes define their own local maps; for example, there is a gud-mode-map. Key bindings in a local keymap will be activated only when the current-buffer is in the respective mode. You can customize a mode specific keymap through the mode's hook. For example, you may put this snippet into your ~/.emacs
(add-hook 'gud-mode-hook
(lambda ()
(local-set-key (kbd "C-n")
(lookup-key (current-local-map) (kbd "C-c C-n")))))
More details about keymaps can be found in Elisp reference manual.
The basic issue here is that there is no current keymap per-se. There's the global keymap which is overridden by the major mode's keymap which in turn is overridden by one or more minor mode keymaps (and they can step on each other in some defined way, I'm sure). Defining a new major mode will still leave the minor mode keys functional, and defining a new minor mode will only affect whatever keys you define in the minor mode's keymap.
For example, you could define a minor mode that will do what you want as long as the minor mode is active. You define a new minor mode my-gud-mode which will have its own keymap. You would then have to define all of your key mappings for it (e.g. n, p, etc) and you would also have to define all of the keys that you didn't want to work to be bound to the function ignore. That's the real pain of this, remapping all of the other keys. The minor mode is easy to switch on and off, though; that's the advantage.
Defining a new major mode would be easier at first blush, as it will let you override more of the "current keymap" in one shot. It should note the current major mode in a buffer-local variable so it can be restored later when the temporary major mode is turned off. But you'll still have other minor modes intruding into your keymap, so it won't be "pure".
What I do in this situation is define an easier prefix! For stuff I use all of the time, all day every day, I give them a function key all on their own (e.g. I have F1 set aside as my jabber-mode key). For less immediately useful things, I have two other function keys set aside, F3 and F12 (I'm sure there was some reason I picked them long ago, but I no longer remember why). F3 defines keys that are always available, regardless of major mode. F12 defines keys that are major-mode-dependent. Some examples:
I have set up F3-m- as a prefix to switch major modes (e.g. F3-m-p switches to cperl-mode) and F3-M- as a prefix for minor modes (e.g. F3-M-v toggles view-mode). These are always available, so you could do something like bind F3-g- to be your gud prefix, and type F3-g-p for previous and so on.
My F12 key is mode-dependent. So, in dired mode F12-e will call dired-nt-open-in-excel on the current file, and in emacs-lisp-mode F12-e will call elint-current-buffer. Somehow I never get them confused.
If you need help in defining keymaps like this, let me know.
Viper mode allows you to map commands to keys or key sequences while in the visual mode (entered using the "esc" key). Go back to insert mode with "i".
Have a look at viper-in-more-modes.elIt uses viper-modify-major-mode.
I also like to use the viper-vi-global-user-map: a snippet from my .emacs file.