How can I change the behavior of a key in Emacs? - emacs

I want to change the behavior of the key TAB. I don't know if it's possible: I want to force TAB to do what M-i does.

Sounds like you want to remap the command that is bound to M-i to TAB.
If you want to do that in the global-map then this does it:
(global-set-key (kbd "TAB") (kbd "M-i"))
If you want to do it in a particular keymap, say foo-map, then this does it:
(define-key foo-map (kbd "TAB") (kbd "M-i"))
But typically users want to remap a command's keys to another command. For that you use [remap OLD-COMMAND] as the first arg to global-set-key or the second arg to define-key, and you use the NEW-COMMAND as the last arg.
Alternatively, for that you can use function substitute-key-definition, which also lets you change keymaps. C-h f substitute-key-definition starts with this:
substitute-key-definition is a compiled Lisp function in subr.el.
(substitute-key-definition OLDDEF NEWDEF KEYMAP &optional OLDMAP)
Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
In other words, OLDDEF is replaced with NEWDEF wherever it appears.
Alternatively, if optional fourth argument OLDMAP is specified, we redefine
in KEYMAP as NEWDEF those keys which are defined as OLDDEF in OLDMAP.

Related

C-d and C-S-d key bindings in emacs

I try to bind Ctrl+d and Ctrl+Shif+d like this
(global-set-key (kbd "C-d") 'mc/mark-next-like-this)
(global-set-key (kbd "C-S-d") 'mc/mark-next-like-this)
I'm unable to bind Ctrl+Shift combination, the firs one "C-d" binds to both with and without shift. What I do wrong?
You already have the correct syntax. It is likely that C-S-d is bound in a major- or minor-mode keymap which is taking precedence over the global keymap.
Try C-h k C-S-d (or M-x describe-key C-S-d) to find out what it the conflicting command is and what keymap it is in.
Then you can unset that key binding by adding one of the following to that mode's mode hook.
(local-unset-key (kbd "C-S-d"))
OR:
I like to use the bind-key package. With it you would do something like the following:
(unbind-key "C-S-d" the-offending-mode-map)

Elisp code to bind a keychord to another keychord

In Emacs, with the idea of binding a keychord to another keychord, why is this elisp code not working?
(global-set-key (kbd "C-f") (kbd "C-s"))
(The idea being, in this example, to get "C-f" to do the same as "C-s".)
I don't know why it not work either, but the usual way to achieve your purpose is just binding a key to a interactive command, instead of a string or keyboard macro, in this case (kbd "C-s"):
(global-set-key (kbd "C-f") #'isearch-forward)
or (the above is better)
(global-set-key (kbd "C-f") (key-binding (kbd "C-s")))
According to the documentation, I was expecting the following to be true: What you are attempting doesn't work, because you're binding the result of (kbd "C-s") to a key, which is an internal Emacs key representation and not the function that is (globally) set to the key. However, as xuchunyang pointed out, that's not entirely correct. global-set-key calls define-key internally which has in its documentation the following part:
(define-key KEYMAP KEY DEF)
In KEYMAP, define key sequence KEY as DEF. KEYMAP is a keymap.
KEY is a string or a vector of symbols and characters, representing a
sequence of keystrokes and events. [...]
DEF is anything that can be a key's definition:
nil (means key is undefined in this keymap),
a command (a Lisp function suitable for interactive calling),
a string (treated as a keyboard macro), [...]
And indeed, xunchunyang's example (global-set-key [?l] (kbd "C-f") works as you expect. (global-set-key [?l] (kbd "C-s") doesn't work, because isearch-forward expects an argument (the search regexp) which interactive will ask for. Only if you provide one, this particular keyboard macro will work, i.e. (global-set-key [?l] (concat (kbd "C-s") "foo")) will bind a search for "foo" to the key "l".
xuchunyang's answer is absolutely right: the best way is to name the function explicitly via (global-set-key (kbd "C-f") #'isearch-forward).
You can easily figure out the function that is bound to a key by typing C-h k and then the key which you want to "copy": e.g. C-h k C-s) will show you that C-s is (usually, cf. below) bound to isearch-forward.
The approach using key-binding could, in the general case, lead to strange results: depending on where and how you execute this (i.e. interactively in some buffer or in your .emacs), results may differ, because key-binding honours current keymaps, which might assign different functions to keys.

emacs unbound key bindings

How do I clear a binding or edit a binding an emacs package provide?
For instance I had keybindings M-c to capitalize a word.
After I install some 3rd party emacs package, it is changed to calc-dispatch.
I'd like to use M-c as capitalize as before, and set calc-dispatch to something else.
How can I do this in general?
The keybind maps are loaded by order. The keybind map which loaded later will have higher priority. This is why the local key map will override the global keymap, because the global key map is loaded before the local key map(the mode key map). Something is wrong here. Look phils's comment.
What I solve this problem is add a hook to that specify mode to disable that key bind and rebind it to other key in that key map.
First, you need to find the key-map name which defines the M-c bind to calc-dispatch.
It is usually the combination of mode name and mode-map.
For example, the name of python mode key map is py-mode-map.
Second, remove the M-c bind in that mode and rebind to other key using hook.
For example, in python mode, I want to remove the bind C-j (py-newline-and-indent). And rebind it to C-i. Because globally I bind C-j to linum-ace-jump. This is the similar case with yours.
(add-hook 'python-mode-hook
#'(lambda ()
(define-key py-mode-map "\C-j" nil)
(define-key py-mode-map "\C-i" 'py-newline-and-indent)))
What you ask for is:
(global-set-key (kbd "M-c") 'capitalize-word)
This is in general the way to set words globally.
Maybe if you want to substite the two, you can try this:
(substitute-key-definition
'capitalize-word 'calc-dispatch (current-global-map))
(define-key KEYMAPNAME (kbd "KEYCOMBO") 'FUNCNAME)
Is for specific mode. For example: (define-key emacs-lisp-mode (kbd "M-c) 'capitalize-word).
(global-set-key (kbd "M-c") nil)
Is to generally unbind a key (globally).
You can easily find more on this by just googling.

Preventing a key binding on a key-map from shadowing global key bindings

I would like to bind the following key sequence C-x r l to a function called helm-bookmarks.
From what I understand, I could do this with a keymap that is triggered with C-x, e.g.
(define-prefix-command 'my_sense_map)
(global-set-key (kbd "C-x") 'my_sense_map)
(define-key my_sense_map (kbd "r l") 'helm-bookmarks)
but this shadows all my other bindings (e.g. C-x 2 or C-x 3 for window splitting), i.e. they stop working.
How can I bind C-x r l to 'helm-bookmarks without changing any other key bindings?
All you need to do is to just set the binding of C-xrl in the current global map to helm-bookmarks:
(global-set-key (kbd "C-x r l") 'helm-bookmarks)
Emacs defines C-x as a prefix key that uses a keymap stored in the variable ctl-x-map, which contains most bindings for key sequences starting with C-x. If you re-define it so that it uses a new keymap with no entries, you will lose all those bindings stored in ctl-x-map.

Assign multiple Emacs keybindings to a single command?

I'm giving ErgoEmacs mode a try to see if I can use Emacs more comfortably. Some of its keybindings are fairly intuitive, but in many cases I don't want to outright replace the defaults.
For example, in the context of ErgoEmacs' navigation shortcut structure, M-h makes sense as a replacement for C-a--but I want to be able to use both, not just M-h. I tried simply duplicating the commands:
;; Move to beginning/ending of line
(defconst ergoemacs-move-beginning-of-line-key (kbd "C-a")) ; original
(defconst ergoemacs-move-end-of-line-key (kbd "C-e")) ; original
(defconst ergoemacs-move-beginning-of-line-key (kbd "M-h")) ; ergoemacs
(defconst ergoemacs-move-end-of-line-key (kbd "M-H")) ; ergoemacs
But Emacs simply overwrites the first keybinding with the second. What's the best way to address this?
To re-post reply from ergo-emacs mailing list:
Xah Lee said:
that's very easy.
in the
ergoemacs-mode.el file, there's this
line (load "ergoemacs-unbind") just
comment it out. That should be all
you need to do. However, note that
ErgoEmacs keybinding defines those
common shortcuts such as Open, Close,
New, Save... with keys Ctrl+o,
Ctrl+w, Ctrl+n, Ctrl+s etc. About 7 of
them or so. So, i think some of these
will hit on emacs traditional
bindings with Ctrl. if you are new to
ErgoEmacs and trying to explore it,
you might just try starting with few
keys. this page might have some
useful info:
http://code.google.com/p/ergoemacs/wiki/adoption
thanks for checking out ErgoEmacs!
Xah ∑ http://xahlee.org/
As it turns out, ErgoEmacs uses two files to define the keybinding. One is the main ergoemacs-mode.el file, and the other is the specific keyboard layout you select (e.g. ergoemacs-layout-us.el). The latter document creates a constant, which the former uses to create the keybinding. So while I thought I was duplicating the keybinding, I was actually changing the constant which was subsequently used for that purpose.
Solution:
In ergomacs-mode.el:
;; Move to beginning/ending of line
(define-key ergoemacs-keymap ergoemacs-move-beginning-of-line-key 'move-beginning-of-line)
(define-key ergoemacs-keymap ergoemacs-move-end-of-line-key 'move-end-of-line)
(define-key ergoemacs-keymap ergoemacs-move-beginning-of-line-key2 'move-beginning-of-line) ; new
(define-key ergoemacs-keymap ergoemacs-move-end-of-line-key2 'move-end-of-line) ; new
In ergoemacs-layout-us.el:
;; Move to beginning/ending of line
(defconst ergoemacs-move-beginning-of-line-key (kbd "M-h"))
(defconst ergoemacs-move-end-of-line-key (kbd "M-H"))
(defconst ergoemacs-move-beginning-of-line-key2 (kbd "C-a")) ; new
(defconst ergoemacs-move-end-of-line-key2 (kbd "C-e")) ; new
Huh? Is having one and only one way for every function some golden principle of ErgoEmacs? Because normal keybinding works exactly the opposite way: you name one key at a time and specify what it should do. If a mode defines a global variable to mean "the key that end-of-line is bound to", then of course there can be only one value, but with the normal binding commands you can bind the same function to as many combinations as you like. In fact, every keybinding I have ever seen used looked either like this
(global-set-key [(meta space)] 'just-one-space)
or like this
(add-hook 'c-mode-hook 'my-c-mode-hook)
(defun my-c-mode-hook ()
(define-key c-mode-map [(control c) b] 'c-insert-block))
if it's only for a specific mode.