diff --git a/core/autoload/help.el b/core/autoload/help.el index ccbe8face..8f01f4a01 100644 --- a/core/autoload/help.el +++ b/core/autoload/help.el @@ -226,6 +226,8 @@ will be automatically appended to the result." #'+ivy-file-search) ((fboundp '+helm-file-search) #'+helm-file-search) + ((fboundp '+vertico-file-search) + #'+vertico-file-search) ((rgrep (read-regexp "Search for" (or initial-input 'grep-tag-default) diff --git a/core/autoload/projects.el b/core/autoload/projects.el index 0af779171..93c3117e8 100644 --- a/core/autoload/projects.el +++ b/core/autoload/projects.el @@ -128,11 +128,13 @@ If DIR is not a project, it will be indexed (but not cached)." (if (doom-module-p :completion 'ivy) #'counsel-projectile-find-file #'projectile-find-file))) - ((fboundp 'counsel-file-jump) ; ivy only + ((and (bound-and-true-p ivy-mode) + (fboundp 'counsel-file-jump)) (call-interactively #'counsel-file-jump)) ((project-current nil dir) (project-find-file-in nil nil dir)) - ((fboundp 'helm-find-files) + ((and (bound-and-true-p helm-mode) + (fboundp 'helm-find-files)) (call-interactively #'helm-find-files)) ((call-interactively #'find-file))))) diff --git a/docs/modules.org b/docs/modules.org index 4b1c91c5f..2187b1cb5 100644 --- a/docs/modules.org +++ b/docs/modules.org @@ -46,6 +46,7 @@ completion. + helm =+fuzzy +childframe= - *Another* search engine for love and life + ido - The /other/ *other* search engine for love and life + [[file:../modules/completion/ivy/README.org][ivy]] =+fuzzy +prescient +childframe +icons= - /The/ search engine for love and life ++ [[file:../modules/completion/vertico/README.org][vertico]] =+icons= - The search engine of the future * :config Modules that configure Emacs one way or another, or focus on making it easier diff --git a/init.example.el b/init.example.el index 21381a1cd..2db8a0009 100644 --- a/init.example.el +++ b/init.example.el @@ -24,6 +24,7 @@ ;;helm ; the *other* search engine for love and life ;;ido ; the other *other* search engine... ivy ; a search engine for love and life + ;;vertico ; the search engine of the future :ui ;;deft ; notational velocity for Emacs diff --git a/modules/app/irc/autoload/irc.el b/modules/app/irc/autoload/irc.el index fac63139f..b44c47070 100644 --- a/modules/app/irc/autoload/irc.el +++ b/modules/app/irc/autoload/irc.el @@ -68,8 +68,19 @@ workspace for it." argument) is non-nil only show channels in current server." (interactive "P") (call-interactively - (cond ((featurep! :completion ivy) #'+irc/ivy-jump-to-channel) - ((user-error "No jump-to-channel backend is enabled. Enable ivy!"))))) + (cond ((featurep! :completion ivy) #'+irc/ivy-jump-to-channel) + ((featurep! :completion vertico) #'+irc/vertico-jump-to-channel) + ((user-error "No jump-to-channel backend is enabled. Enable vertico or ivy!"))))) + +;;;###autoload +(defun +irc--circe-all-buffers () + (cl-loop with servers = (circe-server-buffers) + for server in servers + collect server + nconc + (with-current-buffer server + (cl-loop for buf in (circe-server-chat-buffers) + collect buf)))) ;;;###autoload (defun +irc/tracking-next-buffer () diff --git a/modules/app/irc/autoload/vertico.el b/modules/app/irc/autoload/vertico.el new file mode 100644 index 000000000..c97edece9 --- /dev/null +++ b/modules/app/irc/autoload/vertico.el @@ -0,0 +1,23 @@ +;;; app/irc/autoload/vertico.el -*- lexical-binding: t; -*- +;;;###if (featurep! :completion vertico) + +;;;###autoload +(defun +irc/vertico-jump-to-channel () + "Jump to an open channel or server buffer with vertico." + (interactive) + (require 'consult) + (consult--multi (list (plist-put (copy-sequence +irc--consult-circe-source) + :hidden nil)) + :narrow nil + :require-match t + :prompt "Jump to:" + :sort nil)) + +;;;###autoload +(defvar +irc--consult-circe-source + `(:name "circe" + :hidden t + :narrow ?c + :category buffer + :state ,#'consult--buffer-state + :items ,(lambda () (mapcar #'buffer-name (+irc--circe-all-buffers))))) diff --git a/modules/app/irc/config.el b/modules/app/irc/config.el index a232c9fa2..ad079d386 100644 --- a/modules/app/irc/config.el +++ b/modules/app/irc/config.el @@ -141,6 +141,10 @@ playback.") ;; Fail gracefully if not in a circe buffer (global-set-key [remap tracking-next-buffer] #'+irc/tracking-next-buffer) + (when (featurep! :completion vertico) + (after! consult + (add-to-list 'consult-buffer-sources '+irc--consult-circe-source 'append))) + (map! :localleader (:map circe-mode-map "a" #'tracking-next-buffer diff --git a/modules/checkers/spell/README.org b/modules/checkers/spell/README.org index 5312c8d59..b0fb6971f 100644 --- a/modules/checkers/spell/README.org +++ b/modules/checkers/spell/README.org @@ -46,7 +46,7 @@ This module has no dedicated maintainers. + [[https://github.com/d12frosted/flyspell-correct][flyspell-correct]] + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-ivy-interface][flyspell-correct-ivy]] (=completion/ivy=) + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-helm-interface][flyspell-correct-helm]] (=completion/helm=) - + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-popup-interface][flyspell-correct-popup]] (if *neither* =completion/ivy= or =completion/helm=) + + [[https://github.com/d12frosted/flyspell-correct#flyspell-correct-popup-interface][flyspell-correct-popup]] (if *neither* =completion/ivy=, =completion/helm= or =completion/vertico=) + [[https://github.com/rolandwalker/flyspell-lazy][flyspell-lazy]] + else + [[https://gitlab.com/ideasman42/emacs-spell-fu][spell-fu]] diff --git a/modules/checkers/spell/autoload/+spell-fu.el b/modules/checkers/spell/autoload/+spell-fu.el index d90eeeebe..33450eeab 100644 --- a/modules/checkers/spell/autoload/+spell-fu.el +++ b/modules/checkers/spell/autoload/+spell-fu.el @@ -62,7 +62,8 @@ (save-current-buffer (ispell-accept-buffer-local-defs)) (if (not (or (featurep! :completion ivy) - (featurep! :completion helm))) + (featurep! :completion helm) + (featurep! :completion vertico))) (call-interactively #'ispell-word) (cl-destructuring-bind (start . end) (or (bounds-of-thing-at-point 'word) diff --git a/modules/checkers/spell/config.el b/modules/checkers/spell/config.el index aaf5cf4c1..5f94032c4 100644 --- a/modules/checkers/spell/config.el +++ b/modules/checkers/spell/config.el @@ -234,7 +234,8 @@ e.g. proselint and langtool." (require 'flyspell-correct-helm nil t))) ((and (featurep! :completion ivy) (require 'flyspell-correct-ivy nil t))) - ((require 'flyspell-correct-popup nil t) + ((featurep! :completion vertico)) ; vertico doesn't need any extra configuration + ((require 'flyspell-correct-popup nil t) ; only use popup if no compatible completion UI is enabled (setq flyspell-popup-correct-delay 0.8) (define-key popup-menu-keymap [escape] #'keyboard-quit)))) diff --git a/modules/checkers/spell/packages.el b/modules/checkers/spell/packages.el index 5917b8d35..f91114ce7 100644 --- a/modules/checkers/spell/packages.el +++ b/modules/checkers/spell/packages.el @@ -3,10 +3,11 @@ (if (not (featurep! +flyspell)) (package! spell-fu :pin "1abcb5594e1bfe35716d29e64523e4cebdce737c") - (package! flyspell-correct :pin "404233604439117301562deadc952fe82cb02120") + (package! flyspell-correct :pin "00357953a736e21d0a1c8d76f5605820990544fe") (cond ((featurep! :completion ivy) (package! flyspell-correct-ivy)) ((featurep! :completion helm) (package! flyspell-correct-helm)) - ((package! flyspell-correct-popup))) + ((not (featurep! :completion vertico)) + (package! flyspell-correct-popup))) (package! flyspell-lazy :pin "0fc5996bcee20b46cbd227ae948d343c3bef7339")) diff --git a/modules/completion/vertico/README.org b/modules/completion/vertico/README.org new file mode 100644 index 000000000..7b6cb339a --- /dev/null +++ b/modules/completion/vertico/README.org @@ -0,0 +1,221 @@ +#+TITLE: completion/vertico +#+DATE: July 25, 2021 +#+SINCE: v3.0.0 +#+STARTUP: inlineimages + +* Table of Contents :TOC_3:noexport: +- [[#description][Description]] + - [[#maintainers][Maintainers]] + - [[#module-flags][Module Flags]] + - [[#plugins][Plugins]] +- [[#prerequisites][Prerequisites]] +- [[#features][Features]] + - [[#vertico-keybindings][Vertico keybindings]] + - [[#jump-to-navigation][Jump-to navigation]] + - [[#project-search--replace][Project search & replace]] + - [[#in-buffer-searching][In-buffer searching]] + - [[#vertico-integration-for-various-completing-commands][Vertico integration for various completing commands]] + - [[#general][General]] + - [[#jump-to-files-buffers-or-projects][Jump to files, buffers or projects]] + - [[#search][Search]] + - [[#marginalia][Marginalia]] + - [[#orderless-filtering][Orderless filtering]] +- [[#configuration][Configuration]] + +* Description +This module enhances the Emacs search and completion experience, and also +provides a united interface for project search and replace, powered by [[https://github.com/BurntSushi/ripgrep/][ripgrep]]. + +It does this with several modular packages focused on enhancing the built-in +~completing-read~ interface, rather than replacing it with a parallel ecosystem +like =ivy= and =helm= do. The primary packages are: + ++ Vertico, which provides the vertical completion user interface ++ Consult, which provides a suite of useful commands using ~completing-read~ ++ Embark, which provides a set of minibuffer actions ++ Marginalia, which provides annotations to completion candidates ++ Orderless, which provides better filtering methods + +** Maintainers ++ @iyefrat + +** Module Flags ++ =+icons= Adds icons to =file= and =buffer= category completion selections. + +** Plugins ++ [[https://github.com/minad/vertico][vertico]] ++ [[https://github.com/minad/consult][consult]] ++ [[https://github.com/oantolin/embark/][embark]] ++ [[https://github.com/oantolin/embark/][embark-consult]] ++ [[https://github.com/minad/marginalia][marginalia]] ++ [[https://github.com/oantolin/orderless][orderless]] ++ [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]] ++ [[https://github.com/minad/consult/][consult-flycheck]] (=:checkers syntax=) ++ [[https://github.com/iyefrat/all-the-icons-completion][all-the-icons-completion]] (=+icons=) + +* Prerequisites +This module has no prerequisites. + +* Features + +The packages in this module modify and use the built-in ~completing-read~ +function, which is used by any function that requires completion. Due to this +the full scope of these packages is too large to cover here and you are +encouraged to go and read their excellent documentation. We will detail +Doom-specific additions: + +** Vertico keybindings +When in an active Vertico completion session, the following doom added +keybindings are available: + +| Keybind | Description | +|-----------------------+----------------------------------------------------| +| =C-p= | Go to previous candidate | +| =C-n= | Go to next candidate | +| =C-k= | (evil) Go to previous candidate | +| =C-j= | (evil) Go to next candidate | +| =C-;= or = a= | Open an ~embark-act~ menu to chose a useful action | +| =C-c C-;= | export the current candidate list to a buffer | +| =C-SPC= | Preview the current candidate | +| =C-M-k= | (evil) Go to previous candidate and preview. | +| =C-M-j= | (evil) Go to next candidate and preview. | + +~embark-act~ will prompt you with a =which-key= menu with useful commands on the +selected candidate or candidate list, depending on the completion category. Note +that you can press =C-h= instead of choosing a command to filter through the +options with a Vertico buffer, that also has slightly more detailed descriptions +due to Marginalia annotations. + +** Jump-to navigation +This module provides an interface to navigate within a project using +=projectile=: + +https://assets.doomemacs.org/completion/vertico/projectile.png + +| Keybind | Description | +|----------------------+-------------------------------------| +| =SPC p f=, =SPC SPC= | Jump to file in project | +| =SPC f f=, =SPC .= | Jump to file from current directory | +| =SPC s i= | Jump to symbol in file | + +** Project search & replace +This module provides interactive text search and replace using ripgrep. + +| Keybind | Description | +|-----------+--------------------------| +| =SPC s p= | Search project | +| =SPC s P= | Search another project | +| =SPC s d= | Search this directory | +| =SPC s D= | Search another directory | + +https://assets.doomemacs.org/completion/vertico/search.png + +Prefixing these keys with the universal argument (=SPC u= for evil users; =C-u= +otherwise) changes the behavior of these commands, instructing the underlying +search engine to include ignored files. + +This module also provides Ex Commands for evil users: + +| Ex command | Description | +|------------------------+------------------------------------------------------------------| +| ~:pg[rep][!] [QUERY]~ | Search project (if ~!~, include hidden files) | +| ~:pg[rep]d[!] [QUERY]~ | Search from current directory (if ~!~, don't search recursively) | + +The optional `!` is equivalent to the universal argument for the previous +commands. + +----- + +On top of the usual Vertico keybindings, search commands also offer support for +exporting the current candidate list to an editable buffer =C-c C-e=. After +editing the changes can be committed with =C-c C-c= and aborted with =C-c C-k= +(alternatively =ZZ= and =ZQ=, for evil users). It uses =wgrep= for grep +searches, =wdired= for file searches, and =occur= for buffer searches. + +https://assets.doomemacs.org/completion/vertico/search-replace.png + +** In-buffer searching +This module provides some in buffer searching bindings: + ++ =SPC s s= (~isearch~) ++ =SPC s S= (~+vertico/search-symbol-at-point~ via ~consult-line~) ++ =SPC s b= (~consult-line~) + +https://assets.doomemacs.org/completion/vertico/buffer-search.png + +An ~occur-edit~ buffer can be opened from ~consult-line~ with =C-c C-e=. + +** Vertico integration for various completing commands +*** General +| Keybind | Description | +|----------------+-----------------------------| +| =M-x=, =SPC := | Enhanced M-x | +| =SPC '= | Resume last Vertico session | + +*** Jump to files, buffers or projects +| Keybind | Description | +|----------------------+---------------------------------------| +| =SPC RET= | Find bookmark | +| =SPC f f=, =SPC .= | Browse from current directory | +| =SPC p f=, =SPC SPC= | Find file in project | +| =SPC f r= | Find recently opened file | +| =SPC p p= | Open another project | +| =SPC b b=, =SPC ,= | Switch to buffer in current workspace | +| =SPC b B=, =SPC <= | Switch to buffer | + +=SPC b b= and =SPC ,= support changing the workspace you're selecting a buffer from +via [[https://github.com/minad/consult#narrowing-and-grouping][Consult narrowing]], e.g. if you're on the first workspace, you can switch to +selecting a buffer from the third workspace by typing =3 SPC= into the prompt, +or the last workspace by typing =0 SPC=. + +=SPC f f= and =SPC .= support exporting to a =wdired= buffer using =C-c C-e=. + +*** Search +| Keybind | Description | +|-----------+-------------------------------------------| +| =SPC p t= | List all TODO/FIXMEs in project | +| =SPC s b= | Search the current buffer | +| =SPC s d= | Search this directory | +| =SPC s D= | Search another directory | +| =SPC s i= | Search for symbol in current buffer | +| =SPC s p= | Search project | +| =SPC s P= | Search another project | +| =SPC s s= | Search the current buffer (incrementally) | + +** Marginalia +| Keybind | Description | +|---------+---------------------------------| +| =M-A= | Cycle between annotation levels | + +** Orderless filtering +When using orderless to filter through candidates, the default behaviour is for +each space separated input to match the candidate as a regular expression or +literally. + +Note that due to this style of matching, pressing tab does not expand the input +to the longest matching prefix (like shell completion), but rather uses the +first matched candidate as input. Filtering further is instead achieved by +pressing space and entering another input. In essence, when trying to match +=foobar.org=, instead of option 1., use option 2.: + +1. (BAD) Enter =foo TAB=, completes to =foobar.=, enter =org RET= +2. (GOOD) Enter =foo SPC org RET= + +Doom has some builtin [[https://github.com/oantolin/orderless#style-dispatchers][style dispatchers]] for more finegrained filtering, which +you can use to further specify each space separated input in the following ways: +| Input | Description | +|------------------+--------------------------------------------| +| =!foo= | match without literal input =foo= | +| =`bar= or =bar`= | match input =bar= as an initialism | +| ==baz= or =baz== | match only with literal input =baz= | +| =~qux= or =qux~= | match input =qux= with fuzzy/flex matching | + +* Configuration +If you want to further configure this module, here are some good places to start: + ++ Vertico provides several [[https://github.com/minad/vertico#extensions][extentions]] that can be used to extend it's interface ++ You can add more Marginalia annotation levels and change the existing ones by + editing ~marginalia-annotator-registry~ ++ You can change the available commands in Embark for category ~$cat~ by editing + ~embark-$cat-map~, and even add new categories. Note that you add categories + by defining them [[https://github.com/minad/marginalia/#adding-custom-annotators-or-classifiers][through marginalia]], and embark picks up on them. diff --git a/modules/completion/vertico/autoload/evil.el b/modules/completion/vertico/autoload/evil.el new file mode 100644 index 000000000..85e10ce03 --- /dev/null +++ b/modules/completion/vertico/autoload/evil.el @@ -0,0 +1,14 @@ +;; completion/vertico/autoload/evil.el -*- lexical-binding: t; -*- +;;;###if (featurep! :editor evil) + +;;;###autoload (autoload '+vertico:project-search "completion/vertico/autoload/evil" nil t) +(evil-define-command +vertico:project-search (query &optional all-files-p) + "Ex interface for `+vertico/project-search'." + (interactive "") + (+vertico/project-search all-files-p query)) + +;;;###autoload (autoload '+vertico:project-search-from-cwd "completion/vertico/autoload/evil" nil t) +(evil-define-command +vertico:project-search-from-cwd (query &optional recurse-p) + "Ex interface for `+vertico/project-search-from-cwd'." + (interactive "") + (+vertico/project-search-from-cwd (not recurse-p) query)) diff --git a/modules/completion/vertico/autoload/vertico.el b/modules/completion/vertico/autoload/vertico.el new file mode 100644 index 000000000..1c02f1909 --- /dev/null +++ b/modules/completion/vertico/autoload/vertico.el @@ -0,0 +1,148 @@ +;;; completion/vertico/autoload/vertico.el -*- lexical-binding: t; -*- + +;; To prevent "Unused lexical variable" warning from +vertico--company-capf--candidates-a +;;;###autoload +(defvar orderless-match-faces) + +;;;###autoload +(defadvice! +vertico--company-capf--candidates-a (fn &rest args) + "Highlight company matches correctly, and try default completion styles before +orderless." + :around 'company-capf--candidates + (let ((orderless-match-faces [completions-common-part]) + (completion-styles +vertico-company-completion-styles)) + (apply fn args))) + +;;;###autoload +(cl-defun +vertico-file-search (&key query in all-files (recursive t) prompt args) + "Conduct a file search using ripgrep. + +:query STRING + Determines the initial input to search for. +:in PATH + Sets what directory to base the search out of. Defaults to the current project's root. +:recursive BOOL + Whether or not to search files recursively from the base directory." + (declare (indent defun)) + (unless (executable-find "rg") + (user-error "Couldn't find ripgrep in your PATH")) + (require 'consult) + (setq deactivate-mark t) + (let* ((project-root (or (doom-project-root) default-directory)) + (directory (or in project-root)) + (args (split-string + (string-trim + (concat (if all-files "-uu") + (unless recursive "--maxdepth 1") + "--null --line-buffered --color=always --max-columns=500 --no-heading --line-number" + " --hidden -g !.git " + (mapconcat #'shell-quote-argument args " "))) + " ")) + (prompt (or prompt + (format "rg [%s]: " + (cond ((equal directory default-directory) + "./") + ((equal directory project-root) + (projectile-project-name)) + ((file-relative-name directory project-root)))))) + (query (or query + (when (doom-region-active-p) + (replace-regexp-in-string + "[! |]" (lambda (substr) + (cond ((and (string= substr " ") + (not (featurep! +fuzzy))) + " ") + ((string= substr "|") + "\\\\\\\\|") + ((concat "\\\\" substr)))) + (rxt-quote-pcre (doom-thing-at-point-or-region)))))) + (ripgrep-command (mapconcat #'identity `("rg" ,@args "." "-e ARG OPTS" ) " "))) + (consult--grep prompt ripgrep-command directory query))) + +;;;###autoload +(defun +vertico/project-search (&optional arg initial-query directory) + "Peforms a live project search from the project root using ripgrep. +If ARG (universal argument), include all files, even hidden or compressed ones, +in the search." + (interactive "P") + (+vertico-file-search :query initial-query :in directory :all-files arg)) + +;;;###autoload +(defun +vertico/project-search-from-cwd (&optional arg initial-query) + "Performs a live project search from the current directory. +If ARG (universal argument), include all files, even hidden or compressed ones." + (interactive "P") + (+vertico/project-search arg initial-query default-directory)) + +;;;###autoload +(defun +vertico/search-symbol-at-point () + (interactive) + (consult-line (thing-at-point 'symbol))) + +;;;###autoload +(defun +vertico/backward-updir () + "Delete char before or go up directory for file cagetory vertico buffers." + (interactive) + (let ((metadata (completion-metadata (minibuffer-contents) + minibuffer-completion-table + minibuffer-completion-predicate))) + (if (and (eq (char-before) ?/) + (eq (completion-metadata-get metadata 'category) 'file)) + (let ((new-path (minibuffer-contents))) + (delete-region (minibuffer-prompt-end) (point-max)) + (insert (abbreviate-file-name + (file-name-directory + (directory-file-name + (expand-file-name new-path)))))) + (call-interactively 'backward-delete-char)))) + +(defun +vertico--embark-target-package () + "Targets Doom's package! statements and returns the package name" + (when (or (derived-mode-p 'emacs-lisp-mode) (derived-mode-p 'org-mode)) + (save-excursion + (search-backward "(") + (when (looking-at "(\\s-*package!\\s-*\\(\\(\\sw\\|\\s_\\)+\\)\\s-*") + (let ((pkg (match-string 1))) + (set-text-properties 0 (length pkg) nil pkg) + `(package . ,pkg)))))) + +;;;###autoload +(defun +vertico/embark-export-write () + "Export the current vertico results to a writable buffer if possible. + +Supports exporting consult-grep to wgrep, file to wdeired, and consult-location to occur-edit" + (interactive) + (require 'wgrep) + (pcase-let ((`(,type . ,candidates) + (run-hook-with-args-until-success 'embark-candidate-collectors))) + (pcase type + ('consult-grep (let ((embark-after-export-hook #'wgrep-change-to-wgrep-mode)) + (embark-export))) + ('file (let ((embark-after-export-hook #'wdired-change-to-wdired-mode)) + (embark-export))) + ('consult-location (let ((embark-after-export-hook #'occur-edit-mode)) + (embark-export))) + (x (user-error "embark category %S doesn't support writable export" x))))) + +;;;###autoload +(defun +vertico/embark-preview () + "Previews candidate in vertico buffer, unless it's a consult command" + (interactive) + (unless (bound-and-true-p consult--preview-function) + (save-selected-window + (let ((embark-quit-after-action nil)) + (embark-default-action))))) + +;;;###autoload +(defun +vertico/next-candidate-preview (&optional n) + "Go forward N candidates and preivew" + (interactive) + (vertico-next (or n 1)) + (+vertico/embark-preview)) + +;;;###autoload +(defun +vertico/previous-candidate-preview (&optional n) + "Go backward N candidates and preivew" + (interactive) + (vertico-previous (or n 1)) + (+vertico/embark-preview)) diff --git a/modules/completion/vertico/autoload/workspaces.el b/modules/completion/vertico/autoload/workspaces.el new file mode 100644 index 000000000..90586aa2c --- /dev/null +++ b/modules/completion/vertico/autoload/workspaces.el @@ -0,0 +1,53 @@ +;;; completion/vertico/autoload/workspaces.el -*- lexical-binding: t; -*- +;;;###if (featurep! :ui workspaces) + +;;;###autoload +(defun +vertico--workspace-nth-source (n) + "Generate a consult buffer source for buffers in the NTH workspace" + (cond ((numberp n) + `(:name ,(nth n (+workspace-list-names)) + :hidden ,(not (string= (+workspace-current-name) (nth n (+workspace-list-names)))) + :narrow ,(string-to-char (number-to-string (1+ n))) + :category buffer + :state ,#'consult--buffer-state + :items ,(lambda () (mapcar #'buffer-name (+workspace-buffer-list (nth n (+workspace-list))))))) + ((eq n 'final) + `(:name ,(car (last (+workspace-list-names))) + :hidden t + :narrow ?0 + :category buffer + :state ,#'consult--buffer-state + :items ,(lambda () (mapcar #'buffer-name (+workspace-buffer-list (car (last (+workspace-list)))))))) + (t + (user-error "invalid workspace source %s" n)))) + +;;;###autoload +(defun +vertico--workspace-generate-sources () + "Generate list of consult buffer sources for all workspaces" + (mapcar #'+vertico--workspace-nth-source '(0 1 2 3 4 5 6 7 8 final))) + +(autoload 'consult--multi "consult") +;;;###autoload +(defun +vertico/switch-workspace-buffer () + "Switch to another buffer in the same workspace. + +Use consult narrowing with another workspace number to open a buffer from that workspace + BUG but it opens it in the current workspace (ivy also does this, but who cares)" + (interactive) + (when-let (buffer (consult--multi (+vertico--workspace-generate-sources) + :require-match + (confirm-nonexistent-file-or-buffer) + :prompt (format "Switch to buffer (%s): " + (+workspace-current-name) + :history 'consult--buffer-history + :sort nil))) + ;; When the buffer does not belong to a source, + ;; create a new buffer with the name. + (unless (cdr buffer) + (funcall consult--buffer-display (car buffer))))) + +;;;###autoload +(defun +vertico-embark-open-in-new-workspace (x) + "Open X (a file) in a new workspace." + (+workspace/new) + (find-file x)) diff --git a/modules/completion/vertico/config.el b/modules/completion/vertico/config.el new file mode 100644 index 000000000..0b6cc6b9c --- /dev/null +++ b/modules/completion/vertico/config.el @@ -0,0 +1,173 @@ +;;; completion/vertico/config.el -*- lexical-binding: t; -*- + +(defvar +vertico-company-completion-styles '(basic partial-completion orderless) + "Completion styles for company to use. + +The completion/vertico module uses the orderless completion style by default, +but this returns too broad a candidate set for company completion. This +variable overrides `completion-styles' during company completion sessions.") + +(use-package! vertico + :hook (doom-first-input . vertico-mode) + :config + (setq vertico-resize nil + vertico-count 17 + vertico-cycle t) + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + ;; cleans up path when moving directories with shadowed paths syntax, + ;; e.g. cleans ~/foo/bar/// to /, and ~/foo/bar/~/ to ~/. + (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy) + (map! :map vertico-map + [backspace] #'+vertico/backward-updir)) + +(use-package! orderless + :defer t + :after-call doom-first-input-hook + :config + (defun +vertico-orderless-dispatch (pattern _index _total) + (cond + ;; Ensure that $ works with Consult commands, which add disambiguation suffixes + ((string-suffix-p "$" pattern) `(orderless-regexp . ,(concat (substring pattern 0 -1) "[\x100000-\x10FFFD]*$"))) + ;; Ignore single ! + ((string= "!" pattern) `(orderless-literal . "")) + ;; Without literal + ((string-prefix-p "!" pattern) `(orderless-without-literal . ,(substring pattern 1))) + ;; Initialism matching + ((string-prefix-p "`" pattern) `(orderless-initialism . ,(substring pattern 1))) + ((string-suffix-p "`" pattern) `(orderless-initialism . ,(substring pattern 0 -1))) + ;; Literal matching + ((string-prefix-p "=" pattern) `(orderless-literal . ,(substring pattern 1))) + ((string-suffix-p "=" pattern) `(orderless-literal . ,(substring pattern 0 -1))) + ;; Flex matching + ((string-prefix-p "~" pattern) `(orderless-flex . ,(substring pattern 1))) + ((string-suffix-p "~" pattern) `(orderless-flex . ,(substring pattern 0 -1))))) + (setq completion-styles '(orderless) + completion-category-defaults nil + ;; note that despite override in the name orderless can still be used in find-file etc. + completion-category-overrides '((file (styles . (orderless partial-completion)))) + orderless-style-dispatchers '(+vertico-orderless-dispatch) + orderless-component-separator "[ &]") + ;; otherwise find-file gets different highlighting than other commands + (set-face-attribute 'completions-first-difference nil :inherit nil)) + +(use-package! consult + :defer t + :init + (advice-add #'multi-occur :override #'consult-multi-occur) + (define-key! + [remap apropos] #'consult-apropos + [remap bookmark-jump] #'consult-bookmark + [remap evil-show-marks] #'consult-mark + [remap goto-line] #'consult-goto-line + [remap imenu] #'consult-imenu + [remap locate] #'consult-locate + [remap load-theme] #'consult-theme + [remap man] #'consult-man + [remap recentf-open-files] #'consult-recent-file + [remap switch-to-buffer] #'consult-buffer + [remap switch-to-buffer-other-window] #'consult-buffer-other-window + [remap switch-to-buffer-other-frame] #'consult-buffer-other-frame + [remap yank-pop] #'consult-yank-pop + [remap persp-switch-to-buffer] #'+vertico/switch-workspace-buffer) + (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple) + :config + (recentf-mode) + (setq consult-project-root-function #'doom-project-root + consult-narrow-key "<" + consult-line-numbers-widen t) + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file + +default/search-project +default/search-project-for-symbol-at-point + +default/search-other-project +vertico/search-symbol-at-point + +default/search-cwd +default/search-other-cwd + +default/search-notes-for-symbol-at-point + consult--source-file consult--source-project-file consult--source-bookmark + :preview-key (list (kbd "C-SPC") (kbd "C-M-j") (kbd "C-M-k"))) + (consult-customize + consult-theme + :preview-key + (list (kbd "C-SPC") (kbd "C-M-j") (kbd "C-M-k") + :debounce 0.5 'any)) + (after! org + (defvar +vertico--consult-org-source + `(:name "Org" + :narrow ?o + :hidden t + :category buffer + :state ,#'consult--buffer-state + :items ,(lambda () (mapcar #'buffer-name (org-buffer-list))))) + (add-to-list 'consult-buffer-sources '+vertico--consult-org-source 'append))) + +(use-package! consult-flycheck + :when (featurep! :checkers syntax) + :after (consult flycheck)) + +(use-package! embark + :defer t + :init + (map! "C-;" #'embark-act ; to be moved to :config default if accepted + :map minibuffer-local-map + "C-;" #'embark-act + "C-c C-;" #'embark-export + :desc "Export to writable buffer" + "C-c C-e" #'+vertico/embark-export-write + :leader + :desc "Actions" "a" #'embark-act) ; to be moved to :config default if accepted + (define-key! + [remap describe-bindings] #'embark-bindings) + :config + (setq embark-action-indicator + (lambda (map _target) + (which-key--show-keymap "Embark" map nil nil 'no-paging) + #'which-key--hide-popup-ignore-command) + embark-become-indicator embark-action-indicator) + ;; add the package! target finder before the file target finder, + ;; so we don't get a false positive match. + (let ((pos (or (cl-position + 'embark-target-file-at-point + embark-target-finders) + (length embark-target-finders)))) + (cl-callf2 + cons + '+vertico--embark-target-package + (nthcdr pos embark-target-finders))) + (setq embark-package-map (make-sparse-keymap)) + (map! + :map embark-file-map + :desc "Open target with sudo" "s" #'doom/sudo-find-file + :desc "Open in new workspace" "TAB" #'+vertico-embark-open-in-new-workspace + :map embark-package-map + "h" #'doom/help-packages + "b" #'doom/bump-package + "c" #'doom/help-package-config + "u" #'doom/help-package-homepage)) + +(use-package! marginalia + :hook (doom-first-input . marginalia-mode) + :init + (map! :map minibuffer-local-map + :desc "Cycle marginalia views" + "M-A" #'marginalia-cycle) + :config + (when (featurep! +icons) + (add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup)) + (nconc marginalia-command-categories + '((persp-switch-to-buffer . buffer) + (projectile-find-file . project-file) + (doom/describe-active-minor-mode . minor-mode) + (flycheck-error-list-set-filter . builtin)))) + +(use-package! embark-consult + :after (embark consult) + :config + (add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode)) + +(use-package! wgrep + :commands wgrep-change-to-wgrep-mode + :config (setq wgrep-auto-save-buffer t)) diff --git a/modules/completion/vertico/packages.el b/modules/completion/vertico/packages.el new file mode 100644 index 000000000..5f30427f9 --- /dev/null +++ b/modules/completion/vertico/packages.el @@ -0,0 +1,25 @@ +;; -*- no-byte-compile: t; -*- +;;; completion/vertico/packages.el + +(package! vertico + :recipe (:host github :repo "minad/vertico" + :files ("*.el" "extensions/*.el")) + :pin "4a9029714e847832d3ecb3ae74a7049306924f2e") + +(package! orderless :pin "1e84120a28525ccb47b602fc19b7afbeffbbe502") + +(package! consult :pin "28f9ba8bdfdb13257862a658715b6ceb96f4951e") +(when (featurep! :checkers syntax) + (package! consult-flycheck :pin "92b259e6a8ebe6439f67d3d7ffa44b7e64b76478")) + +(package! embark :pin "be03ce9ce1630b32e29cc50118d058c05696cb35") +(package! embark-consult :pin "be03ce9ce1630b32e29cc50118d058c05696cb35") + +(package! marginalia :pin "a3a8edbf25db4b1e167f1fdff6f60a065d0bf9cb") + +(package! wgrep :pin "f9687c28bbc2e84f87a479b6ce04407bb97cfb23") + +(when (featurep! +icons) + (package! all-the-icons-completion + :recipe (:host github :repo "iyefrat/all-the-icons-completion") + :pin "24cdb3b42c6ca0a8926ad6958c76d7928fc559ce")) diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index d88ca6268..b809ee1c2 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -54,13 +54,15 @@ (:when (featurep! :completion helm) :desc "Jump to symbol in current workspace" "j" #'helm-lsp-workspace-symbol :desc "Jump to symbol in any workspace" "J" #'helm-lsp-global-workspace-symbol) + (:when (featurep! :completion vertico) + :desc "Jump to symbol in current workspace" "j" #'consult-lsp-symbols + :desc "Jump to symbol in any workspace" "J" (cmd! #'consult-lsp-symbols '(4))) (:when (featurep! :ui treemacs +lsp) :desc "Errors list" "X" #'lsp-treemacs-errors-list :desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy :desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy t) :desc "References tree" "R" (cmd!! #'lsp-treemacs-references t) :desc "Symbols" "S" #'lsp-treemacs-symbols)) - (:when (featurep! :tools lsp +eglot) :desc "LSP Execute code action" "a" #'eglot-code-actions :desc "LSP Rename" "r" #'eglot-rename @@ -111,8 +113,13 @@ ;;; s --- search (:prefix-map ("s" . "search") :desc "Search project for symbol" "." #'+default/search-project-for-symbol-at-point - :desc "Search buffer" "b" #'swiper - :desc "Search all open buffers" "B" #'swiper-all + :desc "Search buffer" "b" + (cond ((featurep! :completion helm) #'swiper) + ((featurep! :completion ivy) #'swiper) + ((featurep! :completion vertico) #'consult-line)) + :desc "Search all open buffers" "B" + (cond ((featurep! :completion helm) #'swiper-all) + ((featurep! :completion ivy) #'swiper-all)) :desc "Search current directory" "d" #'+default/search-cwd :desc "Search other directory" "D" #'+default/search-other-cwd :desc "Locate file" "f" #'+lookup/file @@ -127,7 +134,10 @@ :desc "Search project" "p" #'+default/search-project :desc "Search other project" "P" #'+default/search-other-project :desc "Search buffer" "s" #'+default/search-buffer - :desc "Search buffer for thing at point" "S" #'swiper-isearch-thing-at-point + :desc "Search buffer for thing at point" "S" + (cond ((featurep! :completion helm) #'swiper-isearch-thing-at-point) + ((featurep! :completion ivy) #'swiper-isearch-thing-at-point) + ((featurep! :completion vertico) #'+vertico/search-symbol-at-point)) :desc "Dictionary" "t" #'+lookup/dictionary-definition :desc "Thesaurus" "T" #'+lookup/synonyms) @@ -146,8 +156,9 @@ :desc "Org agenda" "a" #'org-agenda (:when (featurep! :tools biblio) :desc "Bibliographic entries" "b" - (cond ((featurep! :completion ivy) #'ivy-bibtex) - ((featurep! :completion helm) #'helm-bibtex))) + (cond ((featurep! :completion ivy) #'ivy-bibtex) + ((featurep! :completion helm) #'helm-bibtex) + ((featurep! :completion vertico) #'bibtex-actions-open-entry))) :desc "Toggle last org-clock" "c" #'+org/toggle-last-clock :desc "Cancel current org-clock" "C" #'org-clock-cancel @@ -422,7 +433,9 @@ :desc "Reconnect all" "r" #'circe-reconnect-all :desc "Send message" "s" #'+irc/send-message (:when (featurep! :completion ivy) - :desc "Jump to channel" "j" #'+irc/ivy-jump-to-channel))) + :desc "Jump to channel" "j" #'+irc/ivy-jump-to-channel) + (:when (featurep! :completion vertico) + :desc "Jump to channel" "j" #'+irc/vertico-jump-to-channel))) ;;; T --- twitter (:when (featurep! :app twitter) @@ -450,6 +463,8 @@ (:when (featurep! :completion helm) "C-S-s" #'swiper-helm "C-S-r" #'helm-resume) + (:when (featurep! :completion vertico) + "C-S-r" #'vertico-repeat) ;;; objed (:when (featurep! :editor objed +manual) @@ -481,8 +496,12 @@ [C-tab] #'company-complete-common-or-cycle [tab] #'company-complete-common-or-cycle [backtab] #'company-select-previous - "C-RET" #'counsel-company - "C-" #'counsel-company + "C-RET" (cond ((featurep! :completion helm) #'helm-company) + ((featurep! :completion ivy) #'counsel-company) + ((featurep! :completion vertico) #'completion-at-point)) + "C-" (cond ((featurep! :completion helm) #'helm-company) + ((featurep! :completion ivy) #'counsel-company) + ((featurep! :completion vertico) #'completion-at-point)) :map company-search-map "C-n" #'company-search-repeat-forward "C-p" #'company-search-repeat-backward diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index fb7dedcc4..a7bfcd4de 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -138,8 +138,9 @@ "C-u" #'company-previous-page "C-d" #'company-next-page "C-s" #'company-filter-candidates - "C-S-s" (cond ((featurep! :completion helm) #'helm-company) - ((featurep! :completion ivy) #'counsel-company)) + "C-S-s" (cond ((featurep! :completion helm) #'helm-company) + ((featurep! :completion ivy) #'counsel-company) + ((featurep! :completion vertico) #'completion-at-point)) "C-SPC" #'company-complete-common "TAB" #'company-complete-common-or-cycle [tab] #'company-complete-common-or-cycle @@ -200,7 +201,20 @@ (:after helm-occur :map helm-occur-map [C-return] #'helm-occur-run-goto-line-ow) (:after helm-grep :map helm-grep-map - [C-return] #'helm-grep-run-other-window-action))) + [C-return] #'helm-grep-run-other-window-action)) + + (:when (featurep! :completion vertico) + (:after vertico + :map vertico-map + "M-RET" #'vertico-exit-input + "C-SPC" #'+vertico/embark-preview + "C-j" #'vertico-next + "C-M-j" #'+vertico/next-candidate-preview + "C-S-j" #'vertico-next-group + "C-k" #'vertico-previous + "C-M-k" #'+vertico/previous-candidate-preview + "C-S-k" #'vertico-previous-group))) + ;;; :ui (map! (:when (featurep! :ui popup) @@ -290,8 +304,9 @@ :desc "Switch buffer" "<" #'switch-to-buffer) :desc "Switch to last buffer" "`" #'evil-switch-to-windows-last-buffer :desc "Resume last search" "'" - (cond ((featurep! :completion ivy) #'ivy-resume) - ((featurep! :completion helm) #'helm-resume)) + (cond ((featurep! :completion ivy) #'ivy-resume) + ((featurep! :completion helm) #'helm-resume) + ((featurep! :completion vertico) #'vertico-repeat)) :desc "Search for symbol in project" "*" #'+default/search-project-for-symbol-at-point :desc "Search project" "/" #'+default/search-project @@ -369,14 +384,17 @@ (:when (featurep! :completion helm) :desc "Jump to symbol in current workspace" "j" #'helm-lsp-workspace-symbol :desc "Jump to symbol in any workspace" "J" #'helm-lsp-global-workspace-symbol) + (:when (featurep! :completion vertico) + :desc "Jump to symbol in current workspace" "j" #'consult-lsp-symbols + :desc "Jump to symbol in any workspace" "J" (cmd! #'consult-lsp-symbols '(4))) (:when (featurep! :ui treemacs +lsp) :desc "Errors list" "X" #'lsp-treemacs-errors-list :desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy :desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy t) :desc "References tree" "R" (cmd!! #'lsp-treemacs-references t) :desc "Symbols" "S" #'lsp-treemacs-symbols) - :desc "LSP" "l" #'+default/lsp-command-map - :desc "LSP Rename" "r" #'lsp-rename) + :desc "LSP" "l" #'+default/lsp-command-map + :desc "LSP Rename" "r" #'lsp-rename) (:when (featurep! :tools lsp +eglot) :desc "LSP Execute code action" "a" #'eglot-code-actions :desc "LSP Rename" "r" #'eglot-rename @@ -498,8 +516,9 @@ :desc "Org agenda" "a" #'org-agenda (:when (featurep! :tools biblio) :desc "Bibliographic entries" "b" - (cond ((featurep! :completion ivy) #'ivy-bibtex) - ((featurep! :completion helm) #'helm-bibtex))) + (cond ((featurep! :completion ivy) #'ivy-bibtex) + ((featurep! :completion helm) #'helm-bibtex) + ((featurep! :completion vertico) #'bibtex-actions-open-entry))) :desc "Toggle last org-clock" "c" #'+org/toggle-last-clock :desc "Cancel current org-clock" "C" #'org-clock-cancel @@ -658,8 +677,13 @@ ;;; s --- search (:prefix-map ("s" . "search") - :desc "Search buffer" "b" #'swiper - :desc "Search all open buffers" "B" #'swiper-all + :desc "Search buffer" "b" + (cond ((featurep! :completion helm) #'swiper) + ((featurep! :completion ivy) #'swiper) + ((featurep! :completion vertico) #'consult-line)) + :desc "Search all open buffers" "B" + (cond ((featurep! :completion helm) #'swiper-all) + ((featurep! :completion ivy) #'swiper-all)) :desc "Search current directory" "d" #'+default/search-cwd :desc "Search other directory" "D" #'+default/search-other-cwd :desc "Locate file" "f" #'locate @@ -676,7 +700,10 @@ :desc "Search other project" "P" #'+default/search-other-project :desc "Jump to mark" "r" #'evil-show-marks :desc "Search buffer" "s" #'+default/search-buffer - :desc "Search buffer for thing at point" "S" #'swiper-isearch-thing-at-point + :desc "Search buffer for thing at point" "S" + (cond ((featurep! :completion helm) #'swiper-isearch-thing-at-point) + ((featurep! :completion ivy) #'swiper-isearch-thing-at-point) + ((featurep! :completion vertico) #'+vertico/search-symbol-at-point)) :desc "Dictionary" "t" #'+lookup/dictionary-definition :desc "Thesaurus" "T" #'+lookup/synonyms) diff --git a/modules/config/default/autoload/search.el b/modules/config/default/autoload/search.el index 41bd8489c..329043464 100644 --- a/modules/config/default/autoload/search.el +++ b/modules/config/default/autoload/search.el @@ -10,8 +10,9 @@ If prefix ARG is set, prompt for a directory to search from." (read-directory-name "Search directory: ") default-directory))) (call-interactively - (cond ((featurep! :completion ivy) #'+ivy/project-search-from-cwd) - ((featurep! :completion helm) #'+helm/project-search-from-cwd) + (cond ((featurep! :completion ivy) #'+ivy/project-search-from-cwd) + ((featurep! :completion helm) #'+helm/project-search-from-cwd) + ((featurep! :completion vertico) #'+vertico/project-search-from-cwd) (#'rgrep))))) ;;;###autoload @@ -26,9 +27,11 @@ If prefix ARG is set, prompt for a directory to search from." If a selection is active, pre-fill the prompt with it." (interactive) (call-interactively - (if (region-active-p) - #'swiper-isearch-thing-at-point - #'swiper-isearch))) + (cond ((or (featurep! :completion helm) (featurep! :completion ivy)) + (if (region-active-p) + #'swiper-isearch-thing-at-point + #'swiper-isearch)) + ((featurep! :completion vertico) #'consult-line)))) ;;;###autoload (defun +default/search-project (&optional arg) @@ -45,8 +48,9 @@ If prefix ARG is set, include ignored/hidden files." (user-error "There are no known projects")) default-directory))) (call-interactively - (cond ((featurep! :completion ivy) #'+ivy/project-search) - ((featurep! :completion helm) #'+helm/project-search) + (cond ((featurep! :completion ivy) #'+ivy/project-search) + ((featurep! :completion helm) #'+helm/project-search) + ((featurep! :completion vertico) #'+vertico/project-search) (#'projectile-ripgrep))))) ;;;###autoload @@ -73,6 +77,8 @@ If prefix ARG is set, prompt for a known project to search from." (+ivy/project-search nil symbol)) ((featurep! :completion helm) (+helm/project-search nil symbol)) + ((featurep! :completion vertico) + (+vertico/project-search nil symbol)) ((rgrep (regexp-quote symbol)))))) ;;;###autoload diff --git a/modules/config/default/autoload/text.el b/modules/config/default/autoload/text.el index 056d3defd..cb9ef34c8 100644 --- a/modules/config/default/autoload/text.el +++ b/modules/config/default/autoload/text.el @@ -27,9 +27,10 @@ "Interactively select what text to insert from the kill ring." (interactive) (call-interactively - (cond ((fboundp 'counsel-yank-pop) #'counsel-yank-pop) + (cond ((fboundp 'consult-yank-pop) #'consult-yank-pop) ;HACK see @ymarco's comment on #5013 and TODO.org in the selecturm module. + ((fboundp 'counsel-yank-pop) #'counsel-yank-pop) ((fboundp 'helm-show-kill-ring) #'helm-show-kill-ring) - ((error "No kill-ring search backend available. Enable ivy or helm!"))))) + ((error "No kill-ring search backend available. Enable ivy, helm or vertico!"))))) ;;;###autoload (defun +default/yank-buffer-path (&optional root) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 215b52e70..b99d9be08 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -402,11 +402,13 @@ Continues comments if executed from a commented line. Consults "A-x" #'execute-extended-command) ;; A Doom convention where C-s on popups and interactive searches will invoke - ;; ivy/helm for their superior filtering. + ;; ivy/helm/vertico for their superior filtering. (when-let (command (cond ((featurep! :completion ivy) #'counsel-minibuffer-history) ((featurep! :completion helm) - #'helm-minibuffer-history))) + #'helm-minibuffer-history) + ((featurep! :completion vertico) + #'consult-history))) (define-key! :keymaps (append +default-minibuffer-maps (when (featurep! :editor evil +everywhere) diff --git a/modules/editor/evil/+commands.el b/modules/editor/evil/+commands.el index f7063a26f..7ebc8378c 100644 --- a/modules/editor/evil/+commands.el +++ b/modules/editor/evil/+commands.el @@ -68,7 +68,10 @@ ((featurep! :completion helm) (evil-ex-define-cmd "pg[rep]" #'+helm:project-search) - (evil-ex-define-cmd "pg[grep]d" #'+helm:project-search-from-cwd))) + (evil-ex-define-cmd "pg[grep]d" #'+helm:project-search-from-cwd)) + ((featurep! :completion vertico) + (evil-ex-define-cmd "pg[rep]" #'+vertico:project-search) + (evil-ex-define-cmd "pg[grep]d" #'+vertico:project-search-from-cwd))) ;;; Project tools (evil-ex-define-cmd "com[pile]" #'+evil:compile) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index a736d3e19..bf7e46cd4 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -42,10 +42,11 @@ mu4e-context-policy 'pick-first ;; compose with the current context, or ask mu4e-compose-context-policy 'ask-if-none - ;; use helm/ivy + ;; use helm/ivy/vertico mu4e-completing-read-function - (cond ((featurep! :completion ivy) #'ivy-completing-read) - ((featurep! :completion helm) #'completing-read) + (cond ((featurep! :completion ivy) #'ivy-completing-read) + ((featurep! :completion helm) #'completing-read) + ((featurep! :completion vertico) #'completing-read) (t #'ido-completing-read)) ;; no need to ask mu4e-confirm-quit nil diff --git a/modules/email/notmuch/config.el b/modules/email/notmuch/config.el index 34ec3f90d..1ebc040ae 100644 --- a/modules/email/notmuch/config.el +++ b/modules/email/notmuch/config.el @@ -103,3 +103,9 @@ OR a shell command string such as :when (featurep! :completion helm) :commands helm-notmuch :after notmuch) + + +(use-package! consult-notmuch + :when (featurep! :completion vertico) + :commands consult-notmuch + :after notmuch) diff --git a/modules/email/notmuch/packages.el b/modules/email/notmuch/packages.el index 8da851ba7..e6fc02bd7 100644 --- a/modules/email/notmuch/packages.el +++ b/modules/email/notmuch/packages.el @@ -8,3 +8,5 @@ (package! counsel-notmuch :pin "a4a1562935e4180c42524c51609d1283e9be0688")) (when (featurep! :completion helm) (package! helm-notmuch :pin "97a01497e079a7b6505987e9feba6b603bbec288")) +(when (featurep! :completion vertico) + (package! consult-notmuch :pin "67cf219fcce211237347a783ce6982402341d5fd")) diff --git a/modules/input/layout/+bepo.el b/modules/input/layout/+bepo.el index fd582dce9..8fa1edcc8 100644 --- a/modules/input/layout/+bepo.el +++ b/modules/input/layout/+bepo.el @@ -105,7 +105,7 @@ In all cases, 'h' functions go to 'c' and 'l' ones go to 'r' so the navigation k :n "C-#" #'+popup/raise)) (after! treemacs (+layout-bepo-rotate-ts-bare-keymap '(evil-treemacs-state-map))) - (after! (:or helm ivy selectrum icomplete) + (after! (:or helm ivy vertico icomplete) (+layout-bepo-rotate-keymaps '(minibuffer-local-map minibuffer-local-ns-map @@ -135,9 +135,6 @@ In all cases, 'h' functions go to 'c' and 'l' ones go to 'r' so the navigation k (after! helm-files (+layout-bepo-rotate-bare-keymap '(helm-read-file-map) +layout-bepo-cr-rotation-style) (+layout-bepo-rotate-keymaps '(helm-read-file-map))) - (after! selectrum - (+layout-bepo-rotate-bare-keymap '(selectrum-minibuffer-map) +layout-bepo-cr-rotation-style) - (+layout-bepo-rotate-keymaps '(selectrum-minibuffer-map))) (after! company (+layout-bepo-rotate-bare-keymap '(company-active-map company-search-map) +layout-bepo-cr-rotation-style)) (after! evil-snipe diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index 444470847..76a176f59 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -724,6 +724,9 @@ between the two." (:when (featurep! :completion helm) "." #'helm-org-in-buffer-headings "/" #'helm-org-agenda-files-headings) + (:when (featurep! :completion vertico) + "." #'consult-org-heading + "/" #'consult-org-agenda) "A" #'org-archive-subtree "e" #'org-export-dispatch "f" #'org-footnote-new @@ -807,6 +810,9 @@ between the two." (:when (featurep! :completion helm) "g" #'helm-org-in-buffer-headings "G" #'helm-org-agenda-files-headings) + (:when (featurep! :completion vertico) + "g" #'consult-org-heading + "G" #'consult-org-agenda) "c" #'org-clock-goto "C" (cmd! (org-clock-goto 'select)) "i" #'org-id-goto diff --git a/modules/tools/biblio/config.el b/modules/tools/biblio/config.el index 936370c6d..532fc552f 100644 --- a/modules/tools/biblio/config.el +++ b/modules/tools/biblio/config.el @@ -12,3 +12,11 @@ :defer t :config (add-to-list 'ivy-re-builders-alist '(ivy-bibtex . ivy--regex-plus))) + + +(use-package! bibtex-actions + :when (featurep! :completion vertico) + :after embark + :defer t + :config + (add-to-list 'embark-keymap-alist '(bibtex . bibtex-actions-map))) diff --git a/modules/tools/biblio/packages.el b/modules/tools/biblio/packages.el index a9b7165ab..d4a1c28aa 100644 --- a/modules/tools/biblio/packages.el +++ b/modules/tools/biblio/packages.el @@ -1,8 +1,10 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/biblio/packages.el -(package! bibtex-completion :pin "9f6ea920a49457d85096caa0e61f086a42b2908e") +(package! bibtex-completion :pin "a0d32ab16748b7b0c43d6421f1b497b7caf8e590") (when (featurep! :completion ivy) - (package! ivy-bibtex :pin "9f6ea920a49457d85096caa0e61f086a42b2908e")) + (package! ivy-bibtex :pin "a0d32ab16748b7b0c43d6421f1b497b7caf8e590")) (when (featurep! :completion helm) - (package! helm-bibtex :pin "9f6ea920a49457d85096caa0e61f086a42b2908e")) + (package! helm-bibtex :pin "a0d32ab16748b7b0c43d6421f1b497b7caf8e590")) +(when (featurep! :completion vertico) + (package! bibtex-actions :pin "6e3a194c3ab655693f8194be78542366755c58c9")) diff --git a/modules/tools/lookup/autoload/lookup.el b/modules/tools/lookup/autoload/lookup.el index 531dd7ca0..37c2744d4 100644 --- a/modules/tools/lookup/autoload/lookup.el +++ b/modules/tools/lookup/autoload/lookup.el @@ -234,8 +234,8 @@ This backend prefers \"just working\" over accuracy." (defun +lookup-project-search-backend-fn (identifier) "Conducts a simple project text search for IDENTIFIER. -Uses and requires `+ivy-file-search' or `+helm-file-search'. Will return nil if -neither is available. These require ripgrep to be installed." +Uses and requires `+ivy-file-search', `+helm-file-search', or `+vertico-file-search'. +Will return nil if neither is available. These require ripgrep to be installed." (unless identifier (let ((query (rxt-quote-pcre identifier))) (ignore-errors @@ -244,6 +244,9 @@ neither is available. These require ripgrep to be installed." t) ((featurep! :completion helm) (+helm-file-search :query query) + t) + ((featurep! :completion vertico) + (+vertico-file-search :query query) t)))))) (defun +lookup-evil-goto-definition-backend-fn (_identifier) diff --git a/modules/tools/lookup/config.el b/modules/tools/lookup/config.el index e3840ae87..b7e1a0d73 100644 --- a/modules/tools/lookup/config.el +++ b/modules/tools/lookup/config.el @@ -178,7 +178,13 @@ Dictionary.app behind the scenes to get definitions.") (funcall orig-fn fetcher alist))) (use-package! helm-xref - :when (featurep! :completion helm))) + :when (featurep! :completion helm)) + + (use-package! consult-xref + :when (featurep! :completion vertico) + :init + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref))) ;; diff --git a/modules/tools/lsp/README.org b/modules/tools/lsp/README.org index bbd277d8e..4dfefa79b 100644 --- a/modules/tools/lsp/README.org +++ b/modules/tools/lsp/README.org @@ -67,8 +67,9 @@ As of this writing, this is the state of LSP support in Doom Emacs: ** Plugins + [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]] + [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]] -+ [[https://github.com/emacs-lsp/lsp-ivy][lsp-ivy]] -+ [[https://github.com/emacs-lsp/helm-lsp][helm-lsp]] ++ [[https://github.com/emacs-lsp/lsp-ivy][lsp-ivy]] (=:completion ivy=) ++ [[https://github.com/emacs-lsp/helm-lsp][helm-lsp]] (=:completion helm=) ++ [[https://github.com/gagbo/consult-lsp][consult-lsp]] (=:completion vertico=) + [[https://github.com/joaotavora/eglot][eglot]] * Prerequisites @@ -85,8 +86,9 @@ including instructions to register your own. * TODO Features ** LSP-powered project search -Without the =+eglot= flag, and when =:completion ivy= or =:completion helm= is -active, LSP is used to search a symbol indexed by the LSP server : +Without the =+eglot= flag, and when =:completion ivy=, =:completion helm= or +=:completion vertico= is active, LSP is used to search a symbol indexed by the +LSP server : | Keybind | Description | |-----------+-------------------------------------| | =SPC c j= | Jump to symbol in current workspace | diff --git a/modules/tools/lsp/packages.el b/modules/tools/lsp/packages.el index 3e6288229..110c982c2 100644 --- a/modules/tools/lsp/packages.el +++ b/modules/tools/lsp/packages.el @@ -8,4 +8,6 @@ (when (featurep! :completion ivy) (package! lsp-ivy :pin "bccd86028e669f5a1cad78364775fe7a0741ff93")) (when (featurep! :completion helm) - (package! helm-lsp :pin "c2c6974dadfac459b1a69a1217441283874cea92"))) + (package! helm-lsp :pin "c2c6974dadfac459b1a69a1217441283874cea92")) + (when (featurep! :completion vertico) + (package! consult-lsp :pin "c882749e91e4de3bae17d825ac9950cc074b1595"))) diff --git a/modules/ui/workspaces/config.el b/modules/ui/workspaces/config.el index 3ecf9d6b1..2caa13b7b 100644 --- a/modules/ui/workspaces/config.el +++ b/modules/ui/workspaces/config.el @@ -185,7 +185,8 @@ stored in `persp-save-dir'.") (add-hook 'server-done-hook #'+workspaces-delete-associated-workspace-h) ;; per-project workspaces, but reuse current workspace if empty - (setq projectile-switch-project-action #'+workspaces-set-project-action-fn + ;; HACK?? needs review + (setq projectile-switch-project-action (lambda () (+workspaces-set-project-action-fn) (+workspaces-switch-to-project-h)) counsel-projectile-switch-project-action '(1 ("o" +workspaces-switch-to-project-h "open project in new workspace") ("O" counsel-projectile-switch-project-action "jump to a project buffer or file")