dotfiles/emacs/.emacs.d/config/init-completion.el

165 lines
6.2 KiB
EmacsLisp

;; -*- lexical-binding: t; -*-
;; Nicer minibuffer completion
;; First Selectrum, which provides the core incremental minibuffer completion engine
(use-package selectrum
:config
(selectrum-mode 1)
(leader-def-key "z" #'selectrum-repeat))
;; Then prescient, which adds the ability to sort and filter completions
(use-package selectrum-prescient
:after selectrum
:config
(selectrum-prescient-mode 1)
(prescient-persist-mode 1))
;; Marginalia adds annotations to completion candidates
(use-package marginalia
:demand t
:config
(marginalia-mode 1)
;; When using Selectrum, ensure that Selectrum is refreshed when cycling annotations.
(advice-add #'marginalia-cycle :after
(lambda ()
(when (bound-and-true-p selectrum-mode) (selectrum-exhibit))))
(add-to-list 'marginalia-prompt-categories '("Find file:" . project-file))
(add-to-list 'marginalia-prompt-categories '("Find dir:" . project-file))
(add-to-list 'marginalia-prompt-categories '("Switch to project" . file))
(add-to-list 'marginalia-prompt-categories '("recipe\\|package" . straight))
(add-to-list 'marginalia-prompt-categories '("Password entry" . password-store))
:general
(minibuffer-local-map "M-A" #'marginalia-cycle)
:custom
(marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)))
;; Embark adds context actions to completion candidates (and other things!)
(use-package embark
:config
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (caar targets) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t))))
(embark-define-keymap embark-straight-map
"Keymap for actions for straight.el"
("u" straight-visit-package-website)
("r" straight-get-recipe)
("i" straight-use-package)
("c" straight-check-package)
("F" straight-pull-package)
("f" straight-fetch-package)
("p" straight-push-package)
("n" straight-normalize-package)
("m" straight-merge-package))
(add-to-list 'embark-keymap-alist '(straight . embark-straight-map))
(embark-define-keymap embark-password-store-actions
"Keymap for actions for password-store."
("c" password-store-copy)
("f" password-store-copy-field)
("i" password-store-insert)
("I" password-store-generate)
("r" password-store-rename)
("e" password-store-edit)
("k" password-store-remove)
("U" password-store-url))
(add-to-list 'embark-keymap-alist '(password-store . embark-password-store-actions))
;; Add identifiers in LSP-mode as their own target type
(with-eval-after-load 'lsp-mode
(defun embark-target-lsp-identifier-at-point ()
(when lsp-mode
(when-let ((sym (embark-target-identifier-at-point)))
(cons 'lsp-identifier (cdr sym)))))
(add-to-list 'embark-target-finders 'embark-target-lsp-identifier-at-point)
(embark-define-keymap embark-lsp-identifier-actions
"Keymap for actions on LSP identifiers."
:parent embark-identifier-map
("a" lsp-execute-code-action)
("s" lsp-describe-thing-at-point))
(add-to-list 'embark-keymap-alist '(lsp-identifier . embark-lsp-identifier-actions))
(add-to-list 'embark-target-injection-hooks '(lsp-execute-code-action embark--ignore-target))
(add-to-list 'embark-target-injection-hooks '(lsp-describe-thing-at-point embark--ignore-target)))
:general
("C-." #'embark-act)
("M-." #'embark-dwim)
('normal "C-." #'embark-act)
('normal "M-." #'embark-dwim)
(embark-file-map "s" #'sudo-edit-find-file
"l" #'vlf
"g" #'magit-file-dispatch)
('normal embark-collect-mode-map
"TAB" #'forward-button
"?" #'describe-mode
"A" #'embark-collect-direct-action-minor-mode
"S" #'tabulated-list-sort
"a" #'embark-act
"b" #'backward-button
"e" #'embark-export
"f" #'forward-button
"gr" #'revert-buffer
"n" #'next-line
"p" #'previous-line
"q" #'quit-window
"s" #'isearch-forward
"v" #'embark-collect-toggle-view
"z" #'embark-collect-zebra-minor-mode
"{" #'tabulated-list-narrow-current-column
"}" #'tabulated-list-widen-current-column
"<backtab>" #'backward-button)
:custom
(embark-prompter 'embark-keymap-prompter)
(embark-indicators '(embark-which-key-indicator
embark-highlight-indicator
embark-isearch-highlight-indicator)))
;; Consult adds a bunch of completing-read based utilities
(use-package consult
:after selectrum
:commands (consult-xref)
:init
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:custom
(consult-project-root-function #'projectile-project-root)
(consult-find-args "find . -not ( -wholename */.git/* -prune )")
(consult-config '((consult-ripgrep :preview-key nil)
(consult-grep :preview-key nil)))
:general
([remap switch-to-buffer] #'consult-buffer)
([remap imenu] #'consult-imenu)
([remap projectile-ripgrep] #'consult-ripgrep)
([remap projectile-grep] #'consult-grep)
("C-c p" #'consult-yank-from-kill-ring))
(use-package consult-flycheck
:after flycheck
:general
(flycheck-command-map "!" #'consult-flycheck))
(use-package embark-consult
:defer 1)
;; Make grep-like embark collect buffers editable
(use-package wgrep
:general
(grep-mode-map "C-x C-q" #'wgrep-change-to-wgrep-mode))
(provide 'init-completion)