diff options
Diffstat (limited to 'emacs/.emacs.d/wpc/wpc-keybindings.el')
-rw-r--r-- | emacs/.emacs.d/wpc/wpc-keybindings.el | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/emacs/.emacs.d/wpc/wpc-keybindings.el b/emacs/.emacs.d/wpc/wpc-keybindings.el new file mode 100644 index 000000000000..2ff4fe375829 --- /dev/null +++ b/emacs/.emacs.d/wpc/wpc-keybindings.el @@ -0,0 +1,229 @@ +;;; keybindings.el --- My Evil preferences -*- lexical-binding: t -*- +;; Author: William Carroll <wpcarro@gmail.com> + +;;; Commentary: +;; This module hosts my Evil preferences +;; +;; Wish List: +;; - restore support for concise (n <kbd> <function>) instead of `general-mmap' +;; - restore support for `general-unbind' + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dependencies +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'general) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Packages +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; This may be contraversial, but I never use the prefix key, and I'd prefer to +;; have to bound to the readline function that deletes the entire line. +(general-unbind "C-u") + +(use-package evil + :init + ;; Should remove the warning messages on init. + (setq evil-want-integration t) + ;; TODO: Troubleshoot why this binding causes the following warning: + ;; "Warning (evil-collection): `evil-want-keybinding' was set to nil but not + ;; before loading evil." + (setq evil-want-keybinding nil) + (general-evil-setup) + :config + ;; Ensure that evil's command mode behaves with readline bindings. + (general-define-key + :keymaps 'evil-ex-completion-map + "C-a" #'move-beginning-of-line + "C-e" #'move-end-of-line + "C-k" #'kill-line + "C-u" #'evil-delete-whole-line + "C-v" #'evil-paste-after + "C-d" #'delete-char + "C-f" #'forward-char + "M-b" #'backward-word + "M-f" #'forward-word + "M-d" #'kill-word + "M-DEL" #'backward-kill-word + "C-b" #'backward-char) + ;; TODO: Ensure all of my custom keybindings end up in a single map that is + ;; easy to enable or disable. + (general-mmap + :keymaps 'override + "RET" #'evil-goto-line + "H" #'evil-first-non-blank + "L" #'evil-end-of-line + "_" #'ranger + "-" #'dired-jump + "sl" #'wpc/evil-window-vsplit-right + "sh" #'evil-window-vsplit + "sk" #'evil-window-split + "sj" #'wpc/evil-window-split-down) + (general-nmap + :keymaps 'override + "gd" #'xref-find-definitions + ;; Wrapping `xref-find-references' in the `let' binding to prevent xref from + ;; prompting. There are other ways to handle this variable, such as setting + ;; it globally with `setq' or buffer-locally with `setq-local'. For now, I + ;; prefer setting it with `let', which should bind it in the dynamic scope + ;; for the duration of the `xref-find-references' function call. + "gx" (lambda () + (interactive) + (let ((xref-prompt-for-identifier nil)) + (call-interactively #'xref-find-references)))) + (general-unbind 'motion "M-." "C-p") + (general-unbind 'normal "s" "M-." "C-p" "C-n") + (general-unbind 'insert "C-v" "C-d" "C-a" "C-e" "C-n" "C-p" "C-k") + (setq evil-symbol-word-search t) + (evil-mode 1)) + +;; TODO: Write `evil-collection' KBDs for `refine'. +;; evil keybindings +(use-package evil-collection + :after (evil) + :config + (evil-collection-init)) + +;; `evil-collection' does not support `magit', and the preferred way to get evil +;; kbds for magit is with `evil-magit'. +(use-package evil-magit) + +;; TODO: Consider moving this to another module. +(general-define-key + :prefix "<SPC>" + :states '(normal) + "i" #'counsel-semantic-or-imenu + "I" #'ibuffer + "hk" #'helpful-callable + "hf" #'helpful-function + "hm" #'helpful-macro + "hc" #'helpful-command + "hk" #'helpful-key + "hv" #'helpful-variable + "hp" #'helpful-at-point + "s" #'flyspell-mode + "S" #'sort-lines + "a" #'wpc-terminal/toggle + "=" #'align + "p" #'flycheck-previous-error + "f" #'wpc/find-file + "n" #'flycheck-next-error + "N" #'smerge-next + "W" #'balance-windows + "gs" #'magit-status + "E" #'refine + "es" #'wpc/create-snippet + ;; TODO: Replace with `macros/ilambda' when that is working again. + "ev" (lambda () (interactive) (wpc/find-file-split "~/.config/nvim/init.vim")) + "ee" (lambda () (interactive) (wpc/find-file-split "~/.emacs.d/init.el")) + "ez" (lambda () (interactive) (wpc/find-file-split "~/.zshrc")) + "ea" (lambda () (interactive) (wpc/find-file-split "~/aliases.zsh")) + "ef" (lambda () (interactive) (wpc/find-file-split "~/functions.zsh")) + "el" (lambda () (interactive) (wpc/find-file-split "~/variables.zsh")) + "ex" (lambda () (interactive) (wpc/find-file-split "~/.Xresources")) + "em" (lambda () (interactive) (wpc/find-file-split "~/.tmux.conf")) + "l" #'locate + "L" #'list-packages + "B" #'magit-blame + "w" #'save-buffer + "r" #'wpc/evil-replace-under-point + "R" #'deadgrep) + +;; create comments easily +(use-package evil-commentary + :after (evil) + :config + (evil-commentary-mode)) + +;; evil surround +(use-package evil-surround + :after (evil) + :config + (global-evil-surround-mode 1)) + +;; I expect in insert mode: +;; C-a: beginning-of-line +;; C-e: end-of-line +;; C-b: backwards-char +;; C-f: forwards-char + +;; TODO: Move these KBD constants to kbd.el. + +(defconst wpc/up-kbds + '("C-p" "C-k" "<backtab>" "<up>") + "The keybindings that I expect to work for moving upwards in lists.") + +(defconst wpc/down-kbds + '("C-n" "C-j" "<tab>" "<down>") + "The keybindings that I expect to work for moving downwards in lists.") + +(defconst wpc/left-kbds + '("C-b" "<left>") + "The keybindings that I expect to move leftwards in insert-like modes.") + +(defconst wpc/right-kbds + '("C-f" "<right>") + "The keybindings that I expect to move rightwards in insert-like modes.") + +(defun wpc/ensure-kbds (_ignore) + "Try to ensure that my keybindings retain priority over other minor modes." + (unless (eq (caar minor-mode-map-alist) 'wpc/kbds-minor-mode) + (let ((mykbds (assq 'wpc/kbds-minor-mode minor-mode-map-alist))) + (assq-delete-all 'wpc/kbds-minor-mode minor-mode-map-alist) + (add-to-list 'minor-mode-map-alist mykbds)))) + +;; Custom minor mode that ensures that my kbds are available no matter which +;; major or minor modes are active. +(add-hook 'after-load-functions #'wpc/ensure-kbds) + +;; TODO: Prefer using general and 'override maps to implement this. +(defvar wpc/kbds + (let ((map (make-sparse-keymap))) + (bind-keys :map map + ("M-q" . delete-window) + ("<s-return>" . toggle-frame-fullscreen) + ("M-h" . windmove-left) + ("M-l" . windmove-right) + ("M-k" . windmove-up) + ("M-j" . windmove-down) + ("M-q" . delete-window)) + map) + "William Carroll's keybindings that should have the highest precedence.") + +;; Support pasting in M-:. +(general-define-key + :keymaps 'read-expression-map + "C-v" #'clipboard-yank + "C-S-v" #'clipboard-yank) + +(define-minor-mode wpc/kbds-minor-mode + "A minor mode so that my key settings override annoying major modes." + :init-value t + :lighter " wpc/kbds" + :keymap wpc/kbds) + +;; allow jk to escape +(use-package key-chord + :after (evil) + :config + (key-chord-mode 1) + (key-chord-define evil-insert-state-map "jk" 'evil-normal-state)) + +;; Ensure the Evil search results get centered vertically. +;; TODO: Consider packaging this up for others. +(progn + (defadvice isearch-update + (before advice-for-isearch-update activate) + (evil-scroll-line-to-center (line-number-at-pos))) + (defadvice evil-search-next + (after advice-for-evil-search-next activate) + (evil-scroll-line-to-center (line-number-at-pos))) + (defadvice evil-search-previous + (after advice-for-evil-search-previous activate) + (evil-scroll-line-to-center (line-number-at-pos)))) + +(provide 'wpc-keybindings) +;;; wpc-keybindings.el ends here |