Assign a keymap to a derived mode in emacs - 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.

Related

describe binding filtering in emacs

Is there a way to filter the list of available bindings (C-h b), so it will not show all the possible bindings but just the relevant ones for the used mode?
For example on org-mode, I get all the general C-x list plus all the bindings of the modes that have general key bindings plus all the major mode bindings, followed by all the org mode ones, followed by global bindings... 1369 lines in total... I'm using this view for learning my way around, perhaps there is a way to filter so as to find my way around.
I think you are looking for C-h m which runs the command describe-mode.
You will find more goodies in C-h C-h which runs the command help-for-help.
C-h m shows the doc for the current major mode, as well as currently enabled minor modes.
Often C-h m lists some of the more important local key bindings, that is, some of the bindings made for the current major mode. But not always, and typically it does not list all of the local bindings.
If you use library help-fns+.el then you can use command describe-keymap to list all of the local key bindings:
M-: (describe-keymap (current-local-map))
If you know the name of the local keymap variable (e.g. emacs-lisp-mode) then you can invoke describe-keymap interactively using C-h M-k, providing the map name at the prompt.
If you use Icicles then you can see all of the currently available key bindings using S-TAB (key completion). By default, the local bindings (i.e, those for the current major mode) are shown first, and are highlighted specially. (You can use C-, to sort the candidate bindings in other ways (by key name, prefix keys first; by command name).
After C-h b switch into Help-buffer and call M-xoccurRETorgRET which will display all lines containing "org".

org mode - how to disable some keybindings?

I started using Emacs (currently for org mode only). I don't use priorities in my TODOs, hence I'd like to disable S-UP and S-DOWN key bindings (which loop through the priorities). How can I do this?
#lawlist gave you the recipe in his comment. Here's how to find this out for yourself.
See if there is a keymap variable for the mode in question - typically there is one. In this case, try C-h v org-mode-map. If you find no such variable, fish around a little, using the apropos commands - for example, M-x apropos-variable org-mode.
Bind the key(s) in question to nil in that keymap:
(define-key org-mode-map (kbd "S-<up>") nil)
C-h m gives you info about the current mode. Sometimes it lists the important key bindings for the mode. And C-h b (anywhere) lists lots of key bindings for the current context.
If you want to see all of the key bindings that belong to a given keymap variable (in human-readable form), then load library help-fns+.el and then use C-h M-k followed by the keymap variable name (e.g. org-mode-map). See Help+.

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.

Emacs .dir-locals.el - setting key bindings

I'm not sure this is possible, but I'd like to setup some project specific key bindings by using .dir-locals.el
Of course .dir-locals.el has to contain a special list of settings, so I can't do:
(global-set-key [24 down] 'move-text-down)
Is there any way I can inject a lambda to run arbitrary code or some other way to set key bindings in .dir-locals.el?
The eval pseudo-variable enables you to specify arbitrary elisp for evaluation with your local variables.
e.g. https://stackoverflow.com/a/7340962/324105
See EmacsWiki for more details.
Note that this is not a particularly useful mechanism for setting key bindings, as every buffer using the keymap in question will be affected. You would probably be better off using the dir-local config to enable a minor mode with the specific keymap for that project. Alternatively, you might adapt this approach to file-local bindings (but a minor mode would be nicer).
That being said...
A fairly minimal form is ((nil . ((eval . (progn BODY))))) with BODY being the expressions to be evaluated. Of course if BODY is only a single expression, you do not need progn.
The following therefore displays a message when you visit any file (under the directory in question):
((nil . ((eval . (message "hello")))))
The car of each list in the dir-locals form is generally a major mode symbol, or nil (as in the above example) in which case the settings apply in any major mode.
The car can also specify a sub-directory string, in which case the cdr is another dir-locals form with settings applicable to that sub-dir.

Globally overriding emacs keybindings

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