doomemacs/modules/editor/evil/config.el

584 lines
23 KiB
EmacsLisp
Raw Normal View History

;;; editor/evil/config.el -*- lexical-binding: t; -*-
(defvar +evil-want-o/O-to-continue-comments t
"If non-nil, the o/O keys will continue comment lines if the point is on a
line with a linewise comment.")
(defvar +evil-want-move-window-to-wrap-around nil
"If non-nil, `+evil/window-move-*' commands will wrap around.")
(defvar +evil-preprocessor-regexp "^\\s-*#[a-zA-Z0-9_]"
"The regexp used by `+evil/next-preproc-directive' and
`+evil/previous-preproc-directive' on ]# and [#, to jump between preprocessor
directives. By default, this only recognizes C directives.")
;; Set these defaults before `evil'; use `defvar' so they can be changed prior
;; to loading.
(defvar evil-want-C-g-bindings t)
2020-12-14 15:48:29 -05:00
(defvar evil-want-C-i-jump nil) ; we do this ourselves
(defvar evil-want-C-u-scroll t) ; moved the universal arg to <leader> u
(defvar evil-want-C-u-delete t)
(defvar evil-want-C-w-delete t)
(defvar evil-want-Y-yank-to-eol t)
(defvar evil-want-abbrev-expand-on-insert-exit nil)
(defvar evil-respect-visual-line-mode nil)
(use-package! evil
refactor!: redesign module init/config hooks BREAKING CHANGE: For consistency and correctness, I've renamed the module init/config hooks, and added new ones: - Adds doom-before-modules-config-hook - Adds doom-after-modules-config-hook (replaced doom-before-init-modules-hook) - Adds doom-before-modules-init-hook - Adds doom-after-modules-init-hook (replaced doom-init-modules-hook) - Removed doom-after-init-modules-hook (replaced w/ after-init-hook) The old naming (and timing) was counterintuitive. Now, it's named after the loaded file group (init.el vs config.el), and I added before/after variants. Altogether, this should make them less ambiguous. I've also moved some functions in various modules to more correct hooks. Load order before this change: - $EMACSDIR/early-init.el - $EMACSDIR/lisp/doom.el - $EMACSDIR/lisp/doom-start.el - $DOOMDIR/init.el - {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el - `doom-before-init-modules-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el - `doom-init-modules-hook' - $DOOMDIR/config.el - `doom-after-init-modules-hook' - `after-init-hook' - `emacs-startup-hook' - `window-setup-hook' Load order after this change: - $EMACSDIR/early-init.el - $EMACSDIR/lisp/doom.el - $EMACSDIR/lisp/doom-start.el - $DOOMDIR/init.el - `doom-before-modules-init-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el - `doom-after-modules-init-hook' - `doom-before-modules-config-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el - `doom-after-modules-config-hook' - $DOOMDIR/config.el - `after-init-hook' - `emacs-startup-hook' - `window-setup-hook'
2022-09-14 14:48:21 +02:00
:hook (doom-after-modules-config . evil-mode)
:demand t
:preface
(setq evil-ex-search-vim-style-regexp t
2017-01-31 19:50:02 -05:00
evil-ex-visual-char-range t ; column range for ex commands
2017-05-15 13:52:22 +02:00
evil-mode-line-format 'nil
;; more vim-like behavior
evil-symbol-word-search t
2021-05-23 21:48:38 -04:00
;; if the current state is obvious from the cursor's color/shape, then
;; we won't need superfluous indicators to do it instead.
evil-default-cursor '+evil-default-cursor-fn
evil-normal-state-cursor 'box
evil-emacs-state-cursor '(box +evil-emacs-cursor-fn)
evil-insert-state-cursor 'bar
evil-visual-state-cursor 'hollow
;; Only do highlighting in selected window so that Emacs has less work
;; to do highlighting them all.
evil-ex-interactive-search-highlight 'selected-window
;; It's infuriating that innocuous "beginning of line" or "end of line"
;; errors will abort macros, so suppress them:
evil-kbd-macro-suppress-motion-error t
evil-undo-system
(cond ((modulep! :emacs undo +tree) 'undo-tree)
((modulep! :emacs undo) 'undo-fu)
((> emacs-major-version 27) 'undo-redo)))
2017-01-31 19:50:02 -05:00
;; Fix #7141
(defadvice! +evil--persist-state-a (fn &rest args)
"When changing major modes, Evil's state is lost. This advice preserves it."
:around #'set-auto-mode
(if evil-state
(evil-save-state (apply fn args))
(apply fn args)))
;; Slow this down from 0.02 to prevent blocking in large or folded buffers
;; like magit while incrementally highlighting matches.
2020-08-08 03:06:26 -04:00
(setq-hook! '(magit-mode-hook so-long-minor-mode-hook)
evil-ex-hl-update-delay 0.25)
:config
2017-02-19 18:14:46 -05:00
(evil-select-search-module 'evil-search-module 'evil-search)
;; PERF: Stop copying the selection to the clipboard each time the cursor
;; moves in visual mode. Why? Because on most non-X systems (and in terminals
;; with clipboard plugins like xclip.el active), Emacs will spin up a new
;; process to communicate with the clipboard for each movement. On Windows,
;; older versions of macOS (pre-vfork), and Waylang (without pgtk), this is
;; super expensive and can lead to freezing and/or zombie processes.
;;
;; UX: It also clobbers clipboard managers (see emacs-evil/evil#336).
(setq evil-visual-update-x-selection-p nil)
;; Start help-with-tutorial in emacs state
(advice-add #'help-with-tutorial :after (lambda (&rest _) (evil-emacs-state +1)))
;; Done in a hook to ensure the popup rules load as late as possible
refactor!: redesign module init/config hooks BREAKING CHANGE: For consistency and correctness, I've renamed the module init/config hooks, and added new ones: - Adds doom-before-modules-config-hook - Adds doom-after-modules-config-hook (replaced doom-before-init-modules-hook) - Adds doom-before-modules-init-hook - Adds doom-after-modules-init-hook (replaced doom-init-modules-hook) - Removed doom-after-init-modules-hook (replaced w/ after-init-hook) The old naming (and timing) was counterintuitive. Now, it's named after the loaded file group (init.el vs config.el), and I added before/after variants. Altogether, this should make them less ambiguous. I've also moved some functions in various modules to more correct hooks. Load order before this change: - $EMACSDIR/early-init.el - $EMACSDIR/lisp/doom.el - $EMACSDIR/lisp/doom-start.el - $DOOMDIR/init.el - {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el - `doom-before-init-modules-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el - `doom-init-modules-hook' - $DOOMDIR/config.el - `doom-after-init-modules-hook' - `after-init-hook' - `emacs-startup-hook' - `window-setup-hook' Load order after this change: - $EMACSDIR/early-init.el - $EMACSDIR/lisp/doom.el - $EMACSDIR/lisp/doom-start.el - $DOOMDIR/init.el - `doom-before-modules-init-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el - `doom-after-modules-init-hook' - `doom-before-modules-config-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el - `doom-after-modules-config-hook' - $DOOMDIR/config.el - `after-init-hook' - `emacs-startup-hook' - `window-setup-hook'
2022-09-14 14:48:21 +02:00
(add-hook! 'doom-after-modules-config-hook
(defun +evil--init-popup-rules-h ()
(set-popup-rules!
'(("^\\*evil-registers" :size 0.3)
("^\\*Command Line" :size 8)))))
2017-02-21 16:04:35 -05:00
;; Change the cursor color in emacs state. We do it this roundabout way
;; to ensure changes in theme doesn't break these colors.
refactor!: redesign module init/config hooks BREAKING CHANGE: For consistency and correctness, I've renamed the module init/config hooks, and added new ones: - Adds doom-before-modules-config-hook - Adds doom-after-modules-config-hook (replaced doom-before-init-modules-hook) - Adds doom-before-modules-init-hook - Adds doom-after-modules-init-hook (replaced doom-init-modules-hook) - Removed doom-after-init-modules-hook (replaced w/ after-init-hook) The old naming (and timing) was counterintuitive. Now, it's named after the loaded file group (init.el vs config.el), and I added before/after variants. Altogether, this should make them less ambiguous. I've also moved some functions in various modules to more correct hooks. Load order before this change: - $EMACSDIR/early-init.el - $EMACSDIR/lisp/doom.el - $EMACSDIR/lisp/doom-start.el - $DOOMDIR/init.el - {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el - `doom-before-init-modules-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el - `doom-init-modules-hook' - $DOOMDIR/config.el - `doom-after-init-modules-hook' - `after-init-hook' - `emacs-startup-hook' - `window-setup-hook' Load order after this change: - $EMACSDIR/early-init.el - $EMACSDIR/lisp/doom.el - $EMACSDIR/lisp/doom-start.el - $DOOMDIR/init.el - `doom-before-modules-init-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el - `doom-after-modules-init-hook' - `doom-before-modules-config-hook' - {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el - `doom-after-modules-config-hook' - $DOOMDIR/config.el - `after-init-hook' - `emacs-startup-hook' - `window-setup-hook'
2022-09-14 14:48:21 +02:00
(add-hook! '(doom-load-theme-hook doom-after-modules-config-hook)
(defun +evil-update-cursor-color-h ()
(put 'cursor 'evil-emacs-color (face-foreground 'warning))
(put 'cursor 'evil-normal-color (face-background 'cursor))))
(defun +evil-default-cursor-fn ()
(evil-set-cursor-color (get 'cursor 'evil-normal-color)))
(defun +evil-emacs-cursor-fn ()
(evil-set-cursor-color (get 'cursor 'evil-emacs-color)))
2017-02-19 18:14:46 -05:00
;; Ensure `evil-shift-width' always matches `tab-width'; evil does not police
;; this itself, so we must.
(setq-hook! 'after-change-major-mode-hook evil-shift-width tab-width)
2017-01-31 19:50:02 -05:00
2017-05-15 13:52:22 +02:00
;; --- keybind fixes ----------------------
(after! wgrep
;; A wrapper that invokes `wgrep-mark-deletion' across lines you use
;; `evil-delete' in wgrep buffers.
(define-key wgrep-mode-map [remap evil-delete] #'+evil-delete))
2019-07-26 22:46:05 +02:00
(add-hook! 'doom-escape-hook
(defun +evil-disable-ex-highlights-h ()
"Disable ex search buffer highlights."
(when (evil-ex-hl-active-p 'evil-ex-search)
(evil-ex-nohighlight)
t)))
2018-01-06 03:00:45 -05:00
2017-05-15 13:52:22 +02:00
;; --- evil hacks -------------------------
(after! eldoc
;; Allow eldoc to trigger directly after changing modes
(eldoc-add-command 'evil-normal-state
'evil-insert
'evil-change
'evil-delete
'evil-replace))
(unless noninteractive
(setq save-silently t)
2019-07-26 22:46:05 +02:00
(add-hook! 'after-save-hook
(defun +evil-display-vimlike-save-message-h ()
"Shorter, vim-esque save messages."
(message "\"%s\" %dL, %dC written"
(if buffer-file-name
(file-relative-name (file-truename buffer-file-name) (doom-project-root))
(buffer-name))
(count-lines (point-min) (point-max))
(buffer-size)))))
;; HACK '=' moves the cursor to the beginning of selection. Disable this,
;; since it's more disruptive than helpful.
(defadvice! +evil--dont-move-cursor-a (fn &rest args)
:around #'evil-indent
(save-excursion (apply fn args)))
;; REVIEW In evil, registers 2-9 are buffer-local. In vim, they're global,
;; so... Perhaps this should be PRed upstream?
(defadvice! +evil--make-numbered-markers-global-a (char)
:after-until #'evil-global-marker-p
(and (>= char ?2) (<= char ?9)))
;; Make J (evil-join) remove comment delimiters when joining lines.
(advice-add #'evil-join :around #'+evil-join-a)
;; Prevent gw (`evil-fill') and gq (`evil-fill-and-move') from squeezing
;; spaces. It doesn't in vim, so it shouldn't in evil.
(defadvice! +evil--no-squeeze-on-fill-a (fn &rest args)
:around '(evil-fill evil-fill-and-move)
(letf! (defun fill-region (from to &optional justify nosqueeze to-eop)
(funcall fill-region from to justify t to-eop))
(apply fn args)))
;; Make ESC (from normal mode) the universal escaper. See `doom-escape-hook'.
:boom: revise advice naming convention (1/2) This is first of three big naming convention updates that have been a long time coming. With 2.1 on the horizon, all the breaking updates will batched together in preparation for the long haul. In this commit, we do away with the asterix to communicate that a function is an advice function, and we replace it with the '-a' suffix. e.g. doom*shut-up -> doom-shut-up-a doom*recenter -> doom-recenter-a +evil*static-reindent -> +evil--static-reindent-a The rationale behind this change is: 1. Elisp's own formatting/indenting tools would occasionally struggle with | and * (particularly pp and cl-prettyprint). They have no problem with / and :, fortunately. 2. External syntax highlighters (like pygmentize, discord markdown or github markdown) struggle with it, sometimes refusing to highlight code beyond these symbols. 3. * and | are less expressive than - and -- in communicating the intended visibility, versatility and stability of a function. 4. It complicated the regexps we must use to search for them. 5. They were arbitrary and over-complicated to begin with, decided on haphazardly way back when Doom was simply "my private config". Anyhow, like how predicate functions have the -p suffix, we'll adopt the -a suffix for advice functions, -h for hook functions and -fn for variable functions. Other noteable changes: - Replaces advice-{add,remove}! macro with new def-advice! macro. The old pair weren't as useful. The new def-advice! saves on a lot of space. - Removed "stage" assertions to make sure you were using the right macros in the right place. Turned out to not be necessary, we'll employ better checks later.
2019-07-18 15:42:52 +02:00
(advice-add #'evil-force-normal-state :after #'+evil-escape-a)
2018-05-05 07:49:20 +02:00
;; monkey patch `evil-ex-replace-special-filenames' to improve support for
;; file modifiers like %:p:h. This adds support for most of vim's modifiers,
;; and one custom one: %:P (expand to the project root).
(advice-add #'evil-ex-replace-special-filenames :override #'+evil-replace-filename-modifiers-a)
;; make `try-expand-dabbrev' (from `hippie-expand') work in minibuffer
(add-hook 'minibuffer-inactive-mode-hook #'+evil--fix-dabbrev-in-minibuffer-h)
;; Focus and recenter new splits
:boom: revise advice naming convention (1/2) This is first of three big naming convention updates that have been a long time coming. With 2.1 on the horizon, all the breaking updates will batched together in preparation for the long haul. In this commit, we do away with the asterix to communicate that a function is an advice function, and we replace it with the '-a' suffix. e.g. doom*shut-up -> doom-shut-up-a doom*recenter -> doom-recenter-a +evil*static-reindent -> +evil--static-reindent-a The rationale behind this change is: 1. Elisp's own formatting/indenting tools would occasionally struggle with | and * (particularly pp and cl-prettyprint). They have no problem with / and :, fortunately. 2. External syntax highlighters (like pygmentize, discord markdown or github markdown) struggle with it, sometimes refusing to highlight code beyond these symbols. 3. * and | are less expressive than - and -- in communicating the intended visibility, versatility and stability of a function. 4. It complicated the regexps we must use to search for them. 5. They were arbitrary and over-complicated to begin with, decided on haphazardly way back when Doom was simply "my private config". Anyhow, like how predicate functions have the -p suffix, we'll adopt the -a suffix for advice functions, -h for hook functions and -fn for variable functions. Other noteable changes: - Replaces advice-{add,remove}! macro with new def-advice! macro. The old pair weren't as useful. The new def-advice! saves on a lot of space. - Removed "stage" assertions to make sure you were using the right macros in the right place. Turned out to not be necessary, we'll employ better checks later.
2019-07-18 15:42:52 +02:00
(advice-add #'evil-window-split :override #'+evil-window-split-a)
(advice-add #'evil-window-vsplit :override #'+evil-window-vsplit-a)
2017-05-15 13:52:22 +02:00
2020-02-28 16:29:49 -05:00
;; Make o/O continue comments (see `+evil-want-o/O-to-continue-comments' to disable)
:boom: revise advice naming convention (1/2) This is first of three big naming convention updates that have been a long time coming. With 2.1 on the horizon, all the breaking updates will batched together in preparation for the long haul. In this commit, we do away with the asterix to communicate that a function is an advice function, and we replace it with the '-a' suffix. e.g. doom*shut-up -> doom-shut-up-a doom*recenter -> doom-recenter-a +evil*static-reindent -> +evil--static-reindent-a The rationale behind this change is: 1. Elisp's own formatting/indenting tools would occasionally struggle with | and * (particularly pp and cl-prettyprint). They have no problem with / and :, fortunately. 2. External syntax highlighters (like pygmentize, discord markdown or github markdown) struggle with it, sometimes refusing to highlight code beyond these symbols. 3. * and | are less expressive than - and -- in communicating the intended visibility, versatility and stability of a function. 4. It complicated the regexps we must use to search for them. 5. They were arbitrary and over-complicated to begin with, decided on haphazardly way back when Doom was simply "my private config". Anyhow, like how predicate functions have the -p suffix, we'll adopt the -a suffix for advice functions, -h for hook functions and -fn for variable functions. Other noteable changes: - Replaces advice-{add,remove}! macro with new def-advice! macro. The old pair weren't as useful. The new def-advice! saves on a lot of space. - Removed "stage" assertions to make sure you were using the right macros in the right place. Turned out to not be necessary, we'll employ better checks later.
2019-07-18 15:42:52 +02:00
(advice-add #'evil-open-above :around #'+evil--insert-newline-above-and-respect-comments-a)
(advice-add #'evil-open-below :around #'+evil--insert-newline-below-and-respect-comments-a)
;; Lazy load evil ex commands
(delq! 'evil-ex features)
(add-transient-hook! 'evil-ex (provide 'evil-ex))
(after! evil-ex (load! "+commands")))
2017-01-31 19:50:02 -05:00
;;
;;; Packages
2017-01-31 19:50:02 -05:00
(use-package! evil-easymotion
:after-call doom-first-input-hook
:commands evilem-create evilem-default-keybindings
:config
;; Use evil-search backend, instead of isearch
(evilem-make-motion evilem-motion-search-next #'evil-ex-search-next
:bind ((evil-ex-search-highlight-all nil)))
(evilem-make-motion evilem-motion-search-previous #'evil-ex-search-previous
:bind ((evil-ex-search-highlight-all nil)))
(evilem-make-motion evilem-motion-search-word-forward #'evil-ex-search-word-forward
:bind ((evil-ex-search-highlight-all nil)))
(evilem-make-motion evilem-motion-search-word-backward #'evil-ex-search-word-backward
:bind ((evil-ex-search-highlight-all nil)))
;; Rebind scope of w/W/e/E/ge/gE evil-easymotion motions to the visible
;; buffer, rather than just the current line.
(put 'visible 'bounds-of-thing-at-point (lambda () (cons (window-start) (window-end))))
(evilem-make-motion evilem-motion-forward-word-begin #'evil-forward-word-begin :scope 'visible)
(evilem-make-motion evilem-motion-forward-WORD-begin #'evil-forward-WORD-begin :scope 'visible)
(evilem-make-motion evilem-motion-forward-word-end #'evil-forward-word-end :scope 'visible)
(evilem-make-motion evilem-motion-forward-WORD-end #'evil-forward-WORD-end :scope 'visible)
(evilem-make-motion evilem-motion-backward-word-begin #'evil-backward-word-begin :scope 'visible)
(evilem-make-motion evilem-motion-backward-WORD-begin #'evil-backward-WORD-begin :scope 'visible)
(evilem-make-motion evilem-motion-backward-word-end #'evil-backward-word-end :scope 'visible)
(evilem-make-motion evilem-motion-backward-WORD-end #'evil-backward-WORD-end :scope 'visible))
2017-01-31 19:50:02 -05:00
(use-package! evil-embrace
:commands embrace-add-pair embrace-add-pair-regexp
:hook (LaTeX-mode . embrace-LaTeX-mode-hook)
:hook (LaTeX-mode . +evil-embrace-latex-mode-hook-h)
:hook (org-mode . embrace-org-mode-hook)
2020-03-12 11:29:54 -04:00
:hook (ruby-mode . embrace-ruby-mode-hook)
:hook (emacs-lisp-mode . embrace-emacs-lisp-mode-hook)
:hook ((c++-mode c++-ts-mode rustic-mode csharp-mode java-mode swift-mode typescript-mode)
. +evil-embrace-angle-bracket-modes-hook-h)
:hook (scala-mode . +evil-embrace-scala-mode-hook-h)
:init
(after! evil-surround
(evil-embrace-enable-evil-surround-integration))
;; HACK: This must be done ASAP, before embrace has a chance to
;; buffer-localize `embrace--pairs-list' (which happens right after it calls
;; `embrace--setup-defaults'), otherwise any new, global default pairs we
;; define won't be in scope.
(defadvice! +evil--embrace-init-escaped-pairs-a (&rest args)
"Add escaped-sequence support to embrace."
:after #'embrace--setup-defaults
(embrace-add-pair-regexp ?\\ "\\[[{(]" "\\[]})]" #'+evil--embrace-escaped
(embrace-build-help "\\?" "\\?")))
2017-01-31 19:50:02 -05:00
:config
(setq evil-embrace-show-help-p nil)
(defun +evil-embrace-scala-mode-hook-h ()
(embrace-add-pair ?$ "${" "}"))
(defun +evil-embrace-latex-mode-hook-h ()
(dolist (pair '((?\' . ("`" . "\'"))
(?\" . ("``" . "\'\'"))))
(delete (car pair) evil-embrace-evil-surround-keys)
;; Avoid `embrace-add-pair' because it would overwrite the default
;; rules, which we want for other modes
(push (cons (car pair) (make-embrace-pair-struct
:key (car pair)
:left (cadr pair)
:right (cddr pair)
:left-regexp (regexp-quote (cadr pair))
:right-regexp (regexp-quote (cddr pair))))
embrace--pairs-list))
(embrace-add-pair-regexp ?l "\\[a-z]+{" "}" #'+evil--embrace-latex))
(defun +evil-embrace-angle-bracket-modes-hook-h ()
(let ((var (make-local-variable 'evil-embrace-evil-surround-keys)))
(set var (delq ?< evil-embrace-evil-surround-keys))
(set var (delq ?> evil-embrace-evil-surround-keys)))
(embrace-add-pair-regexp ?< "\\_<[a-z0-9-_]+<" ">" #'+evil--embrace-angle-brackets)
(embrace-add-pair ?> "<" ">")))
2017-01-31 19:50:02 -05:00
(use-package! evil-escape
:commands evil-escape
2021-05-23 21:48:38 -04:00
:hook (doom-first-input . evil-escape-mode)
2017-01-31 19:50:02 -05:00
:init
(setq evil-escape-excluded-states '(normal visual multiedit emacs motion)
evil-escape-excluded-major-modes '(neotree-mode treemacs-mode vterm-mode)
evil-escape-key-sequence "jk"
2019-09-20 23:55:25 -04:00
evil-escape-delay 0.15)
(evil-define-key* '(insert replace visual operator) 'global "\C-g" #'evil-escape)
2017-01-31 19:50:02 -05:00
:config
2021-05-23 21:48:38 -04:00
;; `evil-escape' in the minibuffer is more disruptive than helpful. That is,
;; unless we have `evil-collection-setup-minibuffer' enabled, in which case we
;; want the same behavior in insert mode as we do in normal buffers.
(add-hook! 'evil-escape-inhibit-functions
(defun +evil-inhibit-escape-in-minibuffer-fn ()
(and (minibufferp)
(or (not (bound-and-true-p evil-collection-setup-minibuffer))
2021-05-23 21:48:38 -04:00
(evil-normal-state-p))))))
2017-01-31 19:50:02 -05:00
(use-package! evil-exchange
2017-01-31 19:50:02 -05:00
:commands evil-exchange
:config
2019-07-26 22:46:05 +02:00
(add-hook! 'doom-escape-hook
(defun +evil--escape-exchange-h ()
(when evil-exchange--overlays
(evil-exchange-cancel)
t))))
2017-01-31 19:50:02 -05:00
(use-package! evil-quick-diff
:commands (evil-quick-diff evil-quick-diff-cancel))
2017-01-31 19:50:02 -05:00
(use-package! evil-nerd-commenter
:commands (evilnc-comment-operator
evilnc-inner-comment
evilnc-outer-commenter)
:general ([remap comment-line] #'evilnc-comment-or-uncomment-lines))
(use-package! evil-snipe
2021-05-23 21:48:38 -04:00
:commands evil-snipe-local-mode evil-snipe-override-local-mode
:hook (doom-first-input . evil-snipe-override-mode)
:hook (doom-first-input . evil-snipe-mode)
2017-01-31 19:50:02 -05:00
:init
(setq evil-snipe-smart-case t
evil-snipe-scope 'line
evil-snipe-repeat-scope 'visible
evil-snipe-char-fold t))
2017-01-31 19:50:02 -05:00
(use-package! evil-surround
2017-01-31 19:50:02 -05:00
:commands (global-evil-surround-mode
evil-surround-edit
evil-Surround-edit
evil-surround-region)
:config (global-evil-surround-mode 1))
(use-package! evil-textobj-anyblock
:defer t
:config
(setq evil-textobj-anyblock-blocks
'(("(" . ")")
("{" . "}")
("\\[" . "\\]")
("<" . ">"))))
(use-package! evil-traces
:after evil-ex
:config
(pushnew! evil-traces-argument-type-alist
'(+evil:align . evil-traces-global)
'(+evil:align-right . evil-traces-global)
'(+multiple-cursors:evil-mc . evil-traces-substitute))
(evil-traces-mode))
;; Allows you to use the selection for * and #
(use-package! evil-visualstar
:commands (evil-visualstar/begin-search
2017-01-31 19:50:02 -05:00
evil-visualstar/begin-search-forward
evil-visualstar/begin-search-backward)
:init
(evil-define-key* 'visual 'global
"*" #'evil-visualstar/begin-search-forward
"#" #'evil-visualstar/begin-search-backward))
2017-01-31 19:50:02 -05:00
2017-06-05 00:47:56 +02:00
;;
;;; Text object plugins
2017-06-05 00:47:56 +02:00
(use-package! exato
:commands evil-outer-xml-attr evil-inner-xml-attr)
;;
;;; Keybinds
;; Keybinds that have no Emacs+evil analogues (i.e. don't exist):
;; zu{q,w} - undo last marking
2019-10-30 22:26:00 -04:00
(map! :v "@" #'+evil:apply-macro
2020-12-11 01:44:41 -05:00
:m [C-i] #'evil-jump-forward
;; implement dictionary keybinds
;; evil already defines 'z=' to `ispell-word' = correct word at point
(:when (modulep! :checkers spell)
:n "zg" #'+spell/add-word
:n "zw" #'+spell/remove-word
:m "[s" #'+spell/previous-error
:m "]s" #'+spell/next-error)
;; ported from vim-unimpaired
:n "] SPC" #'+evil/insert-newline-below
:n "[ SPC" #'+evil/insert-newline-above
:n "]b" #'next-buffer
:n "[b" #'previous-buffer
:n "]f" #'+evil/next-file
:n "[f" #'+evil/previous-file
:m "]u" #'+evil:url-encode
:m "[u" #'+evil:url-decode
:m "]y" #'+evil:c-string-encode
:m "[y" #'+evil:c-string-decode
(:when (modulep! :lang web)
:m "]x" #'+web:encode-html-entities
:m "[x" #'+web:decode-html-entities)
(:when (modulep! :ui vc-gutter)
:m "]d" #'+vc-gutter/next-hunk
:m "[d" #'+vc-gutter/previous-hunk)
(:when (modulep! :ui hl-todo)
:m "]t" #'hl-todo-next
:m "[t" #'hl-todo-previous)
(:when (modulep! :ui workspaces)
:n "gt" #'+workspace:switch-next
:n "gT" #'+workspace:switch-previous
:n "]w" #'+workspace/switch-right
:n "[w" #'+workspace/switch-left)
(:when (modulep! :ui tabs)
:n "gt" #'+tabs:next-or-goto
2021-06-06 17:49:26 -04:00
:n "gT" #'+tabs:previous-or-goto)
;; custom vim-unmpaired-esque keys
2019-10-30 22:26:00 -04:00
:m "]#" #'+evil/next-preproc-directive
:m "[#" #'+evil/previous-preproc-directive
:m "]a" #'evil-forward-arg
:m "[a" #'evil-backward-arg
:m "]c" #'+evil/next-comment
:m "[c" #'+evil/previous-comment
:m "]e" #'next-error
:m "[e" #'previous-error
:n "]F" #'+evil/next-frame
:n "[F" #'+evil/previous-frame
:m "]h" #'outline-next-visible-heading
:m "[h" #'outline-previous-visible-heading
2019-10-30 22:26:00 -04:00
:m "]m" #'+evil/next-beginning-of-method
:m "[m" #'+evil/previous-beginning-of-method
:m "]M" #'+evil/next-end-of-method
:m "[M" #'+evil/previous-end-of-method
:n "[o" #'+evil/insert-newline-above
:n "]o" #'+evil/insert-newline-below
:n "gp" #'+evil/reselect-paste
:v "gp" #'+evil/alt-paste
:nv "g@" #'+evil:apply-macro
:nv "gc" #'evilnc-comment-operator
:nv "gO" #'imenu
:nv "gx" #'evil-exchange
:nv "gy" #'+evil:yank-unindented
:n "g=" #'evil-numbers/inc-at-pt
:n "g-" #'evil-numbers/dec-at-pt
:v "g=" #'evil-numbers/inc-at-pt-incremental
:v "g-" #'evil-numbers/dec-at-pt-incremental
:v "g+" #'evil-numbers/inc-at-pt
(:when (modulep! :tools lookup)
:nv "K" #'+lookup/documentation
:nv "gd" #'+lookup/definition
:nv "gD" #'+lookup/references
:nv "gf" #'+lookup/file
:nv "gI" #'+lookup/implementations)
(:when (modulep! :tools eval)
:nv "gr" #'+eval:region
:n "gR" #'+eval/buffer
:v "gR" #'+eval:replace-region
;; Restore these keybinds, since the blacklisted/overwritten gr/gR will
;; undo them:
(:after compile
:map (compilation-mode-map compilation-minor-mode-map)
:n "gr" #'recompile)
(:after dired
:map dired-mode-map
:n "gr" #'revert-buffer)
(:after notmuch
:map notmuch-common-keymap
:n "gr" #'notmuch-refresh-this-buffer
:n "gR" #'notmuch-poll-and-refresh-this-buffer)
(:after elfeed
:map elfeed-search-mode-map
:n "gr" #'elfeed-search-update--force
:n "gR" #'elfeed-search-fetch)
(:after eglot
:map eglot-mode-map
:nv "gd" #'+lookup/definition
:nv "gD" #'+lookup/references))
;; custom evil keybinds
:nv "zn" #'+evil:narrow-buffer
:n "zN" #'doom/widen-indirectly-narrowed-buffer
:n "zx" #'kill-current-buffer
:n "ZX" #'doom/save-and-kill-buffer
;; don't leave visual mode after shifting
:v "<" #'+evil/shift-left ; vnoremap < <gv
:v ">" #'+evil/shift-right ; vnoremap > >gv
;; window management (prefix "C-w")
(:map evil-window-map
;; Navigation
"C-h" #'evil-window-left
"C-j" #'evil-window-down
"C-k" #'evil-window-up
"C-l" #'evil-window-right
"C-w" #'other-window
;; Extra split commands
"S" #'+evil/window-split-and-follow
"V" #'+evil/window-vsplit-and-follow
;; Swapping windows
"H" #'+evil/window-move-left
"J" #'+evil/window-move-down
"K" #'+evil/window-move-up
"L" #'+evil/window-move-right
"C-S-w" #'ace-swap-window
;; Window undo/redo
(:prefix "m"
"m" #'doom/window-maximize-buffer
"v" #'doom/window-maximize-vertically
"s" #'doom/window-maximize-horizontally)
"u" #'winner-undo
"C-u" #'winner-undo
"C-r" #'winner-redo
"o" #'doom/window-enlargen
;; Delete window
"d" #'evil-window-delete
"C-C" #'ace-delete-window
"T" #'tear-off-window)
;; text objects
:textobj "a" #'evil-inner-arg #'evil-outer-arg
:textobj "B" #'evil-textobj-anyblock-inner-block #'evil-textobj-anyblock-a-block
:textobj "c" #'evilnc-inner-comment #'evilnc-outer-commenter
:textobj "f" #'+evil:defun-txtobj #'+evil:defun-txtobj
:textobj "g" #'+evil:whole-buffer-txtobj #'+evil:whole-buffer-txtobj
:textobj "i" #'evil-indent-plus-i-indent #'evil-indent-plus-a-indent
:textobj "j" #'evil-indent-plus-i-indent-up-down #'evil-indent-plus-a-indent-up-down
:textobj "k" #'evil-indent-plus-i-indent-up #'evil-indent-plus-a-indent-up
2020-10-27 23:18:06 -04:00
:textobj "q" #'+evil:inner-any-quote #'+evil:outer-any-quote
2020-02-04 13:58:43 -05:00
:textobj "u" #'+evil:inner-url-txtobj #'+evil:outer-url-txtobj
:textobj "x" #'evil-inner-xml-attr #'evil-outer-xml-attr
2021-03-27 18:08:56 -04:00
;; evil-easymotion
(:after evil-easymotion
:m "gs" evilem-map
(:map evilem-map
"a" (evilem-create #'evil-forward-arg)
"A" (evilem-create #'evil-backward-arg)
"s" #'evil-avy-goto-char-2
2020-07-21 16:18:46 -04:00
"SPC" (cmd! (let ((current-prefix-arg t)) (evil-avy-goto-char-timer)))
"/" #'evil-avy-goto-char-timer))
;; evil-snipe
(:after evil-snipe
:map evil-snipe-parent-transient-map
"C-;" (cmd! (require 'evil-easymotion)
(call-interactively
(evilem-create #'evil-snipe-repeat
:bind ((evil-snipe-scope 'whole-buffer)
(evil-snipe-enable-highlight)
(evil-snipe-enable-incremental-highlight))))))
;; evil-surround
:v "S" #'evil-surround-region
:o "s" #'evil-surround-edit
:o "S" #'evil-Surround-edit
;; evil-lion
:n "gl" #'evil-lion-left
:n "gL" #'evil-lion-right
:v "gl" #'evil-lion-left
:v "gL" #'evil-lion-right
;; Emulation of Vim's omni-completion keybinds
(:unless evil-disable-insert-state-bindings
(:prefix "C-x"
(:when (modulep! :completion company)
:i "C-l" #'+company/whole-lines
:i "C-k" #'+company/dict-or-keywords
:i "C-f" #'company-files
:i "C-]" #'company-etags
:i "s" #'company-ispell
:i "C-s" #'company-yasnippet
:i "C-o" #'company-capf
:i "C-n" #'+company/dabbrev
:i "C-p" #'+company/dabbrev-code-previous)
(:when (modulep! :completion corfu)
:i "C-l" #'cape-line
:i "C-k" #'cape-keyword
:i "C-f" #'cape-file
:i "C-]" #'complete-tag
:i "s" #'cape-dict
:i "C-s" #'yasnippet-capf
:i "C-o" #'completion-at-point
:i "C-n" #'cape-dabbrev
:i "C-p" #'+corfu/dabbrev-this-buffer))))