232 lines
8.5 KiB
EmacsLisp
232 lines
8.5 KiB
EmacsLisp
;; -*- lexical-binding: t; -*-
|
|
|
|
;; Nicer minibuffer completion
|
|
|
|
;; First Vertico, which provides the core incremental minibuffer completion engine
|
|
(use-package vertico
|
|
:straight (:files (:defaults "extensions/vertico-repeat.el"
|
|
"extensions/vertico-directory.el"))
|
|
:init
|
|
(vertico-mode))
|
|
|
|
(use-package vertico-repeat
|
|
:straight (:type built-in)
|
|
:after vertico
|
|
:config
|
|
(add-hook 'minibuffer-setup-hook #'vertico-repeat-save)
|
|
:general
|
|
(leader-map "r" #'vertico-repeat))
|
|
|
|
(use-package vertico-directory
|
|
:straight (:type built-in)
|
|
:after vertico
|
|
:general
|
|
(vertico-map "RET" #'vertico-directory-enter
|
|
"DEL" #'vertico-directory-delete-char
|
|
"M-DEL" #'vertico-directory-delete-word)
|
|
;; Tidy shadowed file names
|
|
:hook (rfn-eshadow-update-overlay . vertico-directory-tidy))
|
|
|
|
;; Save history in order to persist sort order across emacs sessions
|
|
(use-package savehist
|
|
:straight (:type built-in)
|
|
:config
|
|
(savehist-mode 1)
|
|
:custom
|
|
(savehist-additional-variables '(projectile-project-command-history
|
|
evil-jumps-history
|
|
vertico-repeat-history)))
|
|
|
|
;; Then orderless, which adds the ability to filter completions in an intuitive way
|
|
(use-package orderless
|
|
:ensure t
|
|
:custom
|
|
(completion-styles '(orderless basic))
|
|
(completion-category-overrides '((file (styles basic partial-completion)))))
|
|
|
|
;; Marginalia adds annotations to completion candidates
|
|
(use-package marginalia
|
|
:demand t
|
|
:config
|
|
(marginalia-mode 1)
|
|
(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
|
|
;; Put xref targets at the top of the list in programming modes
|
|
(defun embark-prod-mode-hook ()
|
|
(setq-local embark-target-finders (remove #'embark-target-identifier-at-point embark-target-finders))
|
|
(add-to-list 'embark-target-finders #'embark-target-identifier-at-point))
|
|
(add-hook 'prog-mode-hook #'embark-prod-mode-hook)
|
|
(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))))
|
|
(defvar-keymap embark-straight-map
|
|
:doc "Keymap for actions for straight.el"
|
|
:parent embark-general-map
|
|
"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))
|
|
(with-eval-after-load 'pass
|
|
(defun embark-target-finder-pass ()
|
|
"Identify password-store entries at point."
|
|
(when-let ((entry (and (eq major-mode 'pass-mode)
|
|
(pass-closest-entry))))
|
|
`(password-store . ,entry)))
|
|
(add-to-list 'embark-target-finders #'embark-target-finder-pass)
|
|
(defvar-keymap embark-password-store-actions
|
|
:doc "Keymap for actions for password-store."
|
|
:parent embark-general-map
|
|
"c" #'password-store-copy
|
|
"RET" #'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-to-list 'embark-target-injection-hooks '(xref-find-references embark--ignore-target))
|
|
(defun embark-target-finder-forge ()
|
|
"Identify Forge commits/issues/PRs at point."
|
|
(when-let ((target (and
|
|
(fboundp 'forge--browse-target)
|
|
(forge--browse-target))))
|
|
`(forge ,(or
|
|
(and (stringp target) target)
|
|
(ignore-errors (forge-get-url target))
|
|
(s-chomp (thing-at-point 'line t)))
|
|
,(line-beginning-position)
|
|
. ,(line-end-position))))
|
|
(defun embark-forge-magit-setup ()
|
|
(make-local-variable 'embark-target-finders)
|
|
(add-to-list 'embark-target-finders #'embark-target-finder-forge))
|
|
(add-hook 'magit-mode-hook #'embark-forge-magit-setup)
|
|
(defvar-keymap embark-forge-actions
|
|
:doc "Keymap for actions for forge."
|
|
:parent embark-general-map
|
|
"RET" #'forge-browse
|
|
"y" #'forge-copy-url-at-point-as-kill)
|
|
(add-to-list 'embark-keymap-alist '(forge . embark-forge-actions))
|
|
:general
|
|
((emacs normal motion insert visual) "C-." #'embark-act)
|
|
((emacs normal motion insert visual) "M-." #'embark-dwim)
|
|
("C-." #'embark-act)
|
|
("M-." #'embark-dwim)
|
|
(embark-general-map "C-k" #'browse-url-or-search
|
|
"/" #'consult-line)
|
|
(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
|
|
:init
|
|
(setq xref-show-xrefs-function #'consult-xref
|
|
xref-show-definitions-function #'consult-xref)
|
|
:custom
|
|
(consult-project-function #'projectile-project-root)
|
|
(consult-find-args "find . -not ( -wholename */.git/* -prune )")
|
|
(consult-narrow-key "<")
|
|
: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)
|
|
(minibuffer-local-map "M-r" #'consult-history))
|
|
|
|
(use-package consult-projectile
|
|
:after (consult projectile)
|
|
:commands (consult-projectile)
|
|
:general
|
|
(projectile-command-map "RET" #'consult-projectile))
|
|
|
|
|
|
(use-package consult-eglot
|
|
:after (consult eglot)
|
|
:general
|
|
(eglot-prefix-map "s" #'consult-eglot-symbols))
|
|
|
|
(use-package consult-org-roam
|
|
:after (consult org-roam)
|
|
:config
|
|
(consult-org-roam-mode 1)
|
|
:custom
|
|
(consult-org-roam-grep-func #'consult-ripgrep)
|
|
(consult-org-roam-buffer-after-buffers t)
|
|
:general
|
|
(org-roam-commands-map "b" #'consult-org-roam-backlinks
|
|
"B" #'consult-org-roam-backlinks-recursive
|
|
"l" #'consult-org-roam-forward-links))
|
|
|
|
(use-package embark-consult
|
|
:general
|
|
(leader-map "/" embark-consult-search-map))
|
|
|
|
;; 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)
|