Globally overriding emacs keybindings - emacs

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-/")))

Related

Emacs: How to bind key only in regular buffers and not in the minibuffer?

I have written a fancy function, which I would like to bind to TAB. The functionality is only meaningful in any non-read-only text buffer. Currently, I bind it either like that:
(global-set-key (kbd "<tab>") 'my-indent-region)
or
(define-key global-map (kbd "<tab>") 'my-indent-region)
The problem with this binding is that now tab-completion does no longer work in the minibuffer, which is an essential feature (e.g. for buffer/file names, or M-x).
Is it possible to bind TAB only for regular modes? I know that I can use define-key some-major-mode-map, but since I want it in all modes except for the minibuffer, this would be annoying to maintain. Thus, I'm probably looking for something like a define-key any-mode-except-minibuffer ....
If such a functionality does not exist: Is there a workaround to get the tab-completion working in the minibuffer again? Maybe I can re-set the original minibuffer tab binding after changing the global binding? I couldn't figure out though which function I actually have to bind to make it work.
After some more research I found a workaround/solution to the problem in this answer.
Apparently, my problem was that I was binding to (kbd "<tab>"). If I understand it correctly, my problem was in fact not that I overwrote the actual keymap of the minibuffer -- I guess they are correctly loaded when entering the minibuffer minor modes. However, there seems to be a precedence of a binding to (kbd "<tab>") over a binding to just "\t". According to the above answer, the minibuffer bindings just use "\t", so binding to (kbd "<tab>") shadows them. I'm now using the following binding instead:
(global-set-key "\t" 'my-indent-region)
Now everything seems to be working fine.
Do you see this behavior when you start Emacs without your init file (emacs -Q)? I doubt it. If not, then recursively bisect your init file to find out what is causing the problem.
The minibuffer uses its own keymaps, which are local and which therefore take precedence over global keymap bindings.
However, any minor-mode keymaps take precedence over local keymaps. So if, for example, you have a (global) minor mode turned on that binds <tab> then that will override any binding for that key in the minibuffer keymaps.
Another thing you can do is simply bind whatever command you want to <tab> in the minibuffer keymaps. But again, you should not need to do that, if you want the usual <tab> behavior for the minibuffer.
[Another possible confusion: Some things, such as Isearch, which you might think use the minibuffer do not use it. Isearch uses its own keymap, isearch-mode-map.]
UPDATE after your comment:
Assigning a key in the global map, as you have done, should not affect what that key does in the minibuffer, provided it has a different binding in the minibuffer keymaps. TAB is typically bound in all of the minibuffer completion keymaps (but not in the non-completion minibuffer keymaps).
See the Elisp manual, nodes Completion Commands and Text from Minibuffer for information about the minibuffer keymaps.
To see what the current bindings are for a keymap that is associated with a variable (such as minibuffer-local-completion-map), load library help-fns+.el and use C-h M-k followed by the keymap variable's name. (See Help+ for more information about the library.)
If you do not want TAB to use your global command binding in the non-completion minibuffer maps (minibuffer-local-map, minibuffer-local-ns-map), then just bind it in those maps to whatever command you like. But for the completion maps you should not need to do anything - TAB should already be bound there.
Did you try emacs -Q, to see if something in your init file is interfering? If not, do that first.

How to know emacs true mode names?

Sometimes I copy configuration options from the Internet to my .emacs. Sometimes they don't work.
(add-hook 'laTeX-mode-hook 'turn-on-flyspell)
doesn't work:
(add-hook 'LaTeX-mode-hook 'turn-on-flyspell)
(notice the uppercase in Latex). But,
(add-hook 'flyspell-mode-hook 'flyspell-buffer)
is correct. Although Emacs shows "Fly" in the lower bar and also M-: major-mode shows latex-mode and not Latex-mode.
How do I know how to write emacs modes name?
It sounds like you're actually more interested in the names of modes' hook variables than in the modes themselves.
You have several options. I will suggest some, based around discovering flyspell-mode-hook:
M-x apropos-variable RET flyspell RET, then search the results buffer for hook
C-h v flyspell-, then tab-complete
Any time you are in the minibuffer tab-completion is a good thing to try
M-x find-function flyspell-mode RET will open up the source code for flyspell, you can then search for hook
If you have configured your Emacs to provide completion for Emacs Lisp, you can simply type
(add-hook 'flyspell-
into your .emacs buffer and let Emacs suggest valid completion
Tools like Helm and ido can simplify the process of finding things
Using the find-function technique with latex-mode (which I tab-completed), I discovered that my version of Emacs calls its LaTeX mode function latex-mode. Searching for LaTeX- showed me that LaTeX-mode is an alias for latex-mode.
Your use of M-: major-mode is good, and gives you the correct major mode name (i.e. the symbol name for the mode function).
I don't believe there's a standard function to list the symbol names for the current buffer's enabled minor modes, but you can see all (loaded) minor mode symbols with C-hv minor-mode-list, so it's not hard to verify a name if you find you need to.
The symbol name for a mode's hook is literally the mode's symbol name with the suffix -hook.
Minor modes also have (in addition) an -on-hook and -off-hook.
The hook variables don't necessarily exist when not in use, but this naming is hard-coded in the standard macros for defining modes (and running their hooks at the appropriate times); and the modes which don't use those macros invariably follow the same conventions, to ensure consistency.

How can I set buffer-local value for a variable defined by defcustom?

In emacs, we can define customizable user option variable.
defcustom - Programming in Emacs Lisp http://www.gnu.org/software/emacs/manual/html_node/eintr/defcustom.html
And we can make variable to have buffer-local binding.
Creating Buffer-Local - GNU Emacs Lisp Reference Manual http://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Buffer_002dLocal.html#Creating-Buffer_002dLocal
If I want to make non-customizable variable, I can use make-local-variable or setq-local.
But I can't find any ways how to make customizable variable to have buffer-local binding.
Even if I call make-local-variable for variable defined by defcustom, custom-set-variables set to global-value.
If I call setq-local, value is set to local-variable. It is better. But I don't think this is best practice.
Is there any valid ways how to set buffer-local value for a variable defined by defcustom?
The answer is: You can't, at least not using the Customize UI.
What you can do is add a sexp that sets the buffer-local value of the variable to your init file.
Do one of the following:
Make it always buffer-local, no matter what the buffer is:
(make-variable-buffer-local 'the-variable)
You can put this anywher in your init file.
Make it buffer-local only for the current buffer, i.e., for some buffer after you select it:
(make-local-variable 'the-variable)
For that, you need to put the sexp in a sexp that selects the buffer you want. That could be, for example:
(with-current-buffer (get-buffer-create "the-buffer-name")
(make-local-variable 'the-variable))
That assumes that the buffer can be reasonably created or already exists. If you do this, do it after your custom-file has been loaded. That is, in your init file, either after loading custom-file (which I recommend) or, if you do not use custom-file, after any code generated automatically by Customize (e.g., custom-set-variables).
You can alternatively put the make-local-variable sexp on a mode hook, so whenever you are in a buffer that has a particular mode, it is executed.
All of that said, I submitted an enhancement request to Emacs Dev in 2012, requesting that user's be able to use the Customize UI to set (and possibly save) buffer-local values of user options. It sleeps in category "wishlist", so far.
After defcustom form write
(make-variable-buffer-local 'my-var)
Now, if you change the value in some buffer, other buffers will keep resp. deliver the old customized one.
The problem is that Customize is mostly designed for persistent configuration, i.e. configuration that is saved in the config file so it also applies to future Emacs sessions. But buffers are not persistent: when you restart Emacs you get a new buffer object.
So persistent customization "per-buffer" is not a clearly defined concept. We could/should add Customize support for settings that are specific to some major modes (i.e. "per-mode" settings), on the other hand.

emacs mode-specific custom key bindings: local-set-key vs define-key

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)

Assign a keymap to a derived mode in emacs

How can I assign a keymap to a derived mode in emacs (I am using the define-derived-mode function). There is a derived-mode-set-keymap function but without examples or good documentation.
define-derived-mode itself creates a keymap with the name MODE-map, where MODE is the name of the keymap you've just defined. I'm not sure what derive-mode-set-keymap does that is not already done with define-derived-mode; looking at the source, they do similar things, and I'm unsure of the very low-level differences between the two (e.g. define-derived-mode leaves the parent-mode's keymap as the parent of the new keymap while `derive-mode-set-keymap also merges the keymaps; what's the functional difference between the two?).
If you do the following:
(define-derived-mode foobar-mode text-mode "foo")
Then the following variables will be defined:
foobar-mode-abbrev-table
foobar-mode-hook
foobar-mode-map
foobar-mode-syntax-table
You can then start manipulating any of these as you like.