💾 Archived View for idiomdrottning.org › on-top-of-emacs-god-mode captured on 2023-09-28 at 17:00:05. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
I’ve been using god-mode for a few years. It’s an Emacs mode that’s sort of like if Control was held down all the time. The key sequence C-c C-s C-p becomes just csp and C-x n n becomes x nn. I’ve built some cruft of my own on top of it.
Let’s start with the unusualest stuff first:
(define-key god-local-mode-map (kbd "o") 'insert-one-character) (defun insert-one-character (times) (interactive "p") (overwrite-mode 1) (dotimes (x times) (quoted-insert 1)) (overwrite-mode 0))
C-q already existed, so if you want to insert one character you could already use q. The difference between q and o is how they deal with prefix arguments, where q will insert more of the same while o will listen that amount of times. If you want to insert three hyphens, 3q-. If you want to insert the word “and”, 3oand. Or 5o and if you want spaces.
This version deletes as many characters (to the right) as it inserts:
(define-key god-local-mode-map (kbd ">") 'overwrite-insert) (defun overwrite-insert (times) (interactive "p") (delete-char times) (insert-one-character times))
Often enough I just wanna insert a space. This one does work like q, in that the prefix sets the number of spaces you get.
(define-key god-local-mode-map (kbd "O") 'spacer) (defun spacer (times) (interactive "p") (dotimes (x times) (insert " ")))
Then, for my-dumb-del, it’s just a way to make h work as a backspace in god-mode. I use F1 as a help key.
(define-key god-local-mode-map (kbd "h") 'my-dumb-del) (defun my-dumb-del () (interactive) (setq unread-command-events (listify-key-sequence "\C-\?")))
Incarnate switches out of god-mode except that RET returns to god-mode (and then to insert a newline after, hit RET again. Use C-j to insert newlines without leaving the incarnation.)
Great when I just wanna insert just a handful of words, so I don’t need to toggle out of god-mode completely, but it’s more than I wanna bother to count so the prefix and o solution isn’t the best. I just hit i, type some words, then RET.
On a physical keyboard, just toggling in and out of god-mode is easy enough, but on the tablet’s touch screen, there aren’t that many freely accessible remappable keys, so this is a great way to work.
My god-mode cursor is a red box, my normal cursor is a black box, and my incarnate cursor is a black bar.
(define-key god-local-mode-map (kbd "i") 'incarnate) (defun unincarnate () (interactive) (incarnate-mode -1) (setq cursor-type 'box) (god-local-mode 1) (set-cursor-color "#b0381e")) (defun incarnate () (interactive) (when (bound-and-true-p god-local-mode) (god-local-mode 0) (unless (display-graphic-p) (set-cursor-color "black") (setq cursor-type 'bar) (incarnate-mode)))) (define-minor-mode incarnate-mode "As normal but toggle to God mode on RET" :lighter " God-Inc" :keymap '(("\r" . unincarnate)))
In addition to i, I also have many of my paredit commands also incarnate, and many that work regardless of whether I’m in god-mode or not, giving me sort of a very DWIMmy experience that works well for me on tablet.
This is still pretty experimental, but it’s an alternative to incarnation where instead it turns off god-mode and turns it back on when the typing has been idle for a number of seconds (it can handle decinal seconds just fine). In the sample code here, it’s set to two seconds.
(defun type-something-quickly () (interactive) (run-with-idle-timer 2 nil #'(lambda () (god-local-mode 1))) (god-local-mode -1))
Here’s a way to dispatch between those two methods based on whether you’re on graphic display or not (as a proxy for finding out whether you are on SSH).
(defun type-quickly-or-incarnate () (interactive) (if (display-graphic-p) (type-something-quickly) (incarnate)))
Isearch with god-mode can be a bit sticky and I wanted a few extra ways to exit or abort (exit affirms the jump and takes you to what you found, while abort cancels the search).
(require 'god-mode-isearch) (define-key isearch-mode-map (kbd "<escape>") 'god-mode-isearch-activate) (define-key isearch-mode-map (kbd "=") 'isearch-exit) (define-key isearch-mode-map (kbd "<f3>") 'isearch-abort) (define-key god-mode-isearch-map (kbd "<escape>") 'god-mode-isearch-disable) (define-key god-mode-isearch-map (kbd "m") 'isearch-exit) (define-key god-mode-isearch-map (kbd "g") 'isearch-abort) (define-key god-mode-isearch-map (kbd "h") 'isearch-delete-char)
I also have “leaping” (r and s in god-mode) as something different from full on isearch (C-r and C-s, that is to say, deliberately using control even though it’s god-mode).
This has been so awesome in practice and I use it all the time. Just being able to leap back to a recent character or handful of characters is great while if I’m doing a more tricky, remote, deliberate search I’ll hit control first. I haven’t been getting them confused since “leaping” feels more like a relation to stuff like forward-sentence, backward-sexp etc, a way to navigate locally, it doesn’t “feel like searching”, I dunno.
(global-set-key (kbd "C-r") 'isearch-backward) (global-set-key (kbd "C-s") 'isearch-forward) (define-key god-local-mode-map (kbd "r") 'leap-back) (define-key god-local-mode-map (kbd "s") 'leap-forward) (defun leap-skele (proc) (run-with-idle-timer .5 nil (lambda () (when (= 0 (length isearch-string)) (message "")) (isearch-done))) (funcall proc)) (defun leap-back () (interactive) (leap-skele 'isearch-backward)) (defun leap-forward () (interactive) (leap-skele 'isearch-forward))
I’m only recently starting to experiment with more stuff that’s totally different with god-mode on or off. Having / for replace-regex has quickly become something I’ve gotten spoiled by.
(define-key god-local-mode-map (kbd "/") 'replace-regexp)
OK, that was it for the new and interesting things. Time for the settings I use.
Escape doesn’t work very well over SSH so I have a bunch of touch-screen–specific methods, along with F3 as a more reliable alternative.
(global-set-key (kbd "•") 'god-mode) (global-set-key (kbd "ğ") 'god-mode) (global-set-key (kbd "ȩ") 'god-mode) (global-set-key (kbd "<f3>") 'god-mode)
Since I use C-z so heavily (I have it set to toggle a shell buffer), I use comma for repeat instead:
(define-key god-local-mode-map (kbd ",") 'repeat) (defun split-window-func-with-other-buffer (split-function) (lexical-let ((s-f split-function)) (lambda () (interactive) (funcall s-f) (set-window-buffer (next-window) (other-buffer))))) (global-set-key (kbd "C-x C-1") 'delete-other-windows) (global-set-key (kbd "C-x C-'") 'delete-other-windows) (global-set-key (kbd "C-x '") 'delete-other-windows) (global-set-key (kbd "C-x C-o") 'other-window) (global-set-key (kbd "C-x C-2") (split-window-func-with-other-buffer 'split-window-vertically)) (global-set-key (kbd "C-x C-,") (split-window-func-with-other-buffer 'split-window-vertically)) (global-set-key (kbd "C-x ,") (split-window-func-with-other-buffer 'split-window-vertically)) (global-set-key (kbd "C-x C-3") (split-window-func-with-other-buffer 'split-window-horizontally)) (global-set-key (kbd "C-x C-.") (split-window-func-with-other-buffer 'split-window-horizontally)) (global-set-key (kbd "C-x .") (split-window-func-with-other-buffer 'split-window-horizontally)) (global-set-key (kbd "C-x 2") (split-window-func-with-other-buffer 'split-window-vertically)) (global-set-key (kbd "C-x 3") (split-window-func-with-other-buffer 'split-window-horizontally)) (global-set-key (kbd "C-x C-0") 'delete-window) (add-to-list 'god-exempt-major-modes 'Buffer-Selection-Menu-mode) (add-to-list 'god-exempt-major-modes 'notmuch-search-mode) (add-to-list 'god-exempt-major-modes 'notmuch-show-mode) (add-to-list 'god-exempt-major-modes 'Info-mode)
Love function keys:
(setq god-mode-enable-function-key-translation nil)