diff --git a/users/crumb/programs/emacs/modules/syd-keybinds.el b/users/crumb/programs/emacs/modules/syd-keybinds.el index f196f1e..0051875 100755 --- a/users/crumb/programs/emacs/modules/syd-keybinds.el +++ b/users/crumb/programs/emacs/modules/syd-keybinds.el @@ -59,6 +59,23 @@ are active.") More specifically, when `syd/escape' is pressed. If any hook returns non-nil, all hooks after it are ignored.") +;; +;;; Universal, non-nuclear escape + +;; `keyboard-quit' is too much of a nuclear option. I wanted an ESC/C-g to +;; do-what-I-mean. It serves four purposes (in order): +;; +;; 1. Quit active states; e.g. highlights, searches, snippets, iedit, +;; multiple-cursors, recording macros, etc. +;; 2. Close popup windows remotely (if it is allowed to) +;; 3. Refresh buffer indicators, like diff-hl and flycheck +;; 4. Or fall back to `keyboard-quit' +;; +;; And it should do these things incrementally, rather than all at once. And it +;; shouldn't interfere with recording macros or the minibuffer. This may require +;; you press ESC/C-g two or three times on some occasions to reach +;; `keyboard-quit', but this is much more intuitive. + (defun syd/escape (&optional interactive) "Run `syd-escape-hook'." (interactive (list 'interactive)) @@ -77,10 +94,18 @@ all hooks after it are ignored.") (when interactive (setq this-command 'keyboard-quit))))))) - (with-eval-after-load 'eldoc (eldoc-add-command 'syd/escape)) +;; In normal state, pressing escape should run `syd-escape-hook'. +(with-eval-after-load 'evil + (defun evil-syd/escape-a (&rest _) + "Call `syd/escape' if `evil-force-normal-state' is called interactively." + (when (called-interactively-p 'any) + (call-interactively #'syd/escape))) + (advice-add #'evil-force-normal-state + :after #'evil-syd/escape-a)) + (defun syd-keybinds-initialise () (syd--initialise-leader)