doomemacs/modules/editor/evil/init.el

363 lines
9.7 KiB
EmacsLisp
Raw Normal View History

;;; editor/evil/init.el -*- lexical-binding: t; -*-
(defvar evil-collection-key-blacklist)
;; We load evil-collection ourselves for these reasons:
;;
;; 1. To truly lazy load it. Some of its modules, like
;; evil-collection-{elisp-mode,buff-menu} are loaded immediately, because
;; Emacs loads their packages immediately, which pulls in all of
;; evil-collection (and other packages with it, sometimes).
;; 2. This ensures a predictable load order, versus lazy loading using :defer or
;; :after-call. This means users can use (after! org ...) and be sure that
;; their changes will override evil-collection's.
;; 3. Ideally, we'd do away with evil-collection entirely. It changes too often,
;; introduces breaking bugs too frequently, and I don't agree with all their
;; design choices. Regardless, it does more good than trouble, so it may be
;; here to stay.
;; 4. Adds `+evil-collection-disabled-list', to make it easier for users to
;; disable modules, and to reduce the effort required to maintain our copy of
;; `evil-collection-list' (now I can just copy it from time to time).
(when (and (not noninteractive)
refactor: introduce doom-context Introduces a system to announce what execution contexts are active, so I can react appropriately, emit more helpful logs/warnings in the case of issues, and throw more meaningful errors. * bin/doom: load module CLIs in the 'modules' context. * lisp/cli/doctor.el: load package files in 'packages' context. * lisp/doom-cli.el: - (doom-before-init-hook, doom-after-init-hook): trigger hooks at the correct time. This may increase startup load time, as the benchmark now times more of the startup process. - (doom-cli-execute, doom-cli-context-execute, doom-cli-context-restore, doom-cli-context-parse, doom-cli--output-benchmark-h, doom-cli-call, doom-cli--restart, doom-cli-load, run!): remove redundant context prefix in debug logs, it's now redundant with doom-context, which doom-log now prefixes them with. * lisp/doom-lib.el (doom-log): prefix doom-context to doom-log output, unless it starts with :. * lisp/doom-packages.el (package!, doom-packages--read): throw error if not used in a packages.el file or in the context of our package manager. * lisp/doom-profiles.el (doom-profile--generate-init-vars, doom-profile--generate-load-modules): use modules doom-context instead of doom-init-time to detect startup. * lisp/doom-start.el (doom-load-packages-incrementally-h): move function closer to end of doom-after-init-hook. * lisp/doom.el: - (doom-before-init-hook, doom--set-initial-values-h, doom--begin-init-h): rename doom--set-initial-values-h to doom--begin-init-h and ensure it runs as late in doom-before-init-hook as possible, as that is the point where Doom's "initialization" formally begins. - (doom-after-init-hook): don't trigger at the end of command-line-1 in non-interactive sessions. This will be triggered manually in doom-cli.el's run!. * lisp/lib/config.el (doom/reload, doom/reload-autoloads, doom/reload-env): use 'reload' context for reload commands. * modules/lang/emacs-lisp/autoload.el (+emacs-lisp-eval): use 'eval' context. * modules/lang/org/config.el: remove doom-reloading-p; check for 'reload' doom context instead.
2022-09-24 12:38:25 +02:00
(not (doom-context-p 'reload))
(modulep! +everywhere))
(setq evil-collection-company-use-tng (modulep! :completion company +tng)
2020-04-08 15:54:16 -04:00
;; must be set before evil/evil-collection is loaded
evil-want-keybinding nil)
(defvar +evil-collection-disabled-list
'(anaconda-mode
buff-menu
calc
comint
company
custom
eldoc
elisp-mode
ert
free-keys
helm
help
image
indent
kotlin-mode
lispy
outline
replace
shortdoc
simple
slime
tab-bar)
"A list of `evil-collection' modules to ignore. See the definition of this
variable for an explanation of the defaults (in comments). See
`evil-collection-mode-list' for a list of available options.")
(defvar evil-collection-setup-minibuffer nil)
;; We do this ourselves, and better.
(defvar evil-collection-want-unimpaired-p nil)
;; Doom binds goto-reference on gD and goto-assignments on gA ourselves
(defvar evil-collection-want-find-usages-bindings-p nil)
;; Reduces keybind conflicts between outline-mode and org-mode (which is
;; derived from outline-mode).
(defvar evil-collection-outline-enable-in-minor-mode-p nil)
;; We handle loading evil-collection ourselves
(defvar evil-collection--supported-modes nil)
;; This has to be defined here since evil-collection doesn't autoload its own.
;; It must be updated whenever evil-collection updates theirs. Here's an easy
;; way to update it:
;;
;; (with-current-buffer
;; (url-retrieve-synchronously "https://raw.githubusercontent.com/emacs-evil/evil-collection/master/evil-collection.el" t t)
;; (goto-char (point-min))
;; (when (re-search-forward "^(defvar evil-collection--supported-modes\n[^(]+")
;; (let ((list (sexp-at-point)))
;; ;; Fixes
;; (when (assq 'pdf list)
;; (setf (alist-get 'pdf list) '(pdf-tools)))
;; (let ((diff (cl-set-difference evil-collection-mode-list list :test #'equal)))
;; (list (- (length list) (length evil-collection-mode-list))
;; diff)
;; (message "diff: %s" diff)
;; (kill-new (prin1-to-string list))))))
(defvar evil-collection-mode-list
`(2048-game
ag
alchemist
anaconda-mode
apropos
arc-mode
atomic-chrome
auto-package-update
beginend
bluetooth
bm
bookmark
(buff-menu "buff-menu")
bufler
calc
calendar
cider
cmake-mode
color-rg
comint
company
compile
consult
corfu
crdt
(csv "csv-mode")
(custom cus-edit)
cus-theme
dashboard
daemons
deadgrep
debbugs
debug
devdocs
dictionary
diff-hl
diff-mode
dired
dired-sidebar
disk-usage
distel
doc-view
docker
eat
ebib
ebuku
edbi
edebug
ediff
eglot
elpaca
ement
explain-pause-mode
eldoc
elfeed
elisp-mode
elisp-refs
elisp-slime-nav
embark
emms
,@(if (> emacs-major-version 28) '(emoji))
epa
ert
eshell
eval-sexp-fu
evil-mc
eww
fanyi
finder
flycheck
flymake
forge
free-keys
geiser
ggtags
git-timemachine
gited
gnus
go-mode
grep
guix
hackernews
helm
help
helpful
hg-histedit
hungry-delete
ibuffer
(image image-mode)
image-dired
image+
imenu
imenu-list
(indent "indent")
indium
info
ivy
js2-mode
,@(if (>= emacs-major-version 30) '(kmacro))
leetcode
lispy
lms
log-edit
log-view
lsp-ui-imenu
lua-mode
kotlin-mode
macrostep
man
(magit magit-repos magit-submodule)
magit-repos
magit-section
magit-todos
markdown-mode
monky
mpc
mpdel
mu4e
mu4e-conversation
neotree
newsticker
notmuch
nov
omnisharp
org
org-present
org-roam
osx-dictionary
outline
p4
(package-menu package)
pass
(pdf pdf-tools)
popup
proced
prodigy
profiler
python
quickrun
racer
racket-describe
realgud
reftex
replace
restclient
rg
ripgrep
rjsx-mode
robe
rtags
ruby-mode
scheme
scroll-lock
selectrum
sh-script
,@(if (> emacs-major-version 27) '(shortdoc))
simple
simple-mpc
slime
sly
snake
so-long
speedbar
tab-bar
tablist
tar-mode
telega
(term term ansi-term multi-term)
tetris
thread
tide
timer-list
transmission
trashed
tuareg
typescript-mode
vc-annotate
vc-dir
vc-git
vdiff
vertico
view
vlf
vterm
vundo
w3m
wdired
wgrep
which-key
woman
xref
xwidget
yaml-mode
youtube-dl
zmusic
(ztree ztree-diff)))
(defun +evil-collection-init (module &optional disabled-list)
"Initialize evil-collection-MODULE.
Unlike `evil-collection-init', this respects `+evil-collection-disabled-list',
and complains if a module is loaded too early (during startup)."
(unless (memq (or (car-safe module) module) disabled-list)
(doom-log "editor:evil: loading evil-collection-%s %s"
(or (car-safe module) module)
(if after-init-time "" "(too early!)"))
(with-demoted-errors "evil-collection error: %s"
(evil-collection-init (list module)))))
(defadvice! +evil-collection-disable-blacklist-a (fn)
:around #'evil-collection-vterm-toggle-send-escape ; allow binding to ESC
(let (evil-collection-key-blacklist)
(funcall-interactively fn)))
;; These modes belong to packages that Emacs always loads at startup, causing
;; evil-collection and it's co-packages to all load immediately. We avoid this
;; by loading them after evil-collection has first loaded...
(with-eval-after-load 'evil-collection
;; Don't let evil-collection interfere with certain keys
(setq evil-collection-key-blacklist
(append (list doom-leader-key doom-localleader-key
doom-leader-alt-key)
evil-collection-key-blacklist
(when (modulep! :tools lookup)
'("gd" "gf" "K"))
(when (modulep! :tools eval)
'("gr" "gR"))
'("[" "]" "gz" "<escape>")))
(evil-define-key* 'normal process-menu-mode-map
"q" #'kill-current-buffer
"d" #'process-menu-delete-process)
(mapc #'+evil-collection-init '(comint custom)))
;; ...or on first invokation of their associated major/minor modes.
(after! evil
;; Emacs loads these two packages immediately, at startup, which needlessly
;; convolutes load order for evil-collection-help.
(add-transient-hook! 'help-mode
(+evil-collection-init 'help))
(add-transient-hook! 'Buffer-menu-mode
(+evil-collection-init '(buff-menu "buff-menu")))
(add-transient-hook! 'calc-mode
(+evil-collection-init 'calc))
(add-transient-hook! 'image-mode
(+evil-collection-init 'image))
(add-transient-hook! 'emacs-lisp-mode
(+evil-collection-init 'elisp-mode))
(add-transient-hook! 'occur-mode
(+evil-collection-init 'replace))
(add-transient-hook! 'indent-rigidly
(+evil-collection-init '(indent "indent")))
(add-transient-hook! 'minibuffer-setup-hook
(when evil-collection-setup-minibuffer
(+evil-collection-init 'minibuffer)
(evil-collection-minibuffer-insert)))
(add-transient-hook! 'process-menu-mode
(+evil-collection-init '(process-menu simple)))
(add-transient-hook! 'shortdoc-mode
(+evil-collection-init 'shortdoc))
(add-transient-hook! 'tabulated-list-mode
(+evil-collection-init 'tabulated-list))
(add-transient-hook! 'tab-bar-mode
(+evil-collection-init 'tab-bar))
;; HACK Do this ourselves because evil-collection break's `eval-after-load'
;; load order by loading their target plugin before applying keys. This
;; makes it hard for end-users to overwrite these keybinds with a
;; simple `after!' or `with-eval-after-load'.
(dolist (mode evil-collection-mode-list)
(dolist (req (or (cdr-safe mode) (list mode)))
(with-eval-after-load req
(+evil-collection-init mode +evil-collection-disabled-list))))))