god-mode
god-mode copied to clipboard
Rebind more commands than just self-insert-command
Some modes bind some keys to functions other than self-insert-command. This is so that they can do something clever as well as insert the character. eg. in c-mode "/" is bound to c-electric-slash. This means that when in god-mode, pressing these keys will still insert the character instead of doing C-key.
I have these workarounds in my init.el:
(define-key god-local-mode-map [remap c-electric-slash] 'god-mode-self-insert)
(define-key god-local-mode-map [remap c-electric-brace] 'god-mode-self-insert)
; etc
This appears to have been encountered by people before (tickets #16 and #41). I'd imagine that "/" doing c-electric-slash instead of undo is a common problem. Perhaps it would be sensible to have a customisable list of commands god-mode should remap, and maintain a default list (which people are encouraged to submit pull requests to modify, like for god-exempt-major-modes).
Or perhaps not, in which case feel free to close and I'll just stick with remapping some commands myself.
Even if you decide against god mode remapping more commands, a note in the readme showing how to do this would be really helpful. It took me a wee while to work out, so I'm sure it'd help others too!
(Thanks for making god mode by the way, only been using it a few days but I'm really liking it so far!)
I've had to remap some things too, like / in html-mode. Adding these suggestions in the README sounds like a good idea.
Ideally god-mode could work in a different way to solve this problem more generally, but I have no idea how to implement that -- I love the idea behind god-mode but it sometimes acts a bit weirdly and sometimes you still need to use ctrl. (For C-g if nothing else, but also sometimes for other things like C-/ in C-mode if you haven't remapped it specifically.)
Based on this Stackoverflow answer I added this to my god-mode-enabled-hook and it appears to solve this issue. Basically it just makes sure that the god-mode local map is always first in the list of minor mode key maps.
(defun god-has-priority ()
"Try to ensure that god mode keybindings retain priority over other minor modes."
(unless (and (consp (car minor-mode-map-alist))
(eq (caar minor-mode-map-alist) 'god-local-mode-map))
(let ((godkeys (assq 'god-local-mode minor-mode-map-alist)))
(assq-delete-all 'god-local-mode minor-mode-map-alist)
(add-to-list 'minor-mode-map-alist godkeys))))
In the Emacs Lisp manual I read that minor-mode-map-alist comes after emulation-mode-map-alists. What if God mode would add god-local-mode-map to
emulation-mode-map-alists instead of minor-mode-map-alist when initializing? Isn't God mode more an emulation mode than an ordinary minor mode anyway?
First, it could solve what the previously suggested adding of god-has-priority to god-mode-enabled-hook solves.
Second, it could help to get God mode in command state of Viper mode (vi emulation).
Currently the second is not possible because the keymaps of Viper mode are in emulation-mode-map-alists and therefore god-mode-self-insert even with
god-has-priority is too late. As a workaround I tried
(add-to-ordered-list 'emulation-mode-map-alists 'god-local-mode-map 50)
and it added god-local-mode-map in front of viper--intercept-key-maps and viper--key-maps as expected but for example b is still bound to
viper-backward-word instead of god-mode-self-insert when god-local-mode is on. How can I make this work?
The following solution has worked for me in evil-mode/evil-god-state, but should be adaptable generally:
- Move
god-local-mode-mapentry to the front ofemulation-mode-map-alists, as in @brandm's answer. (In my Evil setup, I instead achieve this by settinggod-local-mode-mapas an "intercept map," using the Evil-specific sense of that term. Evil's emulation map alist already comes first within myemulation-mode-map-alistsso this effectively givesgod-local-mode-mappriority over all other keymaps.) - Create a separate keymap containing the extra keybindings you want available in God mode. I use
(make-composed-keymap (current-active-maps))to suck up all active keybindings just before entering God mode. - Use
set-keymap-parentto set this keymap as the parent keymap ofgod-local-mode-map. This way, all its bindings get priority just below God mode's special self-insertion bindings, but still override anything below.