After a few years customizing my .emacs file, I find I used two different
kinds of constructs to setup major-mode-specific key bindings:
1. using a hook and local-set-key. For example:
(defun my/bindkey-recompile ()
"Bind <F5> to `recompile'."
(local-set-key (kbd "<f5>") 'recompile))
(add-hook 'c-mode-common-hook 'my/bindkey-recompile)
I would say this construct makes it easy to use the same key bindings for
different major-modes by adding the same function to all relevant major-mode
hooks (in other words, the "which keybindings do I want" is clearly separated
from the "for which modes do I want them"). However, I'm not comfortable with
the fact that such customizations are done at the buffer level, whereas I would
think they belong to the major mode.
2. using define-key (often combined with eval-after-load to delay
evaluation until the relevant keymap is loaded). For example:
(eval-after-load "cc-mode"
'(progn
(define-key c-mode-map (kbd "C-c o") 'ff-find-other-file)
(define-key c++-mode-map (kbd "C-c o") 'ff-find-other-file)))
By contrast, this construct customizes the major-mode itself, but is less
flexible: if I want to use the same key bindings for another mode, I will have
to find the correct file and keymap names for this mode, and almost duplicate
the eval-after-load expression (although this could probably be automated with
a function/macro).
Question: although both construct types work well and produce the result I
want, they are technically very different, setting-up the key bindings in
different keymaps at different times. So my question is: among these two
constructs, is there a "preferred/better" way to do things? (Or maybe the "best"
construct is a third one which I'm not aware of?)
By "preferred/better", I mean such things as:
less prone to break with new emacs versions
less prone to disturb/be disturbed by active minor-modes
more idiomatic / readable / shareable with others
I believe the two approaches you describe are less different than you think.
Notice that local-set-key does in fact evaluate (define-key map key command) where map is the value of (current-local-map), which is typically set by the major mode.
So although they could be doing different things; most of the time the only real difference will be that the hook function with the local-set-key call will be setting that same key repeatedly/redundantly, whereas the other approach sets it only once.
You can demonstrate this to yourself by using local-set-key in a mode hook, removing that hook function after it has been used, and then creating a new buffer in that same major mode, and testing the binding.
less prone to break with new emacs versions
I guess you could argue that the name of a keymap might change in future and therefore not needing to know the name is an advantage, but you could equally say the name of the mode hook might change. I don't think either is enough of a concern to worry about.
One thing to note is that local-set-key will work even if the major mode did not establish a current-local-map, which I guess makes it slightly more robust as far as generalised approaches go.
less prone to disturb/be disturbed by active minor-modes
There's no difference. All minor mode keymaps take precedence over all major mode keymaps, and neither approach is going to have any effect on the order of minor-mode-map-alist (which determines the precedence of minor mode keymaps).
more idiomatic / readable / shareable with others
They're both entirely readable to my mind, so I can't distinguish them in this aspect either.
I say just use whichever approach seems best to you in each context. I do think it's good to have a standard approach for most things for the sake of consistency in your code, but I doubt it matters which one you choose. There's obviously a saving of a few CPU cycles to be had by not evaluating the same code unnecessarily, but that should matter so very little as to be of no concern whatsoever.
I think the most obvious case for one over the other is the one you already mentioned -- if you want to apply the same binding to multiple modes using a common hook (but not to all modes -- for that I thoroughly recommend creating a custom minor mode), then a local-set-key within that hook is definitely the way to go.
I have lots of custom keyboard commands and I couldn't bother with various ways to set them in Emacs and all these keymaps overriding each other, so I just installed John Wiegley's bind-key as per my relevant answer.
(require 'bind-key)
(bind-key "C-l" 'goto-line)
Related
I'd like to find all the modes which do assign a function to some specific shortcut.
For example if I'm not mistaken a stock Emacs simply assigns (or defaults to) newline for S-return but while in org-mode S-return does invoke org-table-copy-down.
Is there an easy way to figure out which modes (both major and minor) do map a function to a specific shortcut? I can find all the shortcuts of one major mode using describe-mode but I'd like to find those for all the various modes. I don't mind if it were to only work for all the currently loaded modes.
Basically I'd like to find "free" or "relatively rarely re-mapped" key shortcuts, which are also easy to type (i.e. I'm not after doing "C-c a" because for a start C-c is a very convoluted key to reach and then having to then hit another key is one key too many for me. I'm more after re-mapping C-o, S-return, M-/ and other combo trivial and fast to reach).
You can find the current-mode bindings using C-h b.
You can get all of the keymaps currently available, using accessible-keymaps. You can find all the features loaded via variable features. But you would have to work to find all possible bindings for all possible modes from all files that you have loaded so far.
I recommend that you do it for a particular mode, one mode at a time. It's easy to check a given mode's key bindings.
You can even check the bindings of keymaps (such as minibuffer maps or the Isearch map) that are hard to see otherwise, if you use command C-h M-k (describe-keymap) from library `help-fns+.el. I use that when I want to see what keys are still available in a given keymap etc.
You can use
M-x describe-unbound-keys
to find out the free keys.
This is from third party library as said in comments.
I don't know the answer to your specific question, but I can give you my solution to getting easy-to-type keybindings that don't conflict with other modes.
In my set up, I've remappped CAPS-LOCK to Alt. Most people map it to CTRL, but I can hit CTRL relatively easily, while ALT is difficult. With this set-up, one of the easiest key combos to hit is M-space. So I use this as my own private keymap:
(define-prefix-command 'ty-keymap)
(global-set-key "\M- " ty-keymap)
(define-key ty-keymap " " 'just-one-space)
(define-key ty-keymap "j" 'join-next-line)
(define-key ty-keymap "s" 'mark-sexp)
(define-key ty-keymap "c" 'org-capture)
...
Note: by default, M-space is bound to just-one-space, which is useful. I've moved that to M-space-space. Bouncing my thumb twice on the spacebar is only a fraction slower than hitting it once, so it's not a big loss.
Since M-space isn't a keymap by default, this setup allows me to use all the keys on the keyboard, without further modification. That's a lot of real-estate, guaranteed to be free of any conflict with other packages - since well-behaved packages won't clobber a basic Emacs keybinding.
You might prefer another key combo, but the idea is the same. You could even use a function key as your prefix-command, so you could do <f5> followed by a letter for your commands.
I have done some searching around and can not quite find what I am looking for so I figured I would ask. This could be due to not using the right terms however.
I am new to emacs, having used vim for eight years or so, but I really need an editor I can morph to my will so I am switching. Now in vim there is a leader key you can define to avoid overlapping bindings with various extensions. In emacs there are supposed to be chords set aside for the user only but various modes do not adhere to this. Is there a way in emacs I can ensure my custom bindings do not overlap similar to the vim leader key? The reason I ask is I want to keep my bindings sane.
The manual details the conventions:
C-hig (elisp) Key Binding Conventions RET
Sequences reserved for the end-user are:
C-c<letter> for any (un-modified) upper or lower case letter: [A-Za-z]
Function keys F5, F6, F7, F8, F9 (again, without modifier keys)
I recommend using the easiest of these sequences as prefix bindings, as you can then follow them with any key at all, giving you a large number of options.
Someone else's recommendation that I liked was to unbind C-z if you don't commonly use suspend-frame, as that opens up another convenient prefix.
Of course, if you set up Super and Hyper modifier keys for your OS & keyboard, you would likely gain more convenient sequences than you could find uses for. This is a very reasonable option for many people with the additional modifier keys found on many modern keyboards.
Finally, the key-chord library is quite a popular way of creating new convenient and non-conflicting bindings by using pairs of (un-modified) keys typed together or in quick succession (or a single key tapped twice). This works very well in my experience, although you obviously have to be very careful to avoid binding sequences which might occur naturally.
I personally use C-' as my 'leader key' for my personal keybinding map. You can create the prefix and bind keys to it like so:
(global-set-key (kbd "C-'") ctl-quote-map)
(define-key ctl-quote-map (kbd "C-p") 'stumpwm-move-window-up)
(define-key ctl-quote-map (kbd "C-n") 'stumpwm-move-window-down)
(define-key ctl-quote-map (kbd "C-f") 'stumpwm-move-window-right)
(define-key ctl-quote-map (kbd "C-b") 'stumpwm-move-window-left)
(define-key ctl-quote-map (kbd "r") 'stumpwm-interactive-resize-window)
Nobbody steps over something that obscure, and if you use the left control it's a balanced double pinky motion. C-; is also good, which is what I use for the stumpwm escape key.
There are Emacs keybinding conventions, some of which honestly surprised me.
The relevant pieces are that C-c [a-zA-Z] and <F[5-9]> are reserved for end users.
Good answers so far:
I'd throw in free-keys as a good way to check your binding is free before creating it - to avoid overlapping with yourself. helm-descbinds is good for finding your existing bindings to help you remember them as well incidentally.
I want to enable rainbow-mode everytime I start emacs, rather than having to use M-x rainbow-mode.
I guess there is some command I put in my .emacs file.
I tried all of the following, but none of them worked:
(require 'rainbow-mode)
(rainbow-mode initialize)
(global-rainbow-mode)
More generally, how do I load any mode/package automatically on startup?
rainbow-mode isn't a global minor mode, so it needs to be enabled on a per-buffer basis.
I only use it for CSS, so I have:
(add-hook 'css-mode-hook 'my-css-mode-hook)
(defun my-css-mode-hook ()
(rainbow-mode 1))
If you genuinely want it to be global, everywhere, you can easily define a global minor mode yourself:
(define-globalized-minor-mode my-global-rainbow-mode rainbow-mode
(lambda () (rainbow-mode 1)))
(my-global-rainbow-mode 1)
You can add any arbitrary logic to that (lambda () (rainbow-mode 1)) function (which will be evaluated in every buffer) in order to decide whether or not to actually call (rainbow-mode 1) for a given buffer, so if you're comfortable with elisp then you can easily extend this approach to cover your specific requirements for the mode in question.
More generally, how do I load any mode/package automatically on startup?
It can vary, but the approaches I've shown would suffice for most minor modes: Either you want them enabled whenever MODE is enabled (being some specific other mode name), in which case you can use the MODE-hook variable (which will always be available) as per the css-mode-hook example; or else you want the mode enabled permanently, in which case a global minor mode is a good approach (because you can toggle it on and off globally). Some minor modes are global by default (or provide global variants), but you can create your own if necessary, as per the my-global-rainbow-mode example.
Also be aware that modes can be derived from other modes, in which case all relevant MODE-hook hooks will be run (for details see https://stackoverflow.com/a/19295380/324105). A common use-case is to use prog-mode-hook to enable functionality wanted for all the programming modes which are derived from it (which is most programming modes).
Remember that many (hopefully most) libraries and packages will provide usage instructions. If you can't find documentation, be sure to try M-x find-library to visit the library file, and then read through the comments at the top. There is often a very informative "Commentary" section, and sometimes this is the primary source of end-user documentation, and explain how to enable its functionality.
I'm familiar with scheme, but new to emacs (switching over from VIM) and elisp.
I know how to do the following:
make a simple key binding
C-c iwb = indent whole buffer
F2 = turns folding on/off
use slime from emacs
some basic keys, like C-x 2, paredit keys, some basic movement keys
I need help doing something a bit more advanced:
I want F3 to equal:
put emacs into C-x 2 mode
in bottom window, switch to "slime-repl" buffer
in the "slime-repl" buffer, send the command "(test/run)" <-- note, this is meant to be sent to the swank server, NOT to elisp
I realize it's terrible form to ask people to write a script for me; however, if anyone could do that, I would learn rather quickly from it. [And it would allow me to do more complicated types of scripting through studying your example.]
Thanks!
This is not exactly what you want, but should be a good starting point for further tweaking:
(defun slime-run-test ()
(interactive)
(slime-interactive-eval "(test/run)")
(slime-pop-to-buffer (slime-output-buffer) t))
(global-set-key (kbd "<f3>") 'slime-run-test)
I don't use slime, but assuming it uses comint-mode then I would think the following might do the trick:
(defun my-slime-test-run ()
(interactive)
(delete-other-windows)
(split-window-below)
(with-selected-window (next-window)
(switch-to-buffer "slime-repl")
(goto-char (point-max))
(insert "(test-run)")
(comint-send-input)))
(global-set-key (kbd "<f3>") 'my-slime-test-run)
There is probably a better way to do this, but hopefully that gives you a little insight into how you can write elisp functions to carry out tasks in the editor (and note how the function reads very much like a set of editor instructions -- you can do a lot simply by converting the keystrokes you would use into equivalent code -- or even not writing code at all, and simply recording & saving keyboard macros).
Use C-hf name-of-the-function RET to get documentation on any of the function/macro calls in that function.
For the keybinding, I used C-hkF3 to check how Emacs referred to that key, and then used that string as the argument to kbd (and note how you can use that sequence to find the name of the function bound to any given key sequence, which you can then utilise in code if desired).
Many things are far less obvious if you don't already know them, but that's only to be expected with a code base as large as this (and dating back as long as this).
The great thing is that if you don't know what you're looking for, you can always search for function names matching patterns with C-uC-ha (and similarly for variables, values, libraries, and documentation; see M-: (info "(emacs) Apropos") RET for more about this facility). Plus the info manuals (complete with indexes -- press I or i within any particular manual, or use the info-apropos command to search all info manuals at once).
Truly one of the very best things you can do is to learn how to use the self-documenting nature of Emacs to find answers to the things you don't already know.
Is there a command to globally override a keybinding such that it overrides even the local settings of major modes? global-set-key is overridden by major mode bindings, as stated here: http://www.gnu.org/software/emacs/manual/html_node/emacs/Rebinding.html
No, there is no (built-in) way to set up a key binding that overrides all others. Look at how Emacs searches the keymap by reading "Searching the Active Keymaps".
You could set overriding-terminal-local-map or overriding-local-map to a keymap containing the binding you want, but that'd prevent your buffer from having any buffer/overlay/minor-mode keymaps, pretty much disabling the majority of Emacs.
The next area Emacs looks for a binding is in the character property at the current point - which probably isn't used all over the place, but it's one way your binding would be overridden (unless you muck with character properties to define your key everywhere, really icky).
The next place Emacs looks is in the variable emulation-mode-map-alists, which is probably your best bet. It was set up for packages to use in cases where there are multiple minor-mode keymaps it wants to juggle.
Make a global minor mode (see Defining Minor Modes), put your key binding in there, add your minor mode and keymap into the emulation-mode-map-alists, and turn on your minor mode.
Your key binding will now have precedence over all others, except those earlier in the emulation-mode-map-alist list, or found in character properties, or in the overriding-local-map...
I believe that's the best you can do, w/out hacking Emacs source.
In the case of minor mode keybindings overriding my personal global bindings i have had luck using add-hook + local-unset-key
(add-hook 'undo-tree-mode
(lambda ()
(local-unset-key "C-/")))