C-d and C-S-d key bindings in emacs - 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)

Related

How can I change the behavior of a key in 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.

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.

Can't map Ctrl + minus in Emacs in Mac OS X

I'm trying to map Ctrl + minus ("C--") to undo in Emacs 24.3 (from http://emacsformacosx.com) in Mac OS X 10.8.4, but I can't get it to work. There seems to be some very global key binding for decreasing the font size, which I can't seem to override. Can anyone tell me what I'm doing wrong?
I have the following in my .emacs.
(global-set-key (kbd "C--") 'undo) ;; Doesn't work
(global-set-key (kbd "C-u") 'undo) ;; Just for testing, does work
When I press Ctrl+U, it triggers undo, but when I press Ctrl+minus, it decreases the font size. It might be simply that I should use something other than "C--", but it looks like it should work. I checked the key bindings (via C-h b) and there, C-u is bound to undo, but C-- is bound to text-scale-decrease. It would probably be possible to find where that key is bound and get some clue, but my Emacs-fu is too weak.
I'm using the graphical version of Emacs, not the terminal version.
With these type of problems I usually
try f1 k and right after the key combination that I'm having a problem with,
C-- in your case.
One of two things should happen:
Nothing happens - this means that the shortcut is being intercepted
at the level of the operating system.
It gives you a description of a function that's being called.
It's probable that it was set by either your major mode or one of the minor modes.
So you should investigate that as well, searching though the references
to this function, which is text-scale-decrease in you case.
After you find either global-set-key, or local-set-key or define-key
with this function, either comment it out, or better just
call the same function with same shortcut and nil in your ~/.emacs.
UPD: how to unset a key
When you find that some source that you're loading e.g. starter-kit is setting the key,
you just need to unset it later in the same way:
If it was set with (global-set-key (kbd "C--") 'text-scale-decrease),
you unset it with (global-set-key (kbd "C--") nil).
If it was set with (define-key markdown-mode-map (kbd "C--") 'text-scale-descrease),
you unset it with (define-key markdown-mode-map (kbd "C--") nil).
If it was set with
(add-hook 'markdown-mode-hook
(lambda()(local-set-key (kbd "C--") 'text-scale-descrease))
you unset with
(add-hook 'markdown-mode-hook
(lambda()(local-set-key (kbd "C--") nil))

Define key-bindings in emacs

I'd like to map a command in emacs to a key-binding. I want the command Control-l to have the same effect as the command Alt-x goto-line followed by a return (since that command first needs a return to be invoked and then a line number).
I modified the init file as follows:
(define-key (M-x goto-line) '\C-l)
but that didn't work. The error was that define-key was being given more than 1 arguments.
Does anyone know how to reset key-bindings in emacs?
Thanks!
M-g g is the default shortcut for goto-line. You might want to try that.
To redefine C-l use:
(global-set-key (kbd "C-l") 'goto-line)
Easiest way to customize lots of keybindings is to install John Wiegley's bind-key module, which is a part of use-package Lisp package. Solution in your init.el:
(require 'bind-key)
(bind-key "C-l" 'goto-line)
Minor modes keys usually override global keys, so if you don't want such behavior, use function bind-key* instead. The package is on MELPA, if you don't know what is it, quickly learn about Emacs package management (should take you 2 minutes to set up MELPA as your repository).
The main problem with keybindings in Emacs is that minor modes keys often override your custom ones. In vanilla Emacs people workaround by creating a minor mode for your own keybindings. If you really wanna understand how Emacs keys work, read Key Bindings # Emacs Manual and Keymaps # Elisp Manual carefully.
I have set as (global-set-key (kbd "C-x g") 'goto-line). You can use that or (global-set-key (kbd "C-l") 'goto-line). I would personally do not touch the C-l key from its default behavior.
If you must use M-x define-key, use
(define-key global-map (kbd "C-l") 'goto-line). The 1st argument to define-key is a KEYMAP.

Rebind C-space in Emacs

I've tried various version to no avail:
(global-set-key (kbd "C-<space>") 'tempo-complete-tag)
(global-set-key [C-space] 'tempo-complete-tag)
I'm using CUA mode and running Emacs on Ubuntu, version: GNU Emacs 23.1.50.1 (x86_64-pc-linux-gnu, GTK+ Version 2.18.0)
of 2009-09-27 on crested, modified by Debian
When I run tempo-complete-tag manually it tells me it is bound to C-space but C-space still runs cua-set-mark (or if CUA is disable, set-mark-command).
How can I rebind the C-space shortcut in Emacs to a command I decide?
C-h k (key) will tell you how Emacs refers to a given key (which is "C-SPC" in this instance). (global-set-key (kbd "C-SPC") 'tempo-complete-tag) will do what you want.
I always use the (kbd) function for key-bindings, as it allows you to refer to the key the same way it is typically written everywhere else.
Do keep in mind that C-SPC is a standard set-mark-command binding! Personally I'd pick something different :)
Also keep in mind that "global-set-key" will only do what you want, if your mode doesn't override it. I'm too lazy to load tempo to see if it does indeed override C-SPC, but it might well do so, in which case, you want to put this in your .emacs:
(add-hook 'tempo-mode-hook
(lambda ()
(local-set-key (kbd "C-SPC") 'tempo-complete-tag)
))
Alternative syntax for key binding is via vector:
(global-set-key [?\M-\ ] 'cycle-spacing)
(global-set-key [?\C-\ ] 'tempo-complete-tag)