dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

commit 2bcfe73f1b2b57b3f8b1e887c006e3e6ed43aff4
parent 59937cae6bec04c7039fcfddba3235d95f28af6f
Author: Lukas Henkel <lh@entf.net>
Date:   Tue,  1 Feb 2022 20:06:18 +0100

Update some packages

Diffstat:
Aelpa/consult-0.14.signed | 2++
Aelpa/consult-0.14/CHANGELOG.org | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/README.org | 1212+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-autoloads.el | 506+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-compile.el | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-compile.elc | 0
Aelpa/consult-0.14/consult-flymake.el | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-flymake.elc | 0
Aelpa/consult-0.14/consult-icomplete.el | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-icomplete.elc | 0
Aelpa/consult-0.14/consult-imenu.el | 232+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-imenu.elc | 0
Aelpa/consult-0.14/consult-org.el | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-org.elc | 0
Aelpa/consult-0.14/consult-pkg.el | 2++
Aelpa/consult-0.14/consult-register.el | 266+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-register.elc | 0
Aelpa/consult-0.14/consult-selectrum.el | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-selectrum.elc | 0
Aelpa/consult-0.14/consult-vertico.el | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-vertico.elc | 0
Aelpa/consult-0.14/consult-xref.el | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult-xref.elc | 0
Aelpa/consult-0.14/consult.el | 4539++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/consult.elc | 0
Aelpa/consult-0.14/consult.info | 1476+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/consult-0.14/dir | 18++++++++++++++++++
Aelpa/corfu-0.17.signed | 2++
Aelpa/corfu-0.17/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.17/README.org | 227+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.17/corfu-autoloads.el | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.17/corfu-pkg.el | 2++
Aelpa/corfu-0.17/corfu.el | 1214+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.17/corfu.elc | 0
Aelpa/corfu-0.17/corfu.info | 327+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.17/dir | 18++++++++++++++++++
Aelpa/marginalia-0.11.signed | 2++
Aelpa/marginalia-0.11/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/marginalia-0.11/README.org | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/marginalia-0.11/dir | 18++++++++++++++++++
Aelpa/marginalia-0.11/marginalia-autoloads.el | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/marginalia-0.11/marginalia-mode.png | 0
Aelpa/marginalia-0.11/marginalia-pkg.el | 2++
Aelpa/marginalia-0.11/marginalia.el | 1131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/marginalia-0.11/marginalia.elc | 0
Aelpa/marginalia-0.11/marginalia.info | 257+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19.signed | 2++
Aelpa/vertico-0.19/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/README.org | 562+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/dir | 18++++++++++++++++++
Aelpa/vertico-0.19/vertico-autoloads.el | 321+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-buffer.el | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-buffer.elc | 0
Aelpa/vertico-0.19/vertico-directory.el | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-directory.elc | 0
Aelpa/vertico-0.19/vertico-flat.el | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-flat.elc | 0
Aelpa/vertico-0.19/vertico-grid.el | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-grid.elc | 0
Aelpa/vertico-0.19/vertico-indexed.el | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-indexed.elc | 0
Aelpa/vertico-0.19/vertico-mouse.el | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-mouse.elc | 0
Aelpa/vertico-0.19/vertico-multiform.el | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-multiform.elc | 0
Aelpa/vertico-0.19/vertico-pkg.el | 2++
Aelpa/vertico-0.19/vertico-quick.el | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-quick.elc | 0
Aelpa/vertico-0.19/vertico-repeat.el | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-repeat.elc | 0
Aelpa/vertico-0.19/vertico-reverse.el | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-reverse.elc | 0
Aelpa/vertico-0.19/vertico-unobtrusive.el | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico-unobtrusive.elc | 0
Aelpa/vertico-0.19/vertico.el | 789+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.19/vertico.elc | 0
Aelpa/vertico-0.19/vertico.info | 748+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.5.1.signed | 2++
Aelpa/vertico-posframe-0.5.1/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.5.1/README.org | 26++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.5.1/vertico-posframe-autoloads.el | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.5.1/vertico-posframe-pkg.el | 2++
Aelpa/vertico-posframe-0.5.1/vertico-posframe.el | 310+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.5.1/vertico-posframe.elc | 0
85 files changed, 20179 insertions(+), 0 deletions(-)

diff --git a/elpa/consult-0.14.signed b/elpa/consult-0.14.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2021-12-31T11:05:01+0100 using RSA +\ No newline at end of file diff --git a/elpa/consult-0.14/CHANGELOG.org b/elpa/consult-0.14/CHANGELOG.org @@ -0,0 +1,155 @@ +#+title: consult.el - Changelog +#+author: Daniel Mendler +#+language: en + +* Version 0.14 (2021-12-31) + +- Bugfixes +- Add =consult-recent-file-filter= +- Rename =consult--source-(project-)file= to =consult-source-(project-)recent-file= +- =consult-keep-lines= makes read-only buffers temporarily writable if confirmed + +* Version 0.13 (2021-11-12) + +- Bugfixes +- =consult-register=: Add support for file register values. +- Rename =consult-isearch= to =consult-isearch-history=. The command is a history + browsing command and not a replacement for Isearch. +- =consult-grep= support -[ABC] grep options +- Add =consult-grep-context= face + +* Version 0.12 (2021-10-11) + +- Bugfixes +- Removed obsolete =consult-project-imenu= and =consult-x-command= variables +- =consult-grep=: Use ~--null~ argument to support file names with colons + +* Version 0.11 (2021-08-18) + +- Bugfixes only + +* Version 0.10 (2021-08-11) + +- =consult-mark=, =consult-global-mark=: Add optional marker list argument +- =consult-completing-read-multiple=: New function +- Rename =consult-project-imenu= to =consult-imenu-multi= +- Add =consult-line-multi= to search multiple buffers +- Removed obsolete =consult-yank=, =consult-async-default-split=, =consult-config= +- =consult-ripgrep=: Use =--smart-case= +- =consult-grep/git-grep=: Use =--ignore-case= +- Deprecate =consult-<cmd>-command= in favor of =consult-<cmd>-config.= +- =consult-find=: Use regular expressions instead of globbing/wildcards by default. + Due to the changes to =consult-find= it is not possible anymore to configure + =fd= as backend for =consult-find=. A replacement is documented in the wiki. +- =consult-find/locate/man=: Add highlighting to the matching file/man page names. +- =consult-grep/git-grep/ripgrep/find/locate=: Add support for multiple unordered + patterns. Each of the input patterns must be matched. For example, + =consult-find= transforms the input "first second third" to "first -and second + -and third". +- =consult-grep/git-grep/ripgrep=: Compute the highlighting based on the input, + instead of relying on the ANSI-escaped output. This works better with multiple + patterns, but may occasionally produce false highlighting. +- Deprecate =consult-x-command= configuration variables in favor of =consult-x-args=. + The variables have been renamed since the configuration format changed. +- =consult-async-split-styles-alist=: Remove the =space= splitting style, since + it has been obsoleted by the support for multiple unordered patterns. + +* Version 0.9 (2021-06-22) + +- Add =consult-preview-excluded-hooks= +- =consult--read/consult--prompt=: Add =:inherit-input-method= argument +- Add debouncing support for preview + +* Version 0.8 (2021-05-30) + +- Async commands: Do not fix vertical height in Selectrum. +- =consult-imenu=: Deduplicate items (some imenu backends generate duplicates). +- =consult-org-heading=: Deduplicate items. +- =consult-buffer-filter=: Hide more buffers. +- =consult-line=: Matching line preview overlay only in the selected window. +- =consult-yank/completion-in-region=: Insertion preview only in selected window. +- =consult-yank=: Rename to =consult-yank-from-kill-ring= (Emacs 28 naming). +- =consult-yank= commands: =delete-selection-mode= support, added properties. +- =consult-preview-at-point=, =consult-preview-at-point-mode=: New command and + minor mode to preview candidate at point in =*Completions*= buffer. +- Add =consult-async-split-style= and =consult-async-split-styles-alist=. +- =consult-async-default-split=: Obsoleted in favor of =consult-async-split-style=. +- Deprecate =consult-config= in favor of new =consult-customize= macro. +- =consult-buffer=: Enable previews for files and bookmarks by default. +- =consult-buffer=/=consult--multi=: Add support for =:preview-key= per source. +- =consult-buffer=: Push visible buffers down in the buffer list. +- =consult-flycheck=: Moved to separate repository prior to ELPA submission. +- Submitted Consult to ELPA. + +* Version 0.7 (2021-04-29) + +- Bugfixes +- =consult-buffer=: Respect =confirm-nonexistent-file-or-buffer= +- =consult-widen-key=: Change default setting to twice the =consult-narrow-key= +- =consult-flycheck=: Sort errors first +- Added support for the Vertico completion system +- Consult adds disambiguation suffixes as suffix instead of as prefix now + for the commands =consult-line=, =consult-buffer=, etc. + This enables support for the =basic= completion style and TAB completion. +- =consult--read=: The =:title= function must accept two arguments now, + the candidate string and a flag. If the flag is nil, the function should + return the title of the candidate, otherwise the function should return the + transformed candidate. +- =consult-grep= and related commands: Strip the file name if grouping is used. +- =consult-find/grep=: Ensure that the commands work with Tramp +- =consult-outline=: Add narrowing +- Added =consult-org-heading= and =consult-org-agenda= +- =consult-line=: Highlight visual line during jump preview +- =consult-line=: Start search at current line, add configuration variable + =consult-start-from-top=. The starting point can be toggled by the prefix + argument =C-u=. + +* Version 0.6 (2021-03-02) + +- Bugfixes +- =consult-keep/focus-lines=: Align behavior on regions with built-in =keep-lines=. +- =consult-buffer=: Enable file sources only when =recentf-mode= is enabled +- =consult--multi=: Add =:default= flag, use flag for =consult--source-buffer= +- Add =consult-grep-max-columns= to prevent performance issues for long lines +- Add =consult-fontify-preserve= customization variable +- =consult-line=: Quits Isearch, when started from an Isearch session +- =consult-register-load=: Align prefix argument handling with =insert-register= +- Rename =consult-error= to =consult-compile-error= +- =consult-compile-error=: Allow calling the command from any buffer, + use the errors from all compilation buffers related to the current buffer. +- =consult-man=: Handle aggreated entries returned by mandoc +- =consult-completion-in-region=: Added preview and =consult-preview-region= face +- Added =consult-completion-in-region-styles= customization variable +- Added =consult-xref=. The function can be set as =xref-show-xrefs-function= + and =xref-show-definitions-function=. +- Added support for the candidate grouping function =x-group-function= + +* Version 0.5 (2021-02-09) + +- Bugfixes +- =consult-keep/focus-lines=: If region is active, operate only on the region. +- =consult-register-format=: Do not truncate register strings. +- =consult-buffer= multi sources: Ensure that original buffer is + shown, when the currently selected source does not perform preview. +- Add =consult-preview-raw-size= +- Expose preview functionality for multi-source bookmarks/files +- Multi sources: Add =:enabled=, =:state= and =:action= fields +- =consult-imenu=: Add faces depending on item types + +* Version 0.4 (2021-02-01) + +- Bugfixes +- Introduce multi sources, reimplement =consult-buffer= with multi sources +- =consult-isearch=: Add preview highlighting +- =consult-line=: Use =isearch-string= when invoked from running isearch + +* Version 0.3 (2021-01-28) + +- Bugfixes +- New command =consult-isearch= +- New functions =consult-register-format=, =consult-register-window=, + removed =consult-register-preview= + +* Version 0.2 (2021-01-16) + +- Initial stable release diff --git a/elpa/consult-0.14/LICENSE b/elpa/consult-0.14/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/elpa/consult-0.14/README.org b/elpa/consult-0.14/README.org @@ -0,0 +1,1212 @@ +#+title: consult.el - Consulting completing-read +#+author: Daniel Mendler +#+language: en +#+export_file_name: consult.texi +#+texinfo_dir_category: Emacs +#+texinfo_dir_title: Consult: (consult). +#+texinfo_dir_desc: Useful commands built on completing-read. + +#+html: <a href="https://www.gnu.org/software/emacs/"><img alt="GNU Emacs" src="https://github.com/minad/corfu/blob/screenshots/emacs.svg?raw=true"/></a> +#+html: <a href="http://elpa.gnu.org/packages/consult.html"><img alt="GNU ELPA" src="https://elpa.gnu.org/packages/consult.svg"/></a> +#+html: <a href="http://elpa.gnu.org/devel/consult.html"><img alt="GNU-devel ELPA" src="https://elpa.gnu.org/devel/consult.svg"/></a> +#+html: <a href="https://melpa.org/#/consult"><img alt="MELPA" src="https://melpa.org/packages/consult-badge.svg"/></a> +#+html: <a href="https://stable.melpa.org/#/consult"><img alt="MELPA Stable" src="https://stable.melpa.org/packages/consult-badge.svg"/></a> + +* Introduction + :properties: + :description: Why Consult? + :end: +#+cindex: introduction + +Consult provides practical commands based on the Emacs completion function +[[https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Completion.html][completing-read]]. Completion allows you to quickly select an item from a list of +candidates. Consult offers in particular an advanced buffer switching command +=consult-buffer= to switch between buffers and recently opened files. Furthermore +Consult provides multiple search commands, an asynchronous =consult-grep= and +=consult-ripgrep=, and =consult-line=, which resembles [[https://github.com/abo-abo/swiper#swiper][Swiper]]. Some of the Consult +commands are enhanced versions of built-in Emacs commands. For example the +command =consult-imenu= presents a flat list of the Imenu with [[#live-previews][live preview]], +[[#narrowing-and-grouping][grouping and narrowing]]. Please take a look at the [[#available-commands][full list of commands]]. + +Consult is fully compatible with completion systems based on the standard Emacs +=completing-read= API, notably the default completion system, [[https://github.com/minad/vertico][Vertico]], +[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html][Icomplete]]/[[https://github.com/oantolin/icomplete-vertical][Icomplete-vertical]], [[https://github.com/raxod502/selectrum][Selectrum]], [[https://github.com/oantolin/embark/][Embark]] and [[https://github.com/protesilaos/mct][Mct]]. + +This package keeps the completion system specifics to a minimum. The ability of +the Consult commands to work well with arbitrary completion systems is one of +the main advantages of the package. Consult fits well into existing setups and +it helps you to create a full completion environment out of small and +independent components. Note that, if you use [[https://github.com/abo-abo/swiper#ivy][Ivy]] or [[https://github.com/emacs-helm/helm][Helm]], you probably don't +need Consult, since both packages bring their own Consult-like functionality. + +You can combine the complementary packages [[https://github.com/minad/marginalia/][Marginalia]], [[https://github.com/oantolin/embark/][Embark]] and [[https://github.com/oantolin/orderless][Orderless]] with +Consult. Marginalia enriches the completion display with annotations, e.g., +documentation strings or file information. The versatile Embark package provides +local actions, comparable to a context menu. These actions operate on the +selected candidate in the minibuffer or at point in normal buffers. For example, +when selecting from a list of files, Embark offers an action to delete the file. +Additionally Embark offers a completion system by itself through its +live-updating collect buffer. The section [[#embark-integration][Embark integration]] documents in +greater detail how Consult and Embark work together. + +** Screenshots :noexport: + +#+caption: consult-grep +[[https://github.com/minad/consult/blob/main/images/consult-grep.gif?raw=true]] +Fig. 1: Command =consult-git-grep= + +#+caption: consult-imenu +[[https://github.com/minad/consult/blob/main/images/consult-imenu.png?raw=true]] +Fig. 2: Command =consult-imenu= + +#+caption: consult-line +[[https://github.com/minad/consult/blob/main/images/consult-line.png?raw=true]] +Fig. 3: Command =consult-line= + +* Available commands + :properties: + :custom_id: available-commands + :description: Navigation, search, editing commands and more + :end: +#+cindex: commands + +Most Consult commands follow the meaningful naming scheme =consult-<thing>=. +Many commands implement a little known but convenient Emacs feature called +"future history", which guesses what input the user wants. At a command prompt +type =M-n= and typically Consult will insert the symbol or thing at point into +the input. + +*TIP:* If you have [[https://github.com/minad/marginalia][Marginalia]] annotators activated, type =M-x ^consult= to see +all Consult commands with their abbreviated description. Alternatively, type +=C-h a ^consult= to get an overview of all Consult variables and functions with +their descriptions. + +** Virtual Buffers + :properties: + :description: Buffers, bookmarks and recent files + :end: + #+cindex: virtual buffers + + #+findex: consult-buffer + #+findex: consult-buffer-other-window + #+findex: consult-buffer-other-frame + #+findex: consult-recent-file + #+findex: consult-bookmark + - =consult-buffer= (=-other-window=, =-other-frame=): Enhanced version + of =switch-to-buffer= with support for virtual buffers. Supports live preview + of buffers and narrowing to the virtual buffer types. You can type =f SPC= in + order to narrow to recent files. Press =SPC= to show ephemeral buffers. + Supported narrowing keys: + - b Buffers + - f Files (Requires =recentf-mode=) + - m Bookmarks + - p Project (Requires configuration of the =consult-project-root-function= + as shown in the [[#use-package-example][example configuration]]). + - Arbitrary [[#multiple-sources][other sources]] configured in =consult-buffer-sources=. + - =consult-bookmark=: Select or create bookmark. To select bookmarks you might use the + =consult-buffer= as an alternative, which can include a bookmark virtual buffer + source. Note that =consult-bookmark= supports preview of bookmarks and + narrowing. + - =consult-recent-file=: Select from recent files with preview. + You might prefer the powerful =consult-buffer= instead, which can include + recent files as a virtual buffer source. The =recentf-mode= enables tracking of + recent files. + +** Editing + :properties: + :description: Commands useful for editing + :end: + #+cindex: editing + + #+findex: consult-yank-pop + #+findex: consult-yank-from-kill-ring + #+findex: consult-yank-replace + #+findex: consult-kmacro + - =consult-yank-from-kill-ring=: Enhanced version of =yank= to select an item + from the =kill-ring=. The selected text previewed as overlay in the buffer. + - =consult-yank-pop=: Enhanced version of =yank-pop= with DWIM-behavior, which + either replaces the last =yank= by cycling through the =kill-ring=, or if there + has not been a last =yank= consults the =kill-ring=. The selected text previewed + as overlay in the buffer. + - =consult-yank-replace=: Like =consult-yank-pop=, but always replaces the last + =yank= with an item from the =kill-ring=. + - =consult-kmacro=: Select macro from the macro ring and execute it. + +** Register + :properties: + :description: Searching through registers and fast access + :end: + #+cindex: register + + #+findex: consult-register + #+findex: consult-register-load + #+findex: consult-register-store + #+findex: consult-register-format + #+findex: consult-register-window + - =consult-register=: Select from list of registers. The command + supports narrowing to register types and preview of marker positions. This + command is useful to search the register contents. For quick access use the + commands =consult-register-load=, =consult-register-store= or the built-in Emacs + register commands. + - =consult-register-format=: Set =register-preview-function= to this function for + an enhanced register formatting. See the [[#use-package-example][example configuration]]. + - =consult-register-window=: Replace =register-preview= with this function for a + better register window. See the [[#use-package-example][example configuration]]. + - =consult-register-load=: Utility command to quickly load a register. + The command either jumps to the register value or inserts it. + - =consult-register-store=: Improved UI to store registers depending on the current + context with an action menu. With an active region, store/append/prepend the + contents, optionally deleting the region when a prefix argument is given. + With a numeric prefix argument, store/add the number. Otherwise store point, + frameset, window or kmacro. Usage examples: + * =M-' x=: If no region is active, store point in register =x=. + If a region is active, store the region in register =x=. + * =M-' M-w x=: Store window configuration in register =x=. + * =C-u 100 M-' x=: Store number in register =x=. + +** Navigation + :properties: + :description: Mark rings, outlines and imenu + :end: + #+cindex: navigation + + #+findex: consult-goto-line + #+findex: consult-mark + #+findex: consult-global-mark + #+findex: consult-outline + #+findex: consult-imenu + #+findex: consult-imenu-multi + - =consult-goto-line=: Jump to line number enhanced with live preview. + This is a drop-in replacement for =goto-line=. + - =consult-mark=: Jump to a marker in the =mark-ring=. Supports live + preview and recursive editing. + - =consult-global-mark=: Jump to a marker in the =global-mark-ring=. + Supports live preview and recursive editing. + - =consult-outline=: Jump to a heading of the outline. Supports narrowing + to a heading level, live preview and recursive editing. + - =consult-imenu=: Jump to imenu item in the current buffer. Supports + live preview, recursive editing and narrowing. + - =consult-imenu-multi=: Jump to imenu item in project buffers, with + the same major mode as the current buffer. Supports live preview, + recursive editing and narrowing. This feature has been inspired by + [[https://github.com/vspinu/imenu-anywhere][imenu-anywhere]]. + +** Search + :properties: + :description: Line search, grep and file search + :end: + #+cindex: search + + #+findex: consult-line + #+findex: consult-line-multi + #+findex: consult-multi-occur + #+findex: consult-keep-lines + #+findex: consult-focus-lines + - =consult-line=: Enter search string and select from matching lines. + Supports live preview and recursive editing. The symbol at point and the + recent Isearch string are added to the "future history" and can be accessed + by pressing =M-n=. When =consult-line= is bound to the =isearch-mode-map= and + is invoked during a running Isearch, it will use the current Isearch string. + - =consult-line-multi=: Search across multiple buffers. By default search across + project buffers. If invoked with a prefix argument search across all buffers. + Behaves like =consult-line=. + - =consult-multi-occur=: Replacement for =multi-occur= which uses + =completing-read-multiple=. + - =consult-keep-lines=: Replacement for =keep/flush-lines= + which uses the current completion style for filtering the buffer. The + function updates the buffer while typing. In particular =consult-keep-lines= + can narrow down an exported Embark collect buffer further, relying on the + same completion filtering as ~completing-read~. If the input begins with the + negation operator, i.e., ~! SPC~, the filter matches the complement. If a + region is active, the region restricts the filtering. + - =consult-focus-lines=: Temporarily hide lines by filtering them using the current + completion style. Call with =C-u= prefix argument in order to show the hidden + lines again. If the input begins with the negation operator, i.e., ~! SPC~, + the filter matches the complement. In contrast to =consult-keep-lines= this + function does not edit the buffer. If a region is active, the region restricts + the filtering. + +** Grep and Find + :properties: + :description: Searching through the filesystem + :end: + #+cindex: grep + #+cindex: find + #+cindex: locate + + #+findex: consult-grep + #+findex: consult-ripgrep + #+findex: consult-git-grep + #+findex: consult-find + #+findex: consult-locate + - =consult-grep=, =consult-ripgrep=, =consult-git-grep=: Search for regular expression + in files. Consult invokes Grep asynchronously, while you enter the search + term. After at least =consult-async-min-input= characters, the search gets + started. Consult splits the input string into two parts, if the first + character is a punctuation character, like =#=. For example + =#regexps#filter-string=, is split at the second =#=. The string =regexps= is + passed to Grep. Note that Consult transforms Emacs regular expressions to + expressions understand by the search program. Always use Emacs regular + expressions at the prompt. If you enter multiple regular expressions + separated by space only lines matching all regular expressions are shown. In + order to match space literally, escape the space with a backslash. The + =filter-string= is passed to the /fast/ Emacs filtering to further narrow down + the list of matches. This is particularly useful if you are using an advanced + completion style like orderless. =consult-grep= supports preview. If the + =consult-project-root-function= is [[#use-package-example][configured]] and returns non-nil, =consult-grep= + searches the current project directory. Otherwise the =default-directory= is + searched. If =consult-grep= is invoked with prefix argument =C-u M-s g=, you can + specify the directory manually. + - =consult-find=, =consult-locate=: Find file by + matching the path against a regexp. Like for =consult-grep,= either the project + root or the current directory is the root directory for the search. The input + string is treated similarly to =consult-grep=, where the first part is passed + to find, and the second part is used for Emacs filtering. + +** Compilation + :properties: + :description: Jumping to references and compilation errors + :end: + #+cindex: compilation errors + + #+findex: consult-compile-error + #+findex: consult-flymake + #+findex: consult-flycheck + #+findex: consult-xref + - =consult-compile-error=: Jump to a compilation error. Supports live preview + narrowing and recursive editing. + - =consult-flymake=: Jump to flymake diagnostic. Supports live preview and + recursive editing. The command supports narrowing. Press =e SPC=, =w SPC=, =n + SPC= to only show errors, warnings and notes respectively. + - =consult-flycheck=: Jump to flycheck error, similar to =consult-flymake=. + This command requires the installation of the additional =consult-flycheck= + package since the main =consult= package only depends on Emacs core + components. + - =consult-xref=: Integration with xref. This function can be set as + as =xref-show-xrefs-function= and =xref-show-definitions-function=. + +** Histories + :properties: + :description: Navigating histories + :end: + #+cindex: history + + #+findex: consult-complex-command + #+findex: consult-history + #+findex: consult-isearch-history + - =consult-complex-command=: Select a command from the + =command-history=. This command is a =completing-read= version of + =repeat-complex-command= and is also a replacement for the =command-history= + command from chistory.el. + - =consult-history=: Insert a string from the current buffer history. + You can invoke this command from the minibuffer. In that case =consult-history= + uses the history stored in the =minibuffer-history-variable=. + - =consult-isearch-history=: During an Isearch session, this command picks a + search string from history and continues the search with the newly selected + string. Outside of Isearch, the command allows you to pick a string from the + history and starts a new Isearch. =consult-isearch-history= acts as a drop-in + replacement for =isearch-edit-string=. + +** Modes + :properties: + :description: Toggling minor modes and executing commands + :end: + #+cindex: minor mode + #+cindex: major mode + + #+findex: consult-minor-mode-menu + #+findex: consult-mode-command + - =consult-minor-mode-menu=: Enable/disable minor mode. Supports + narrowing to on/off/local/global modes by pressing =i/o/l/g SPC= + respectively. + - =consult-mode-command=: Run a command from the currently active minor + or major modes. Supports narrowing to local-minor/global-minor/major + mode via the keys =l/g/m=. + +** Org Mode + :properties: + :description: Org-specific commands + :end: + + #+findex: consult-org-heading + #+findex: consult-org-agenda + - =consult-org-heading=: Similar to =consult-outline=, for Org + buffers. Supports narrowing by heading level, priority and TODO + state, as well as live preview and recursive editing. + - =consult-org-agenda=: Jump to an agenda heading. Supports + narrowing by heading level, priority and TODO state, as well as + live preview and recursive editing. + +** Miscellaneous + :properties: + :description: Various other useful commands + :end: + + #+findex: consult-apropos + #+findex: consult-file-externally + #+findex: consult-completion-in-region + #+findex: consult-completing-read-multiple + #+findex: consult-theme + #+findex: consult-man + #+findex: consult-preview-at-point + #+findex: consult-preview-at-point-mode + - =consult-apropos=: Replacement for =apropos= with completion. As a better + alternative, you can run =embark-export= from commands like =M-x= or + =describe-symbol=. + - =consult-man=: Find Unix man page, via Unix =apropos= or =man -k=. + =consult-man= opens the selected man page using the Emacs =man= command. + - =consult-file-externally=: Select a file and open it externally, + e.g. using =xdg-open= on Linux. + - =consult-theme=: Select a theme and disable all currently enabled + themes. Supports live preview of the theme while scrolling through the + candidates. + - =consult-preview-at-point= and =consult-preview-at-point-mode=: Command and + minor mode which previews the candidate at point in the =*Completions*= buffer. + This is mainly relevant if you use the default =*Completions*= UI or if you + want to enable preview in Embark Collect buffers. + - =consult-completion-in-region=: This function can be set as + =completion-in-region-function=. Then the minibuffer completion UI will be + used for =completion-at-point=. This function is particularly useful in + combination with Vertico or Icomplete, since these UIs do not provide their + own =completion-in-region-function=. Selectrum provides its own function + similar to =consult-completion-in-region=. If you use the default + =*Completions*= UI, note that =consult-completion-in-region= is not useful. + #+begin_src emacs-lisp + ;; Use `consult-completion-in-region' if Vertico is enabled. + ;; Otherwise use the default `completion--in-region' function. + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + #+end_src + Instead of =consult-completion-in-region=, you may prefer to see the + completions directly in the buffer as a small popup. In that case, I + recommend either the [[https://github.com/minad/corfu][Corfu]] or the [[https://github.com/company-mode/company-mode][Company]] package. There is a technical + caveat of =consult-completion-in-region= in combination with Lsp-mode or Eglot. + The Lsp server relies on the input at point, in order to generate refined + candidate strings. Since the completion is transferred from the original + buffer to the minibuffer, the server does not receive the updated input. Lsp + completion should work with Corfu or Company though, which perform the + completion directly in the original buffer. + - =consult-completing-read-multiple=: Enhanced drop-in replacement for + =completing-read-multiple= which works better for long candidates. You can + select/deselect multiple candidates by pressing ~RET~. Afterwards the + selections are confirmed by pressing ~RET~ again. + +* Special features + :properties: + :description: Enhancements over built-in `completing-read' + :end: + + Consult enhances =completing-read= with live previews of candidates, additional + narrowing capabilities to candidate groups and asynchronously generated + candidate lists. The internal =consult--read= function, which is used by most + Consult commands, is a thin wrapper around =completing-read= and provides the + special functionality. In order to support multiple candidate sources there + exists the high-level function =consult--multi=. The architecture of Consult + allows it to work with different completion systems in the backend, while still + offering advanced features. + +** Live previews + :properties: + :description: Preview the currently selected candidate + :custom_id: live-previews + :end: + #+cindex: preview + + Some Consult commands support live previews. For example when you scroll + through the items of =consult-line=, the buffer will scroll to the + corresponding position. It is possible to jump back and forth between the + minibuffer and the buffer to perform recursive editing while the search is + ongoing. + + Consult enables previews by default. You can disable them by adjusting the + =consult-preview-key= variable. Furthermore it is possible to specify keybindings + which trigger the preview manually as shown in the [[#use-package-example][example configuration]]. The + default setting of =consult-preview-key= is =any= which means that Consult triggers + the preview /immediately/ on any key press when the selected candidate changes. + You can configure each command individually with its own =:preview-key=. The + following settings are possible: + + - Automatic and immediate ='any= + - Automatic and delayed =(list :debounce 0.5 'any)= + - Manual and immediate =(kbd "M-.")= + - Manual and delayed =(list :debounce 0.5 (kbd "M-."))= + - Disabled =nil= + + A safe recommendation is to leave automatic immediate previews enabled in + general and disable the automatic preview only for commands, where the preview + may be expensive due to file loading. + + #+begin_src emacs-lisp + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-recent-file consult--source-project-recent-file consult--source-bookmark + :preview-key (kbd "M-.")) + #+end_src + + In this case one may wonder what the difference is between using an Embark + action on the current candidate in comparison to a manually triggered preview. + The main difference is that the files opened by manual preview are closed again + after the completion session. Furthermore during preview some functionality is + disabled to improve the performance, see for example + =consult-preview-excluded-hooks=. Files larger than =consult-preview-raw-size= + are previewed literally without syntax highlighting and without changing the + major mode. + + Delaying the preview is particularly useful for =consult-theme=, since the theme + preview is a little bit slow. The delay can result in a smoother UI. + + #+begin_src emacs-lisp + ;; Preview on any key press, but delay 0.5s + (consult-customize consult-theme :preview-key '(:debounce 0.5 any)) + ;; Preview immediately on M-., on up/down after 0.5s, on any other key after 1s + (consult-customize consult-theme + :preview-key + (list (kbd "M-.") + :debounce 0.5 (kbd "<up>") (kbd "<down>") + :debounce 1 'any)) + #+end_src + +** Narrowing and grouping + :properties: + :description: Restricting the completion to a candidate group + :custom_id: narrowing-and-grouping + :end: + #+cindex: narrowing + + Consult has special support for candidate groups. If the completion UI supports + the grouping functionality, the UI separates the groups with thin lines and + shows group titles. Grouping is useful if the list of candidates consists of + candidates of multiple types or candidates from [[#multiple-sources][multiple sources]], like the + =consult-buffer= command, which shows both buffers and recently opened files. + Note that you can disable the group titles by setting the =:group= property of + the corresponding command to nil using the =consult-customize= macro. + + By entering a narrowing prefix or by pressing a narrowing key it is possible to + restrict the completion candidates to a certain candidate group. When you use + the =consult-buffer= command, you can enter the prefix =b SPC= to restrict list of + candidates to buffers only. If you press =DEL= afterwards, the full candidate + list will be shown again. Furthermore a narrowing prefix key and a widening key + can be configured which can be pressed to achieve the same effect, see the + configuration variables =consult-narrow-key= and =consult-widen-key=. + + After pressing =consult-narrow-key=, the possible narrowing keys can be shown + by pressing =C-h=. When pressing =C-h= after some prefix key, the + =prefix-help-command= is invoked, which shows the keybinding help window by + default. As a more compact alternative, there is the =consult-narrow-help= + command which can be bound to a key, for example =?= or =C-h= in the + =consult-narrow-map=, as shown in the [[#use-package-example][example configuration]]. If [[https://github.com/justbur/emacs-which-key][which-key]] is + installed, the narrowing keys are automatically shown in the which-key window + after pressing the =consult-narrow-key=. + +** Asynchronous search + :properties: + :description: Filtering asynchronously generated candidate lists + :end: + #+cindex: asynchronous search + + Consult has support for asynchronous generation of candidate lists. This + feature is used for search commands like =consult-grep=, where the list of + matches is generated dynamically while the user is typing a regular expression. + The grep process is executed in the background. When modifying the regular + expression, the background process is terminated and a new process is started + with the modified regular expression. + + The matches, which have been found, can then be narrowed using the installed + Emacs completion-style. This can be powerful if you are using for example the + =orderless= completion style. + + This two-level filtering is possible by splitting the input string. Part of the + input string is treated as input to grep and part of the input is used for + filtering. There are multiple splitting styles available, configured in + ~consult-async-split-styles-alist~: =nil=, =comma=, =semicolon= and =perl=. The default + splitting style is configured with the variable ~consult-async-split-style~. + + With the =comma= and =semicolon= splitting styles, the first word before the comma + or semicolon is passed to grep, the remaining string is used for filtering. The + =nil= splitting style does not perform any splitting, the whole input is passed + to grep. + + The =perl= splitting style splits the input string at a punctuation character, + using a similar syntax as Perl regular expressions. + + Examples: + + - =#defun=: Search for "defun" using grep. + - =#consult embark=: Search for both "consult" and "embark" using grep in any order. + - =#first.*second=: Search for "first" followed by "second" using grep. + - =#\(consult\|embark\)=: Search for "consult" or "embark" using grep. Note the + usage of Emacs-style regular expressions. + - =#defun#consult=: Search for "defun" using grep, filter with the word + "consult". + - =/defun/consult=: It is also possible to use other punctuation + characters. + - =#to#=: Force searching for "to" using grep, since the grep pattern + must be longer than =consult-async-min-input= characters by default. + - =#defun -- --invert-match#=: Pass argument =--invert-match= to grep. + + Asynchronous processes like =find= and =grep= create an error log buffer + =_*consult-async*= (note the leading space), which is useful for + troubleshooting. The prompt has a small indicator showing the process status: + + - =:= the usual prompt colon, before input is provided. + - =*= with warning face, the process is running. + - =:= with success face, success, process exited with an error code of zero. + - =!= with error face, failure, process exited with a nonzero error code. + - =;= with error face, interrupted, for example if more input is provided. + +** Multiple sources + :properties: + :description: Combining candidates from different sources + :custom_id: multiple-sources + :end: + #+cindex: multiple sources + + Multiple synchronous candidate sources can be combined. This feature + is used by the =consult-buffer= command to present buffer-like candidates in a + single menu for quick access. By default =consult-buffer= includes buffers, + bookmarks, recent files and project-specific buffers and files. It is possible + to configure the list of sources via the =consult-buffer-sources= variable. + Arbitrary custom sources can be defined. + + As an example, the bookmark source is defined as follows: + + #+begin_src emacs-lisp + (defvar consult--source-bookmark + `(:name "Bookmark" + :narrow ?m + :category bookmark + :face consult-bookmark + :history bookmark-history + :items ,#'bookmark-all-names + :action ,#'consult--bookmark-action)) + #+end_src + + Required source fields: + - =:category= Completion category. + - =:items= List of strings to select from or function returning list of strings. + A list of cons cells is not supported. + + Optional source fields: + - =:name= Name of the source, used for narrowing, group titles and annotations. + - =:narrow= Narrowing character or =(character . string)= pair. + - =:preview-key= Preview key or keys which trigger preview. + - =:enabled= Function which must return t if the source is enabled. + - =:hidden= When t candidates of this source are hidden by default. + - =:face= Face used for highlighting the candidates. + - =:annotate= Annotation function called for each candidate, returns string. + - =:history= Name of history variable to add selected candidate. + - =:default= Must be t if the first item of the source is the default value. + - =:action= Action function called with the selected candidate. + - =:state= State constructor for the source, must return the state function. + - Other source fields can be added specifically to the use case. + + The =:state= and =:action= fields of the sources deserve a longer explanation. + The =:action= function takes a single argument and is only called after + selection with the selected candidate, if the selection has not been aborted. + This functionality is provided for convenience and easy definition of sources. + The =:state= field is more complicated and general. The =:state= function is a + constructor function without arguments, which can perform some setup + necessary for the preview. It must return a closure with two arguments: The + first argument is the candidate string, the second argument is the restore + flag. The state function is called during preview, if a preview key has been + pressed, with the selected candidate or nil and the restore argument being + nil. Furthermore the state function is always called after selection with the + selected candidate or nil. The state function is called with nil for the + candidate if for example the selection process has been aborted or if the + original preview state should be restored during preview. The restore flag is + t for the final call. The final call happens even if preview is disabled. For + this reason you can also use the final call to the state function in a similar + way as =:action=. You probably only want to specify both =:state= and + =:action= if =:state= is purely responsible for preview and =:action= is then + responsible for the real action after selection. + + In order to avoid slowness, =consult-buffer= only preview buffers by default. + Loading recent files, bookmarks or views can result in expensive operations. + However it is possible to configure the bookmark and file sources to also + perform preview. + + #+begin_src emacs-lisp + (consult-customize + consult--source-recent-file consult--source-project-recent-file consult--source-bookmark + :preview-key (kbd "M-.")) + #+end_src + + Sources can be added directly to the =consult-buffer-source= list for + convenience. For example views can be added to the list of virtual buffers + from a library like https://github.com/minad/bookmark-view/. + + #+begin_src emacs-lisp + ;; Configure new bookmark-view source + (add-to-list 'consult-buffer-sources + (list :name "View" + :narrow ?v + :category 'bookmark + :face 'font-lock-keyword-face + :history 'bookmark-view-history + :action #'consult--bookmark-action + :items #'bookmark-view-names) + 'append) + + ;; Modify bookmark source, such that views are hidden + (setq consult--source-bookmark + (plist-put + consult--source-bookmark :items + (lambda () + (bookmark-maybe-load-default-file) + (mapcar #'car + (seq-remove (lambda (x) + (eq #'bookmark-view-handler + (alist-get 'handler (cdr x)))) + bookmark-alist))))) + #+end_src + + Other useful sources allow the creation of terminal and eshell + buffers if they do not exist yet. + + #+begin_src emacs-lisp + (defun mode-buffer-exists-p (mode) + (seq-some (lambda (buf) + (provided-mode-derived-p + (buffer-local-value 'major-mode buf) + mode)) + (buffer-list))) + + (defvar eshell-source + `(:category 'consult-new + :face 'font-lock-constant-face + :action ,(lambda (_) (eshell)) + :items + ,(lambda () + (unless (mode-buffer-exists-p 'eshell-mode) + '("*eshell* (new)"))))) + + (defvar term-source + `(:category 'consult-new + :face 'font-lock-constant-face + :action + ,(lambda (_) + (ansi-term (or (getenv "SHELL") "/bin/sh"))) + :items + ,(lambda () + (unless (mode-buffer-exists-p 'term-mode) + '("*ansi-term* (new)"))))) + + (add-to-list 'consult-buffer-sources 'eshell-source 'append) + (add-to-list 'consult-buffer-sources 'term-source 'append) + #+end_src + + For more details, see the documentation of =consult-buffer= and of the + internal =consult--multi= API. The =consult--multi= function can be used to + create new multi-source commands, but is part of the internal API as of now, + since some details may still change. + +** Embark integration + :properties: + :description: Actions, Grep/Occur-buffer export + :custom_id: embark-integration + :end: + #+cindex: embark + + *NOTE*: Install the =embark-consult= package from MELPA, which provides + Consult-specific Embark actions and the Occur buffer export. + + Embark is a versatile package which offers context dependent actions, + comparable to a context menu. See the [[https://github.com/oantolin/embark][Embark manual]] for an extensive + description of its capabilities. + + Actions are commands which can operate on the currently selected candidate (or + target in Embark terminology). When completing files, for example the + =delete-file= command is offered. With Embark you can execute arbitrary commands + on the currently selected candidate via =M-x=. + + Furthermore Embark provides the =embark-collect-snapshot= command, which collects + candidates and presents them in an Embark collect buffer, where further actions + can be applied to them. A related feature is the =embark-export= command, which + exports candidate lists to a buffer of a special type. For example in the case + of file completion, a Dired buffer is opened. + + In the context of Consult, particularly exciting is the possibility to export + the matching lines from =consult-line=, =consult-outline=, =consult-mark= and + =consult-global-mark=. The matching lines are exported to an Occur buffer where + they can be edited via the =occur-edit-mode= (press key =e=). Similarly, + Embark supports exporting the matches found by =consult-grep=, + =consult-ripgrep= and =consult-git-grep= to a Grep buffer, where the matches + across files can be edited, if the [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]] package is installed. These three + workflows are symmetric. + + + =consult-line= -> =embark-export= to =occur-mode= buffer + -> =occur-edit-mode= for editing of matches in buffer. + + =consult-grep= -> =embark-export= to =grep-mode= buffer + -> =wgrep= for editing of all matches. + + =consult-find= -> =embark-export= to =dired-mode= buffer + -> =wdired-change-to-wdired-mode= for editing. + +* Configuration + :properties: + :description: Example configuration and customization variables + :end: + +Consult can be installed from [[http://elpa.gnu.org/packages/consult.html][ELPA]] or [[https://melpa.org/#/consult][MELPA]] via the Emacs built-in package +manager. Alternatively it can be directly installed from the development +repository via other non-standard package managers. + +There is the [[https://github.com/minad/consult/wiki][Consult wiki]], where additional configuration examples can be +contributed. + +*IMPORTANT:* It is strongly recommended that you enable [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html][lexical binding]] in your +configuration. Consult uses a functional programming style, relying on lambdas +and lexical closures. For this reason many Consult-related snippets require +lexical binding. + +** Use-package example + :properties: + :description: Configuration example based on use-package + :custom_id: use-package-example + :end: + #+cindex: use-package + +The Consult package only provides commands and does not add any keybindings or +modes. Therefore the package is non-intrusive but requires a little setup +effort. In order to use the Consult commands, it is advised to add keybindings +for commands which are accessed often. Rarely used commands can be invoked via +=M-x=. Feel free to only bind the commands you consider useful to your workflow. +The configuration shown here relies on the =use-package= macro, which is a +convenient tool to manage package configurations. + +*NOTE:* There is the [[https://github.com/minad/consult/wiki][Consult wiki]], where you can contribute additional +configuration examples. + + #+begin_src emacs-lisp + ;; Example configuration for Consult + (use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings (mode-specific-map) + ("C-c h" . consult-history) + ("C-c m" . consult-mode-command) + ("C-c k" . consult-kmacro) + ;; C-x bindings (ctl-x-map) + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ("<help> a" . consult-apropos) ;; orig. apropos-command + ;; M-g bindings (goto-map) + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings (search-map) + ("M-s d" . consult-find) + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s m" . consult-multi-occur) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi)) ;; needed by consult-line to detect isearch + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. You may want to also + ;; enable `consult-preview-at-point-mode` in Embark Collect buffers. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Optionally replace `completing-read-multiple' with an enhanced version. + (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key (kbd "M-.")) + ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>"))) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme + :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-recent-file consult--source-project-recent-file consult--source-bookmark + :preview-key (kbd "M-.")) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; (kbd "C-+") + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; Optionally configure a function which returns the project root directory. + ;; There are multiple reasonable alternatives to chose from. + ;;;; 1. project.el (project-roots) + (setq consult-project-root-function + (lambda () + (when-let (project (project-current)) + (car (project-roots project))))) + ;;;; 2. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-root-function #'projectile-project-root) + ;;;; 3. vc.el (vc-root-dir) + ;; (setq consult-project-root-function #'vc-root-dir) + ;;;; 4. locate-dominating-file + ;; (setq consult-project-root-function (lambda () (locate-dominating-file "." ".git"))) + ) + #+end_src + +** Custom variables + :properties: + :description: Short description of all customization settings + :end: + #+cindex: customization + + *TIP:* If you have [[https://github.com/minad/marginalia][Marginalia]] installed, type =M-x customize-variable RET + ^consult= to see all Consult-specific customizable variables with their current + values and abbreviated description. Alternatively, type =C-h a ^consult= to get + an overview of all Consult variables and functions with their descriptions. + + | Variable | Description | + |----------------------------------+-------------------------------------------------------| + | consult-after-jump-hook | Functions to call after jumping to a location | + | consult-async-input-debounce | Input debounce for asynchronous commands | + | consult-async-input-throttle | Input throttle for asynchronous commands | + | consult-async-min-input | Minimum numbers of letters needed for async process | + | consult-async-refresh-delay | Refresh delay for asynchronous commands | + | consult-async-split-style | Splitting style used for async commands | + | consult-async-split-styles-alist | Available splitting styles used for async commands | + | consult-bookmark-narrow | Narrowing configuration for =consult-bookmark= | + | consult-buffer-filter | Filter for =consult-buffer= | + | consult-buffer-sources | List of virtual buffer sources | + | consult-crm-prefix | Prefix string for CRM candidates | + | consult-find-args | Command line arguments for find | + | consult-fontify-max-size | Buffers larger than this limit are not fontified | + | consult-fontify-preserve | Preserve fontification for line-based commands. | + | consult-git-grep-args | Command line arguments for git-grep | + | consult-goto-line-numbers | Show line numbers for =consult-goto-line= | + | consult-grep-max-columns | Maximal number of columns of the matching lines | + | consult-grep-args | Command line arguments for grep | + | consult-imenu-config | Mode-specific configuration for =consult-imenu= | + | consult-line-numbers-widen | Show absolute line numbers when narrowing is active. | + | consult-line-point-placement | Placement of the point used by =consult-line= | + | consult-line-start-from-top | Start the =consult-line= search from the top | + | consult-locate-args | Command line arguments for locate | + | consult-man-args | Command line arguments for man | + | consult-mode-command-filter | Filter for =consult-mode-command= | + | consult-mode-histories | Mode-specific history variables | + | consult-narrow-key | Narrowing prefix key during completion | + | consult-preview-key | Keys which triggers preview | + | consult-preview-excluded-hooks | List of =find-file= hooks to avoid during preview | + | consult-preview-max-count | Maximum number of files to keep open during preview | + | consult-preview-max-size | Files larger than this size are not previewed | + | consult-preview-raw-size | Files larger than this size are previewed in raw form | + | consult-project-root-function | Function which returns current project root | + | consult-recent-file-filter | Filter for =consult-recent-file= | + | consult-register-narrow | Narrowing configuration for =consult-register= | + | consult-ripgrep-args | Command line arguments for ripgrep | + | consult-themes | List of themes to be presented for selection | + | consult-widen-key | Widening key during completion | + +** Fine-tuning of individual commands + :properties: + :alt_title: Fine-tuning + :description: Fine-grained configuration for special requirements + :end: + + *NOTE:* Consult supports fine-grained customization of individual commands. This + configuration feature exists for experienced users with special requirements. + There is the [[https://github.com/minad/consult/wiki][Consult wiki]], where we collect further configuration examples. + + Commands and buffer sources allow flexible, individual customization by using + the =consult-customize= macro. You can override any option passed to the internal + =consult--read= API. The [[https://github.com/minad/consult/wiki][Consult wiki]] already contains a numerous useful + configuration examples. Note that since =consult--read= is part of the internal + API, options could be removed, replaced or renamed in future versions of the + package. + + Useful options are: + - =:prompt= set the prompt string + - =:preview-key= set the preview key, default is =consult-preview-key= + - =:initial= set the initial input + - =:default= set the default value + - =:history= set the history variable symbol + - =:add-history= add items to the future history, for example symbol at point + - =:sort= enable or disable sorting + - =:group= set to nil to disable candidate grouping and titles. + - =:inherit-input-method= set to non-nil to inherit the input method. + + #+begin_src emacs-lisp + (consult-customize + ;; Disable preview for `consult-theme' completely. + consult-theme :preview-key nil + ;; Set preview for `consult-buffer' to key `M-.' + consult-buffer :preview-key (kbd "M-.") + ;; For `consult-line' change the prompt and specify multiple preview + ;; keybindings. Note that you should bind <S-up> and <S-down> in the + ;; `minibuffer-local-completion-map' or `vertico-map' to the commands which + ;; select the previous or next candidate. + consult-line :prompt "Search: " + :preview-key (list (kbd "<S-down>") (kbd "<S-up>"))) + #+end_src + + Generally it is possible to modify commands for your individual needs by the + following techniques: + + 1. Use =consult-customize= in order to change the command or source settings. + 2. Create your own wrapper function which passes modified arguments to the Consult functions. + 3. Create your own buffer [[#multiple-sources][multi sources]] for =consult-buffer=. + 4. Create advices to modify some internal behavior. + 5. Write or propose a patch. + +* Recommended packages + :properties: + :description: Related packages recommended for installation + :end: + +I use and recommend this combination of packages: + +- consult: This package +- [[https://github.com/minad/vertico][vertico]]: Fast and minimal vertical completion system +- [[https://github.com/minad/marginalia][marginalia]]: Annotations for the completion candidates +- [[https://github.com/oantolin/embark][embark and embark-consult]]: Action commands, which can act on the completion candidates +- [[https://github.com/oantolin/orderless][orderless]]: Completion style which offers flexible candidate filtering + +There exist many other fine completion UIs beside Vertico, which are supported +by Consult. Give them a try and find out which interaction model fits best for +you! + +- [[https://github.com/raxod502/selectrum][selectrum by Radon Rosborough]]: Alternative vertical completion system. +- [[https://github.com/oantolin/icomplete-vertical][icomplete-vertical by Omar Antolín Camarena]]: Vertical completion system based on Icomplete. + Icomplete-vertical is only needed for Emacs 27, built-in on Emacs 28. +- [[https://github.com/oantolin/embark][embark by Omar Antolín Camarena]]: Completion based on live updating Embark collect buffer. +- [[https://gitlab.com/protesilaos/mct][mct by Protesilaos Stavrou]]: Minibuffer and Completions in Tandem, which builds + on the default completion UI. + +You can integrated Consult with special programs or with other packages in the +wider Emacs ecosystem. You may want to install some of theses packages depending +on your preferences and requirements. + +- [[https://github.com/mohkale/consult-company][consult-company]]: Completion at point using the company backends. +- [[https://github.com/karthink/consult-dir][consult-dir]]: Directory jumper using Consult multi sources. +- [[https://github.com/mohkale/consult-eglot][consult-eglot]]: Integration with eglot (lsp client). +- [[https://github.com/minad/consult-flycheck][consult-flycheck]]: Provides the =consult-flycheck= command. +- [[https://github.com/gagbo/consult-lsp][consult-lsp]]: Integration with =lsp-mode= (lsp client). +- [[https://codeberg.org/jao/consult-notmuch][consult-notmuch]]: Access the [[https://notmuchmail.org/][Notmuch]] email system using Consult. +- [[https://codeberg.org/jao/espotify][consult-spotify]]: Access the Spotify API and control your local music player. +- [[https://gitlab.com/OlMon/consult-projectile/][consult-projectile]]: Projectile integration, buffer sources for Projectile. +- [[https://codeberg.org/jao/consult-recoll][consult-recoll]]: Access the [[https://www.lesbonscomptes.com/recoll/][Recoll]] desktop full-text search using Consult. +- [[https://github.com/mohkale/consult-yasnippet][consult-yasnippet]]: Integration with yasnippet. +- [[https://github.com/minad/affe][affe]]: Asynchronous Fuzzy Finder for Emacs (uses Consult under the hood). + +Not directly related to Consult, but maybe still of interest are the following +packages. These packages should work well with Consult, follow a similar spirit or +offer functionality based on ~completing-read~. + +- [[https://github.com/minad/corfu][corfu]]: Completion systems for =completion-at-point= using small popups (Alternative to [[https://github.com/company-mode/company-mode][company]]). +- [[https://github.com/minad/cape][cape]]: Completion At Point Extensions, which can be used with =consult-completion-in-region= and [[https://github.com/minad/corfu][Corfu]]. +- [[https://github.com/minad/bookmark-view][bookmark-view]]: Store window configuration as bookmarks, possible integration with =consult-buffer=. +- [[https://github.com/bdarcus/citar][citar]]: Versatile package for citation insertion and bibliography management. +- [[https://github.com/d12frosted/flyspell-correct][flyspell-correct]]: Apply spelling corrections by selecting via =completing-read=. +- [[https://github.com/mhayashi1120/Emacs-wgrep][wgrep]]: Editing of grep buffers, use together with =consult-grep= via =embark-export=. +- [[https://github.com/iyefrat/all-the-icons-completion][all-the-icons-completion]]: Icons for the completion UI. + +Note that all packages are independent and can be exchanged with alternative +components, since there exist no hard dependencies. Furthermore it is possible +to get started with only default completion and Consult and add more components +later to the mix. For example you can omit Marginalia if you don't need +annotations. I highly recommend the Embark package, but in order to familarize +yourself with the other components, you can first start without it - or you could +even start with Embark right away and add the other components later on. + +* Bug reports + :properties: + :description: How to create reproducible bug reports + :end: + +If you find a bug or suspect that there is a problem with Consult, please carry +out the following steps: + +1. *Update all the relevant packages to the newest version*. + This includes Consult, Vertico, Mct, Selectrum, Icomplete-vertical, + Marginalia, Embark, Orderless and Prescient in case you are using any of + those packages. +2. Either use the default completion UI or ensure that exactly one of + =vertico-mode=, =selectrum-mode=, =mct-mode=, or =icomplete-mode= is enabled. + Furthermore =ivy-mode= and =helm-mode= must be disabled. +3. Ensure that the =completion-styles= variable is properly configured. Try to set + =completion-styles= to a list including =substring= or =orderless=. +4. Try to reproduce the issue by starting a bare bone Emacs instance with =emacs -Q= + on the command line. Execute the following minimal code snippets in the + scratch buffer. This way we can exclude side effects due to configuration + settings. If other packages are relevant to reproduce the issue, include them + in the minimal configuration snippet. + +Minimal setup with Vertico for =emacs -Q=: +#+begin_src emacs-lisp +(package-initialize) +(require 'consult) +(require 'vertico) +(vertico-mode) +(setq completion-styles '(substring)) +#+end_src + +Minimal setup with the default completion system for =emacs -Q=: +#+begin_src emacs-lisp +(package-initialize) +(require 'consult) +(setq completion-styles '(substring)) +#+end_src + +Please provide the necessary important information with your bug report: + +- The minimal configuration snippet used to reproduce the issue. +- Your completion UI (Default completion, Vertico, Mct, Selectrum or Icomplete). +- The full stack trace in case the bug triggers an exception. +- Your Emacs version, since bugs may be fixed or introduced in newer versions. +- Your operating system, since Emacs behavior varies between Linux, Mac and + Windows. +- The package manager, e.g., straight.el or package.el, used to install + the Emacs packages, in order to exclude update issues. Did you install + Consult as part of the Doom or Spacemacs Emacs distributions? +- If you are using Evil or other packages which change Emacs fundamentally, + since Consult does not provide Evil integration out of the box. + +When evaluating Consult-related code snippets you should enable [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html][lexical binding]]. +Consult often uses a functional programming style, relying on lambdas and +lexical closures. + +The Selectrum repository provides a [[https://github.com/raxod502/selectrum/tree/master/test][set of scripts]] which allow experimenting +with multiple package combinations of completion systems and Consult. After +cloning the repository, you can execute the scripts with =cd selectrum/test; +./run.sh <package-combo.el>=. The scripts do not modify your existing Emacs +configuration, but create a separate Emacs configuration in =/tmp=. + +* Contributions + :properties: + :description: Feature requests and pull requests + :end: + +Consult is a community effort, please participate in the discussions. +Contributions are welcome, but you may want to discuss potential contributions +first. Since this package is part of [[http://elpa.gnu.org/packages/consult.html][GNU ELPA]] contributions require a copyright +assignment to the FSF. + +If you have a proposal, take a look at the [[https://github.com/consult/issues][Consult issue tracker]] and the [[https://github.com/minad/consult/issues/6][Consult +wishlist]]. There have been many prior feature discussions. Please search through +the issue tracker, maybe your issue or feature request has already been +discussed. You can contribute to the [[https://github.com/minad/consult/wiki][Consult wiki]], in case you want to share +small configuration or command snippets. + +* Acknowledgments + :properties: + :description: Contributors and Sources of Inspiration + :end: + +You probably guessed from the name that this package took inspiration from +[[https://github.com/abo-abo/swiper#counsel][Counsel]] by Oleh Krehel. Some of the Consult commands originated in the Counsel +package or the [[https://github.com/raxod502/selectrum/wiki/Useful-Commands][Selectrum wiki]]. The commands have been rewritten and greatly +enhanced in comparison to the original versions. + +Code contributions: +- [[https://github.com/oantolin/][Omar Antolín Camarena]] +- [[https://github.com/s-kostyaev/][Sergey Kostyaev]] +- [[https://github.com/okamsn/][okamsn]] +- [[https://github.com/clemera/][Clemens Radermacher]] +- [[https://github.com/tomfitzhenry/][Tom Fitzhenry]] +- [[https://github.com/jakanakaevangeli][jakanakaevangeli]] +- [[https://hg.serna.eu][Iñigo Serna]] +- [[https://github.com/aspiers/][Adam Spiers]] +- [[https://github.com/omar-polo][Omar Polo]] +- [[https://github.com/astoff][Augusto Stoffel]] +- [[https://github.com/noctuid][Fox Kiester]] +- [[https://github.com/tecosaur][Tecosaur]] +- [[https://github.com/mohamed-abdelnour][Mohamed Abdelnour]] +- [[https://github.com/thisirs][Sylvain Rousseau]] + +Advice and useful discussions: +- [[https://github.com/clemera/][Clemens Radermacher]] +- [[https://github.com/oantolin/][Omar Antolín Camarena]] +- [[https://gitlab.com/protesilaos/][Protesilaos Stavrou]] +- [[https://github.com/purcell/][Steve Purcell]] +- [[https://github.com/alphapapa/][Adam Porter]] +- [[https://github.com/manuel-uberti/][Manuel Uberti]] +- [[https://github.com/tomfitzhenry/][Tom Fitzhenry]] +- [[https://github.com/hmelman/][Howard Melman]] +- [[https://github.com/monnier/][Stefan Monnier]] +- [[https://github.com/dgutov/][Dmitry Gutov]] +- [[https://github.com/iyefrat][Itai Y. Efrat]] +- [[https://github.com/bdarcus][Bruce d'Arcus]] + +Authors of supplementary =consult-*= packages: + +- [[https://codeberg.org/jao/][Jose A Ortega Ruiz]] ([[https://codeberg.org/jao/consult-notmuch][consult-notmuch]], [[https://codeberg.org/jao/consult-recoll][consult-recoll]], [[https://codeberg.org/jao/espotify][consult-spotify]]) +- [[https://github.com/gagbo/][Gerry Agbobada]] ([[https://github.com/gagbo/consult-lsp][consult-lsp]]) +- [[https://github.com/karthink][Karthik Chikmagalur]] ([[https://github.com/karthink/consult-dir][consult-dir]]) +- [[https://github.com/mohkale][Mohsin Kaleem]] ([[https://github.com/mohkale/consult-company][consult-company]], [[https://github.com/mohkale/consult-eglot][consult-eglot]], [[https://github.com/mohkale/consult-yasnippet][consult-yasnippet]]) +- [[https://gitlab.com/OlMon][Marco Pawłowski]] ([[https://gitlab.com/OlMon/consult-projectile][consult-projectile]]) + +#+html: <!-- + +* Indices + :properties: + :description: Indices of concepts and functions + :end: + +** Function index + :properties: + :description: List of all Consult commands + :index: fn + :end: + +** Concept index + :properties: + :description: List of all Consult-specific concepts + :index: cp + :end: + +#+html: --> diff --git a/elpa/consult-0.14/consult-autoloads.el b/elpa/consult-0.14/consult-autoloads.el @@ -0,0 +1,506 @@ +;;; consult-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "consult" "consult.el" (0 0 0 0)) +;;; Generated autoloads from consult.el + +(autoload 'consult-completion-in-region "consult" "\ +Use minibuffer completion as the UI for `completion-at-point'. + +The function is called with 4 arguments: START END COLLECTION PREDICATE. +The arguments and expected return value are as specified for +`completion-in-region'. Use as a value for `completion-in-region-function'. + +The function can be configured via `consult-customize'. + + (consult-customize consult-completion-in-region + :completion-styles (basic) + :cycle-threshold 3) + +These configuration options are supported: + + * :cycle-threshold - Cycling threshold (def: `completion-cycle-threshold') + * :completion-styles - Use completion styles (def: `completion-styles') + * :require-match - Require matches when completing (def: nil) + * :prompt - The prompt string shown in the minibuffer + +\(fn START END COLLECTION &optional PREDICATE)" nil nil) + +(autoload 'consult-completing-read-multiple "consult" "\ +Enhanced replacement for `completing-read-multiple'. +See `completing-read-multiple' for the documentation of the arguments. + +\(fn PROMPT TABLE &optional PRED REQUIRE-MATCH INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)" nil nil) + +(autoload 'consult-multi-occur "consult" "\ +Improved version of `multi-occur' based on `completing-read-multiple'. + +See `multi-occur' for the meaning of the arguments BUFS, REGEXP and NLINES. + +\(fn BUFS REGEXP &optional NLINES)" t nil) + +(autoload 'consult-outline "consult" "\ +Jump to an outline heading, obtained by matching against `outline-regexp'. + +This command supports narrowing to a heading level and candidate preview. +The symbol at point is added to the future history." t nil) + +(autoload 'consult-mark "consult" "\ +Jump to a marker in MARKERS list (defaults to buffer-local `mark-ring'). + +The command supports preview of the currently selected marker position. +The symbol at point is added to the future history. + +\(fn &optional MARKERS)" t nil) + +(autoload 'consult-global-mark "consult" "\ +Jump to a marker in MARKERS list (defaults to `global-mark-ring'). + +The command supports preview of the currently selected marker position. +The symbol at point is added to the future history. + +\(fn &optional MARKERS)" t nil) + +(autoload 'consult-line "consult" "\ +Search for a matching line. + +Depending on the setting `consult-line-point-placement' the command jumps to +the beginning or the end of the first match on the line or the line beginning. +The default candidate is the non-empty line next to point. This command obeys +narrowing. Optional INITIAL input can be provided. The search starting point is +changed if the START prefix argument is set. The symbol at point and the last +`isearch-string' is added to the future history. + +\(fn &optional INITIAL START)" t nil) + +(autoload 'consult-line-multi "consult" "\ +Search for a matching line in multiple buffers. + +By default search across all project buffers. If the prefix argument QUERY is +non-nil, all buffers are searched. Optional INITIAL input can be provided. See +`consult-line' for more information. In order to search a subset of buffers, +QUERY can be set to a plist according to `consult--buffer-query'. + +\(fn QUERY &optional INITIAL)" t nil) + +(autoload 'consult-keep-lines "consult" "\ +Select a subset of the lines in the current buffer with live preview. + +The selected lines are kept and the other lines are deleted. When called +interactively, the lines selected are those that match the minibuffer input. In +order to match the inverse of the input, prefix the input with `! '. When +called from elisp, the filtering is performed by a FILTER function. This +command obeys narrowing. + +FILTER is the filter function. +INITIAL is the initial input. + +\(fn &optional FILTER INITIAL)" t nil) + +(autoload 'consult-focus-lines "consult" "\ +Hide or show lines using overlays. + +The selected lines are shown and the other lines hidden. When called +interactively, the lines selected are those that match the minibuffer input. In +order to match the inverse of the input, prefix the input with `! '. With +optional prefix argument SHOW reveal the hidden lines. Alternatively the +command can be restarted to reveal the lines. When called from elisp, the +filtering is performed by a FILTER function. This command obeys narrowing. + +FILTER is the filter function. +INITIAL is the initial input. + +\(fn &optional SHOW FILTER INITIAL)" t nil) + +(autoload 'consult-goto-line "consult" "\ +Read line number and jump to the line with preview. + +Jump directly if a line number is given as prefix ARG. The command respects +narrowing and the settings `consult-goto-line-numbers' and +`consult-line-numbers-widen'. + +\(fn &optional ARG)" t nil) + +(autoload 'consult-recent-file "consult" "\ +Find recent file using `completing-read'." t nil) + +(autoload 'consult-file-externally "consult" "\ +Open FILE externally using the default application of the system. + +\(fn FILE)" t nil) + +(autoload 'consult-mode-command "consult" "\ +Run a command from any of the given MODES. + +If no MODES are specified, use currently active major and minor modes. + +\(fn &rest MODES)" t nil) + +(autoload 'consult-yank-from-kill-ring "consult" "\ +Select STRING from the kill ring and insert it. +With prefix ARG, put point at beginning, and mark at end, like `yank' does. + +This command behaves like `yank-from-kill-ring' in Emacs 28, which also offers +a `completing-read' interface to the `kill-ring'. Additionally the Consult +version supports preview of the selected string. + +\(fn STRING &optional ARG)" t nil) + +(autoload 'consult-yank-pop "consult" "\ +If there is a recent yank act like `yank-pop'. + +Otherwise select string from the kill ring and insert it. +See `yank-pop' for the meaning of ARG. + +This command behaves like `yank-pop' in Emacs 28, which also offers a +`completing-read' interface to the `kill-ring'. Additionally the Consult +version supports preview of the selected string. + +\(fn &optional ARG)" t nil) + +(autoload 'consult-yank-replace "consult" "\ +Select STRING from the kill ring. + +If there was no recent yank, insert the string. +Otherwise replace the just-yanked string with the selected string. + +There exists no equivalent of this command in Emacs 28. + +\(fn STRING)" t nil) + +(autoload 'consult-bookmark "consult" "\ +If bookmark NAME exists, open it, otherwise create a new bookmark with NAME. + +The command supports preview of file bookmarks and narrowing. See the +variable `consult-bookmark-narrow' for the narrowing configuration. + +\(fn NAME)" t nil) + +(autoload 'consult-apropos "consult" "\ +Select pattern and call `apropos'. + +The default value of the completion is the symbol at point. As a better +alternative, you can run `embark-export' from commands like `M-x' and +`describe-symbol'." t nil) + +(autoload 'consult-complex-command "consult" "\ +Select and evaluate command from the command history. + +This command can act as a drop-in replacement for `repeat-complex-command'." t nil) + +(autoload 'consult-history "consult" "\ +Insert string from HISTORY of current buffer. + +In order to select from a specific HISTORY, pass the history variable +as argument. + +\(fn &optional HISTORY)" t nil) + +(autoload 'consult-isearch-history "consult" "\ +Read a search string with completion from the Isearch history. + +This replaces the current search string if Isearch is active, and +starts a new Isearch session otherwise." t nil) + +(autoload 'consult-minor-mode-menu "consult" "\ +Enable or disable minor mode. + +This is an alternative to `minor-mode-menu-from-indicator'." t nil) + +(autoload 'consult-theme "consult" "\ +Disable current themes and enable THEME from `consult-themes'. + +The command supports previewing the currently selected theme. + +\(fn THEME)" t nil) + +(autoload 'consult-buffer "consult" "\ +Enhanced `switch-to-buffer' command with support for virtual buffers. + +The command supports recent files, bookmarks, views and project files as virtual +buffers. Buffers are previewed. Furthermore narrowing to buffers (b), files (f), +bookmarks (m) and project files (p) is supported via the corresponding keys. In +order to determine the project-specific files and buffers, the +`consult-project-root-function' is used. See `consult-buffer-sources' and +`consult--multi' for the configuration of the virtual buffer sources." t nil) + +(autoload 'consult-buffer-other-window "consult" "\ +Variant of `consult-buffer' which opens in other window." t nil) + +(autoload 'consult-buffer-other-frame "consult" "\ +Variant of `consult-buffer' which opens in other frame." t nil) + +(autoload 'consult-kmacro "consult" "\ +Run a chosen keyboard macro. + +With prefix ARG, run the macro that many times. +Macros containing mouse clicks are omitted. + +\(fn ARG)" t nil) + +(autoload 'consult-grep "consult" "\ +Search for regexp with grep in DIR with INITIAL input. + +The input string is split, the first part of the string (grep input) is +passed to the asynchronous grep process and the second part of the string is +passed to the completion-style filtering. + +The input string is split at a punctuation character, which is given as the +first character of the input string. The format is similar to Perl-style +regular expressions, e.g., /regexp/. Furthermore command line options can be +passed to grep, specified behind --. The overall prompt input has the form +`#async-input -- grep-opts#filter-string'. + +Note that the grep input string is transformed from Emacs regular expressions +to Posix regular expressions. Always enter Emacs regular expressions at the +prompt. `consult-grep' behaves like builtin Emacs search commands, e.g., +Isearch, which take Emacs regular expressions. Furthermore the asynchronous +input split into words, each word must match separately and in any order. See +`consult--regexp-compiler' for the inner workings. In order to disable +transformations of the grep input, adjust `consult--regexp-compiler' +accordingly. + +Here we give a few example inputs: + +#alpha beta : Search for alpha and beta in any order. +#alpha.*beta : Search for alpha before beta. +#\\(alpha\\|beta\\) : Search for alpha or beta (Note Emacs syntax!) +#word -- -C3 : Search for word, include 3 lines as context +#first#second : Search for first, quick filter for second. + +The symbol at point is added to the future history. If `consult-grep' +is called interactively with a prefix argument, the user can specify +the directory to search in. By default the project directory is used +if `consult-project-root-function' is defined and returns non-nil. +Otherwise the `default-directory' is searched. + +\(fn &optional DIR INITIAL)" t nil) + +(autoload 'consult-git-grep "consult" "\ +Search for regexp with grep in DIR with INITIAL input. + +See `consult-grep' for more details. + +\(fn &optional DIR INITIAL)" t nil) + +(autoload 'consult-ripgrep "consult" "\ +Search for regexp with rg in DIR with INITIAL input. + +See `consult-grep' for more details. + +\(fn &optional DIR INITIAL)" t nil) + +(autoload 'consult-find "consult" "\ +Search for regexp with find in DIR with INITIAL input. + +The find process is started asynchronously, similar to `consult-grep'. +See `consult-grep' for more details regarding the asynchronous search. + +\(fn &optional DIR INITIAL)" t nil) + +(autoload 'consult-locate "consult" "\ +Search for regexp with locate with INITIAL input. + +The locate process is started asynchronously, similar to `consult-grep'. +See `consult-grep' for more details regarding the asynchronous search. + +\(fn &optional INITIAL)" t nil) + +(autoload 'consult-man "consult" "\ +Search for regexp with man with INITIAL input. + +The man process is started asynchronously, similar to `consult-grep'. +See `consult-grep' for more details regarding the asynchronous search. + +\(fn &optional INITIAL)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult" '("consult-"))) + +;;;*** + +;;;### (autoloads nil "consult-compile" "consult-compile.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from consult-compile.el + +(autoload 'consult-compile-error "consult-compile" "\ +Jump to a compilation error in the current buffer. + +This command collects entries from compilation buffers and grep +buffers related to the current buffer. The command supports +preview of the currently selected error." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-compile" '("consult-compile--"))) + +;;;*** + +;;;### (autoloads nil "consult-flymake" "consult-flymake.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from consult-flymake.el + +(autoload 'consult-flymake "consult-flymake" "\ +Jump to Flymake diagnostic." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-flymake" '("consult-flymake--"))) + +;;;*** + +;;;### (autoloads nil "consult-icomplete" "consult-icomplete.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from consult-icomplete.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-icomplete" '("consult-icomplete--refresh"))) + +;;;*** + +;;;### (autoloads nil "consult-imenu" "consult-imenu.el" (0 0 0 0)) +;;; Generated autoloads from consult-imenu.el + +(autoload 'consult-imenu "consult-imenu" "\ +Select item from flattened `imenu' using `completing-read' with preview. + +The command supports preview and narrowing. See the variable +`consult-imenu-config', which configures the narrowing. +The symbol at point is added to the future history. + +See also `consult-imenu-multi'." t nil) + +(autoload 'consult-imenu-multi "consult-imenu" "\ +Select item from the imenus of all buffers from the same project. + +In order to determine the buffers belonging to the same project, the +`consult-project-root-function' is used. Only the buffers with the +same major mode as the current buffer are used. See also +`consult-imenu' for more details. In order to search a subset of buffers, +QUERY can be set to a plist according to `consult--buffer-query'. + +\(fn &optional QUERY)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-imenu" '("consult-imenu-"))) + +;;;*** + +;;;### (autoloads nil "consult-org" "consult-org.el" (0 0 0 0)) +;;; Generated autoloads from consult-org.el + +(autoload 'consult-org-heading "consult-org" "\ +Jump to an Org heading. + +MATCH and SCOPE are as in `org-map-entries' and determine which +entries are offered. By default, all entries of the current +buffer are offered. + +\(fn &optional MATCH SCOPE)" t nil) + +(autoload 'consult-org-agenda "consult-org" "\ +Jump to an Org agenda heading. + +By default, all agenda entries are offered. MATCH is as in +`org-map-entries' and can used to refine this. + +\(fn &optional MATCH)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-org" '("consult-org--"))) + +;;;*** + +;;;### (autoloads nil "consult-register" "consult-register.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from consult-register.el + +(autoload 'consult-register-window "consult-register" "\ +Enhanced drop-in replacement for `register-preview'. + +BUFFER is the window buffer. +SHOW-EMPTY must be t if the window should be shown for an empty register list. + +\(fn BUFFER &optional SHOW-EMPTY)" nil nil) + +(autoload 'consult-register-format "consult-register" "\ +Enhanced preview of register REG. + +This function can be used as `register-preview-function'. + +\(fn REG)" nil nil) + +(autoload 'consult-register "consult-register" "\ +Load register and either jump to location or insert the stored text. + +This command is useful to search the register contents. For quick access to +registers it is still recommended to use the register functions +`consult-register-load' and `consult-register-store' or the built-in built-in +register access functions. The command supports narrowing, see +`consult-register-narrow'. Marker positions are previewed. See +`jump-to-register' and `insert-register' for the meaning of prefix ARG. + +\(fn &optional ARG)" t nil) + +(autoload 'consult-register-load "consult-register" "\ +Do what I mean with a REG. + +For a window configuration, restore it. For a number or text, insert it. For a +location, jump to it. See `jump-to-register' and `insert-register' for the +meaning of prefix ARG. + +\(fn REG &optional ARG)" t nil) + +(autoload 'consult-register-store "consult-register" "\ +Store register dependent on current context, showing an action menu. + +With an active region, store/append/prepend the contents, optionally deleting +the region when a prefix ARG is given. With a numeric prefix ARG, store/add the +number. Otherwise store point, frameset, window or kmacro. + +\(fn ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-register" '("consult-register-"))) + +;;;*** + +;;;### (autoloads nil "consult-selectrum" "consult-selectrum.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from consult-selectrum.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-selectrum" '("consult-selectrum--"))) + +;;;*** + +;;;### (autoloads nil "consult-vertico" "consult-vertico.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from consult-vertico.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-vertico" '("consult-vertico--"))) + +;;;*** + +;;;### (autoloads nil "consult-xref" "consult-xref.el" (0 0 0 0)) +;;; Generated autoloads from consult-xref.el + +(autoload 'consult-xref "consult-xref" "\ +Show xrefs with preview in the minibuffer. + +This function can be used for `xref-show-xrefs-function'. +See `xref-show-xrefs-function' for the description of the +FETCHER and ALIST arguments. + +\(fn FETCHER &optional ALIST)" nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "consult-xref" '("consult-xref--"))) + +;;;*** + +;;;### (autoloads nil nil ("consult-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; consult-autoloads.el ends here diff --git a/elpa/consult-0.14/consult-compile.el b/elpa/consult-0.14/consult-compile.el @@ -0,0 +1,122 @@ +;;; consult-compile.el --- Provides the command `consult-compile-error' -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides the command `consult-compile-error'. This is an extra +;; package, to allow lazy loading of compile.el. The +;; `consult-compile-error' command is autoloaded. + +;;; Code: + +(require 'consult) +(require 'compile) + +(defvar consult-compile--history nil) + +(defconst consult-compile--narrow + '((?e . "Error") + (?w . "Warning") + (?i . "Info"))) + +(defun consult-compile--font-lock (str) + "Apply `font-lock' faces in STR, copy them to `face'." + (let ((pos 0) (len (length str))) + (while (< pos len) + (let* ((face (get-text-property pos 'font-lock-face str)) + (end (or (text-property-not-all pos len 'font-lock-face face str) len))) + (put-text-property pos end 'face face str) + (setq pos end))) + str)) + +(defun consult-compile--error-candidates (buffer) + "Return alist of errors and positions in BUFFER, a compilation buffer." + (with-current-buffer buffer + (let ((candidates) + (pos (point-min))) + (save-excursion + (while (setq pos (compilation-next-single-property-change pos 'compilation-message)) + (when-let (msg (get-text-property pos 'compilation-message)) + (goto-char pos) + (push (propertize + (consult-compile--font-lock (consult--buffer-substring pos (line-end-position))) + 'consult--type (pcase (compilation--message->type msg) + (0 ?i) + (1 ?w) + (_ ?e)) + 'consult-compile--marker (point-marker) + 'consult-compile--loc (compilation--message->loc msg)) + candidates)))) + (nreverse candidates)))) + +(defun consult-compile--error-lookup (_ candidates cand) + "Lookup marker of CAND by accessing CANDIDATES list." + (when-let ((cand (car (member cand candidates))) + (marker (get-text-property 0 'consult-compile--marker cand)) + (loc (get-text-property 0 'consult-compile--loc cand)) + (buffer (marker-buffer marker)) + (default-directory (buffer-local-value 'default-directory buffer))) + (consult--position-marker + ;; taken from compile.el + (apply #'compilation-find-file + marker + (caar (compilation--loc->file-struct loc)) + (cadar (compilation--loc->file-struct loc)) + (compilation--file-struct->formats + (compilation--loc->file-struct loc))) + (compilation--loc->line loc) + (compilation--loc->col loc)))) + +(defun consult-compile--compilation-buffers (file) + "Return a list of compilation buffers relevant to FILE." + (consult--buffer-query + :sort 'alpha :predicate + (lambda (buffer) + (with-current-buffer buffer + (and (compilation-buffer-internal-p) + (file-in-directory-p file default-directory)))))) + +;;;###autoload +(defun consult-compile-error () + "Jump to a compilation error in the current buffer. + +This command collects entries from compilation buffers and grep +buffers related to the current buffer. The command supports +preview of the currently selected error." + (interactive) + (consult--read + (consult--with-increased-gc + (or (mapcan #'consult-compile--error-candidates + (or (consult-compile--compilation-buffers + default-directory) + (user-error "No compilation buffers found for the current buffer"))) + (user-error "No compilation errors found"))) + :prompt "Go to error: " + :category 'consult-compile-error + :sort nil + :require-match t + :history t ;; disable history + :lookup #'consult-compile--error-lookup + :group (consult--type-group consult-compile--narrow) + :narrow (consult--type-narrow consult-compile--narrow) + :history '(:input consult-compile--history) + :state (consult--jump-state 'consult-preview-error))) + +(provide 'consult-compile) +;;; consult-compile.el ends here diff --git a/elpa/consult-0.14/consult-compile.elc b/elpa/consult-0.14/consult-compile.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-flymake.el b/elpa/consult-0.14/consult-flymake.el @@ -0,0 +1,100 @@ +;;; consult-flymake.el --- Provides the command `consult-flymake' -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides the command `consult-flymake'. This is an extra package, +;; to allow lazy loading of flymake.el. The `consult-flymake' command +;; is autoloaded. + +;;; Code: + +(require 'consult) +(require 'flymake) + +(defconst consult-flymake--narrow + '((?e . "Error") + (?w . "Warning") + (?n . "Note"))) + +(defun consult-flymake--candidates () + "Return Flymake errors as alist." + (consult--forbid-minibuffer) + (let* ((raw-diags (or (flymake-diagnostics) + (user-error "No flymake errors (Status: %s)" + (if (seq-difference (flymake-running-backends) + (flymake-reporting-backends)) + 'running 'finished)))) + (diags + (mapcar + (lambda (diag) + (let ((buffer (flymake-diagnostic-buffer diag)) + (type (flymake-diagnostic-type diag))) + (with-current-buffer buffer + (save-excursion + (save-restriction + (widen) + (goto-char (flymake-diagnostic-beg diag)) + (list (buffer-name buffer) + (line-number-at-pos) + type + (flymake-diagnostic-text diag) + (point-marker) + (pcase (flymake--lookup-type-property type 'flymake-category) + ('flymake-error ?e) + ('flymake-warning ?w) + (_ ?n)))))))) + raw-diags)) + (buffer-width (apply #'max (mapcar (lambda (x) (length (nth 0 x))) diags))) + (line-width (apply #'max (mapcar (lambda (x) (length (number-to-string (nth 1 x)))) diags))) + (fmt (format "%%-%ds %%-%dd %%-7s %%s" buffer-width line-width))) + (mapcar + (pcase-lambda (`(,buffer ,line ,type ,text ,marker ,narrow)) + (propertize (format fmt buffer line + (propertize (format "%s" (flymake--lookup-type-property + type 'flymake-type-name type)) + 'face (flymake--lookup-type-property + type 'mode-line-face 'flymake-error)) + text) + 'consult--candidate marker + 'consult--type narrow)) + (sort diags + (pcase-lambda (`(_ _ ,t1 _ ,m1 _) `(_ _ ,t2 _ ,m2 _)) + (let ((s1 (flymake--severity t1)) + (s2 (flymake--severity t2))) + (or (> s1 s2) (and (= s1 s2) (< m1 m2))))))))) + +;;;###autoload +(defun consult-flymake () + "Jump to Flymake diagnostic." + (interactive) + (consult--read + (consult--with-increased-gc (consult-flymake--candidates)) + :prompt "Flymake diagnostic: " + :category 'consult-flymake-error + :history t ;; disable history + :require-match t + :sort nil + :group (consult--type-group consult-flymake--narrow) + :narrow (consult--type-narrow consult-flymake--narrow) + :lookup #'consult--lookup-candidate + :state (consult--jump-state 'consult-preview-error))) + +(provide 'consult-flymake) +;;; consult-flymake.el ends here diff --git a/elpa/consult-0.14/consult-flymake.elc b/elpa/consult-0.14/consult-flymake.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-icomplete.el b/elpa/consult-0.14/consult-icomplete.el @@ -0,0 +1,55 @@ +;;; consult-icomplete.el --- Icomplete integration for Consult -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Integration code for the Icomplete completion system. This package +;; is automatically loaded by Consult. + +;;; Code: + +(require 'consult) +(require 'icomplete) + +(defun consult-icomplete--refresh (&optional reset) + "Refresh icomplete view, keep current candidate unless RESET is non-nil." + (when icomplete-mode + (let ((top (car completion-all-sorted-completions))) + (completion--flush-all-sorted-completions) + ;; force flushing, otherwise narrowing is broken! + (setq completion-all-sorted-completions nil) + (when (and top (not reset)) + (let* ((completions (completion-all-sorted-completions)) + (last (last completions)) + (before)) ;; completions before top + ;; warning: completions is an improper list + (while (consp completions) + (if (equal (car completions) top) + (progn + (setcdr last (append (nreverse before) (cdr last))) + (setq completion-all-sorted-completions completions + completions nil)) + (push (car completions) before) + (setq completions (cdr completions))))))) + (icomplete-exhibit))) + +(add-hook 'consult--completion-refresh-hook #'consult-icomplete--refresh) + +(provide 'consult-icomplete) +;;; consult-icomplete.el ends here diff --git a/elpa/consult-0.14/consult-icomplete.elc b/elpa/consult-0.14/consult-icomplete.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-imenu.el b/elpa/consult-0.14/consult-imenu.el @@ -0,0 +1,232 @@ +;;; consult-imenu.el --- Consult commands for imenu -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides imenu-related Consult commands. + +;;; Code: + +(require 'consult) +(require 'imenu) + +(defcustom consult-imenu-config + '((emacs-lisp-mode :toplevel "Functions" + :types ((?f "Functions" font-lock-function-name-face) + (?m "Macros" font-lock-function-name-face) + (?p "Packages" font-lock-constant-face) + (?t "Types" font-lock-type-face) + (?v "Variables" font-lock-variable-name-face)))) + "Imenu configuration, faces and narrowing keys used by `consult-imenu'. + +For each type a narrowing key and a name must be specified. The face is +optional. The imenu representation provided by the backend usually puts +functions directly at the toplevel. `consult-imenu' moves them instead under the +type specified by :toplevel." + :type '(repeat (cons symbol plist)) + :group 'consult) + +(defface consult-imenu-prefix + '((t :inherit consult-key)) + "Face used to highlight imenu prefix in `consult-imenu'." + :group 'consult-faces) + +(defvar consult-imenu--history nil) +(defvar-local consult-imenu--cache nil) + +(defun consult-imenu--special (_name pos buf name fn &rest args) + "Wrapper function for special imenu items. + +POS is the position. +BUF is the buffer. +NAME is the item name. +FN is the original special item function. +ARGS are the arguments to the special item function." + (funcall consult--buffer-display buf) + (apply fn name pos args)) + +(defun consult-imenu--flatten (prefix face list types) + "Flatten imenu LIST. + +PREFIX is prepended in front of all items. +FACE is the item face. +TYPES is the mode-specific types configuration." + (mapcan + (lambda (item) + (if (imenu--subalist-p item) + (let ((name (car item)) + (next-prefix prefix) + (next-face face)) + (if prefix + (setq next-prefix (concat prefix "/" (propertize name 'face 'consult-imenu-prefix))) + (if-let (type (cdr (assoc name types))) + (setq next-prefix (propertize name + 'face 'consult-imenu-prefix + 'consult--type (car type)) + next-face (cadr type)) + (setq next-prefix (propertize name 'face 'consult-imenu-prefix)))) + (consult-imenu--flatten next-prefix next-face (cdr item) types)) + (let* ((name (car item)) + (key (if prefix (concat prefix " " (propertize name 'face face)) name)) + (payload (cdr item))) + (list (cons key + (pcase payload + ;; Simple marker item + ((pred markerp) payload) + ;; Simple integer item + ((pred integerp) (copy-marker payload)) + ;; Semantic uses overlay for positions + ((pred overlayp) (copy-marker (overlay-start payload))) + ;; Wrap special item + (`(,pos ,fn . ,args) + (nconc + (list pos #'consult-imenu--special (current-buffer) name fn) + args)) + (_ (error "Unknown imenu item: %S" item)))))))) + list)) + +(defun consult-imenu--compute () + "Compute imenu candidates." + (consult--forbid-minibuffer) + (let* ((imenu-use-markers t) + ;; Generate imenu, see `imenu--make-index-alist'. + (items (imenu--truncate-items + (save-excursion + (save-restriction + (widen) + (funcall imenu-create-index-function))))) + (config (cdr (seq-find (lambda (x) (derived-mode-p (car x))) consult-imenu-config)))) + ;; Fix toplevel items, e.g., emacs-lisp-mode toplevel items are functions + (when-let (toplevel (plist-get config :toplevel)) + (let ((tops (seq-remove (lambda (x) (listp (cdr x))) items)) + (rest (seq-filter (lambda (x) (listp (cdr x))) items))) + (setq items (nconc rest (and tops (list (cons toplevel tops))))))) + ;; Apply our flattening in order to ease searching the imenu. + (consult-imenu--flatten + nil nil items + (mapcar (pcase-lambda (`(,x ,y ,z)) (list y x z)) + (plist-get config :types))))) + +(defun consult-imenu--deduplicate (items) + "Deduplicate imenu ITEMS by appending a counter." + ;; Some imenu backends generate duplicate items (e.g. for overloaded methods in java) + (let ((ht (make-hash-table :test #'equal :size (length items)))) + (dolist (item items) + (if-let (count (gethash (car item) ht)) + (setcar item (format "%s (%s)" (car item) + (puthash (car item) (1+ count) ht))) + (puthash (car item) 0 ht))))) + +(defun consult-imenu--items () + "Return cached imenu candidates, may error." + (unless (equal (car consult-imenu--cache) (buffer-modified-tick)) + (setq consult-imenu--cache (cons (buffer-modified-tick) (consult-imenu--compute)))) + (cdr consult-imenu--cache)) + +(defun consult-imenu--items-safe () + "Return cached imenu candidates, will not error." + (condition-case err + (consult-imenu--items) + (t (message "Cannot create Imenu for buffer %s (%s)" + (buffer-name) (error-message-string err)) + nil))) + +(defun consult-imenu--multi-items (buffers) + "Return all imenu items from BUFFERS." + (apply #'append (consult--buffer-map buffers #'consult-imenu--items-safe))) + +(defun consult-imenu--jump (item) + "Jump to imenu ITEM via `consult--jump'. + +In contrast to the builtin `imenu' jump function, +this function can jump across buffers." + (pcase item + (`(,name ,pos ,fn . ,args) (apply fn name pos args)) + (`(,_ . ,pos) (consult--jump pos)) + (_ (error "Unknown imenu item: %S" item)))) + +(defun consult-imenu--select (prompt items) + "Select from imenu ITEMS given PROMPT string." + (let ((narrow + (mapcar (lambda (x) (cons (car x) (cadr x))) + (plist-get (cdr (seq-find (lambda (x) (derived-mode-p (car x))) + consult-imenu-config)) + :types)))) + (consult-imenu--deduplicate items) + (consult-imenu--jump + (consult--read + (or items (user-error "Imenu is empty")) + :prompt prompt + :state + (let ((preview (consult--jump-preview))) + (lambda (cand restore) + ;; Only preview simple menu items which are markers, + ;; in order to avoid any bad side effects. + (funcall preview (and (markerp (cdr cand)) (cdr cand)) restore))) + :require-match t + :group + (when narrow + (lambda (cand transform) + (when-let (type (get-text-property 0 'consult--type cand)) + (if transform + (substring cand (1+ (next-single-property-change 0 'consult--type cand))) + (alist-get type narrow))))) + :narrow + (when narrow + (list :predicate + (lambda (cand) + (eq (get-text-property 0 'consult--type (car cand)) consult--narrow)) + :keys narrow)) + :category 'imenu + :lookup #'consult--lookup-cons + :history 'consult-imenu--history + :add-history (thing-at-point 'symbol) + :sort nil)))) + +;;;###autoload +(defun consult-imenu () + "Select item from flattened `imenu' using `completing-read' with preview. + +The command supports preview and narrowing. See the variable +`consult-imenu-config', which configures the narrowing. +The symbol at point is added to the future history. + +See also `consult-imenu-multi'." + (interactive) + (consult-imenu--select "Go to item: " (consult-imenu--items))) + +;;;###autoload +(defun consult-imenu-multi (&optional query) + "Select item from the imenus of all buffers from the same project. + +In order to determine the buffers belonging to the same project, the +`consult-project-root-function' is used. Only the buffers with the +same major mode as the current buffer are used. See also +`consult-imenu' for more details. In order to search a subset of buffers, +QUERY can be set to a plist according to `consult--buffer-query'." + (interactive "P") + (unless (keywordp (car-safe query)) + (setq query (list :sort 'alpha :mode major-mode + :directory (and (not query) 'project)))) + (let ((buffers (consult--buffer-query-prompt "Go to item" query))) + (consult-imenu--select (car buffers) + (consult-imenu--multi-items (cdr buffers))))) + +(provide 'consult-imenu) +;;; consult-imenu.el ends here diff --git a/elpa/consult-0.14/consult-imenu.elc b/elpa/consult-0.14/consult-imenu.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-org.el b/elpa/consult-0.14/consult-org.el @@ -0,0 +1,124 @@ +;;; consult-org.el --- Consult commands for org-mode -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides a `completing-read' interface for Org mode navigation. +;; This is an extra package, to allow lazy loading of Org. + +;;; Code: + +(require 'consult) +(require 'org) + +(defvar consult-org--history nil) + +(defun consult-org--narrow () + "Narrowing configuration for `consult-org' commands." + (let ((todo-kws + (seq-filter + (lambda (x) (<= ?a (car x) ?z)) + (mapcar (lambda (s) + (pcase-let ((`(,a ,b) (split-string s "("))) + (cons (downcase (string-to-char (or b a))) a))) + (apply #'append (mapcar #'cdr org-todo-keywords)))))) + (list :predicate + (lambda (cand) + (pcase-let ((`(_ ,level ,todo ,prio) + (get-text-property 0 'consult-org--heading cand))) + (cond + ((<= ?1 consult--narrow ?9) (<= level (- consult--narrow ?0))) + ((<= ?A consult--narrow ?Z) (eq prio consult--narrow)) + (t (equal todo (alist-get consult--narrow todo-kws)))))) + :keys + (nconc (mapcar (lambda (c) (cons c (format "Level %c" c))) + (number-sequence ?1 ?9)) + (mapcar (lambda (c) (cons c (format "Priority %c" c))) + (number-sequence (max ?A org-highest-priority) + (min ?Z org-lowest-priority))) + todo-kws)))) + +(defun consult-org--headings (prefix match scope &rest skip) + "Return a list of Org heading candidates. + +If PREFIX is non-nil, prefix the candidates with the buffer name. +MATCH, SCOPE and SKIP are as in `org-map-entries'." + (let (buffer) + (apply + #'org-map-entries + (lambda () + ;; Reset the cache when the buffer changes, since `org-get-outline-path' uses the cache + (unless (eq buffer (buffer-name)) + (setq buffer (buffer-name) + org-outline-path-cache nil)) + (pcase-let ((`(_ ,level ,todo ,prio . _) (org-heading-components)) + (cand (org-format-outline-path + (org-get-outline-path 'with-self 'use-cache) + most-positive-fixnum))) + (setq cand (if prefix + (concat buffer " " cand (consult--tofu-encode (point))) + (concat cand (consult--tofu-encode (point))))) + (put-text-property 0 1 'consult-org--heading (list (point-marker) level todo prio) cand) + cand)) + match scope skip))) + +;;;###autoload +(defun consult-org-heading (&optional match scope) + "Jump to an Org heading. + +MATCH and SCOPE are as in `org-map-entries' and determine which +entries are offered. By default, all entries of the current +buffer are offered." + (interactive (unless (derived-mode-p 'org-mode) + (user-error "Must be called from an Org buffer"))) + (let ((prefix (not (memq scope '(nil tree region region-start-level file))))) + (consult--read + (consult--with-increased-gc (consult-org--headings prefix match scope)) + :prompt "Go to heading: " + :category 'consult-org-heading + :sort nil + :require-match t + :history '(:input consult-org--history) + :narrow (consult-org--narrow) + :state (consult--jump-state) + :group + (when prefix + (lambda (cand transform) + (let ((name (buffer-name + (marker-buffer + (car (get-text-property 0 'consult-org--heading cand)))))) + (if transform (substring cand (1+ (length name))) name)))) + :lookup + (lambda (_ candidates cand) + (when-let (found (member cand candidates)) + (car (get-text-property 0 'consult-org--heading (car found)))))))) + +;;;###autoload +(defun consult-org-agenda (&optional match) + "Jump to an Org agenda heading. + +By default, all agenda entries are offered. MATCH is as in +`org-map-entries' and can used to refine this." + (interactive) + (unless org-agenda-files + (user-error "No agenda files")) + (consult-org-heading match 'agenda)) + +(provide 'consult-org) +;;; consult-org.el ends here diff --git a/elpa/consult-0.14/consult-org.elc b/elpa/consult-0.14/consult-org.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-pkg.el b/elpa/consult-0.14/consult-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from consult.el -*- no-byte-compile: t -*- +(define-package "consult" "0.14" "Consulting completing-read" '((emacs "26.1")) :authors '(("Daniel Mendler and Consult contributors")) :maintainer '("Daniel Mendler" . "mail@daniel-mendler.de") :url "https://github.com/minad/consult") diff --git a/elpa/consult-0.14/consult-register.el b/elpa/consult-0.14/consult-register.el @@ -0,0 +1,266 @@ +;;; consult-register.el --- Consult commands for registers -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides register-related Consult commands. + +;;; Code: + +(require 'consult) + +(defcustom consult-register-narrow + `((?n "Number" ,#'numberp) + (?s "String" ,#'stringp) + (?p "Point" ,#'markerp) + (?r "Rectangle" ,(lambda (x) (stringp (car-safe x)))) + ;; frameset-register-p and kmacro-register-p exists since 27.1 + (?t "Frameset" ,(lambda (x) (eq (type-of x) 'frameset-register))) + (?k "Kmacro" ,(lambda (x) (eq (type-of x) 'kmacro-register))) + (?f "File" ,(lambda (x) (memq (car-safe x) '(file file-query)))) + (?w "Window" ,(lambda (x) (window-configuration-p (car-safe x))))) + "Register narrowing configuration. + +Each element of the list must have the form '(char name predicate)." + :type '(repeat (list character string function)) + :group 'consult) + +;;;###autoload +(defun consult-register-window (buffer &optional show-empty) + "Enhanced drop-in replacement for `register-preview'. + +BUFFER is the window buffer. +SHOW-EMPTY must be t if the window should be shown for an empty register list." + (let ((regs (seq-filter #'cdr register-alist)) + (separator + (and (display-graphic-p) + (propertize (concat (propertize " " 'display '(space :align-to right)) "\n") + 'face '(:inherit consult-separator :height 1 :underline t))))) + (when (or show-empty regs) + (with-current-buffer-window buffer + (cons 'display-buffer-below-selected + '((window-height . fit-window-to-buffer) + (preserve-size . (nil . t)))) + nil + (setq-local cursor-in-non-selected-windows nil) + (setq-local mode-line-format nil) + (setq-local truncate-lines t) + (setq-local window-min-height 1) + (setq-local window-resize-pixelwise t) + (insert (mapconcat + (lambda (reg) + (concat (funcall register-preview-function reg) separator)) + (seq-sort #'car-less-than-car regs) nil)))))) + +;;;###autoload +(defun consult-register-format (reg) + "Enhanced preview of register REG. + +This function can be used as `register-preview-function'." + (concat (consult-register--format reg) "\n")) + +(defun consult-register--format (reg) + "Format register REG for preview." + (pcase-let ((`(,key . ,val) reg)) + (let* ((key-str (propertize (single-key-description key) 'face 'consult-key)) + (len (max 3 (length key-str)))) + (concat + key-str + (make-string (- len (length key-str)) ?\s) + ;; Special printing for certain register types + (cond + ;; Display full string + ((or (stringp val) (stringp (car-safe val))) + (when (consp val) + (setq val (mapconcat #'identity val "\n"))) + (mapconcat #'identity + (seq-take (split-string (string-trim val) "\n") 3) + (concat "\n" (make-string len ?\s)))) + ;; Display 'file-query + ((eq (car-safe val) 'file-query) + (format "%s at position %d" + (propertize (abbreviate-file-name (cadr val)) 'face 'consult-file) + (caddr val))) + ;; Display 'file + ((eq (car-safe val) 'file) + (propertize (abbreviate-file-name (cdr val)) 'face 'consult-file)) + ;; Display full line of buffer + ((and (markerp val) (marker-buffer val)) + (with-current-buffer (marker-buffer val) + (save-restriction + (save-excursion + (widen) + (goto-char val) + (consult--format-location (buffer-name) (line-number-at-pos) + (consult--line-with-cursor val)))))) + ;; Default printing for the other types + (t (register-describe-oneline key))))))) + +(defun consult-register--alist () + "Return register list or raise an error if the list is empty." + ;; Sometimes, registers are made without a `cdr'. + ;; Such registers don't do anything, and can be ignored. + (or (seq-filter #'cdr register-alist) (user-error "All registers are empty"))) + +(defun consult-register--candidates () + "Return list of formatted register candidates." + (mapcar (lambda (reg) + (propertize + (consult-register--format reg) + 'consult--candidate (car reg) + 'consult--type + (car (seq-find (lambda (x) (funcall (caddr x) (cdr reg))) + consult-register-narrow)))) + (sort (consult-register--alist) #'car-less-than-car))) + +;;;###autoload +(defun consult-register (&optional arg) + "Load register and either jump to location or insert the stored text. + +This command is useful to search the register contents. For quick access to +registers it is still recommended to use the register functions +`consult-register-load' and `consult-register-store' or the built-in built-in +register access functions. The command supports narrowing, see +`consult-register-narrow'. Marker positions are previewed. See +`jump-to-register' and `insert-register' for the meaning of prefix ARG." + (interactive "P") + (let ((narrow (mapcar (lambda (x) (cons (car x) (cadr x))) + consult-register-narrow))) + (consult-register-load + (consult--read + (consult-register--candidates) + :prompt "Register: " + :category 'consult-register + :state + (let ((preview (consult--jump-preview))) + (lambda (cand restore) + ;; Preview only markers + (funcall preview + (when-let (reg (get-register cand)) + (and (markerp reg) reg)) + restore))) + :group (consult--type-group narrow) + :narrow (consult--type-narrow narrow) + :sort nil + :require-match t + :history t ;; disable history + :lookup #'consult--lookup-candidate) + arg))) + +;;;###autoload +(defun consult-register-load (reg &optional arg) + "Do what I mean with a REG. + +For a window configuration, restore it. For a number or text, insert it. For a +location, jump to it. See `jump-to-register' and `insert-register' for the +meaning of prefix ARG." + (interactive + (list + (and (consult-register--alist) + (register-read-with-preview "Load register: ")) + current-prefix-arg)) + (condition-case nil + (jump-to-register reg arg) + (user-error (insert-register reg (not arg))))) + +(defun consult-register--action (action-list) + "Read register key and execute action from ACTION-LIST. + +This function is derived from `register-read-with-preview'." + (let* ((buffer "*Register Preview*") + (prefix (car action-list)) + (action-list (cdr action-list)) + (action (car (nth 0 action-list))) + (reg) + (preview + (lambda () + (unless (get-buffer-window buffer) + (register-preview buffer 'show-empty) + (when-let (win (get-buffer-window buffer)) + (with-selected-window win + (let ((inhibit-read-only t)) + (goto-char (point-max)) + (insert + (propertize (concat prefix ": ") 'face 'consult-help) + (mapconcat + (lambda (x) + (concat (propertize (format "M-%c" (car x)) 'face 'consult-key) + " " (propertize (cadr x) 'face 'consult-help))) + action-list " ")) + (fit-window-to-buffer))))))) + (timer (when (numberp register-preview-delay) + (run-at-time register-preview-delay nil preview))) + (help-chars (seq-remove #'get-register (cons help-char help-event-list)))) + (unwind-protect + (while (not reg) + (while (memq (read-key (propertize (caddr (assq action action-list)) + 'face 'minibuffer-prompt)) + help-chars) + (funcall preview)) + (cond + ((or (eq ?\C-g last-input-event) + (eq 'escape last-input-event) + (eq ?\C-\[ last-input-event)) + (keyboard-quit)) + ((and (numberp last-input-event) (assq (logxor #x8000000 last-input-event) action-list)) + (setq action (logxor #x8000000 last-input-event))) + ((characterp last-input-event) + (setq reg last-input-event)) + (t (error "Non-character input-event")))) + (when (timerp timer) + (cancel-timer timer)) + (let ((w (get-buffer-window buffer))) + (when (window-live-p w) + (delete-window w))) + (when (get-buffer buffer) + (kill-buffer buffer))) + (when reg + (funcall (cadddr (assq action action-list)) reg)))) + +;;;###autoload +(defun consult-register-store (arg) + "Store register dependent on current context, showing an action menu. + +With an active region, store/append/prepend the contents, optionally deleting +the region when a prefix ARG is given. With a numeric prefix ARG, store/add the +number. Otherwise store point, frameset, window or kmacro." + (interactive "P") + (consult-register--action + (cond + ((use-region-p) + (let ((beg (region-beginning)) + (end (region-end))) + `("Region" + (?c "copy" "Copy region to register: " ,(lambda (r) (copy-to-register r beg end arg t))) + (?a "append" "Append region to register: " ,(lambda (r) (append-to-register r beg end arg))) + (?p "prepend" "Prepend region to register: " ,(lambda (r) (prepend-to-register r beg end arg)))))) + ((numberp arg) + `(,(format "Number %s" arg) + (?s "store" ,(format "Store %s in register: " arg) ,(lambda (r) (number-to-register arg r))) + (?a "add" ,(format "Add %s to register: " arg) ,(lambda (r) (increment-register arg r))))) + (t + `("Store" + (?p "point" "Point to register: " ,#'point-to-register) + (?f "file" "File to register: " ,(lambda (r) (set-register r `(file . ,(buffer-file-name))))) + (?t "frameset" "Frameset to register: " ,#'frameset-to-register) + (?w "window" "Window to register: " ,#'window-configuration-to-register) + ,@(and last-kbd-macro `((?k "kmacro" "Kmacro to register: " ,#'kmacro-to-register)))))))) + +(provide 'consult-register) +;;; consult-register.el ends here diff --git a/elpa/consult-0.14/consult-register.elc b/elpa/consult-0.14/consult-register.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-selectrum.el b/elpa/consult-0.14/consult-selectrum.el @@ -0,0 +1,104 @@ +;;; consult-selectrum.el --- Selectrum integration for Consult -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Integration code for the Selectrum completion system. This package +;; is automatically loaded by Consult. + +;;; Code: + +(require 'consult) + +;; NOTE: It is not guaranteed that Selectrum is available during compilation! +(defvar selectrum-default-value-format) +(defvar selectrum-highlight-candidates-function) +(defvar selectrum-is-active) +(defvar selectrum-refine-candidates-function) +(defvar selectrum--history-hash) +(declare-function selectrum-exhibit "ext:selectrum") +(declare-function selectrum-get-current-candidate "ext:selectrum") + +(defun consult-selectrum--filter-adv (orig pattern cands category highlight) + "Advice for ORIG `consult--completion-filter' function. +See `consult--completion-filter' for arguments PATTERN, CANDS, CATEGORY +and HIGHLIGHT." + ;; Do not use selectrum-is-active here, since we want to always use + ;; the Selectrum filtering when Selectrum is installed, even when + ;; Selectrum is currently not active. + ;; However if `selectrum-refine-candidates-function' is the default + ;; function, which uses the completion styles, the Selectrum filtering + ;; is not used and the original function is called. + (if (and (eq completing-read-function 'selectrum-completing-read) + (not (eq selectrum-refine-candidates-function + 'selectrum-refine-candidates-using-completions-styles))) + (if highlight + (funcall selectrum-highlight-candidates-function pattern + (funcall selectrum-refine-candidates-function pattern cands)) + (funcall selectrum-refine-candidates-function pattern cands)) + (funcall orig pattern cands category highlight))) + +(defun consult-selectrum--candidate () + "Return current selectrum candidate." + (and selectrum-is-active (selectrum-get-current-candidate))) + +(defun consult-selectrum--refresh (&optional reset) + "Refresh completion UI, keep current candidate unless RESET is non-nil." + (when selectrum-is-active + (when consult--narrow + (setq-local selectrum-default-value-format nil)) + (when reset + (setq-local selectrum--history-hash nil)) + (selectrum-exhibit (not reset)))) + +(defun consult-selectrum--split-wrap (orig split) + "Wrap candidates highlight/refinement ORIG function, splitting +the input using SPLIT." + (lambda (str cands) + (funcall orig (cadr (funcall split str 0)) cands))) + +(defun consult-selectrum--split-setup-adv (orig split) + "Advice for `consult--split-setup' to be used by Selectrum. + +ORIG is the original function. +SPLIT is the splitter function." + (if (not selectrum-is-active) + (funcall orig split) + (setq-local selectrum-refine-candidates-function + (consult-selectrum--split-wrap selectrum-refine-candidates-function split)) + (setq-local selectrum-highlight-candidates-function + (consult-selectrum--split-wrap selectrum-highlight-candidates-function split)))) + +(defun consult-selectrum--crm-adv (&rest args) + "Setup crm for Selectrum given ARGS." + (consult--minibuffer-with-setup-hook + (lambda () + (when selectrum-is-active + (setq-local selectrum-default-value-format nil))) + (apply args))) + +(add-hook 'consult--completion-candidate-hook #'consult-selectrum--candidate) +(add-hook 'consult--completion-refresh-hook #'consult-selectrum--refresh) +(advice-add #'consult-completing-read-multiple :around #'consult-selectrum--crm-adv) +(advice-add #'consult--completion-filter :around #'consult-selectrum--filter-adv) +(advice-add #'consult--split-setup :around #'consult-selectrum--split-setup-adv) +(define-key consult-async-map [remap selectrum-insert-current-candidate] 'selectrum-next-page) + +(provide 'consult-selectrum) +;;; consult-selectrum.el ends here diff --git a/elpa/consult-0.14/consult-selectrum.elc b/elpa/consult-0.14/consult-selectrum.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-vertico.el b/elpa/consult-0.14/consult-vertico.el @@ -0,0 +1,68 @@ +;;; consult-vertico.el --- Vertico integration for Consult -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Integration code for the Vertico completion system. This package +;; is automatically loaded by Consult. + +;;; Code: + +(require 'consult) + +;; NOTE: It is not guaranteed that Vertico is available during compilation! +(defvar vertico--input) +(defvar vertico--history-hash) +(defvar vertico--lock-candidate) +(declare-function vertico--exhibit "ext:vertico") +(declare-function vertico--candidate "ext:vertico") +(declare-function vertico--all-completions "ext:vertico") + +(defun consult-vertico--candidate () + "Return current candidate for Consult preview." + (and vertico--input (vertico--candidate 'highlight))) + +(defun consult-vertico--refresh (&optional reset) + "Refresh completion UI, keep current candidate unless RESET is non-nil." + (when vertico--input + (setq vertico--input t) + (when reset + (setq vertico--history-hash nil + vertico--lock-candidate nil)) + (vertico--exhibit))) + +(defun consult-vertico--filter-adv (orig pattern cands category highlight) + "Advice for ORIG `consult--completion-filter' function. +See `consult--completion-filter' for arguments PATTERN, CANDS, CATEGORY +and HIGHLIGHT." + (if (and (bound-and-true-p vertico-mode) (not highlight)) + ;; Optimize `consult--completion-filter' using the deferred highlighting + ;; from Vertico. The advice is not necessary - it is a pure optimization. + (nconc (car (vertico--all-completions pattern cands nil (length pattern) + `(metadata (category . ,category)))) + nil) + (funcall orig pattern cands category highlight))) + +(advice-add #'consult--completion-filter :around #'consult-vertico--filter-adv) +(add-hook 'consult--completion-candidate-hook #'consult-vertico--candidate) +(add-hook 'consult--completion-refresh-hook #'consult-vertico--refresh) +(define-key consult-async-map [remap vertico-insert] 'vertico-next-group) + +(provide 'consult-vertico) +;;; consult-vertico.el ends here diff --git a/elpa/consult-0.14/consult-vertico.elc b/elpa/consult-0.14/consult-vertico.elc Binary files differ. diff --git a/elpa/consult-0.14/consult-xref.el b/elpa/consult-0.14/consult-xref.el @@ -0,0 +1,116 @@ +;;; consult-xref.el --- Xref integration for Consult -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Provides Xref integration for Consult. This is an extra package, to +;; allow lazy loading of xref.el. The `consult-xref' function is +;; autoloaded. + +;;; Code: + +(require 'consult) +(require 'xref) + +(defvar consult-xref--history nil) + +(defun consult-xref--candidates (xrefs) + "Return candidate list from XREFS." + (mapcar (lambda (xref) + (let* ((loc (xref-item-location xref)) + (group (xref-location-group loc)) + (cand (consult--format-location group + (or (xref-location-line loc) 0) + (xref-item-summary xref)))) + (add-text-properties + 0 1 `(consult--candidate ,xref consult-xref--group ,group) cand) + cand)) + xrefs)) + +(defun consult-xref--preview (display) + "Xref preview with DISPLAY function." + (let ((open (consult--temporary-files)) + (preview (consult--jump-preview))) + (lambda (cand restore) + (cond + (restore + (funcall preview nil t) + (funcall open nil)) + (cand + (let ((loc (xref-item-location cand)) + (consult--buffer-display display)) + (funcall preview + ;; Only preview file and buffer markers + (cl-typecase loc + (xref-buffer-location + (xref-location-marker loc)) + (xref-file-location + (consult--position-marker + (funcall open + ;; xref-location-group returns the file name + (let ((xref-file-name-display 'abs)) + (xref-location-group loc))) + (xref-location-line loc) + (xref-file-location-column loc))) + (t (message "No preview for %s" (type-of loc)) nil)) + nil))))))) + +(defun consult-xref--group (cand transform) + "Return title for CAND or TRANSFORM the candidate." + (if transform + (substring cand (1+ (length (get-text-property 0 'consult-xref--group cand)))) + (get-text-property 0 'consult-xref--group cand))) + +;;;###autoload +(defun consult-xref (fetcher &optional alist) + "Show xrefs with preview in the minibuffer. + +This function can be used for `xref-show-xrefs-function'. +See `xref-show-xrefs-function' for the description of the +FETCHER and ALIST arguments." + (let ((candidates (consult--with-increased-gc + (consult-xref--candidates (funcall fetcher)))) + (display (alist-get 'display-action alist))) + (xref-pop-to-location + (if (cdr candidates) + (apply + #'consult--read + candidates + (append + (alist-get #'consult-xref consult--read-config) + (list + :prompt "Go to xref: " + :history 'consult-xref--history + :require-match t + :sort nil + :category 'xref-location + :group #'consult-xref--group + :state + ;; do not preview other frame + (when-let (fun (pcase-exhaustive display + ('frame nil) + ('window #'switch-to-buffer-other-window) + ('nil #'switch-to-buffer))) + (consult-xref--preview fun)) + :lookup #'consult--lookup-candidate))) + (get-text-property 0 'consult--candidate (car candidates))) + display))) + +(provide 'consult-xref) +;;; consult-xref.el ends here diff --git a/elpa/consult-0.14/consult-xref.elc b/elpa/consult-0.14/consult-xref.elc Binary files differ. diff --git a/elpa/consult-0.14/consult.el b/elpa/consult-0.14/consult.el @@ -0,0 +1,4539 @@ +;;; consult.el --- Consulting completing-read -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler and Consult contributors +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2020 +;; Version: 0.14 +;; Package-Requires: ((emacs "26.1")) +;; Homepage: https://github.com/minad/consult + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Consult implements a set of `consult-<thing>' commands which use +;; `completing-read' to select from a list of candidates. Consult provides an +;; enhanced buffer switcher `consult-buffer' and search and navigation commands +;; like `consult-imenu' and `consult-line'. Searching through multiple files is +;; supported by the asynchronous `consult-grep' command. Many Consult commands +;; allow previewing candidates - if a candidate is selected in the completion +;; view, the buffer shows the candidate immediately. + +;; The Consult commands are compatible with completion systems based +;; on the Emacs `completing-read' API, including the default completion +;; system, Vertico, Icomplete, Mct, Selectrum and Embark. + +;; Consult has been inspired by Counsel. Some of the Consult commands +;; originated in the Counsel package or the Selectrum wiki. See the +;; README for a full list of contributors. + +;;; Code: + +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) +(require 'bookmark) +(require 'kmacro) +(require 'recentf) +(require 'seq) + +(defgroup consult nil + "Consulting `completing-read'." + :group 'convenience + :group 'minibuffer + :prefix "consult-") + +;;;; Customization + +(defcustom consult-narrow-key nil + "Prefix key for narrowing during completion. + +Good choices for this key are (kbd \"<\") or (kbd \"C-+\") for example. + +The key must be either a string or a vector. +This is the key representation accepted by `define-key'." + :type '(choice key-sequence (const nil))) + +(defcustom consult-widen-key nil + "Key used for widening during completion. + +If this key is unset, defaults to twice the `consult-narrow-key'. + +The key must be either a string or a vector. +This is the key representation accepted by `define-key'." + :type '(choice key-sequence (const nil))) + +(defcustom consult-project-root-function nil + "Function which returns project root directory. + +The root directory is used by `consult-buffer' and `consult-grep'." + :type '(choice function (const nil))) + +(defcustom consult-async-refresh-delay 0.2 + "Refreshing delay of the completion ui for asynchronous commands. + +The completion ui is only updated every `consult-async-refresh-delay' +seconds. This applies to asynchronous commands like for example +`consult-grep'." + :type 'float) + +(defcustom consult-async-input-throttle 0.4 + "Input throttle for asynchronous commands. + +The asynchronous process is started only every +`consult-async-input-throttle' seconds. This applies to asynchronous +commands, e.g., `consult-grep'." + :type 'float) + +(defcustom consult-async-input-debounce 0.2 + "Input debounce for asynchronous commands. + +The asynchronous process is started only when there has not been new +input for `consult-async-input-debounce' seconds. This applies to +asynchronous commands, e.g., `consult-grep'." + :type 'float) + +(defcustom consult-async-min-input 3 + "Minimum number of letters needed, before asynchronous process is called. + +This applies to asynchronous commands, e.g., `consult-grep'." + :type 'integer) + +(defcustom consult-async-split-style 'perl + "Async splitting style, see `consult-async-split-styles-alist'." + :type '(choice (const :tag "No splitting" nil) + (const :tag "Comma" comma) + (const :tag "Semicolon" semicolon) + (const :tag "Perl" perl))) + +(defcustom consult-async-split-styles-alist + '((nil :type nil) + (comma :separator ?, :type separator) + (semicolon :separator ?\; :type separator) + (perl :initial "#" :type perl)) + "Async splitting styles." + :type '(alist :key-type symbol :value-type plist)) + +(defcustom consult-mode-histories + '((eshell-mode . eshell-history-ring) + (comint-mode . comint-input-ring) + (term-mode . term-input-ring)) + "Alist of (mode . history) pairs of mode histories. +The histories can be rings or lists." + :type '(alist :key-type symbol :value-type symbol)) + +(defcustom consult-themes nil + "List of themes to be presented for selection. +nil shows all `custom-available-themes'." + :type '(repeat symbol)) + +(defcustom consult-after-jump-hook '(recenter) + "Function called after jumping to a location. + +Commonly used functions for this hook are `recenter' and `reposition-window'. +This is called during preview and for the jump after selection." + :type 'hook) + +(defcustom consult-line-start-from-top nil + "Start search from the top if non-nil. +Otherwise start the search at the current line and wrap around." + :type 'boolean) + +(defcustom consult-line-point-placement 'match-beginning + "Where to leave point after `consult-line' jumps to a match." + :type '(choice (const :tag "Beginning of the line" line-beginning) + (const :tag "Beginning of the match" match-beginning) + (const :tag "End of the match" match-end))) + +(defcustom consult-line-numbers-widen t + "Show absolute line numbers when narrowing is active. + +See also `display-line-numbers-widen'." + :type 'boolean) + +(defcustom consult-goto-line-numbers t + "Show line numbers for `consult-goto-line'." + :type 'boolean) + +(defcustom consult-fontify-preserve t + "Preserve fontification for line-based commands." + :type 'boolean) + +(defcustom consult-fontify-max-size 1048576 + "Buffers larger than this byte limit are not fontified. + +This is necessary in order to prevent a large startup time +for navigation commands like `consult-line'." + :type 'integer) + +(defcustom consult-buffer-filter + '("\\` " + "\\`\\*Completions\\*\\'" + "\\`\\*Flymake log\\*\\'" + "\\`\\*Semantic SymRef\\*\\'" + "\\`\\*tramp/.*\\*\\'") + "Filter regexps for `consult-buffer'. + +The default setting is to filter ephemeral buffer names beginning with a space +character, the *Completions* buffer and a few log buffers." + :type '(repeat regexp)) + +(defcustom consult-recent-file-filter nil + "Filter regexps for `consult-recent-file'." + :type '(repeat regexp)) + +(defcustom consult-buffer-sources + '(consult--source-hidden-buffer + consult--source-buffer + consult--source-recent-file + consult--source-bookmark + consult--source-project-buffer + consult--source-project-recent-file) + "Sources used by `consult-buffer'. + +See `consult--multi' for a description of the source values." + :type '(repeat symbol)) + +(defcustom consult-mode-command-filter + '(;; Filter commands + "-mode\\'" "--" + ;; Filter whole features + simple mwheel time so-long recentf) + "Filter commands for `consult-mode-command'." + :type '(repeat (choice symbol regexp))) + +(defcustom consult-grep-max-columns 300 + "Maximal number of columns of grep output." + :type 'integer) + +(defconst consult--grep-match-regexp + "\\`\\(?:\\./\\)?\\([^\n\0]+\\)\0\\([0-9]+\\)\\([-:\0]\\)" + "Regexp used to match file and line of grep output.") + +(defcustom consult-grep-args + "grep --null --line-buffered --color=never --ignore-case\ + --exclude-dir=.git --line-number -I -r ." + "Command line arguments for grep, see `consult-grep'. +The dynamically computed arguments are appended." + :type 'string) + +(defcustom consult-git-grep-args + "git --no-pager grep --null --color=never --ignore-case\ + --extended-regexp --line-number -I" + "Command line arguments for git-grep, see `consult-git-grep'. +The dynamically computed arguments are appended." + :type 'string) + +(defcustom consult-ripgrep-args + "rg --null --line-buffered --color=never --max-columns=1000 --path-separator /\ + --smart-case --no-heading --line-number ." + "Command line arguments for ripgrep, see `consult-ripgrep'. +The dynamically computed arguments are appended." + :type 'string) + +(defcustom consult-find-args + "find . -not ( -wholename */.* -prune )" + "Command line arguments for find, see `consult-find'. +The dynamically computed arguments are appended." + :type 'string) + +(defcustom consult-locate-args + "locate --ignore-case --existing --regexp" + "Command line arguments for locate, see `consult-locate'. +The dynamically computed arguments are appended." + :type 'string) + +(defcustom consult-man-args + "man -k" + "Command line arguments for man, see `consult-man'. +The dynamically computed arguments are appended." + :type 'string) + +(defcustom consult-preview-key 'any + "Preview trigger keys, can be nil, 'any, a single key or a list of keys." + :type '(choice (const :tag "Any key" any) + (list :tag "Debounced" (const :debounce) (float :tag "Seconds" 0.1) (const any)) + (const :tag "No preview" nil) + (key-sequence :tag "Key") + (repeat :tag "List of keys" key-sequence))) + +(defcustom consult-preview-max-size 10485760 + "Files larger than this byte limit are not previewed." + :type 'integer) + +(defcustom consult-preview-raw-size 102400 + "Files larger than this byte limit are previewed in raw form." + :type 'integer) + +(defcustom consult-preview-max-count 10 + "Number of files to keep open at once during preview." + :type 'integer) + +(defcustom consult-preview-excluded-hooks + '(epa-file-find-file-hook + recentf-track-opened-file + vc-refresh-state) + "List of `find-file' hooks, which should not be executed during file preview. +In particular we don't want to modify the list of recent files and we +don't want to see epa password prompts." + :type '(repeat symbol)) + +(defcustom consult-bookmark-narrow + `((?f "File" ,#'bookmark-default-handler) + (?h "Help" ,#'help-bookmark-jump) + (?i "Info" ,#'Info-bookmark-jump) + (?p "Picture" ,#'image-bookmark-jump) + (?d "Docview" ,#'doc-view-bookmark-jump) + (?m "Man" ,#'Man-bookmark-jump) + (?w "Woman" ,#'woman-bookmark-jump) + (?g "Gnus" ,#'gnus-summary-bookmark-jump)) + "Bookmark narrowing configuration. + +Each element of the list must have the form '(char name handler)." + :type '(repeat (list character string function))) + +(defcustom consult-crm-prefix + (cons " " (propertize "✓ " 'face 'success)) + "Prefix for `consult-completing-read-multiple' candidates." + :type '(cons (string :tag "Not selected") (string :tag "Selected"))) + +;;;; Faces + +(defgroup consult-faces nil + "Faces used by Consult." + :group 'consult + :group 'faces) + +(defface consult-preview-line + '((t :inherit consult-preview-insertion :extend t)) + "Face used to for line previews.") + +(defface consult-preview-match + '((t :inherit match)) + "Face used to for match previews in `consult-grep'.") + +(defface consult-preview-cursor + '((t :inherit consult-preview-match)) + "Face used to for cursor previews and marks in `consult-mark'.") + +(defface consult-preview-error + '((t :inherit isearch-fail)) + "Face used to for cursor previews and marks in `consult-compile-error'.") + +(defface consult-preview-insertion + '((t :inherit region)) + "Face used to for previews of text to be inserted. +Used by `consult-completion-in-region', `consult-yank' and `consult-history'.") + +(defface consult-narrow-indicator + '((t :inherit warning)) + "Face used for the narrowing indicator.") + +(defface consult-async-running + '((t :inherit consult-narrow-indicator)) + "Face used if asynchronous process is running.") + +(defface consult-async-finished + '((t :inherit success)) + "Face used if asynchronous process has finished.") + +(defface consult-async-failed + '((t :inherit error)) + "Face used if asynchronous process has failed.") + +(defface consult-async-split + '((t :inherit font-lock-negation-char-face)) + "Face used to highlight punctuation character.") + +(defface consult-help + '((t :inherit shadow)) + "Face used to highlight help, e.g., in `consult-register-store'.") + +(defface consult-key + '((t :inherit font-lock-keyword-face)) + "Face used to highlight keys, e.g., in `consult-register'.") + +(defface consult-line-number + '((t :inherit consult-key)) + "Face used to highlight location line in `consult-global-mark'.") + +(defface consult-file + '((t :inherit font-lock-function-name-face)) + "Face used to highlight files in `consult-buffer'.") + +(defface consult-grep-context + '((t :inherit shadow)) + "Face used to highlight grep context in `consult-grep'.") + +(defface consult-bookmark + '((t :inherit font-lock-constant-face)) + "Face used to highlight bookmarks in `consult-buffer'.") + +(defface consult-buffer + '((t)) + "Face used to highlight buffers in `consult-buffer'.") + +(defface consult-crm-selected + '((t :inherit secondary-selection)) + "Face used to highlight selected items in `consult-completing-read-multiple'.") + +(defface consult-line-number-prefix + '((t :inherit line-number)) + "Face used to highlight line number prefixes.") + +(defface consult-line-number-wrapped + '((t :inherit consult-line-number-prefix :inherit font-lock-warning-face)) + "Face used to highlight line number prefixes, if the line number wrapped around.") + +(defface consult-separator + '((((class color) (min-colors 88) (background light)) + :foreground "#ccc") + (((class color) (min-colors 88) (background dark)) + :foreground "#333")) + "Face used for thin line separators in `consult-register-window'.") + +;;;; History variables + +(defvar consult--keep-lines-history nil) +(defvar consult--grep-history nil) +(defvar consult--find-history nil) +(defvar consult--man-history nil) +(defvar consult--line-history nil) +(defvar consult--apropos-history nil) +(defvar consult--theme-history nil) +(defvar consult--minor-mode-menu-history nil) +(defvar consult--mode-command-history nil) +(defvar consult--kmacro-history nil) +(defvar consult--buffer-history nil) +(defvar consult--crm-history nil) + +;;;; Internal variables + +(defvar consult--regexp-compiler + #'consult--default-regexp-compiler + "Regular expression compiler used by `consult-grep' and other commands. +The function must return a list of regular expressions and a highlighter +function.") + +(defvar consult--read-config nil + "Command configuration alist for fine-grained configuration. + +Each element of the list must have the form (command-name plist...). The options +set here will be passed to `consult--read', when called from the corresponding +command. Note that the options depend on the private `consult--read' API and +should not be considered as stable as the public API.") + +(defvar consult--buffer-display #'switch-to-buffer + "Buffer display function.") + +(defvar consult--completion-candidate-hook + (list #'consult--default-completion-mb-candidate + #'consult--default-completion-list-candidate) + "Get candidate from completion system.") + +(defvar consult--completion-refresh-hook nil + "Refresh completion system.") + +(defvar-local consult--preview-function nil + "Minibuffer-local variable which exposes the current preview function. +This function can be called by custom completion systems from +outside the minibuffer.") + +(defconst consult--tofu-char #x100000 + "Special character used to encode line prefixes for disambiguation. +We use the first character of the private unicode plane b.") + +(defconst consult--tofu-range #xFFFE + "Special character range. +Size of private unicode plane b.") + +(defvar-local consult--narrow nil + "Current narrowing key.") + +(defvar-local consult--narrow-keys nil + "Narrowing prefixes of the current completion.") + +(defvar-local consult--narrow-predicate nil + "Narrowing predicate of the current completion.") + +(defvar-local consult--narrow-overlay nil + "Narrowing indicator overlay.") + +(defvar consult--gc-threshold (* 64 1024 1024) + "Large gc threshold for temporary increase.") + +(defvar consult--gc-percentage 0.5 + "Large gc percentage for temporary increase.") + +(defvar consult--process-chunk (* 1024 1024) + "Increase process output chunk size.") + +(defvar consult--async-log + " *consult-async*" + "Buffer for async logging output used by `consult--async-process'.") + +(defvar-local consult--focus-lines-overlays nil + "Overlays used by `consult-focus-lines'.") + +;;;; Customization helper + +(defun consult--customize-set (cmds prop val) + "Set property PROP to VAL of commands CMDS." + (dolist (cmd cmds) + (cond + ((and (boundp cmd) (consp (symbol-value cmd))) + (set cmd (plist-put (symbol-value cmd) prop val))) + ((functionp cmd) + (setf (alist-get cmd consult--read-config) + (plist-put (alist-get cmd consult--read-config) prop val))) + (t (user-error "%s is neither a Consult command nor a Consult source" + cmd)))) + nil) + +(defmacro consult-customize (&rest args) + "Set properties of commands or sources. +ARGS is a list of commands or sources followed by the list of keyword-value +pairs." + (let ((setter)) + (while args + (let ((cmds (seq-take-while (lambda (x) (not (keywordp x))) args))) + (setq args (seq-drop-while (lambda (x) (not (keywordp x))) args)) + (while (keywordp (car args)) + (push `(consult--customize-set ',cmds ,(car args) ,(cadr args)) setter) + (setq args (cddr args))))) + (macroexp-progn setter))) + +;;;; Helper functions and macros + +(defun consult--command-split (str) + "Return command argument and options list given input STR." + (save-match-data + (let ((opts (when (string-match " +--\\( +\\|\\'\\)" str) + (prog1 (substring str (match-end 0)) + (setq str (substring str 0 (match-beginning 0))))))) + ;; split-string-and-unquote fails if the quotes are invalid. Ignore it. + (cons str (and opts (ignore-errors (split-string-and-unquote opts))))))) + +(defun consult--highlight-regexps (regexps str) + "Highlight REGEXPS in STR. +If a regular expression contains capturing groups, only these are highlighted. +If no capturing groups are used highlight the whole match." + (dolist (re regexps) + (when (string-match re str) + ;; Unfortunately there is no way to avoid the allocation of the match + ;; data, since the number of capturing groups is unknown. + (let ((m (match-data))) + (setq m (or (cddr m) m)) + (while m + (when (car m) + (add-face-text-property (car m) (cadr m) + 'consult-preview-match nil str)) + (setq m (cddr m))))))) + +(defconst consult--convert-regexp-table + (append + ;; For simplicity, treat word beginning/end as word boundaries, + ;; since PCRE does not make this distinction. Usually the + ;; context determines if \b is the beginning or the end. + '(("\\<" . "\\b") ("\\>" . "\\b") + ("\\_<" . "\\b") ("\\_>" . "\\b")) + ;; Treat \` and \' as beginning and end of line. This is more + ;; widely supported and makes sense for line-based commands. + '(("\\`" . "^") ("\\'" . "$")) + ;; Historical: Unescaped *, +, ? are supported at the beginning + (mapcan (lambda (x) + (mapcar (lambda (y) + (cons (concat x y) + (concat (string-remove-prefix "\\" x) "\\" y))) + '("*" "+" "?"))) + '("" "\\(" "\\(?:" "\\|" "^")) + ;; Different escaping + (mapcan (lambda (x) `(,x (,(cdr x) . ,(car x)))) + '(("\\|" . "|") + ("\\(" . "(") ("\\)" . ")") + ("\\{" . "{") ("\\}" . "}")))) + "Regexp conversion table.") + +(defun consult--convert-regexp (regexp type) + "Convert Emacs REGEXP to regexp syntax TYPE." + (if (memq type '(emacs basic)) + regexp + ;; Support for Emacs regular expressions is fairly complete for basic + ;; usage. There are a few unsupported Emacs regexp features: + ;; - \= point matching + ;; - Syntax classes \sx \Sx + ;; - Character classes \cx \Cx + ;; - Explicitly numbered groups (?3:group) + (replace-regexp-in-string + (rx (or "\\\\" "\\^" ;; Pass through + (seq (or "\\(?:" "\\|") (any "*+?")) ;; Historical: \|+ or \(?:* etc + (seq "\\(" (any "*+")) ;; Historical: \(* or \(+ + (seq (or bos "^") (any "*+?")) ;; Historical: + or * at the beginning + (seq (opt "\\") (any "(){|}")) ;; Escape parens/braces/pipe + (seq "\\" (any "'<>`")) ;; Special escapes + (seq "\\_" (any "<>")))) ;; Beginning or end of symbol + (lambda (x) (or (cdr (assoc x consult--convert-regexp-table)) x)) + regexp 'fixedcase 'literal))) + +(defun consult--default-regexp-compiler (input type) + "Compile the INPUT string to a list of regular expressions. +The function should return a pair, the list of regular expressions and a +highlight function. The highlight function should take a single argument, the +string to highlight given the INPUT. TYPE is the desired type of regular +expression, which can be `basic', `extended', `emacs' or `pcre'." + (setq input (consult--split-escaped input)) + (cons (mapcar (lambda (x) (consult--convert-regexp x type)) input) + (when-let (regexps (seq-filter #'consult--valid-regexp-p input)) + (lambda (str) + (consult--highlight-regexps regexps str))))) + +(defun consult--split-escaped (str) + "Split STR at spaces, which can be escaped with backslash." + (mapcar + (lambda (x) (replace-regexp-in-string (string 0) " " x)) + (split-string (replace-regexp-in-string + "\\\\\\\\\\|\\\\ " + (lambda (x) (if (equal x "\\ ") (string 0) x)) + str 'fixedcase 'literal) + " +" t))) + +(defun consult--join-regexps (regexps type) + "Join REGEXPS of TYPE." + ;; Add lookahead wrapper only if there is more than one regular expression + (cond + ((and (eq type 'pcre) (cdr regexps)) + (concat "^" (mapconcat (lambda (x) (format "(?=.*%s)" x)) + regexps ""))) + ((eq type 'basic) + (string-join regexps ".*")) + (t + (when (> (length regexps) 3) + (message "Too many regexps, %S ignored. Use post-filtering!" + (string-join (seq-drop regexps 3) " ")) + (setq regexps (seq-take regexps 3))) + (consult--regexp-join-permutations regexps + (and (memq type '(basic emacs)) "\\"))))) + +(defun consult--regexp-join-permutations (regexps esc) + "Join all permutations of REGEXPS. +ESC is the escaping string for choice and groups." + (pcase regexps + ('nil "") + (`(,r) r) + (`(,r1 ,r2) (concat r1 ".*" r2 esc "|" r2 ".*" r1)) + (_ (mapconcat + (lambda (r) + (concat r ".*" esc "(" + (consult--regexp-join-permutations (remove r regexps) esc) + esc ")")) + regexps (concat esc "|"))))) + +(defun consult--valid-regexp-p (re) + "Return t if regexp RE is valid." + (condition-case nil + (progn (string-match-p re "") t) + (invalid-regexp nil))) + +(defun consult--regexp-filter (regexps) + "Create filter regexp from REGEXPS." + (if (stringp regexps) + regexps + (mapconcat (lambda (x) (concat "\\(?:" x "\\)")) regexps "\\|"))) + +(defmacro consult--keep! (list form) + "Evaluate FORM for every element of LIST and keep the non-nil results." + (declare (indent 1)) + (let ((head (make-symbol "head")) + (prev (make-symbol "prev")) + (result (make-symbol "result"))) + `(let* ((,head (cons nil ,list)) + (,prev ,head)) + (while (cdr ,prev) + (if-let (,result (let ((it (cadr ,prev))) ,form)) + (progn + (pop ,prev) + (setcar ,prev ,result)) + (setcdr ,prev (cddr ,prev)))) + (setq ,list (cdr ,head)) + nil))) + +;; Upstream bug#46326, Consult issue https://github.com/minad/consult/issues/193 +(defmacro consult--minibuffer-with-setup-hook (fun &rest body) + "Variant of `minibuffer-with-setup-hook' using a symbol and `fset'. + +This macro is only needed to prevent memory leaking issues with +the upstream `minibuffer-with-setup-hook' macro. +FUN is the hook function and BODY opens the minibuffer." + (declare (indent 1) (debug t)) + (let ((hook (make-symbol "hook")) + (append)) + (when (eq (car-safe fun) :append) + (setq append '(t) fun (cadr fun))) + `(let ((,hook (make-symbol "consult--minibuffer-setup"))) + (fset ,hook (lambda () + (remove-hook 'minibuffer-setup-hook ,hook) + (funcall ,fun))) + (unwind-protect + (progn + (add-hook 'minibuffer-setup-hook ,hook ,@append) + ,@body) + (remove-hook 'minibuffer-setup-hook ,hook))))) + +(defun consult--completion-filter (pattern cands category _highlight) + "Filter CANDS with PATTERN. + +CATEGORY is the completion category, used to find the completion style via +`completion-category-defaults' and `completion-category-overrides'. +HIGHLIGHT must be non-nil if the resulting strings should be highlighted." + ;; completion-all-completions returns an improper list + ;; where the last link is not necessarily nil. + (nconc (completion-all-completions pattern cands nil (length pattern) + `(metadata (category . ,category))) + nil)) + +(defun consult--completion-filter-complement (pattern cands category _highlight) + "Filter CANDS with complement of PATTERN. +See `consult--completion-filter' for the arguments CATEGORY and HIGHLIGHT." + (let ((ht (consult--string-hash (consult--completion-filter pattern cands category nil)))) + (seq-remove (lambda (x) (gethash x ht)) cands))) + +(defun consult--completion-filter-dispatch (pattern cands category highlight) + "Filter CANDS with PATTERN with optional complement. +Either using `consult--completion-filter' or +`consult--completion-filter-complement', depending on if the pattern starts +with a bang. See `consult--completion-filter' for the arguments CATEGORY and +HIGHLIGHT." + (cond + ((string-match-p "\\`!? ?\\'" pattern) cands) ;; empty pattern + ((string-prefix-p "! " pattern) (consult--completion-filter-complement + (substring pattern 2) cands category nil)) + (t (consult--completion-filter pattern cands category highlight)))) + +(defmacro consult--each-line (beg end &rest body) + "Iterate over each line. + +The line beginning/ending BEG/END is bound in BODY." + (declare (indent 2)) + (let ((max (make-symbol "max"))) + `(save-excursion + (let ((,beg (point-min)) (,max (point-max)) end) + (while (< ,beg ,max) + (goto-char ,beg) + (setq ,end (line-end-position)) + ,@body + (setq ,beg (1+ ,end))))))) + +(defmacro consult--static-if (cond then &rest else) + "If COND yields non-nil at compile time, do THEN, else do ELSE." + (declare (indent 2)) + (if (eval cond 'lexical) then (macroexp-progn else))) + +(defun consult--display-width (string) + "Compute width of STRING taking display and invisible properties into account." + (let ((pos 0) (width 0) (end (length string))) + (while (< pos end) + (let ((nextd (next-single-property-change pos 'display string end)) + (display (get-text-property pos 'display string))) + (if (stringp display) + (setq width (+ width (string-width display)) + pos nextd) + (while (< pos nextd) + (let ((nexti (next-single-property-change pos 'invisible string nextd))) + (unless (get-text-property pos 'invisible string) + (setq width (+ width + ;; bug#47712: Emacs 28 can compute `string-width' of substrings + (consult--static-if (eq 3 (cdr (func-arity #'string-width))) + (string-width string pos nexti) + (string-width + ;; Avoid allocation for the full string. + (if (and (= pos 0) (= nexti end)) + string + (substring-no-properties string pos nexti))))))) + (setq pos nexti)))))) + width)) + +(defun consult--string-hash (strings) + "Create hashtable from STRINGS." + (let ((ht (make-hash-table :test #'equal :size (length strings)))) + (dolist (str strings) + (puthash str t ht)) + ht)) + +(defmacro consult--local-let (binds &rest body) + "Buffer local let BINDS of dynamic variables in BODY." + (declare (indent 1)) + (let ((buffer (make-symbol "buffer")) + (local (mapcar (lambda (x) (cons (make-symbol "local") (car x))) binds))) + `(let ((,buffer (current-buffer)) + ,@(mapcar (lambda (x) `(,(car x) (local-variable-p ',(cdr x)))) local)) + (unwind-protect + (progn + ,@(mapcar (lambda (x) `(make-local-variable ',(car x))) binds) + (let (,@binds) + ,@body)) + (when (buffer-live-p ,buffer) + (with-current-buffer ,buffer + ,@(mapcar (lambda (x) + `(unless ,(car x) + (kill-local-variable ',(cdr x)))) + local))))))) + +(defun consult--abbreviate-directory (dir) + "Return abbreviated directory DIR for use in prompts." + (save-match-data + (let ((adir (abbreviate-file-name dir))) + (if (string-match "/\\([^/]+\\)/\\([^/]+\\)/\\'" adir) + (format "…/%s/%s/" (match-string 1 adir) (match-string 2 adir)) + adir)))) + +(defun consult--directory-prompt (prompt dir) + "Return prompt and directory. + +PROMPT is the prompt prefix. The directory +is appended to the prompt prefix. For projects +only the project name is shown. The `default-directory' +is not shown. Other directories are abbreviated and +only the last two path components are shown. + +If DIR is a string, it is returned. +If DIR is a true value, the user is asked. +Then the `consult-project-root-function' is tried. +Otherwise the `default-directory' is returned." + (let* ((dir + (cond + ((stringp dir) dir) + (dir + ;; HACK Preserve this-command across `read-directory-name' call, + ;; such that `consult-customize' continues to work. + ;; TODO Find a better and more general solution which preserves `this-command'. + (let ((this-command this-command)) + (read-directory-name "Directory: " nil nil t))) + (t (or (consult--project-root) default-directory)))) + (edir (file-name-as-directory (expand-file-name dir))) + ;; Bind default-directory in order to find the project + (pdir (let ((default-directory edir)) (consult--project-root)))) + (cons + (cond + ((equal edir pdir) + (format "%s (Project %s): " prompt (consult--project-name pdir))) + ((equal edir (file-name-as-directory (expand-file-name default-directory))) + (concat prompt ": ")) + (t (format "%s (%s): " prompt (consult--abbreviate-directory dir)))) + edir))) + +(defun consult--project-root () + "Return project root as absolute path." + (when-let (root (and consult-project-root-function (funcall consult-project-root-function))) + (expand-file-name root))) + +(defun consult--project-name (dir) + "Return the project name for DIR." + (if (string-match "/\\([^/]+\\)/\\'" dir) + (match-string 1 dir) + dir)) + +(defun consult--format-location (file line &optional str) + "Format location string 'FILE:LINE:STR'." + (setq line (number-to-string line) + str (concat file ":" line (and str ":") str) + file (length file)) + (put-text-property 0 file 'face 'consult-file str) + (put-text-property (1+ file) (+ 1 file (length line)) 'face 'consult-line-number str) + str) + +(defmacro consult--overlay (beg end &rest props) + "Make consult overlay between BEG and END with PROPS." + (let ((ov (make-symbol "ov")) + (puts)) + (while props + (push `(overlay-put ,ov ,(car props) ,(cadr props)) puts) + (setq props (cddr props))) + `(let ((,ov (make-overlay ,beg ,end))) + ,@puts + ,ov))) + +(defun consult--remove-dups (list) + "Remove duplicate strings from LIST." + (delete-dups (copy-sequence list))) + +(defsubst consult--in-range-p (pos) + "Return t if position POS lies in range `point-min' to `point-max'." + (<= (point-min) pos (point-max))) + +(defun consult--type-group (types) + "Return group function for TYPES." + (lambda (cand transform) + (if transform + cand + (alist-get (get-text-property 0 'consult--type cand) types)))) + +(defun consult--type-narrow (types) + "Return narrowing configuration from TYPES." + (list :predicate + (lambda (cand) (eq (get-text-property 0 'consult--type cand) consult--narrow)) + :keys types)) + +(defun consult--lookup-member (_ candidates cand) + "Lookup CAND in CANDIDATES list, return original element." + (car (member cand candidates))) + +(defun consult--lookup-cons (_ candidates cand) + "Lookup CAND in CANDIDATES alist, return cons." + (assoc cand candidates)) + +(defun consult--lookup-cdr (_ candidates cand) + "Lookup CAND in CANDIDATES alist, return cdr of element." + (cdr (assoc cand candidates))) + +(defun consult--lookup-location (_ candidates cand) + "Lookup CAND in CANDIDATES list of 'consult-location category, return the marker." + (when-let (found (member cand candidates)) + (car (get-text-property 0 'consult-location (car found))))) + +(defun consult--lookup-candidate (_ candidates cand) + "Lookup CAND in CANDIDATES list and return property 'consult--candidate." + (when-let (found (member cand candidates)) + (get-text-property 0 'consult--candidate (car found)))) + +(defun consult--forbid-minibuffer () + "Raise an error if executed from the minibuffer." + (when (minibufferp) + (user-error "`%s' called inside the minibuffer" this-command))) + +(defun consult--require-minibuffer () + "Raise an error if executed outside the minibuffer." + (unless (minibufferp) + (user-error "`%s' must be called inside the minibuffer" this-command))) + +(defun consult--fontify-all () + "Ensure that the whole buffer is fontified." + ;; Font-locking is lazy, i.e., if a line has not been looked at yet, the line + ;; is not font-locked. We would observe this if consulting an unfontified + ;; line. Therefore we have to enforce font-locking now, which is slow. In + ;; order to prevent is hang-up we check the buffer size against + ;; `consult-fontify-max-size'. + (when (and consult-fontify-preserve jit-lock-mode + (< (buffer-size) consult-fontify-max-size)) + (jit-lock-fontify-now))) + +(defun consult--fontify-region (start end) + "Ensure that region between START and END is fontified." + (when (and consult-fontify-preserve jit-lock-mode) + (jit-lock-fontify-now start end))) + +(defmacro consult--with-increased-gc (&rest body) + "Temporarily increase the gc limit in BODY to optimize for throughput." + (let ((overwrite (make-symbol "overwrite"))) + `(let* ((,overwrite (> consult--gc-threshold gc-cons-threshold)) + (gc-cons-threshold (if ,overwrite consult--gc-threshold gc-cons-threshold)) + (gc-cons-percentage (if ,overwrite consult--gc-percentage gc-cons-percentage))) + ,@body))) + +(defun consult--count-lines (pos) + "Move to position POS and return number of lines." + (let ((line 0)) + (while (< (point) pos) + (forward-line) + (when (<= (point) pos) + (setq line (1+ line)))) + (goto-char pos) + line)) + +(defun consult--position-marker (buffer line column) + "Get marker in BUFFER from LINE and COLUMN." + (when (buffer-live-p buffer) + (with-current-buffer buffer + (save-restriction + (save-excursion + (widen) + (goto-char (point-min)) + ;; Location data might be invalid by now! + (ignore-errors + (forward-line (1- line)) + (forward-char column)) + (point-marker)))))) + +(defun consult--line-group (cand transform) + "Group function used by `consult-line-all' and `consult-line-project'. +If TRANSFORM non-nil, return transformed CAND, otherwise return title." + (if transform + cand + (buffer-name + (marker-buffer + (car (get-text-property 0 'consult-location cand)))))) + +(defun consult--line-prefix (&optional curr-line) + "Annotate `consult-location' candidates with line numbers. +CURR-LINE is the current line number." + (setq curr-line (or curr-line -1)) + (let* ((width (length (number-to-string (line-number-at-pos + (point-max) + consult-line-numbers-widen)))) + (fmt-before (propertize (format "%%%dd " width) 'face 'consult-line-number-wrapped)) + (fmt-after (propertize (format "%%%dd " width) 'face 'consult-line-number-prefix))) + (lambda (cand) + (let ((line (cdr (get-text-property 0 'consult-location cand)))) + (list cand (format (if (< line curr-line) fmt-before fmt-after) line) ""))))) + +(defun consult--location-candidate (cand marker line &rest props) + "Add MARKER and LINE as 'consult-location text property to CAND. +Furthermore add the additional text properties PROPS, and append +tofu-encoded MARKER suffix for disambiguation." + (setq cand (concat cand (consult--tofu-encode marker))) + (add-text-properties 0 1 `(consult-location (,marker . ,line) ,@props) cand) + cand) + +(defsubst consult--buffer-substring (beg end &optional fontify) + "Return buffer substring between BEG and END. +If FONTIFY and `consult-fontify-preserve' are non-nil, first ensure that the +region has been fontified." + (if consult-fontify-preserve + (progn + (when fontify + (consult--fontify-region beg end)) + (buffer-substring beg end)) + (buffer-substring-no-properties beg end))) + +(defun consult--region-with-cursor (beg end marker) + "Return region string with a marking at the cursor position. + +BEG is the begin position. +END is the end position. +MARKER is the cursor position." + (let ((str (consult--buffer-substring beg end 'fontify))) + (if (>= marker end) + (concat str #(" " 0 1 (face consult-preview-cursor))) + (put-text-property (- marker beg) (- (1+ marker) beg) + 'face 'consult-preview-cursor str) + str))) + +(defun consult--line-with-cursor (marker) + "Return current line where the cursor MARKER is highlighted." + (consult--region-with-cursor (line-beginning-position) (line-end-position) marker)) + +;;;; Preview support + +(defun consult--kill-clean-buffer (buf) + "Kill BUF if it has not been modified." + (unless (buffer-modified-p buf) + (kill-buffer buf))) + +(defun consult--temporary-files () + "Return a function to open files temporarily." + (let* ((new-buffers) + (dir default-directory)) + (lambda (&optional name) + (if name + (let ((default-directory dir)) + (or (get-file-buffer name) + ;; file-attributes may throw permission denied error + (when-let* ((attrs (ignore-errors (file-attributes name))) + (size (file-attribute-size attrs))) + (if (> size consult-preview-max-size) + (prog1 nil + (message "File `%s' (%s) is too large for preview" + name (file-size-human-readable size))) + (cl-letf* (((default-value 'find-file-hook) + (seq-remove (lambda (x) (memq x consult-preview-excluded-hooks)) + (default-value 'find-file-hook))) + (inhibit-message t) + (non-essential t) + (enable-dir-local-variables nil) + (enable-local-variables (and enable-local-variables :safe)) + (buf (find-file-noselect + name 'nowarn + (> size consult-preview-raw-size)))) + (push buf new-buffers) + ;; Only keep a few buffers alive + (while (> (length new-buffers) consult-preview-max-count) + (consult--kill-clean-buffer (car (last new-buffers))) + (setq new-buffers (nbutlast new-buffers))) + buf))))) + (mapc #'consult--kill-clean-buffer new-buffers))))) + +(defun consult--invisible-open-permanently () + "Open overlays which hide the current line. +See `isearch-open-necessary-overlays' and `isearch-open-overlay-temporary'." + (dolist (ov (overlays-in (line-beginning-position) (line-end-position))) + (when-let (fun (overlay-get ov 'isearch-open-invisible)) + (when (invisible-p (overlay-get ov 'invisible)) + (funcall fun ov))))) + +(defun consult--invisible-open-temporarily () + "Temporarily open overlays which hide the current line. +See `isearch-open-necessary-overlays' and `isearch-open-overlay-temporary'." + (let ((restore)) + (dolist (ov (overlays-in (line-beginning-position) (line-end-position)) restore) + (let ((inv (overlay-get ov 'invisible))) + (when (and (invisible-p inv) (overlay-get ov 'isearch-open-invisible)) + (push (if-let (fun (overlay-get ov 'isearch-open-invisible-temporary)) + (progn + (funcall fun ov nil) + (lambda () (funcall fun ov t))) + (overlay-put ov 'invisible nil) + (lambda () (overlay-put ov 'invisible inv))) + restore)))))) + +(defun consult--jump-nomark (pos) + "Go to POS and recenter." + (cond + ((and (markerp pos) (not (marker-buffer pos))) + ;; Only print a message, no error in order to not mess + ;; with the minibuffer update hook. + (message "Buffer is dead")) + (t + ;; Switch to buffer if it is not visible + (when (and (markerp pos) (not (eq (current-buffer) (marker-buffer pos)))) + (consult--buffer-action (marker-buffer pos) 'norecord)) + ;; Widen if we cannot jump to the position (idea from flycheck-jump-to-error) + (unless (= (goto-char pos) (point)) + (widen) + (goto-char pos)) + (run-hooks 'consult-after-jump-hook)))) + +(defun consult--jump (pos) + "Push current position to mark ring, go to POS and recenter." + (when pos + ;; When the marker is in the same buffer, + ;; record previous location such that the user can jump back quickly. + (unless (and (markerp pos) (not (eq (current-buffer) (marker-buffer pos)))) + (push-mark (point) t)) + (consult--jump-nomark pos) + (consult--invisible-open-permanently)) + nil) + +;; Matched strings are not highlighted as of now. +;; see https://github.com/minad/consult/issues/7 +(defun consult--jump-preview (&optional face) + "The preview function used if selecting from a list of candidate positions. +The function can be used as the `:state' argument of `consult--read'. +FACE is the cursor face." + (let ((overlays) + (invisible) + (face (or face 'consult-preview-cursor)) + (saved-min (point-min-marker)) + (saved-max (point-max-marker)) + (saved-pos (point-marker))) + (set-marker-insertion-type saved-max t) ;; Grow when text is inserted + (lambda (cand restore) + (mapc #'funcall invisible) + (mapc #'delete-overlay overlays) + (setq invisible nil overlays nil) + (cond + (restore + (let ((saved-buffer (marker-buffer saved-pos))) + (if (not saved-buffer) + (message "Buffer is dead") + (set-buffer saved-buffer) + (narrow-to-region saved-min saved-max) + (goto-char saved-pos)))) + ;; Jump to position + (cand + (consult--jump-nomark cand) + (setq invisible (consult--invisible-open-temporarily) + overlays + (list (save-excursion + (let ((vbeg (progn (beginning-of-visual-line) (point))) + (vend (progn (end-of-visual-line) (point))) + (end (line-end-position))) + (consult--overlay vbeg (if (= vend end) (1+ end) vend) + 'face 'consult-preview-line + 'window (selected-window)))) + (consult--overlay (point) (1+ (point)) + 'face face + 'window (selected-window))))) + ;; If position cannot be previewed, return to saved position + (t (consult--jump-nomark saved-pos)))))) + +(defun consult--jump-state (&optional face) + "The state function used if selecting from a list of candidate positions. +The function can be used as the `:state' argument of `consult--read'. +FACE is the cursor face." + (let ((preview (consult--jump-preview face))) + (lambda (cand restore) + (funcall preview cand restore) + (when (and cand restore) + (consult--jump cand))))) + +(defmacro consult--define-state (type) + "Define state function for TYPE." + `(defun ,(intern (format "consult--%s-state" type)) () + (let ((preview (,(intern (format "consult--%s-preview" type))))) + (lambda (cand restore) + (funcall preview cand restore) + (when (and cand restore) + (,(intern (format "consult--%s-action" type)) cand)))))) + +(defun consult--preview-key-normalize (preview-key) + "Normalize PREVIEW-KEY, return alist of keys and debounce times." + (let ((keys) + (debounce 0)) + (setq preview-key (consult--ensure-list preview-key)) + (while preview-key + (if (eq (car preview-key) :debounce) + (setq debounce (cadr preview-key) + preview-key (cddr preview-key)) + (push (cons (car preview-key) debounce) keys) + (pop preview-key))) + keys)) + +(defun consult--preview-key-pressed-p (preview-key cand) + "Return t if PREVIEW-KEY has been pressed given the current candidate CAND." + (when (and (consp preview-key) (memq :keys preview-key)) + (setq preview-key (funcall (plist-get preview-key :predicate) cand))) + (setq preview-key (consult--preview-key-normalize preview-key)) + (let ((keys (this-single-command-keys))) + (cdr (or (seq-find (lambda (x) + (and (not (eq (car x) 'any)) + (equal (vconcat (car x)) keys))) + preview-key) + (assq 'any preview-key))))) + +(defun consult--with-preview-1 (preview-key state transform candidate fun) + "Add preview support for FUN. + +See `consult--with-preview' for the arguments PREVIEW-KEY, STATE, TRANSFORM +and CANDIDATE." + (let ((input "") (selected) (timer)) + (consult--minibuffer-with-setup-hook + (if (and state preview-key) + (lambda () + (setq consult--preview-function + (let ((last-preview)) + (lambda () + (when-let (cand (funcall candidate)) + (with-selected-window (active-minibuffer-window) + (let ((input (minibuffer-contents-no-properties))) + (with-selected-window (or (minibuffer-selected-window) (next-window)) + (let ((transformed (funcall transform input cand)) + (new-preview (cons input cand))) + (when-let (debounce (consult--preview-key-pressed-p preview-key transformed)) + (when timer + (cancel-timer timer) + (setq timer nil)) + (unless (equal last-preview new-preview) + (if (> debounce 0) + (let ((win (selected-window))) + (setq timer + (run-at-time + debounce + nil + (lambda () + (when (window-live-p win) + (with-selected-window win + (funcall state transformed nil) + (setq last-preview new-preview))))))) + (funcall state transformed nil) + (setq last-preview new-preview)))))))))))) + ;; symbol indirection because of bug#46407 + (let ((post-command-sym (make-symbol "consult--preview-post-command"))) + (fset post-command-sym (lambda () + (setq input (minibuffer-contents-no-properties)) + (funcall consult--preview-function))) + (add-hook 'post-command-hook post-command-sym nil 'local))) + (lambda () + ;; symbol indirection because of bug#46407 + (let ((post-command-sym (make-symbol "consult--preview-post-command"))) + (fset post-command-sym (lambda () (setq input (minibuffer-contents-no-properties)))) + (add-hook 'post-command-hook post-command-sym nil 'local)))) + (unwind-protect + (cons (setq selected (when-let (result (funcall fun)) + (funcall transform input result))) + input) + (when timer + (cancel-timer timer)) + ;; If there is a state function, always call restore! + ;; The preview function should be seen as a stateful object, + ;; and we call the destructor here. + (when state + (funcall state selected t)))))) + +(defmacro consult--with-preview (preview-key state transform candidate &rest body) + "Add preview support to BODY. + +STATE is the state function. +TRANSFORM is the transformation function. +CANDIDATE is the function returning the current candidate. +PREVIEW-KEY are the keys which triggers the preview. + +The preview function takes two arguments, the selected candidate and a restore +flag. It is called every time with restore=nil after a preview-key keypress, as +long as a new candidate is selected. Finally the preview function is called in +any case with restore=t even if no preview has actually taken place. The +candidate argument can be nil if the selection has been aborted." + (declare (indent 4)) + `(consult--with-preview-1 ,preview-key ,state ,transform ,candidate (lambda () ,@body))) + +;;;; Narrowing support + +(defun consult--widen-key () + "Return widening key, if `consult-widen-key' is not set. +The default is twice the `consult-narrow-key'." + (or consult-widen-key (and consult-narrow-key (vconcat consult-narrow-key consult-narrow-key)))) + +(defun consult-narrow (key) + "Narrow current completion with KEY. + +This command is used internally by the narrowing system of `consult--read'." + (interactive + (list (unless (equal (this-single-command-keys) (consult--widen-key)) + last-command-event))) + (consult--require-minibuffer) + (setq consult--narrow key) + (when consult--narrow-predicate + (setq minibuffer-completion-predicate (and consult--narrow consult--narrow-predicate))) + (when consult--narrow-overlay + (delete-overlay consult--narrow-overlay)) + (when consult--narrow + (setq consult--narrow-overlay + (consult--overlay + (1- (minibuffer-prompt-end)) (minibuffer-prompt-end) + 'before-string + (propertize (format " [%s]" (alist-get consult--narrow + consult--narrow-keys)) + 'face 'consult-narrow-indicator)))) + (run-hooks 'consult--completion-refresh-hook)) + +(defconst consult--narrow-delete + `(menu-item + "" nil :filter + ,(lambda (&optional _) + (when (string= (minibuffer-contents-no-properties) "") + (lambda () + (interactive) + (consult-narrow nil)))))) + +(defconst consult--narrow-space + `(menu-item + "" nil :filter + ,(lambda (&optional _) + (let ((str (minibuffer-contents-no-properties))) + (when-let (pair (or (and (= 1 (length str)) + (assoc (aref str 0) consult--narrow-keys)) + (and (string= str "") + (assoc 32 consult--narrow-keys)))) + (lambda () + (interactive) + (delete-minibuffer-contents) + (consult-narrow (car pair)))))))) + +(defun consult-narrow-help () + "Print narrowing help as a `minibuffer-message'. + +This command can be bound to a key in `consult-narrow-map', +to make it available for commands with narrowing." + (interactive) + (consult--require-minibuffer) + (let ((minibuffer-message-timeout 1000000)) + (minibuffer-message + (mapconcat + (lambda (x) (concat + (propertize (char-to-string (car x)) 'face 'consult-key) " " + (propertize (cdr x) 'face 'consult-help))) + (seq-filter (lambda (x) (/= (car x) 32)) + consult--narrow-keys) + " ")))) + +(defun consult--narrow-setup (settings map) + "Setup narrowing with SETTINGS and keymap MAP." + (if (memq :keys settings) + (setq consult--narrow-predicate (plist-get settings :predicate) + consult--narrow-keys (plist-get settings :keys)) + (setq consult--narrow-predicate nil + consult--narrow-keys settings)) + (when consult-narrow-key + (dolist (pair consult--narrow-keys) + (define-key map + (vconcat consult-narrow-key (vector (car pair))) + (cons (cdr pair) #'consult-narrow)))) + (when-let (widen (consult--widen-key)) + (define-key map widen (cons "All" #'consult-narrow)))) + +;; Emacs 28: hide in M-X +(put #'consult-narrow-help 'completion-predicate #'ignore) +(put #'consult-narrow 'completion-predicate #'ignore) + +;;;; Splitting completion style + +(defun consult--split-perl (str point) + "Split input STR in async input and filtering part. + +The function returns a list with four elements: The async string, the +completion filter string, the new point position computed from POINT and a +force flag. If the first character is a punctuation character it determines the +separator. Examples: \"/async/filter\", \"#async#filter\"." + (if (string-match-p "^[[:punct:]]" str) + (save-match-data + (let ((q (regexp-quote (substring str 0 1)))) + (string-match (concat "^" q "\\([^" q "]*\\)\\(" q "\\)?") str) + `(,(match-string 1 str) + ,(substring str (match-end 0)) + ,(max 0 (- point (match-end 0))) + ;; Force update it two punctuation characters are entered. + ,(match-end 2) + ;; List of highlights + (0 . ,(match-beginning 1)) + ,@(and (match-end 2) `((,(match-beginning 2) . ,(match-end 2))))))) + `(,str "" 0))) + +(defun consult--split-nil (str _point) + "Treat the complete input STR as async input." + `(,str "" 0)) + +(defun consult--split-separator (sep str point) + "Split input STR in async input and filtering part at the first separator SEP. +POINT is the point position." + (setq sep (regexp-quote (char-to-string sep))) + (save-match-data + (if (string-match (format "^\\([^%s]+\\)\\(%s\\)?" sep sep) str) + `(,(match-string 1 str) + ,(substring str (match-end 0)) + ,(max 0 (- point (match-end 0))) + ;; Force update it space is entered. + ,(match-end 2) + ;; List of highlights + (0 . ,(match-end 1))) + `(,str "" 0)))) + +(defun consult--split-setup (split) + "Setup splitting completion style with splitter function SPLIT." + (let* ((styles completion-styles) + (catdef completion-category-defaults) + (catovr completion-category-overrides) + (try (lambda (str table pred point) + (let ((completion-styles styles) + (completion-category-defaults catdef) + (completion-category-overrides catovr) + (parts (funcall split str point))) + (completion-try-completion (cadr parts) table pred (caddr parts))))) + (all (lambda (str table pred point) + (let ((completion-styles styles) + (completion-category-defaults catdef) + (completion-category-overrides catovr) + (parts (funcall split str point))) + (completion-all-completions (cadr parts) table pred (caddr parts)))))) + (setq-local completion-styles-alist (cons `(consult--split ,try ,all "") + completion-styles-alist)) + (setq-local completion-styles '(consult--split)) + (setq-local completion-category-defaults nil) + (setq-local completion-category-overrides nil))) + +;;;; Async support + +(defmacro consult--with-async (bind &rest body) + "Setup asynchronous completion in BODY. + +BIND is the asynchronous function binding." + (declare (indent 1)) + (let ((async (car bind))) + `(let ((,async ,@(cdr bind)) (orig-chunk)) + (consult--minibuffer-with-setup-hook + ;; Append such that we overwrite the completion style setting of + ;; `fido-mode'. See `consult--async-split' and + ;; `consult--split-setup'. + (:append + (lambda () + (when (functionp ,async) + (setq orig-chunk read-process-output-max + read-process-output-max (max read-process-output-max consult--process-chunk)) + (funcall ,async 'setup) + ;; Push input string to request refresh. + ;; We use a symbol in order to avoid adding lambdas to the hook variable. + ;; Symbol indirection because of bug#46407. + (let ((sym (make-symbol "consult--async-after-change"))) + (fset sym (lambda (&rest _) (funcall ,async (minibuffer-contents-no-properties)))) + (run-at-time 0 nil sym) + (add-hook 'after-change-functions sym nil 'local))))) + (let ((,async (if (functionp ,async) ,async (lambda (_) ,async)))) + (unwind-protect + ,(macroexp-progn body) + (funcall ,async 'destroy) + (when orig-chunk + (setq read-process-output-max orig-chunk)))))))) + +(defun consult--async-sink () + "Create ASYNC sink function. + +An async function must accept a single action argument. For the 'setup action +it is guaranteed that the call originates from the minibuffer. For the other +actions no assumption about the context can be made. + +'setup Setup the internal closure state. Return nil. +'destroy Destroy the internal closure state. Return nil. +'flush Flush the list of candidates. Return nil. +'refresh Request UI refresh. Return nil. +nil Return the list of candidates. +list Append the list to the already existing candidates list and return it. +string Update with the current user input string. Return nil." + (let (candidates last buffer previewed) + (lambda (action) + (pcase-exhaustive action + ('setup + (setq buffer (current-buffer)) + nil) + ((or (pred stringp) 'destroy) nil) + ('flush (setq candidates nil last nil previewed nil)) + ('refresh + ;; Refresh the UI when the current minibuffer window belongs + ;; to the current asynchronous completion session. + (when-let (win (active-minibuffer-window)) + (when (eq (window-buffer win) buffer) + (with-selected-window win + (run-hooks 'consult--completion-refresh-hook) + ;; Interaction between asynchronous completion tables and + ;; preview: We have to trigger preview immediately when + ;; candidates arrive (Issue #436). + (when (and consult--preview-function candidates (not previewed)) + (setq previewed t) + (funcall consult--preview-function))))) + nil) + ('nil candidates) + ((pred consp) + (setq last (last (if last (setcdr last action) (setq candidates action)))) + candidates))))) + +(defun consult--async-split-style () + "Return the async splitting style function and initial string." + (or (alist-get consult-async-split-style consult-async-split-styles-alist) + (user-error "Splitting style `%s' not found" consult-async-split-style))) + +(defun consult--async-split-initial (initial) + "Return initial string for async command. +INITIAL is the additional initial string." + (concat (plist-get (consult--async-split-style) :initial) initial)) + +(defun consult--async-split-thingatpt (thing) + "Return THING at point with async initial prefix." + (when-let (str (thing-at-point thing)) + (consult--async-split-initial str))) + +(defun consult--async-split (async &optional split) + "Create async function, which splits the input string. +ASYNC is the async sink. +SPLIT is the splitting function." + (unless split + (let ((style (consult--async-split-style))) + (setq split (pcase (plist-get style :type) + ('separator (apply-partially #'consult--split-separator + (plist-get style :separator))) + ('perl #'consult--split-perl) + ('nil #'consult--split-nil) + (type (user-error "Invalid style type `%s'" type)))))) + (lambda (action) + (pcase action + ('setup + (consult--split-setup split) + (funcall async 'setup)) + ((pred stringp) + (pcase-let* ((`(,async-str ,_ ,_ ,force . ,highlights) + (funcall split action 0)) + (async-len (length async-str)) + (input-len (length action)) + (end (minibuffer-prompt-end))) + ;; Highlight punctuation characters + (remove-list-of-text-properties end (+ end input-len) '(face)) + (dolist (hl highlights) + (put-text-property (+ end (car hl)) (+ end (cdr hl)) + 'face 'consult-async-split)) + (funcall async + ;; Pass through if the input is long enough! + (if (or force (>= async-len consult-async-min-input)) + async-str + ;; Pretend that there is no input + "")))) + (_ (funcall async action))))) + +(defun consult--async-log (formatted &rest args) + "Log FORMATTED ARGS to variable `consult--async-log'." + (with-current-buffer (get-buffer-create consult--async-log) + (goto-char (point-max)) + (insert (apply #'format formatted args)))) + +(defun consult--process-indicator (event) + "Return the process indicator character for EVENT." + (cond + ((string-prefix-p "killed" event) + #(";" 0 1 (face consult-async-failed))) + ((string-prefix-p "finished" event) + #(":" 0 1 (face consult-async-finished))) + (t + #("!" 0 1 (face consult-async-failed))))) + +(defun consult--async-process (async cmd &rest props) + "Create process source async function. + +ASYNC is the async function which receives the candidates. +CMD is the command line builder function. +PROPS are optional properties passed to `make-process'." + (let (proc proc-buf last-args indicator count) + (lambda (action) + (pcase action + ("" ;; If no input is provided kill current process + (when proc + (delete-process proc) + (kill-buffer proc-buf) + (setq proc nil proc-buf nil)) + (setq last-args nil)) + ((pred stringp) + (funcall async action) + (let* ((args (funcall cmd action)) + (flush t) + (rest "") + (proc-filter + (lambda (_ out) + (when flush + (setq flush nil) + (funcall async 'flush)) + (let ((lines (split-string out "[\r\n]+"))) + (if (not (cdr lines)) + (setq rest (concat rest (car lines))) + (setcar lines (concat rest (car lines))) + (let* ((len (length lines)) + (last (nthcdr (- len 2) lines))) + (setq rest (cadr last) + count (+ count len -1)) + (setcdr last nil) + (funcall async lines)))))) + (proc-sentinel + (lambda (_ event) + (when flush + (setq flush nil) + (funcall async 'flush)) + (overlay-put indicator 'display (consult--process-indicator event)) + (when (and (string-prefix-p "finished" event) (not (string= rest ""))) + (setq count (+ count 1)) + (funcall async (list rest))) + (consult--async-log + "consult--async-process sentinel: event=%s lines=%d\n" + (string-trim event) count) + (with-current-buffer (get-buffer-create consult--async-log) + (goto-char (point-max)) + (insert ">>>>> stderr >>>>>\n") + (insert-buffer-substring proc-buf) + (insert "<<<<< stderr <<<<<\n"))))) + (unless (equal args last-args) + (setq last-args args) + (when proc + (delete-process proc) + (kill-buffer proc-buf) + (setq proc nil proc-buf nil)) + (when args + (overlay-put indicator 'display #("*" 0 1 (face consult-async-running))) + (consult--async-log "consult--async-process started %S\n" args) + (setq count 0 + proc-buf (generate-new-buffer " *consult-async-stderr*") + proc (apply #'make-process + `(,@props + :connection-type pipe + :name ,(car args) + ;;; XXX tramp bug, the stderr buffer must be empty + :stderr ,proc-buf + :noquery t + :command ,args + :filter ,proc-filter + :sentinel ,proc-sentinel)))))) + nil) + ('destroy + (when proc + (delete-process proc) + (kill-buffer proc-buf) + (setq proc nil proc-buf nil)) + (delete-overlay indicator) + (funcall async 'destroy)) + ('setup + (setq indicator (make-overlay (- (minibuffer-prompt-end) 2) + (- (minibuffer-prompt-end) 1))) + (funcall async 'setup)) + (_ (funcall async action)))))) + +(defun consult--async-highlight (async builder) + "Return ASYNC function which highlightes the candidates. +BUILDER is the command line builder." + (let ((highlight)) + (lambda (action) + (cond + ((stringp action) + (setq highlight (plist-get (funcall builder action) :highlight)) + (funcall async action)) + ((and (consp action) highlight) + (dolist (str action) + (funcall highlight str)) + (funcall async action)) + (t (funcall async action)))))) + +(defun consult--async-throttle (async &optional throttle debounce) + "Create async function from ASYNC which throttles input. + +The THROTTLE delay defaults to `consult-async-input-throttle'. +The DEBOUNCE delay defaults to `consult-async-input-debounce'." + (setq throttle (or throttle consult-async-input-throttle) + debounce (or debounce consult-async-input-debounce)) + (let ((input "") (last) (timer)) + (lambda (action) + (pcase action + ((pred stringp) + (unless (string= action input) + (when timer + (cancel-timer timer) + (setq timer nil)) + (funcall async "") ;; cancel running process + (setq input action) + (unless (string= action "") + (setq timer + (run-at-time + (+ debounce + (if last + (min (- (float-time) last) throttle) + 0)) + nil + (lambda () + (setq last (float-time)) + (funcall async action)))))) + nil) + ('destroy + (when timer (cancel-timer timer)) + (funcall async 'destroy)) + (_ (funcall async action)))))) + +(defun consult--async-refresh-immediate (async) + "Create async function from ASYNC, which refreshes the display. + +The refresh happens immediately when candidates are pushed." + (lambda (action) + (pcase action + ((or (pred consp) 'flush) + (prog1 (funcall async action) + (funcall async 'refresh))) + (_ (funcall async action))))) + +(defun consult--async-refresh-timer (async &optional delay) + "Create async function from ASYNC, which refreshes the display. + +The refresh happens after a DELAY, defaulting to `consult-async-refresh-delay'." + (let ((timer) (refresh) (delay (or delay consult-async-refresh-delay))) + (lambda (action) + (prog1 (funcall async action) + (pcase action + ((or (pred consp) 'flush) + (setq refresh t) + (unless timer + (setq timer (run-at-time + nil delay + (lambda () + (when refresh + (setq refresh nil) + (funcall async 'refresh))))))) + ('destroy (when timer (cancel-timer timer)))))))) + +(defmacro consult--async-transform (async &rest transform) + "Use FUN to TRANSFORM candidates of ASYNC." + (let ((async-var (make-symbol "async")) + (action-var (make-symbol "action"))) + `(let ((,async-var ,async)) + (lambda (,action-var) + (funcall ,async-var (if (consp ,action-var) (,@transform ,action-var) ,action-var)))))) + +(defun consult--async-map (async fun) + "Map candidates of ASYNC by FUN." + (consult--async-transform async mapcar fun)) + +(defun consult--async-filter (async fun) + "Filter candidates of ASYNC by FUN." + (consult--async-transform async seq-filter fun)) + +(defun consult--ensure-list (list) + "Ensure that LIST is a list." + (if (listp list) list (list list))) ;; Emacs 28 ensure-list + +(defun consult--command-builder (builder) + "Return command line builder given CMD. +BUILDER is the command line builder function." + (lambda (input) + (setq input (funcall builder input)) + (if (stringp (car input)) + input + (plist-get input :command)))) + +(defmacro consult--async-command (builder &rest args) + "Asynchronous command pipeline. +ARGS is a list of `make-process' properties and transforms. BUILDER is the +command line builder function, which takes the input string and must either +return a list of command line arguments or a plist with the command line +argument list :command and a highlighting function :highlight." + (declare (indent 1)) + `(thread-first (consult--async-sink) + (consult--async-refresh-timer) + ,@(seq-take-while (lambda (x) (not (keywordp x))) args) + (consult--async-process + (consult--command-builder ,builder) + ,@(seq-drop-while (lambda (x) (not (keywordp x))) args)) + (consult--async-throttle) + (consult--async-split))) + +;;;; Special keymaps + +(defvar consult-async-map + (let ((map (make-sparse-keymap))) + ;; Async keys overwriting some unusable defaults for the default completion + (define-key map [remap minibuffer-complete-word] #'self-insert-command) + (define-key map [remap minibuffer-complete] #'minibuffer-completion-help) + map) + "Keymap added for commands with asynchronous candidates.") + +(defvar consult-crm-map (make-sparse-keymap) + "Keymap added by `consult-completing-read-multiple'.") + +(defvar consult-preview-map (make-sparse-keymap) + "Keymap added for commands with preview.") + +(defvar consult-narrow-map + (let ((map (make-sparse-keymap))) + (define-key map " " consult--narrow-space) + (define-key map "\d" consult--narrow-delete) + map) + "Narrowing keymap which is added to the local minibuffer map. +Note that `consult-narrow-key' and `consult-widen-key' are bound dynamically.") + +;;;; Internal API: consult--read + +(defun consult--add-history (async items) + "Add ITEMS to the minibuffer future history. +ASYNC must be non-nil for async completion functions." + (delete-dups + (append + ;; the defaults are at the beginning of the future history + (consult--ensure-list minibuffer-default) + ;; then our custom items + (remove "" (remq nil (consult--ensure-list items))) + ;; Add all the completions for non-async commands. For async commands this feature + ;; is not useful, since if one selects a completion candidate, the async search is + ;; restarted using that candidate string. This usually does not yield a desired + ;; result since the async input uses a special format, e.g., `#grep#filter'. + (unless async + (all-completions "" + minibuffer-completion-table + minibuffer-completion-predicate))))) + +(defun consult--setup-keymap (keymap async narrow preview-key) + "Setup minibuffer keymap. + +KEYMAP is a command-specific keymap. +ASYNC must be non-nil for async completion functions. +NARROW are the narrow settings. +PREVIEW-KEY are the preview keys." + (let ((old-map (current-local-map)) + (map (make-sparse-keymap))) + + ;; Add narrow keys + (when narrow + (consult--narrow-setup narrow map)) + + ;; Preview trigger keys + (when (and (consp preview-key) (memq :keys preview-key)) + (setq preview-key (plist-get preview-key :keys))) + (setq preview-key (mapcar #'car (consult--preview-key-normalize preview-key))) + (when preview-key + (dolist (key preview-key) + (unless (or (eq key 'any) (lookup-key old-map key)) + (define-key map key #'ignore)))) + + ;; Put the keymap together + (use-local-map + (make-composed-keymap + (delq nil (list keymap + (and async consult-async-map) + (and narrow consult-narrow-map) + (and preview-key consult-preview-map) + map)) + old-map)))) + +(defun consult--fry-the-tofus (&rest _) + "Fry the tofus in the minibuffer." + (let* ((min (minibuffer-prompt-end)) + (max (point-max)) + (pos max) + (high (+ consult--tofu-char consult--tofu-range -1))) + (while (and (> pos min) (<= consult--tofu-char (char-before pos) high)) + (setq pos (1- pos))) + (when (< pos max) + (add-text-properties pos max '(invisible t rear-nonsticky t cursor-intangible t))))) + +(defsubst consult--tofu-append (cand id) + "Append tofu-encoded ID to CAND." + (setq id (char-to-string (+ consult--tofu-char id))) + (add-text-properties 0 1 '(invisible t consult-strip t) id) + (concat cand id)) + +(defsubst consult--tofu-get (cand) + "Extract tofu-encoded ID from CAND." + (- (aref cand (1- (length cand))) consult--tofu-char)) + +;; We must disambiguate the lines by adding a prefix such that two lines with +;; the same text can be distinguished. In order to avoid matching the line +;; number, such that the user can search for numbers with `consult-line', we +;; encode the line number as unicode characters in the supplementary private use +;; plane b. By doing that, it is unlikely that accidential matching occurs. +(defun consult--tofu-encode (n) + "Return tofu-encoded number N." + (let ((str "")) + (while (progn + (setq str (concat (char-to-string (+ consult--tofu-char + (% n consult--tofu-range))) + str)) + (and (>= n consult--tofu-range) (setq n (/ n consult--tofu-range))))) + (add-text-properties 0 (length str) '(invisible t consult-strip t) str) + str)) + +(defun consult--read-annotate (fun cand) + "Annotate CAND with annotation function FUN." + (pcase (funcall fun cand) + (`(,_ ,_ ,suffix) suffix) + (ann ann))) + +(defun consult--read-affixate (fun cands) + "Affixate CANDS with annotation function FUN." + (mapcar (lambda (cand) + (let ((ann (funcall fun cand))) + (if (consp ann) + ann + (setq ann (or ann "")) + (list cand "" + ;; The default completion UI adds the `completions-annotations' face + ;; if no other faces are present. + (if (text-property-not-all 0 (length ann) 'face nil ann) + ann + (propertize ann 'face 'completions-annotations)))))) + cands)) + +(cl-defun consult--read-1 (candidates &key + prompt predicate require-match history default + keymap category initial narrow add-history annotate + state preview-key sort lookup group inherit-input-method) + "See `consult--read' for the documentation of the arguments." + (consult--minibuffer-with-setup-hook + (:append (lambda () + (add-hook 'after-change-functions #'consult--fry-the-tofus nil 'local) + (consult--setup-keymap keymap (functionp candidates) narrow preview-key) + (setq-local minibuffer-default-add-function + (apply-partially #'consult--add-history (functionp candidates) add-history)))) + (consult--with-async (async candidates) + ;; NOTE: Do not unnecessarily let-bind the lambdas to avoid + ;; overcapturing in the interpreter. This will make closures and the + ;; lambda string representation larger, which makes debugging much worse. + ;; Fortunately the overcapturing problem does not affect the bytecode + ;; interpreter which does a proper scope analyis. + (let* ((metadata `(metadata + ,@(when category `((category . ,category))) + ,@(when group `((group-function . ,group))) + ,@(when annotate + `((affixation-function + . ,(apply-partially #'consult--read-affixate annotate)) + (annotation-function + . ,(apply-partially #'consult--read-annotate annotate)))) + ,@(unless sort '((cycle-sort-function . identity) + (display-sort-function . identity))))) + (result + (consult--with-preview preview-key state + (lambda (input cand) + (funcall lookup input (funcall async nil) cand)) + (apply-partially #'run-hook-with-args-until-success + 'consult--completion-candidate-hook) + (completing-read prompt + (lambda (str pred action) + (if (eq action 'metadata) + metadata + (complete-with-action action (funcall async nil) str pred))) + predicate require-match initial + (if (symbolp history) history (cadr history)) + default + inherit-input-method)))) + (pcase-exhaustive history + (`(:input ,var) + (set var (cdr (symbol-value var))) + (add-to-history var (cdr result))) + ((pred symbolp))) + (car result))))) + +(cl-defun consult--read (candidates &rest options &key + prompt predicate require-match history default + keymap category initial narrow add-history annotate + state preview-key sort lookup group inherit-input-method) + "Enhanced completing read function selecting from CANDIDATES. + +Keyword OPTIONS: + +PROMPT is the string which is shown as prompt message in the minibuffer. +PREDICATE is a filter function called for each candidate. +REQUIRE-MATCH equals t means that an exact match is required. +HISTORY is the symbol of the history variable. +DEFAULT is the default selected value. +ADD-HISTORY is a list of items to add to the history. +CATEGORY is the completion category. +SORT should be set to nil if the candidates are already sorted. +LOOKUP is a lookup function passed the input, candidates and candidate string. +ANNOTATE is a function passed a candidate string to return an annotation. +INITIAL is the initial input. +STATE is the state function, see `consult--with-preview'. +GROUP is a completion metadata `group-function'. +PREVIEW-KEY are the preview keys (nil, 'any, a single key or a list of keys). +NARROW is an alist of narrowing prefix strings and description. +KEYMAP is a command-specific keymap. +INHERIT-INPUT-METHOD, if non-nil the minibuffer inherits the input method." + ;; supported types + (cl-assert (or (functionp candidates) ;; async table + (obarrayp candidates) ;; obarray + (hash-table-p candidates) ;; hash table + (not candidates) ;; empty list + (stringp (car candidates)) ;; string list + (and (consp (car candidates)) (stringp (caar candidates))) ;; string alist + (and (consp (car candidates)) (symbolp (caar candidates))))) ;; symbol alist + (ignore prompt predicate require-match history default + keymap category initial narrow add-history annotate + state preview-key sort lookup group inherit-input-method) + (apply #'consult--read-1 candidates + (append + (alist-get this-command consult--read-config) + options + (list :prompt "Select: " + :preview-key consult-preview-key + :sort t + :lookup (lambda (_input _cands x) x))))) + +;;;; Internal API: consult--multi + +(defsubst consult--multi-source (sources cand) + "Lookup source for CAND in SOURCES list." + (aref sources (consult--tofu-get cand))) + +(defun consult--multi-predicate (sources cand) + "Predicate function called for each candidate CAND given SOURCES." + (let* ((src (consult--multi-source sources cand)) + (narrow (plist-get src :narrow)) + (type (or (car-safe narrow) narrow -1))) + (or (eq consult--narrow type) + (not (or consult--narrow (plist-get src :hidden)))))) + +(defun consult--multi-narrow (sources) + "Return narrow list from SOURCES." + (thread-last sources + (mapcar (lambda (src) + (when-let (narrow (plist-get src :narrow)) + (if (consp narrow) + narrow + (when-let (name (plist-get src :name)) + (cons narrow name)))))) + (delq nil) + (delete-dups))) + +(defun consult--multi-annotate (sources align cand) + "Annotate candidate CAND with `consult--multi' type, given SOURCES and ALIGN." + (let* ((src (consult--multi-source sources cand)) + (annotate (plist-get src :annotate)) + (ann (if annotate + (funcall annotate (cdr (get-text-property 0 'multi-category cand))) + (plist-get src :name)))) + (and ann (concat align ann)))) + +(defun consult--multi-group (sources cand transform) + "Return title of candidate CAND or TRANSFORM the candidate given SOURCES." + (if transform + cand + (plist-get (consult--multi-source sources cand) :name))) + +(defun consult--multi-preview-key (sources) + "Return preview keys from SOURCES." + (list :predicate + (lambda (cand) + (if (plist-member (cdr cand) :preview-key) + (plist-get (cdr cand) :preview-key) + consult-preview-key)) + :keys + (delete-dups + (seq-mapcat (lambda (src) + (let ((key (if (plist-member src :preview-key) + (plist-get src :preview-key) + consult-preview-key))) + (consult--ensure-list key))) + sources)))) + +(defun consult--multi-lookup (sources _ candidates cand) + "Lookup CAND in CANDIDATES given SOURCES." + (if-let (found (member cand candidates)) + (cons (cdr (get-text-property 0 'multi-category (car found))) + (consult--multi-source sources cand)) + (unless (string-blank-p cand) + (list cand)))) + +(defun consult--multi-candidates (sources) + "Return `consult--multi' candidates from SOURCES." + (let ((def) (idx 0) (max-width 0) (candidates)) + (seq-doseq (src sources) + (let* ((face (and (plist-member src :face) `(face ,(plist-get src :face)))) + (cat (plist-get src :category)) + (items (plist-get src :items)) + (items (if (functionp items) (funcall items) items))) + (when (and (not def) (plist-get src :default) items) + (setq def (consult--tofu-append (car items) idx))) + (dolist (item items) + (let ((cand (consult--tofu-append item idx)) + (width (consult--display-width item))) + (add-text-properties 0 (length item) `(,@face multi-category (,cat . ,item)) cand) + (when (> width max-width) (setq max-width width)) + (push cand candidates)))) + (setq idx (1+ idx))) + (list def (+ 3 max-width) (nreverse candidates)))) + +(defun consult--multi-enabled-sources (sources) + "Return vector of enabled SOURCES." + (vconcat + (seq-filter (lambda (src) + (if-let (pred (plist-get src :enabled)) + (funcall pred) + t)) + (mapcar (lambda (src) + (if (symbolp src) (symbol-value src) src)) + sources)))) + +(defun consult--multi-state (sources) + "State function given SOURCES." + (when-let (states (delq nil (mapcar (lambda (src) + (when-let (fun (plist-get src :state)) + (cons src (funcall fun)))) + sources))) + (let ((last-fun)) + (pcase-lambda (`(,cand . ,src) restore) + ;; Get state function + (let ((selected-fun (cdr (assq src states)))) + (if restore + (progn + ;; If the candidate source changed, destruct first the last source. + (when (and last-fun (not (eq last-fun selected-fun))) + (funcall last-fun nil t)) + ;; Destruct all the sources, except the last and selected source + (dolist (state states) + (let ((fun (cdr state))) + (unless (or (eq fun last-fun) (eq fun selected-fun)) + (funcall fun nil t)))) + ;; Finally destruct the source with the selected candidate + (when selected-fun (funcall selected-fun cand t))) + ;; If the candidate source changed during preview communicate to + ;; the last source, that none of its candidates is previewed anymore. + (when (and last-fun (not (eq last-fun selected-fun))) + (funcall last-fun nil nil)) + (setq last-fun selected-fun) + ;; Call the state function. + (when selected-fun (funcall selected-fun cand nil)))))))) + +(defun consult--multi (sources &rest options) + "Select from candidates taken from a list of SOURCES. + +OPTIONS is the plist of options passed to `consult--read'. The following +options are supported: :require-match, :history, :keymap, :initial, +:add-history, :sort and :inherit-input-method. The other options of +`consult--read' are used by the implementation of `consult--multi' and should +be overwritten only in special scenarios. + +The function returns the selected candidate in the form (cons candidate +source-value). The sources of the source list can either be symbols of source +variables or source values. Source values must be plists with the following +fields: + +Required source fields: +* :category - Completion category. +* :items - List of strings to select from or function returning list of strings. + +Optional source fields: +* :name - Name of the source, used for narrowing, group titles and annotations. +* :narrow - Narrowing character or (character . string) pair. +* :enabled - Function which must return t if the source is enabled. +* :hidden - When t candidates of this source are hidden by default. +* :face - Face used for highlighting the candidates. +* :annotate - Annotation function called for each candidate, returns string. +* :history - Name of history variable to add selected candidate. +* :default - Must be t if the first item of the source is the default value. +* :action - Action function called with the selected candidate. +* :state - State constructor for the source, must return the state function. +* Other source fields can be added specifically to the use case." + (let* ((sources (consult--multi-enabled-sources sources)) + (candidates (consult--with-increased-gc + (consult--multi-candidates sources))) + (align (propertize + " " 'display + `(space :align-to (+ left ,(cadr candidates))))) + (selected (apply #'consult--read + (caddr candidates) + (append + options + (list + :default (car candidates) + :category 'multi-category + :predicate (apply-partially #'consult--multi-predicate sources) + :annotate (apply-partially #'consult--multi-annotate sources align) + :group (apply-partially #'consult--multi-group sources) + :lookup (apply-partially #'consult--multi-lookup sources) + :preview-key (consult--multi-preview-key sources) + :narrow (consult--multi-narrow sources) + :state (consult--multi-state sources)))))) + (when-let (history (plist-get (cdr selected) :history)) + (add-to-history history (car selected))) + (when-let (action (plist-get (cdr selected) :action)) + (funcall action (car selected))) + selected)) + +;;;; Internal API: consult--prompt + +(cl-defun consult--prompt-1 (&key prompt history add-history initial default + keymap state preview-key transform inherit-input-method) + "See `consult--prompt' for documentation." + (consult--minibuffer-with-setup-hook + (:append (lambda () + (consult--setup-keymap keymap nil nil preview-key) + (setq-local minibuffer-default-add-function + (apply-partially #'consult--add-history nil add-history)))) + (car (consult--with-preview preview-key state + (lambda (inp _) (funcall transform inp)) (lambda () t) + (read-from-minibuffer prompt initial nil nil history default inherit-input-method))))) + +(cl-defun consult--prompt (&rest options &key prompt history add-history initial default + keymap state preview-key transform inherit-input-method) + "Read from minibuffer. + +Keyword OPTIONS: + +PROMPT is the string to prompt with. +TRANSFORM is a function which is applied to the current input string. +HISTORY is the symbol of the history variable. +INITIAL is initial input. +DEFAULT is the default selected value. +ADD-HISTORY is a list of items to add to the history. +STATE is the state function, see `consult--with-preview'. +PREVIEW-KEY are the preview keys (nil, 'any, a single key or a list of keys). +KEYMAP is a command-specific keymap." + (ignore prompt history add-history initial default + keymap state preview-key transform inherit-input-method) + (apply #'consult--prompt-1 + (append + (alist-get this-command consult--read-config) + options + (list :prompt "Input: " + :preview-key consult-preview-key + :transform #'identity)))) + +;;;; Functions + +;;;;; Function: consult-completion-in-region + +(defun consult--insertion-preview (start end) + "State function for previewing a candidate in a specific region. +The candidates are previewed in the region from START to END. This function is +used as the `:state' argument for `consult--read' in the `consult-yank' family +of functions and in `consult-completion-in-region'." + (unless (or (minibufferp) + ;; XXX Disable preview if anything odd is going on with the markers. Otherwise we get + ;; "Marker points into wrong buffer errors". See + ;; https://github.com/minad/consult/issues/375, where Org mode source blocks are + ;; completed in a different buffer than the original buffer. This completion is + ;; probably also problematic in my Corfu completion package. + (not (eq (window-buffer) (current-buffer))) + (and (markerp start) (not (eq (marker-buffer start) (current-buffer)))) + (and (markerp end) (not (eq (marker-buffer end) (current-buffer))))) + (let (ov) + (lambda (cand restore) + (if restore + (when ov (delete-overlay ov)) + (unless ov (setq ov (consult--overlay start end + 'invisible t + 'window (selected-window)))) + ;; Use `add-face-text-property' on a copy of "cand in order to merge face properties + (setq cand (copy-sequence cand)) + (add-face-text-property 0 (length cand) 'consult-preview-insertion t cand) + ;; Use the `before-string' property since the overlay might be empty. + (overlay-put ov 'before-string cand)))))) + +;;;###autoload +(defun consult-completion-in-region (start end collection &optional predicate) + "Use minibuffer completion as the UI for `completion-at-point'. + +The function is called with 4 arguments: START END COLLECTION PREDICATE. +The arguments and expected return value are as specified for +`completion-in-region'. Use as a value for `completion-in-region-function'. + +The function can be configured via `consult-customize'. + + (consult-customize consult-completion-in-region + :completion-styles (basic) + :cycle-threshold 3) + +These configuration options are supported: + + * :cycle-threshold - Cycling threshold (def: `completion-cycle-threshold') + * :completion-styles - Use completion styles (def: `completion-styles') + * :require-match - Require matches when completing (def: nil) + * :prompt - The prompt string shown in the minibuffer" + (barf-if-buffer-read-only) + (cl-letf* ((config (alist-get #'consult-completion-in-region consult--read-config)) + ;; Overwrite both the local and global value of `completion-styles', such that the + ;; `completing-read' minibuffer sees the overwritten value in any case. This is + ;; necessary if `completion-styles' is buffer-local. + ;; NOTE: The completion-styles will be overwritten for recursive editing sessions! + (cs (or (plist-get config :completion-styles) completion-styles)) + (completion-styles cs) + ((default-value 'completion-styles) cs) + (prompt (or (plist-get config :prompt) "Completion: ")) + (require-match (plist-get config :require-match)) + (preview-key (if (plist-member config :preview-key) + (plist-get config :preview-key) + consult-preview-key)) + (initial (buffer-substring-no-properties start end)) + (metadata (completion-metadata initial collection predicate)) + (threshold (or (plist-get config :cycle-threshold) (completion--cycle-threshold metadata))) + (all (completion-all-completions initial collection predicate (length initial))) + ;; Provide `:annotation-function' if `:company-docsig' is specified + (completion-extra-properties + (if-let (fun (and (not (plist-get completion-extra-properties :annotation-function)) + (plist-get completion-extra-properties :company-docsig))) + `(:annotation-function + ,(lambda (cand) + (concat (propertize " " 'display '(space :align-to center)) + (funcall fun cand))) + ,@completion-extra-properties) + completion-extra-properties))) + ;; error if `threshold' is t or the improper list `all' is too short + (if (and threshold + (or (not (consp (ignore-errors (nthcdr threshold all)))) + (and completion-cycling completion-all-sorted-completions))) + (completion--in-region start end collection predicate) + (let* ((limit (car (completion-boundaries initial collection predicate ""))) + (category (completion-metadata-get metadata 'category)) + (buffer (current-buffer)) + (completion + (cond + ((atom all) nil) + ((and (consp all) (atom (cdr all))) + (concat (substring initial 0 limit) (car all))) + (t (car + (consult--with-preview + preview-key + ;; preview state + (consult--insertion-preview start end) + ;; transformation function + (if (eq category 'file) + (cond + ;; Transform absolute file names + ((file-name-absolute-p initial) + (lambda (_inp cand) + (substitute-in-file-name cand))) + ;; Ensure that ./ prefix is kept for the shell (#356) + ((string-match-p "\\`\\.\\.?/" initial) + (lambda (_inp cand) + (setq cand (file-relative-name (substitute-in-file-name cand))) + (if (string-match-p "\\`\\.\\.?/" cand) cand (concat "./" cand)))) + ;; Simplify relative file names + (t + (lambda (_inp cand) + (file-relative-name (substitute-in-file-name cand))))) + (lambda (_inp cand) cand)) + ;; candidate function + (apply-partially #'run-hook-with-args-until-success + 'consult--completion-candidate-hook) + (let ((enable-recursive-minibuffers t)) + (if (eq category 'file) + ;; We use read-file-name, since many completion UIs make it nicer to + ;; navigate the file system this way; and we insert the initial text + ;; directly into the minibuffer to allow the user's completion + ;; styles to expand it as appropriate (particularly useful for the + ;; partial-completion and initials styles, which allow for very + ;; condensed path specification). + (consult--minibuffer-with-setup-hook + (lambda () (insert initial)) + (read-file-name prompt nil initial require-match nil predicate)) + (completing-read prompt + ;; Evaluate completion table in the original buffer. + ;; This is a reasonable thing to do and required + ;; by some completion tables in particular by lsp-mode. + ;; See https://github.com/minad/vertico/issues/61. + (if (functionp collection) + (lambda (&rest args) + (with-current-buffer buffer + (apply collection args))) + collection) + predicate require-match initial))))))))) + (if completion + (progn + (delete-region start end) + (insert (substring-no-properties completion)) + (when-let (exit (plist-get completion-extra-properties :exit-function)) + (funcall exit completion + ;; If completion is finished and cannot be further completed, + ;; return 'finished. Otherwise return 'exact. + (if (eq (try-completion completion collection predicate) t) + 'finished 'exact))) + t) + (message "No completion") + nil))))) + +;;;;; Function: consult-completing-read-multiple + +(defun consult--crm-selected () + "Return selected candidates from `consult-completing-read-multiple'." + (when (eq minibuffer-history-variable 'consult--crm-history) + (mapcar + (apply-partially #'get-text-property 0 'consult--crm-selected) + (all-completions + "" minibuffer-completion-table + (lambda (cand) + (and (stringp cand) + (get-text-property 0 'consult--crm-selected cand) + (or (not minibuffer-completion-predicate) + (funcall minibuffer-completion-predicate cand)))))))) + +;;;###autoload +(defun consult-completing-read-multiple (prompt table &optional + pred require-match initial-input + hist def inherit-input-method) + "Enhanced replacement for `completing-read-multiple'. +See `completing-read-multiple' for the documentation of the arguments." + (let* ((orig-items (all-completions "" table pred)) + (prefixed-orig-items + (funcall + (if-let (prefix (car consult-crm-prefix)) + (apply-partially #'mapcar (lambda (item) (propertize item 'line-prefix prefix))) + #'identity) + orig-items)) + (format-item + (lambda (item) + ;; Restore original candidate in order to preserve formatting + (setq item (or (car (member item orig-items)) item) + item (propertize item 'consult--crm-selected item + 'line-prefix (cdr consult-crm-prefix))) + (add-face-text-property 0 (length item) 'consult-crm-selected 'append item) + item)) + (separator (or (bound-and-true-p crm-separator) "[ \t]*,[ \t]*")) + (hist-sym (pcase hist + ('nil 'minibuffer-history) + ('t 'consult--crm-history) + (`(,sym . ,_) sym) ;; ignore history position + (_ hist))) + (hist-val (symbol-value hist-sym)) + (selected + (and initial-input + (or + ;; initial-input is multiple items + (string-match-p separator initial-input) + ;; initial-input is a single candidate + (member initial-input orig-items)) + (prog1 + (mapcar format-item + (split-string initial-input separator 'omit-nulls)) + (setq initial-input nil)))) + (consult--crm-history (append (mapcar #'substring-no-properties selected) hist-val)) + (items (append selected + (seq-remove (lambda (x) (member x selected)) + prefixed-orig-items))) + (orig-md (and (functionp table) (cdr (funcall table "" nil 'metadata)))) + (group-fun (alist-get 'group-function orig-md)) + (sort-fun + (lambda (sort) + (pcase (alist-get sort orig-md) + ('identity `((,sort . identity))) + ((and sort (guard sort)) + `((,sort . ,(lambda (cands) + (setq cands (funcall sort cands)) + (nconc + (seq-filter (lambda (x) (member x selected)) cands) + (seq-remove (lambda (x) (member x selected)) cands))))))))) + (md + `(metadata + (group-function + . ,(lambda (cand transform) + (if (get-text-property 0 'consult--crm-selected cand) + (if transform cand "Selected") + (or (and group-fun (funcall group-fun cand transform)) + (if transform cand "Select multiple"))))) + ,@(funcall sort-fun 'cycle-sort-function) + ,@(funcall sort-fun 'display-sort-function) + ,@(seq-filter (lambda (x) (memq (car x) '(annotation-function + affixation-function + category))) + orig-md))) + (overlay) + (command) + (depth (1+ (recursion-depth))) + (hook (make-symbol "consult--crm-pre-command-hook")) + (wrapper (make-symbol "consult--crm-command-wrapper"))) + (fset wrapper + (lambda () + (interactive) + (pcase (catch 'exit + (call-interactively (setq this-command command)) + 'consult--continue) + ('nil + (with-selected-window (active-minibuffer-window) + (let ((item (minibuffer-contents-no-properties))) + (when (equal item "") + (throw 'exit nil)) + (setq selected (if (member item selected) + ;; Multi selections are not possible. + ;; This is probably no problem, since this is rarely desired. + (delete item selected) + (nconc selected (list (funcall format-item item)))) + consult--crm-history (append (mapcar #'substring-no-properties selected) hist-val) + items (append selected + (seq-remove (lambda (x) (member x selected)) + prefixed-orig-items))) + (when overlay + (overlay-put overlay 'display + (when selected + (format " (%s selected): " (length selected))))) + (delete-minibuffer-contents) + (run-hook-with-args 'consult--completion-refresh-hook 'reset)))) + ('consult--continue nil) + (other (throw 'exit other))))) + (fset hook (lambda () + (when (and this-command (= depth (recursion-depth))) + (setq command this-command this-command wrapper)))) + (consult--minibuffer-with-setup-hook + (:append + (lambda () + (when-let (pos (string-match-p "\\(?: (default[^)]+)\\)?: \\'" prompt)) + (setq overlay (make-overlay (+ (point-min) pos) (+ (point-min) (length prompt)))) + (when selected + (overlay-put overlay 'display (format " (%s selected): " (length selected))))) + (use-local-map (make-composed-keymap (list consult-crm-map) (current-local-map))))) + (unwind-protect + (progn + (add-hook 'pre-command-hook hook 90) + (let ((result + (completing-read + prompt + (lambda (str pred action) + (if (eq action 'metadata) + md + (complete-with-action action items str pred))) + nil ;; predicate + require-match + initial-input + 'consult--crm-history + "" ;; default + inherit-input-method))) + (unless (or (equal result "") selected) + (setq selected (split-string result separator 'omit-nulls) + consult--crm-history (append (mapcar #'substring-no-properties selected) hist-val))))) + (remove-hook 'pre-command-hook hook))) + (when (consp def) + (setq def (car def))) + (if (and def (not (equal "" def)) (not selected)) + (split-string def separator 'omit-nulls) + (setq selected (mapcar #'substring-no-properties selected)) + (set hist-sym (append selected (symbol-value hist-sym))) + selected))) + +;;;; Commands + +;;;;; Command: consult-multi-occur + +;; see https://github.com/raxod502/selectrum/issues/226 +;;;###autoload +(defun consult-multi-occur (bufs regexp &optional nlines) + "Improved version of `multi-occur' based on `completing-read-multiple'. + +See `multi-occur' for the meaning of the arguments BUFS, REGEXP and NLINES." + (interactive (cons + (mapcar #'get-buffer + (completing-read-multiple "Buffer: " + #'internal-complete-buffer)) + (occur-read-primary-args))) + (occur-1 regexp nlines bufs)) + +;;;;; Command: consult-outline + +(defun consult--outline-candidates () + "Return alist of outline headings and positions." + (consult--forbid-minibuffer) + (let* ((line (line-number-at-pos (point-min) consult-line-numbers-widen)) + (heading-regexp (concat "^\\(?:" + ;; default definition from outline.el + (or (bound-and-true-p outline-regexp) "[*\^L]+") + "\\)")) + (heading-alist (bound-and-true-p outline-heading-alist)) + (level-fun (or (bound-and-true-p outline-level) + (lambda () ;; as in the default from outline.el + (or (cdr (assoc (match-string 0) heading-alist)) + (- (match-end 0) (match-beginning 0)))))) + (candidates)) + (save-excursion + (goto-char (point-min)) + (while (save-excursion (re-search-forward heading-regexp nil t)) + (setq line (+ line (consult--count-lines (match-beginning 0)))) + (push (consult--location-candidate + (consult--buffer-substring (line-beginning-position) + (line-end-position) + 'fontify) + (point-marker) line 'consult--outline-level (funcall level-fun)) + candidates) + (unless (eobp) (forward-char 1)))) + (unless candidates + (user-error "No headings")) + (nreverse candidates))) + +;;;###autoload +(defun consult-outline () + "Jump to an outline heading, obtained by matching against `outline-regexp'. + +This command supports narrowing to a heading level and candidate preview. +The symbol at point is added to the future history." + (interactive) + (let* ((cands (consult--with-increased-gc (consult--outline-candidates))) + (min-level (- (apply #'min (mapcar + (lambda (cand) + (get-text-property 0 'consult--outline-level cand)) + cands)) + ?1)) + (narrow-pred (lambda (cand) + (<= (get-text-property 0 'consult--outline-level cand) + (+ consult--narrow min-level)))) + (narrow-keys (mapcar (lambda (c) (cons c (format "Level %c" c))) + (number-sequence ?1 ?9)))) + (consult--read + cands + :prompt "Go to heading: " + :annotate (consult--line-prefix) + :category 'consult-location + :sort nil + :require-match t + :lookup #'consult--line-match + :narrow `(:predicate ,narrow-pred :keys ,narrow-keys) + :history '(:input consult--line-history) + :add-history (thing-at-point 'symbol) + :state (consult--jump-state)))) + +;;;;; Command: consult-mark + +(defun consult--mark-candidates (markers) + "Return list of candidates strings for MARKERS." + (consult--forbid-minibuffer) + (let ((candidates) + (current-buf (current-buffer))) + (save-excursion + (dolist (marker markers) + (when-let ((pos (marker-position marker)) + (buf (marker-buffer marker))) + (when (and (eq buf current-buf) + (consult--in-range-p pos)) + (goto-char pos) + ;; `line-number-at-pos' is a very slow function, which should be replaced everywhere. + ;; However in this case the slow line-number-at-pos does not hurt much, since + ;; the mark ring is usually small since it is limited by `mark-ring-max'. + (push (consult--location-candidate + (consult--line-with-cursor marker) marker + (line-number-at-pos pos consult-line-numbers-widen)) + candidates))))) + (unless candidates + (user-error "No marks")) + (nreverse (delete-dups candidates)))) + +;;;###autoload +(defun consult-mark (&optional markers) + "Jump to a marker in MARKERS list (defaults to buffer-local `mark-ring'). + +The command supports preview of the currently selected marker position. +The symbol at point is added to the future history." + (interactive) + (consult--read + (consult--with-increased-gc + (consult--mark-candidates + (or markers (cons (mark-marker) mark-ring)))) + :prompt "Go to mark: " + :annotate (consult--line-prefix) + :category 'consult-location + :sort nil + :require-match t + :lookup #'consult--lookup-location + :history '(:input consult--line-history) + :add-history (thing-at-point 'symbol) + :state (consult--jump-state))) + +;;;;; Command: consult-global-mark + +(defun consult--global-mark-candidates (markers) + "Return list of candidates strings for MARKERS." + (consult--forbid-minibuffer) + (let ((candidates)) + (save-excursion + (dolist (marker markers) + (when-let ((pos (marker-position marker)) + (buf (marker-buffer marker))) + (unless (minibufferp buf) + (with-current-buffer buf + (when (consult--in-range-p pos) + (goto-char pos) + ;; `line-number-at-pos' is slow, see comment in `consult--mark-candidates'. + (let ((line (line-number-at-pos pos consult-line-numbers-widen))) + (push (concat + (propertize (consult--format-location (buffer-name buf) line "") + 'consult-location (cons marker line) + 'consult-strip t) + (consult--line-with-cursor marker) + (consult--tofu-encode marker)) + candidates)))))))) + (unless candidates + (user-error "No global marks")) + (nreverse (delete-dups candidates)))) + +;;;###autoload +(defun consult-global-mark (&optional markers) + "Jump to a marker in MARKERS list (defaults to `global-mark-ring'). + +The command supports preview of the currently selected marker position. +The symbol at point is added to the future history." + (interactive) + (consult--read + (consult--with-increased-gc + (consult--global-mark-candidates + (or markers global-mark-ring))) + :prompt "Go to global mark: " + ;; Despite `consult-global-mark' formating the candidates in grep-like + ;; style, we are not using the 'consult-grep category, since the candidates + ;; have location markers attached. + :category 'consult-location + :sort nil + :require-match t + :lookup #'consult--lookup-location + :history '(:input consult--line-history) + :add-history (thing-at-point 'symbol) + :state (consult--jump-state))) + +;;;;; Command: consult-line + +(defun consult--line-candidates (top curr-line) + "Return list of line candidates. +Start from top if TOP non-nil. +CURR-LINE is the current line number." + (consult--forbid-minibuffer) + (consult--fontify-all) + (let* ((default-cand) + (candidates) + (line (line-number-at-pos (point-min) consult-line-numbers-widen))) + (consult--each-line beg end + (let ((str (consult--buffer-substring beg end))) + (unless (string-blank-p str) + (push (consult--location-candidate str (point-marker) line) candidates) + (when (and (not default-cand) (>= line curr-line)) + (setq default-cand candidates))) + (setq line (1+ line)))) + (when candidates + (nreverse + (if (or top (not default-cand)) + candidates + (let ((before (cdr default-cand))) + (setcdr default-cand nil) + (nconc before candidates))))))) + +(defun consult--line-match (input candidates cand) + "Lookup position of match. + +INPUT is the input string entered by the user. +CANDIDATES is the line candidates alist. +CAND is the currently selected candidate." + (when-let (pos (consult--lookup-location input candidates cand)) + (if (or (string-blank-p input) + (eq consult-line-point-placement 'line-beginning)) + pos + (let ((beg 0) + (end (length cand)) + (high (+ consult--tofu-char consult--tofu-range -1))) + ;; Ignore tofu-encoded unique line number suffix + (while (and (> end 0) (<= consult--tofu-char (aref cand (1- end)) high)) + (setq end (1- end))) + ;; Find match end position, remove characters from line end until + ;; matching fails + (let ((step 16)) + (while (> step 0) + (while (and (> (- end step) 0) + ;; Use consult-location completion category when + ;; filtering lines. Highlighting is not necessary here, + ;; but it is actually cheaper to highlight a single + ;; candidate, since setting up deferred highlighting is + ;; costly. + (consult--completion-filter input + (list (substring cand 0 (- end step))) + 'consult-location 'highlight)) + (setq end (- end step))) + (setq step (/ step 2)))) + ;; Find match beginning position, remove characters from line beginning + ;; until matching fails + (when (eq consult-line-point-placement 'match-beginning) + (let ((step 16)) + (while (> step 0) + (while (and (< (+ beg step) end) + ;; See comment above, call to `consult--completion-filter'. + (consult--completion-filter input + (list (substring cand (+ beg step) end)) + 'consult-location 'highlight)) + (setq beg (+ beg step))) + (setq step (/ step 2))) + (setq end beg))) + ;; Marker can be dead, therefore ignore errors. Create a new marker instead of an integer, + ;; since the location may be in another buffer, e.g., for `consult-line-all'. + (ignore-errors + (if (or (not (markerp pos)) (eq (marker-buffer pos) (current-buffer))) + (+ pos end) + ;; Only create a new marker when jumping across buffers, to avoid + ;; creating unnecessary markers, when scrolling through candidates. + ;; Creating markers is not free. + (move-marker + (make-marker) + (+ pos end) + (marker-buffer pos)))))))) + +(cl-defun consult--line (candidates &key curr-line prompt initial group) + "Select from from line CANDIDATES and jump to the match. +CURR-LINE is the current line. See `consult--read' for the arguments PROMPT, +INITIAL and GROUP." + (consult--read + candidates + :prompt prompt + :annotate (consult--line-prefix curr-line) + :group group + :category 'consult-location + :sort nil + :require-match t + ;; Always add last isearch string to future history + :add-history (list (thing-at-point 'symbol) isearch-string) + :history '(:input consult--line-history) + :lookup #'consult--line-match + :default (car candidates) + ;; Add isearch-string as initial input if starting from isearch + :initial (or initial + (and isearch-mode + (prog1 isearch-string (isearch-done)))) + :state (consult--jump-state))) + +;;;###autoload +(defun consult-line (&optional initial start) + "Search for a matching line. + +Depending on the setting `consult-line-point-placement' the command jumps to +the beginning or the end of the first match on the line or the line beginning. +The default candidate is the non-empty line next to point. This command obeys +narrowing. Optional INITIAL input can be provided. The search starting point is +changed if the START prefix argument is set. The symbol at point and the last +`isearch-string' is added to the future history." + (interactive (list nil (not (not current-prefix-arg)))) + (let ((curr-line (line-number-at-pos (point) consult-line-numbers-widen)) + (top (not (eq start consult-line-start-from-top)))) + (consult--line + (or (consult--with-increased-gc + (consult--line-candidates top curr-line)) + (user-error "No lines")) + :curr-line (and (not top) curr-line) + :prompt (if top "Go to line from top: " "Go to line: ") + :initial initial))) + +;;;;; Command: consult-line-multi + +(defun consult--line-multi-candidates (buffers) + "Collect the line candidates from multiple buffers. +BUFFERS is the list of buffers." + (or (apply #'nconc + (consult--buffer-map buffers + #'consult--line-candidates 'top most-positive-fixnum)) + (user-error "No lines"))) + +;;;###autoload +(defun consult-line-multi (query &optional initial) + "Search for a matching line in multiple buffers. + +By default search across all project buffers. If the prefix argument QUERY is +non-nil, all buffers are searched. Optional INITIAL input can be provided. See +`consult-line' for more information. In order to search a subset of buffers, +QUERY can be set to a plist according to `consult--buffer-query'." + (interactive "P") + (unless (keywordp (car-safe query)) + (setq query (list :sort 'alpha :directory (and (not query) 'project)))) + (let ((buffers (consult--buffer-query-prompt "Go to line" query))) + (consult--line + (consult--line-multi-candidates (cdr buffers)) + :prompt (car buffers) + :initial initial + :group #'consult--line-group))) + +;;;;; Command: consult-keep-lines + +(defun consult--keep-lines-state (filter) + "State function for `consult-keep-lines' with FILTER function." + (let* ((lines) + (buffer-orig (current-buffer)) + (font-lock-orig font-lock-mode) + (hl-line-orig (bound-and-true-p hl-line-mode)) + (point-orig (point)) + (content-orig) + (replace) + (last-input)) + (if (use-region-p) + (save-restriction + ;; Use the same behavior as `keep-lines'. + (let ((rbeg (region-beginning)) + (rend (save-excursion + (goto-char (region-end)) + (unless (or (bolp) (eobp)) + (forward-line 0)) + (point)))) + (consult--fontify-region rbeg rend) + (narrow-to-region rbeg rend) + (consult--each-line beg end + (push (consult--buffer-substring beg end) lines)) + (setq content-orig (buffer-string) + replace (lambda (content &optional pos) + (delete-region rbeg rend) + (insert content) + (goto-char (or pos rbeg)) + (setq rend (+ rbeg (length content))) + (add-face-text-property rbeg rend 'region t))))) + (consult--fontify-all) + (setq content-orig (buffer-string) + replace (lambda (content &optional pos) + (delete-region (point-min) (point-max)) + (insert content) + (goto-char (or pos (point-min))))) + (consult--each-line beg end + (push (consult--buffer-substring beg end) lines))) + (setq lines (nreverse lines)) + (lambda (input restore) + (with-current-buffer buffer-orig + ;; Restoring content and point position + (when (and restore last-input) + ;; No undo recording, modification hooks, buffer modified-status + (with-silent-modifications (funcall replace content-orig point-orig))) + ;; Committing or new input provided -> Update + (when (and input ;; Input has been povided + (or + ;; Committing, but not with empty input + (and restore (not (string-match-p "\\`!? ?\\'" input))) + ;; Input has changed + (not (equal input last-input)))) + (let ((filtered-content + (if (string-match-p "\\`!? ?\\'" input) + ;; Special case the empty input for performance. + ;; Otherwise it could happen that the minibuffer is empty, + ;; but the buffer has not been updated. + content-orig + (if restore + (apply #'concat (mapcan (lambda (x) (list x "\n")) + (funcall filter input lines))) + (while-no-input + ;; Heavy computation is interruptible if *not* committing! + ;; Allocate new string candidates since the matching function mutates! + (apply #'concat (mapcan (lambda (x) (list x "\n")) + (funcall filter input (mapcar #'copy-sequence lines))))))))) + (when (stringp filtered-content) + (when font-lock-mode (font-lock-mode -1)) + (when (bound-and-true-p hl-line-mode) (hl-line-mode -1)) + (if restore + (atomic-change-group + ;; Disable modification hooks for performance + (let ((inhibit-modification-hooks t)) + (funcall replace filtered-content))) + ;; No undo recording, modification hooks, buffer modified-status + (with-silent-modifications + (funcall replace filtered-content) + (setq last-input input)))))) + ;; Restore modes + (when restore + (when hl-line-orig (hl-line-mode 1)) + (when font-lock-orig (font-lock-mode 1))))))) + +;;;###autoload +(defun consult-keep-lines (&optional filter initial) + "Select a subset of the lines in the current buffer with live preview. + +The selected lines are kept and the other lines are deleted. When called +interactively, the lines selected are those that match the minibuffer input. In +order to match the inverse of the input, prefix the input with `! '. When +called from elisp, the filtering is performed by a FILTER function. This +command obeys narrowing. + +FILTER is the filter function. +INITIAL is the initial input." + (interactive + (list (lambda (pattern cands) + ;; Use consult-location completion category when filtering lines + (consult--completion-filter-dispatch + pattern cands 'consult-location 'highlight)))) + (consult--forbid-minibuffer) + (cl-letf ((ro buffer-read-only) + ((buffer-local-value 'buffer-read-only (current-buffer)) nil)) + (consult--minibuffer-with-setup-hook + (lambda () + (when ro + (minibuffer-message + (substitute-command-keys + " [Unlocked read-only buffer. \\[minibuffer-keyboard-quit] to quit.]")))) + (consult--with-increased-gc + (consult--prompt + :prompt "Keep lines: " + :initial initial + :history 'consult--keep-lines-history + :state (consult--keep-lines-state filter)))))) + +;;;;; Command: consult-focus-lines + +(defun consult--focus-lines-state (filter) + "State function for `consult-focus-lines' with FILTER function." + (let ((lines) (overlays) (last-input) (point-orig (point))) + (save-excursion + (save-restriction + (if (not (use-region-p)) + (consult--fontify-all) + (consult--fontify-region (region-beginning) (region-end)) + (narrow-to-region + (region-beginning) + ;; Behave the same as `keep-lines'. + ;; Move to the next line. + (save-excursion + (goto-char (region-end)) + (unless (or (bolp) (eobp)) + (forward-line 0)) + (point)))) + (consult--each-line beg end + (push (buffer-substring-no-properties beg end) lines) + (push (make-overlay beg (1+ end)) overlays)))) + (unless (use-region-p) + (goto-char (point-min))) + (lambda (input restore) + ;; New input provided -> Update + (when (and input (not (equal input last-input))) + (if (string-match-p "\\`!? ?\\'" input) + ;; Special case the empty input for performance. + (progn + (dolist (ov overlays) + (overlay-put ov 'invisible nil)) + (setq last-input input)) + (let* ((not (string-prefix-p "! " input)) + (stripped (string-remove-prefix "! " input)) + ;; Heavy computation is interruptible if *not* committing! + (ht (if restore + (consult--string-hash (funcall filter stripped lines)) + (while-no-input + (consult--string-hash (funcall filter stripped lines)))))) + (when (hash-table-p ht) + (let ((ov overlays) (li lines)) + (while ov + (overlay-put (car ov) 'invisible (eq not (gethash (car li) ht))) + (setq li (cdr li) ov (cdr ov)))) + (setq last-input input))))) + (when restore + (cond + ((not input) + (goto-char point-orig)) + ((equal input "") + (consult-focus-lines 'show)) + (t + ;; Sucessfully terminated -> Remember invisible overlays + (dolist (ov overlays) + (if (overlay-get ov 'invisible) + (push ov consult--focus-lines-overlays) + (delete-overlay ov))) + (setq overlays nil))) + ;; Destroy remaining overlays + (mapc #'delete-overlay overlays))))) + +;;;###autoload +(defun consult-focus-lines (&optional show filter initial) + "Hide or show lines using overlays. + +The selected lines are shown and the other lines hidden. When called +interactively, the lines selected are those that match the minibuffer input. In +order to match the inverse of the input, prefix the input with `! '. With +optional prefix argument SHOW reveal the hidden lines. Alternatively the +command can be restarted to reveal the lines. When called from elisp, the +filtering is performed by a FILTER function. This command obeys narrowing. + +FILTER is the filter function. +INITIAL is the initial input." + (interactive + (list current-prefix-arg + (lambda (pattern cands) + ;; Use consult-location completion category when filtering lines + (consult--completion-filter-dispatch + pattern cands 'consult-location nil)))) + (if show + (progn + (mapc #'delete-overlay consult--focus-lines-overlays) + (setq consult--focus-lines-overlays nil) + (message "All lines revealed")) + (consult--forbid-minibuffer) + (consult--with-increased-gc + (consult--prompt + :prompt + (if consult--focus-lines-overlays + "Focus on lines (RET to reveal): " + "Focus on lines: ") + :initial initial + :history 'consult--keep-lines-history + :state (consult--focus-lines-state filter))))) + +;;;;; Command: consult-goto-line + +(defun consult--goto-line-position (str msg) + "Transform input STR to line number. +Print an error message with MSG function." + (if-let (line (and str + (string-match-p "\\`[[:digit:]]+\\'" str) + (string-to-number str))) + (let ((pos (save-excursion + (save-restriction + (when consult-line-numbers-widen + (widen)) + (goto-char (point-min)) + (forward-line (1- line)) + (point))))) + (if (consult--in-range-p pos) + pos + (funcall msg "Line number out of range.") + nil)) + (when (and str (not (string= str ""))) + (funcall msg "Please enter a number.")) + nil)) + +;;;###autoload +(defun consult-goto-line (&optional arg) + "Read line number and jump to the line with preview. + +Jump directly if a line number is given as prefix ARG. The command respects +narrowing and the settings `consult-goto-line-numbers' and +`consult-line-numbers-widen'." + (interactive "P") + (if arg + (call-interactively #'goto-line) + (consult--forbid-minibuffer) + (consult--local-let ((display-line-numbers consult-goto-line-numbers) + (display-line-numbers-widen consult-line-numbers-widen)) + (while (if-let (pos (consult--goto-line-position + (consult--prompt + :prompt "Go to line: " + :state (let ((preview (consult--jump-preview))) + (lambda (str restore) + (funcall preview + (consult--goto-line-position str #'ignore) + restore)))) + #'minibuffer-message)) + (consult--jump pos) + t))))) + +;;;;; Command: consult-recent-file + +(defun consult--file-preview () + "Create preview function for files." + (let ((open (consult--temporary-files)) + (preview (consult--buffer-preview))) + (lambda (cand restore) + (if restore + (progn + (funcall preview nil t) + (funcall open)) + (funcall preview (and cand (funcall open cand)) nil))))) + +(defun consult--file-action (file) + "Open FILE via `consult--buffer-action'." + (consult--buffer-action (find-file-noselect file))) + +(consult--define-state file) + +;;;###autoload +(defun consult-recent-file () + "Find recent file using `completing-read'." + (interactive) + (find-file + (consult--read + (or (mapcar #'abbreviate-file-name + (if-let (filter (and consult-recent-file-filter + (consult--regexp-filter consult-recent-file-filter))) + (seq-remove (apply-partially #'string-match-p filter) recentf-list) + recentf-list)) + (user-error "No recent files, `recentf-mode' is %s" + (if recentf-mode "on" "off"))) + :prompt "Find recent file: " + :sort nil + :require-match t + :category 'file + :state (consult--file-preview) + :history 'file-name-history))) + +;;;;; Command: consult-file-externally + +;;;###autoload +(defun consult-file-externally (file) + "Open FILE externally using the default application of the system." + (interactive "fOpen externally: ") + (if (and (eq system-type 'windows-nt) + (fboundp 'w32-shell-execute)) + (w32-shell-execute "open" file) + (call-process (pcase system-type + ('darwin "open") + ('cygwin "cygstart") + (_ "xdg-open")) + nil 0 nil + (expand-file-name file)))) + +;;;;; Command: consult-mode-command + +(defun consult--mode-name (mode) + "Return name part of MODE." + (replace-regexp-in-string + "global-\\(.*\\)-mode" "\\1" + (replace-regexp-in-string + "\\(-global\\)?-mode\\'" "" + (if (eq mode 'c-mode) + "cc" + (symbol-name mode)) + 'fixedcase) + 'fixedcase)) + +(defun consult--mode-command-candidates (modes) + "Extract commands from MODES. + +The list of features is searched for files belonging to the modes. +From these files, the commands are extracted." + (let* ((buffer (current-buffer)) + (command-filter (consult--regexp-filter (seq-filter #'stringp consult-mode-command-filter))) + (feature-filter (seq-filter #'symbolp consult-mode-command-filter)) + (minor-hash (consult--string-hash minor-mode-list)) + (minor-local-modes (seq-filter (lambda (m) + (and (gethash m minor-hash) + (local-variable-if-set-p m))) + modes)) + (minor-global-modes (seq-filter (lambda (m) + (and (gethash m minor-hash) + (not (local-variable-if-set-p m)))) + modes)) + (major-modes (seq-remove (lambda (m) + (gethash m minor-hash)) + modes)) + (major-paths-hash (consult--string-hash (mapcar #'symbol-file major-modes))) + (minor-local-paths-hash (consult--string-hash (mapcar #'symbol-file minor-local-modes))) + (minor-global-paths-hash (consult--string-hash (mapcar #'symbol-file minor-global-modes))) + (major-name-regexp (regexp-opt (mapcar #'consult--mode-name major-modes))) + (minor-local-name-regexp (regexp-opt (mapcar #'consult--mode-name minor-local-modes))) + (minor-global-name-regexp (regexp-opt (mapcar #'consult--mode-name minor-global-modes))) + (commands)) + (dolist (feature load-history commands) + (when-let (name (alist-get 'provide feature)) + (let* ((path (car feature)) + (file (file-name-nondirectory path)) + (key (cond + ((memq name feature-filter) nil) + ((or (gethash path major-paths-hash) + (string-match-p major-name-regexp file)) + ?m) + ((or (gethash path minor-local-paths-hash) + (string-match-p minor-local-name-regexp file)) + ?l) + ((or (gethash path minor-global-paths-hash) + (string-match-p minor-global-name-regexp file)) + ?g)))) + (when key + (dolist (cmd (cdr feature)) + (let ((sym (cdr-safe cmd))) + (when (and (consp cmd) + (eq (car cmd) 'defun) + (commandp sym) + (not (get sym 'byte-obsolete-info)) + ;; Emacs 28 has a `read-extended-command-predicate' + (if (bound-and-true-p read-extended-command-predicate) + (funcall read-extended-command-predicate sym buffer) + t)) + (let ((name (symbol-name sym))) + (unless (string-match-p command-filter name) + (push (propertize name + 'consult--candidate sym + 'consult--type key) + commands)))))))))))) + +;;;###autoload +(defun consult-mode-command (&rest modes) + "Run a command from any of the given MODES. + +If no MODES are specified, use currently active major and minor modes." + (interactive) + (unless modes + (setq modes (cons major-mode + (seq-filter (lambda (m) + (and (boundp m) (symbol-value m))) + minor-mode-list)))) + (let ((narrow `((?m . ,(format "Major: %s" major-mode)) + (?l . "Local Minor") + (?g . "Global Minor")))) + (command-execute + (consult--read + (consult--mode-command-candidates modes) + :prompt "Mode command: " + :predicate + (lambda (cand) + (let ((key (get-text-property 0 'consult--type cand))) + (if consult--narrow + (= key consult--narrow) + (/= key ?g)))) + :lookup #'consult--lookup-candidate + :group (consult--type-group narrow) + :narrow narrow + :require-match t + :history 'consult--mode-command-history + :category 'command)))) + +;;;;; Command: consult-yank + +(defun consult--read-from-kill-ring () + "Open kill ring menu and return selected string." + ;; `current-kill' updates `kill-ring' with a possible interprogram-paste (#443) + (current-kill 0) + ;; Do not specify a :lookup function in order to preserve completion-styles + ;; highlighting of the current candidate. We have to perform a final lookup + ;; to obtain the original candidate which may be propertized with + ;; yank-specific properties, like 'yank-handler. + (consult--lookup-member + nil kill-ring + (consult--read + (consult--remove-dups + (or kill-ring (user-error "Kill ring is empty"))) + :prompt "Yank from kill-ring: " + :history t ;; disable history + :sort nil + :category 'kill-ring + :require-match t + :state + (consult--insertion-preview + (point) + ;; If previous command is yank, hide previously yanked string + (or (and (eq last-command 'yank) (mark t)) (point)))))) + +;; Adapted from the Emacs `yank-from-kill-ring' function. +;;;###autoload +(defun consult-yank-from-kill-ring (string &optional arg) + "Select STRING from the kill ring and insert it. +With prefix ARG, put point at beginning, and mark at end, like `yank' does. + +This command behaves like `yank-from-kill-ring' in Emacs 28, which also offers +a `completing-read' interface to the `kill-ring'. Additionally the Consult +version supports preview of the selected string." + (interactive (list (consult--read-from-kill-ring) current-prefix-arg)) + (when string + (setq yank-window-start (window-start)) + (push-mark) + (insert-for-yank string) + (setq this-command 'yank) + (when (consp arg) + ;; Swap point and mark like in `yank'. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) (point) (current-buffer))))))) + +(put 'consult-yank-replace 'delete-selection 'yank) +(put 'consult-yank-pop 'delete-selection 'yank) +(put 'consult-yank-from-kill-ring 'delete-selection 'yank) + +;;;###autoload +(defun consult-yank-pop (&optional arg) + "If there is a recent yank act like `yank-pop'. + +Otherwise select string from the kill ring and insert it. +See `yank-pop' for the meaning of ARG. + +This command behaves like `yank-pop' in Emacs 28, which also offers a +`completing-read' interface to the `kill-ring'. Additionally the Consult +version supports preview of the selected string." + (interactive "*p") + (if (eq last-command 'yank) + (yank-pop (or arg 1)) + (call-interactively #'consult-yank-from-kill-ring))) + +;; Adapted from the Emacs yank-pop function. +;;;###autoload +(defun consult-yank-replace (string) + "Select STRING from the kill ring. + +If there was no recent yank, insert the string. +Otherwise replace the just-yanked string with the selected string. + +There exists no equivalent of this command in Emacs 28." + (interactive (list (consult--read-from-kill-ring))) + (when string + (if (not (eq last-command 'yank)) + (consult-yank-from-kill-ring string) + (let ((inhibit-read-only t) + (pt (point)) + (mk (mark t))) + (setq this-command 'yank) + (funcall (or yank-undo-function 'delete-region) (min pt mk) (max pt mk)) + (setq yank-undo-function nil) + (set-marker (mark-marker) pt (current-buffer)) + (insert-for-yank string) + (set-window-start (selected-window) yank-window-start t) + (if (< pt mk) + (goto-char (prog1 (mark t) + (set-marker (mark-marker) (point) (current-buffer))))))))) + +;;;;; Command: consult-bookmark + +(defun consult--bookmark-preview () + "Create preview function for bookmarks." + (let ((preview (consult--jump-preview)) + (open (consult--temporary-files))) + (lambda (cand restore) + (if restore + (progn + (funcall open) + (funcall preview nil t)) + (funcall + preview + (when-let (bm (and cand (assoc cand bookmark-alist))) + (let ((handler (or (bookmark-get-handler bm) #'bookmark-default-handler))) + ;; Only preview bookmarks with the default handler. + (if-let* ((file (and (eq handler #'bookmark-default-handler) + (bookmark-get-filename bm))) + (pos (bookmark-get-position bm)) + (buf (funcall open file))) + (set-marker (make-marker) pos buf) + (message "No preview for %s" handler) + nil))) + nil))))) + +(defun consult--bookmark-action (bm) + "Open BM via `consult--buffer-action'." + (bookmark-jump bm consult--buffer-display)) + +(consult--define-state bookmark) + +(defun consult--bookmark-candidates () + "Return bookmark candidates." + (bookmark-maybe-load-default-file) + (let ((narrow (mapcar (pcase-lambda (`(,y ,_ ,x)) (cons x y)) + consult-bookmark-narrow))) + (mapcar (lambda (cand) + (propertize (car cand) + 'consult--type + (alist-get + (or (bookmark-get-handler cand) #'bookmark-default-handler) + narrow))) + bookmark-alist))) + +;;;###autoload +(defun consult-bookmark (name) + "If bookmark NAME exists, open it, otherwise create a new bookmark with NAME. + +The command supports preview of file bookmarks and narrowing. See the +variable `consult-bookmark-narrow' for the narrowing configuration." + (interactive + (list + (let ((narrow (mapcar (pcase-lambda (`(,x ,y ,_)) (cons x y)) + consult-bookmark-narrow))) + (consult--read + (consult--bookmark-candidates) + :prompt "Bookmark: " + :state (consult--bookmark-preview) + :category 'bookmark + :history 'bookmark-history + ;; Add default names to future history. + ;; Ignore errors such that `consult-bookmark' can be used in + ;; buffers which are not backed by a file. + :add-history (ignore-errors (bookmark-prop-get (bookmark-make-record) 'defaults)) + :group (consult--type-group narrow) + :narrow (consult--type-narrow narrow))))) + (bookmark-maybe-load-default-file) + (if (assoc name bookmark-alist) + (bookmark-jump name) + (bookmark-set name))) + +;;;;; Command: consult-apropos + +;;;###autoload +(defun consult-apropos () + "Select pattern and call `apropos'. + +The default value of the completion is the symbol at point. As a better +alternative, you can run `embark-export' from commands like `M-x' and +`describe-symbol'." + (interactive) + (let ((pattern + (consult--read + obarray + :prompt "Apropos: " + :predicate (lambda (x) (or (fboundp x) (boundp x) (facep x) (symbol-plist x))) + :history 'consult--apropos-history + :category 'symbol + :default (thing-at-point 'symbol)))) + (when (string= pattern "") + (user-error "No pattern given")) + (apropos pattern))) + +;;;;; Command: consult-complex-command + +;;;###autoload +(defun consult-complex-command () + "Select and evaluate command from the command history. + +This command can act as a drop-in replacement for `repeat-complex-command'." + (interactive) + (let* ((history (or (delete-dups (mapcar #'prin1-to-string command-history)) + (user-error "There are no previous complex commands"))) + (cmd (read (consult--read + history + :prompt "Command: " + :default (car history) + :sort nil + :history t ;; disable history + :category 'expression)))) + ;; Taken from `repeat-complex-command' + (add-to-history 'command-history cmd) + (apply #'funcall-interactively + (car cmd) + (mapcar (lambda (e) (eval e t)) (cdr cmd))))) + +;;;;; Command: consult-history + +(defun consult--current-history () + "Return the history relevant to the current buffer. + +If the minibuffer is active, returns the minibuffer history, +otherwise the history corresponding to the mode is returned. +There is a special case for `repeat-complex-command', +for which the command history is used." + (cond + ;; If pressing "C-x M-:", i.e., `repeat-complex-command', + ;; we are instead querying the `command-history' and get a full s-expression. + ;; Alternatively you might want to use `consult-complex-command', + ;; which can also be bound to "C-x M-:"! + ((eq last-command 'repeat-complex-command) + (mapcar #'prin1-to-string command-history)) + ;; In the minibuffer we use the current minibuffer history, + ;; which can be configured by setting `minibuffer-history-variable'. + ((minibufferp) + (if (eq minibuffer-history-variable t) + (user-error "Minibuffer history is disabled for `%s'" this-command) + (symbol-value minibuffer-history-variable))) ;; (minibuffer-history-value) is Emacs 27 only + ;; Otherwise we use a mode-specific history, see `consult-mode-histories'. + (t (when-let (history + (or (seq-find (lambda (ring) + (and (derived-mode-p (car ring)) + (boundp (cdr ring)))) + consult-mode-histories) + (user-error + "No history configured for `%s', see `consult-mode-histories'" + major-mode))) + (symbol-value (cdr history)))))) + +(declare-function ring-elements "ring") +;; This command has been adopted from https://github.com/oantolin/completing-history/. +;;;###autoload +(defun consult-history (&optional history) + "Insert string from HISTORY of current buffer. + +In order to select from a specific HISTORY, pass the history variable +as argument." + (interactive) + (let ((str (consult--local-let ((enable-recursive-minibuffers t)) + (consult--read + (let ((history (or history (consult--current-history)))) + (or (consult--remove-dups (if (ring-p history) + (ring-elements history) + history)) + (user-error "History is empty"))) + :prompt "History: " + :history t ;; disable history + :category ;; Report command category for M-x history + (and (minibufferp) + (eq minibuffer-history-variable 'extended-command-history) + 'command) + :state + (consult--insertion-preview (point) (point)) + :sort nil)))) + (when (minibufferp) + (delete-minibuffer-contents)) + (insert (substring-no-properties str)))) + +;;;;; Command: consult-isearch-history + +(defun consult-isearch-forward (&optional reverse) + "Continue isearch forward optionally in REVERSE." + (interactive) + (consult--require-minibuffer) + (setq isearch-new-forward (not reverse) isearch-new-nonincremental nil) + (funcall (or (command-remapping #'exit-minibuffer) #'exit-minibuffer))) + +(defun consult-isearch-backward (&optional reverse) + "Continue isearch backward optionally in REVERSE." + (interactive) + (consult-isearch-forward (not reverse))) + +;; Emacs 28: hide in M-X +(put #'consult-isearch-backward 'completion-predicate #'ignore) +(put #'consult-isearch-forward 'completion-predicate #'ignore) + +(defvar consult-isearch-history-map + (let ((map (make-sparse-keymap))) + (define-key map [remap isearch-forward] #'consult-isearch-forward) + (define-key map [remap isearch-backward] #'consult-isearch-backward) + map) + "Additional keymap used by `consult-isearch-history'.") + +(defun consult--isearch-history-candidates () + "Return isearch history candidates." + ;; NOTE: Do not throw an error on empty history, + ;; in order to allow starting a search. + ;; We do not :require-match here! + (let ((history (if (eq t search-default-mode) + (append regexp-search-ring search-ring) + (append search-ring regexp-search-ring)))) + (cons + (delete-dups + (mapcar + (lambda (cand) + ;; Emacs 27.1 uses settings on the search string, we can use that for narrowing. + (let* ((props (plist-member (text-properties-at 0 cand) + 'isearch-regexp-function)) + (type (pcase (cadr props) + ((and 'nil (guard (not props))) ?r) + ('nil ?l) + ('word-search-regexp ?w) + ('isearch-symbol-regexp ?s) + ('char-fold-to-regexp ?c) + (_ ?u)))) + ;; Disambiguate history items. The same string could + ;; occur with different search types. + (consult--tofu-append cand type))) + history)) + (if history + (+ 4 (apply #'max (mapcar #'length history))) + 0)))) + +(defconst consult--isearch-history-narrow + '((?c . "Char") + (?u . "Custom") + (?l . "Literal") + (?r . "Regexp") + (?s . "Symbol") + (?w . "Word"))) + +;;;###autoload +(defun consult-isearch-history () + "Read a search string with completion from the Isearch history. + +This replaces the current search string if Isearch is active, and +starts a new Isearch session otherwise." + (interactive) + (consult--forbid-minibuffer) + (let* ((isearch-message-function 'ignore) ;; Avoid flicker in echo area + (inhibit-redisplay t) ;; Avoid flicker in mode line + (candidates (consult--isearch-history-candidates)) + (align (propertize " " 'display `(space :align-to (+ left ,(cdr candidates)))))) + (unless isearch-mode (isearch-mode t)) + (with-isearch-suspended + (setq isearch-new-string + (consult--read + (car candidates) + :prompt "I-search: " + :category 'consult-isearch + :history t ;; disable history + :sort nil + :initial isearch-string + :keymap consult-isearch-history-map + :annotate + (lambda (cand) + (concat align (alist-get (consult--tofu-get cand) consult--isearch-history-narrow))) + :group + (lambda (cand transform) + (if transform + cand + (alist-get (consult--tofu-get cand) consult--isearch-history-narrow))) + :lookup + (lambda (_ candidates str) + (if-let (found (member str candidates)) (substring (car found) 0 -1) str)) + :state + (lambda (cand restore) + (unless restore + (setq isearch-string cand) + ;; Emacs 27.1 uses properties on the search string to store settings + (when (fboundp 'isearch-update-from-string-properties) + (isearch-update-from-string-properties cand)) + (isearch-update))) + :narrow + (list :predicate + (lambda (cand) (= (consult--tofu-get cand) consult--narrow)) + :keys consult--isearch-history-narrow)) + isearch-new-message + (mapconcat 'isearch-text-char-description isearch-new-string ""))) + ;; Setting `isearch-regexp' etc only works outside of `with-isearch-suspended'. + (unless (plist-member (text-properties-at 0 isearch-string) 'isearch-regexp-function) + (setq isearch-regexp t + isearch-regexp-function nil)))) + +(define-obsolete-function-alias + 'consult-isearch + 'consult-isearch-history + "0.12") + +;;;;; Command: consult-minor-mode-menu + +(defun consult--minor-mode-candidates () + "Return list of minor-mode candidate strings." + (mapcar + (pcase-lambda (`(,name . ,sym)) + (propertize + name + 'consult--candidate sym + 'consult--minor-mode-narrow + (logior + (lsh (if (local-variable-if-set-p sym) ?l ?g) 8) + (if (and (boundp sym) (symbol-value sym)) ?i ?o)) + 'consult--minor-mode-group + (concat + (if (local-variable-if-set-p sym) "Local " "Global ") + (if (and (boundp sym) (symbol-value sym)) "On" "Off")))) + (nconc + ;; according to describe-minor-mode-completion-table-for-symbol + ;; the minor-mode-list contains *all* minor modes + (mapcar (lambda (sym) (cons (symbol-name sym) sym)) minor-mode-list) + ;; take the lighters from minor-mode-alist + (delq nil + (mapcar (pcase-lambda (`(,sym ,lighter)) + (when (and lighter (not (equal "" lighter))) + (setq lighter (string-trim (format-mode-line lighter))) + (unless (string-blank-p lighter) + (cons lighter sym)))) + minor-mode-alist))))) + +(defconst consult--minor-mode-menu-narrow + '((?l . "Local") + (?g . "Global") + (?i . "On") + (?o . "Off"))) + +;;;###autoload +(defun consult-minor-mode-menu () + "Enable or disable minor mode. + +This is an alternative to `minor-mode-menu-from-indicator'." + (interactive) + (call-interactively + (consult--read + (consult--minor-mode-candidates) + :prompt "Minor mode: " + :require-match t + :category 'minor-mode + :group + (lambda (cand transform) + (if transform cand (get-text-property 0 'consult--minor-mode-group cand))) + :narrow + (list :predicate + (lambda (cand) + (let ((narrow (get-text-property 0 'consult--minor-mode-narrow cand))) + (or (= (logand narrow 255) consult--narrow) + (= (lsh narrow -8) consult--narrow)))) + :keys + consult--minor-mode-menu-narrow) + :lookup #'consult--lookup-candidate + :history 'consult--minor-mode-menu-history))) + +;;;;; Command: consult-theme + +;;;###autoload +(defun consult-theme (theme) + "Disable current themes and enable THEME from `consult-themes'. + +The command supports previewing the currently selected theme." + (interactive + (list + (let ((avail-themes (seq-filter (lambda (x) (or (not consult-themes) + (memq x consult-themes))) + (cons nil (custom-available-themes)))) + (saved-theme (car custom-enabled-themes))) + (consult--read + (mapcar (lambda (x) (if x (symbol-name x) "default")) avail-themes) + :prompt "Theme: " + :require-match t + :category 'theme + :history 'consult--theme-history + :lookup (lambda (_input _cands x) + (unless (equal x "default") + (or (when-let (cand (and x (intern-soft x))) + (car (memq cand avail-themes))) + saved-theme))) + :state (lambda (cand restore) + (consult-theme (if (and restore (not cand)) + saved-theme + cand))) + :default (symbol-name (or saved-theme 'default)))))) + (unless (eq theme (car custom-enabled-themes)) + (mapc #'disable-theme custom-enabled-themes) + (when theme + (if (custom-theme-p theme) + (enable-theme theme) + (load-theme theme :no-confirm))))) + +;;;;; Command: consult-buffer + +(defun consult--buffer-sort-alpha (buffers) + "Sort BUFFERS alphabetically, but push down starred buffers." + (sort buffers + (lambda (x y) + (setq x (buffer-name x) y (buffer-name y)) + (let ((a (and (> (length x) 0) (eq (aref x 0) ?*))) + (b (and (> (length y) 0) (eq (aref y 0) ?*)))) + (if (eq a b) + (string< x y) + (not a)))))) + +(defun consult--buffer-sort-visibility (buffers) + "Sort BUFFERS by visibility." + (let ((hidden) + (current (current-buffer))) + (consult--keep! buffers + (unless (eq it current) + (if (get-buffer-window it 'visible) + it + (push it hidden) + nil))) + (nconc (nreverse hidden) buffers (list (current-buffer))))) + +(defun consult--normalize-directory (dir) + "Normalize directory DIR. +DIR can be project, nil or a path." + (cond + ((eq dir 'project) (consult--project-root)) + (dir (expand-file-name dir)))) + +(defun consult--buffer-query-prompt (prompt query) + "Buffer query function returning a scope description. +PROMPT is the prompt format string. +QUERY is passed to `consult--buffer-query'." + (let* ((dir (plist-get query :directory)) + (ndir (consult--normalize-directory dir)) + (buffers (apply #'consult--buffer-query :directory ndir query)) + (count (length buffers))) + (cons (format "%s (%d buffer%s%s): " prompt count + (if (= count 1) "" "s") + (cond + ((and ndir (eq dir 'project)) + (format ", Project %s" (consult--project-name ndir))) + (ndir (concat ", " (consult--abbreviate-directory ndir))) + (t ""))) + buffers))) + +(cl-defun consult--buffer-query (&key sort directory mode as predicate (filter t) + include (exclude consult-buffer-filter)) + "Buffer query function. +DIRECTORY can either be project or a path. +SORT can be visibility, alpha or nil. +FILTER can be either t, nil or invert. +EXCLUDE is a list of regexps. +INCLUDE is a list of regexps. +MODE can be a mode or a list of modes to restrict the returned buffers. +PREDICATE is a predicate function. +AS is a conversion function." + ;; This function is the backbone of most `consult-buffer' source. The + ;; function supports filtering by various criteria which are used throughout + ;; Consult. + (when-let (root (or (consult--normalize-directory directory) t)) + (let ((buffers (buffer-list))) + (when sort + (setq buffers (funcall (intern (format "consult--buffer-sort-%s" sort)) buffers))) + (when (or filter mode as (stringp root)) + (let ((mode (consult--ensure-list mode)) + (exclude-re (consult--regexp-filter exclude)) + (include-re (consult--regexp-filter include))) + (consult--keep! buffers + (and + (or (not mode) + (apply #'provided-mode-derived-p + (buffer-local-value 'major-mode it) mode)) + (pcase-exhaustive filter + ('nil t) + ((or 't 'invert) + (eq (eq filter t) + (and + (or (not exclude) + (not (string-match-p exclude-re (buffer-name it)))) + (or (not include) + (not (not (string-match-p include-re (buffer-name it))))))))) + (or (not (stringp root)) + (when-let (dir (buffer-local-value 'default-directory it)) + (string-prefix-p root + (if (and (/= 0 (length dir)) (eq (aref dir 0) ?/)) + dir + (expand-file-name dir))))) + (or (not predicate) (funcall predicate it)) + (if as (funcall as it) it))))) + buffers))) + +(defun consult--buffer-map (buffer &rest app) + "Run function application APP for each BUFFER. +Report progress and return a list of the results" + (consult--with-increased-gc + (let* ((count (length buffer)) + (reporter (make-progress-reporter "Collecting" 0 count))) + (prog1 + (seq-map-indexed (lambda (buf idx) + (with-current-buffer buf + (prog1 (apply app) + (progress-reporter-update + reporter (1+ idx) (buffer-name))))) + buffer) + (progress-reporter-done reporter))))) + +(defun consult--buffer-file-hash () + "Return hash table of all buffer file names." + (consult--string-hash (consult--buffer-query :as #'buffer-file-name))) + +(defun consult--buffer-preview () + "Buffer preview function." + (let ((orig-buf (current-buffer))) + (lambda (cand restore) + (when (and (not restore) + ;; Only preview in current window and other window. + ;; Preview in frames and tabs is not possible since these don't get cleaned up. + (or (eq consult--buffer-display #'switch-to-buffer) + (eq consult--buffer-display #'switch-to-buffer-other-window))) + (cond + ((and cand (get-buffer cand)) (consult--buffer-action cand 'norecord)) + ((buffer-live-p orig-buf) (consult--buffer-action orig-buf 'norecord))))))) + +(defun consult--buffer-action (buffer &optional norecord) + "Switch to BUFFER via `consult--buffer-display' function. +If NORECORD is non-nil, do not record the buffer switch in the buffer list." + (funcall consult--buffer-display buffer norecord)) + +(consult--define-state buffer) + +(defvar consult--source-bookmark + `(:name "Bookmark" + :narrow ?m + :category bookmark + :face consult-bookmark + :history bookmark-history + :items ,#'bookmark-all-names + :state ,#'consult--bookmark-state) + "Bookmark candidate source for `consult-buffer'.") + +(defvar consult--source-project-buffer + `(:name "Project Buffer" + :narrow (?p . "Project") + :hidden t + :category buffer + :face consult-buffer + :history buffer-name-history + :state ,#'consult--buffer-state + :enabled ,(lambda () consult-project-root-function) + :items + ,(lambda () + (consult--buffer-query :sort 'visibility + :directory 'project + :as #'buffer-name))) + "Project buffer candidate source for `consult-buffer'.") + +(define-obsolete-variable-alias + 'consult--source-project-file + 'consult--source-project-recent-file "0.14") +(defvar consult--source-project-recent-file + `(:name "Project File" + :narrow (?p . "Project") + :hidden t + :category file + :face consult-file + :history file-name-history + :state ,#'consult--file-state + :enabled ,(lambda () (and consult-project-root-function + recentf-mode)) + :items + ,(lambda () + (when-let (root (consult--project-root)) + (let ((len (length root)) + (inv-root (propertize root 'invisible t)) + (ht (consult--buffer-file-hash)) + (filter (consult--regexp-filter consult-recent-file-filter))) + (mapcar (lambda (x) + (concat inv-root (substring x len))) + (seq-filter (lambda (x) + (and (not (gethash x ht)) + (string-prefix-p root x) + (not (and consult-recent-file-filter + (string-match-p filter x))))) + recentf-list)))))) + "Project file candidate source for `consult-buffer'.") + +(defvar consult--source-hidden-buffer + `(:name "Hidden Buffer" + :narrow 32 + :hidden t + :category buffer + :face consult-buffer + :history buffer-name-history + :action ,#'consult--buffer-action + :items + ,(lambda () (consult--buffer-query :sort 'visibility + :filter 'invert + :as #'buffer-name))) + "Hidden buffer candidate source for `consult-buffer'.") + +(defvar consult--source-buffer + `(:name "Buffer" + :narrow ?b + :category buffer + :face consult-buffer + :history buffer-name-history + :state ,#'consult--buffer-state + :default t + :items + ,(lambda () (consult--buffer-query :sort 'visibility + :as #'buffer-name))) + "Buffer candidate source for `consult-buffer'.") + +(define-obsolete-variable-alias + 'consult--source-file + 'consult--source-recent-file "0.14") +(defvar consult--source-recent-file + `(:name "File" + :narrow ?f + :category file + :face consult-file + :history file-name-history + :state ,#'consult--file-state + :enabled ,(lambda () recentf-mode) + :items + ,(lambda () + (let ((ht (consult--buffer-file-hash)) + (filter (consult--regexp-filter consult-recent-file-filter))) + (mapcar #'abbreviate-file-name + (seq-remove (lambda (x) + (or (gethash x ht) + (and consult-recent-file-filter (string-match-p filter x)))) + recentf-list))))) + "Recent file candidate source for `consult-buffer'.") + +;;;###autoload +(defun consult-buffer () + "Enhanced `switch-to-buffer' command with support for virtual buffers. + +The command supports recent files, bookmarks, views and project files as virtual +buffers. Buffers are previewed. Furthermore narrowing to buffers (b), files (f), +bookmarks (m) and project files (p) is supported via the corresponding keys. In +order to determine the project-specific files and buffers, the +`consult-project-root-function' is used. See `consult-buffer-sources' and +`consult--multi' for the configuration of the virtual buffer sources." + (interactive) + (when-let (buffer (consult--multi consult-buffer-sources + :require-match + (confirm-nonexistent-file-or-buffer) + :prompt "Switch to: " + :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) + (consult--buffer-action (car buffer))))) + +;;;###autoload +(defun consult-buffer-other-window () + "Variant of `consult-buffer' which opens in other window." + (interactive) + (let ((consult--buffer-display #'switch-to-buffer-other-window)) + (consult-buffer))) + +;;;###autoload +(defun consult-buffer-other-frame () + "Variant of `consult-buffer' which opens in other frame." + (interactive) + (let ((consult--buffer-display #'switch-to-buffer-other-frame)) + (consult-buffer))) + +;;;;; Command: consult-kmacro + +(defun consult--kmacro-candidates () + "Return alist of kmacros and indices." + (thread-last + ;; List of macros + (append (when last-kbd-macro + `((,last-kbd-macro ,kmacro-counter ,kmacro-counter-format))) + kmacro-ring) + ;; Add indices + (seq-map-indexed #'cons) + ;; Filter mouse clicks + (seq-remove (lambda (x) (seq-some #'mouse-event-p (caar x)))) + ;; Format macros + (mapcar (pcase-lambda (`((,keys ,counter ,format) . ,index)) + (propertize + (format-kbd-macro keys 1) + 'consult--candidate index + 'consult--kmacro-annotation + ;; If the counter is 0 and the counter format is its default, + ;; then there is a good chance that the counter isn't actually + ;; being used. This can only be wrong when a user + ;; intentionally starts the counter with a negative value and + ;; then increments it to 0. + (cond + ((not (string= format "%d")) ;; show counter for non-default format + (format " (counter=%d, format=%s) " counter format)) + ((/= counter 0) ;; show counter if non-zero + (format " (counter=%d)" counter)))))) + (delete-dups))) + +;;;###autoload +(defun consult-kmacro (arg) + "Run a chosen keyboard macro. + +With prefix ARG, run the macro that many times. +Macros containing mouse clicks are omitted." + (interactive "p") + (let ((selected (consult--read + (or (consult--kmacro-candidates) + (user-error "No keyboard macros defined")) + :prompt "Keyboard macro: " + :category 'consult-kmacro + :require-match t + :sort nil + :history 'consult--kmacro-history + :annotate + (lambda (cand) + (get-text-property 0 'consult--kmacro-annotation cand)) + :lookup #'consult--lookup-candidate))) + (if (= 0 selected) + ;; If the first element has been selected, just run the last macro. + (kmacro-call-macro (or arg 1) t nil) + ;; Otherwise, run a kmacro from the ring. + (let* ((selected (1- selected)) + (kmacro (nth selected kmacro-ring)) + ;; Temporarily change the variables to retrieve the correct + ;; settings. Mainly, we want the macro counter to persist, which + ;; automatically happens when cycling the ring. + (last-kbd-macro (car kmacro)) + (kmacro-counter (cadr kmacro)) + (kmacro-counter-format (caddr kmacro))) + (kmacro-call-macro (or arg 1) t) + ;; Once done, put updated variables back into the ring. + (setf (nth selected kmacro-ring) + (list last-kbd-macro + kmacro-counter + kmacro-counter-format)))))) + +;;;;; Command: consult-grep + +(defun consult--grep-format (async builder) + "Return ASYNC function highlighting grep match results. +BUILDER is the command argument builder." + (let ((highlight)) + (lambda (action) + (cond + ((stringp action) + (setq highlight (plist-get (funcall builder action) :highlight)) + (funcall async action)) + ((consp action) + (let (result) + (save-match-data + (dolist (str action) + (when (and (string-match consult--grep-match-regexp str) + ;; Filter out empty context lines + (or (/= (aref str (match-beginning 3)) ?-) + (/= (match-end 0) (length str)))) + (let* ((file (match-string 1 str)) + (line (match-string 2 str)) + (ctx (= (aref str (match-beginning 3)) ?-)) + (sep (if ctx "-" ":")) + (content (substring str (match-end 0))) + (file-len (length file)) + (line-len (length line))) + (when (> (length content) consult-grep-max-columns) + (setq content (substring content 0 consult-grep-max-columns))) + (when highlight + (funcall highlight content)) + (setq str (concat file sep line sep content)) + ;; Store file name in order to avoid allocations in `consult--grep-group' + (add-text-properties 0 file-len `(face consult-file consult--grep-file ,file) str) + (put-text-property (1+ file-len) (+ 1 file-len line-len) 'face 'consult-line-number str) + (when ctx + (add-face-text-property (+ 2 file-len line-len) (length str) 'consult-grep-context 'append str)) + (push str result))))) + (funcall async (nreverse result)))) + (t (funcall async action)))))) + +(defun consult--grep-position (cand &optional find-file) + "Return the grep position marker for CAND. +FIND-FILE is the file open function, defaulting to `find-file'." + (when cand + (let* ((file-end (next-single-property-change 0 'face cand)) + (line-end (next-single-property-change (+ 1 file-end) 'face cand)) + (col (next-single-property-change (+ 1 line-end) 'face cand)) + (file (substring-no-properties cand 0 file-end)) + (line (string-to-number (substring-no-properties cand (+ 1 file-end) line-end)))) + (setq col (if col (- col line-end 1) 0)) + (consult--position-marker + (funcall (or find-file #'find-file) file) + line col)))) + +(defun consult--grep-state () + "Grep preview state function." + (let ((open (consult--temporary-files)) + (jump (consult--jump-state))) + (lambda (cand restore) + (when restore + (funcall open)) + (funcall jump + (consult--grep-position cand (and (not restore) open)) + restore)))) + +(defun consult--grep-group (cand transform) + "Return title for CAND or TRANSFORM the candidate." + (if transform + (substring cand (1+ (length (get-text-property 0 'consult--grep-file cand)))) + (get-text-property 0 'consult--grep-file cand))) + +(defun consult--grep (prompt builder dir initial) + "Run grep in DIR. + +BUILDER is the command builder. +PROMPT is the prompt string. +INITIAL is inital input." + (let* ((prompt-dir (consult--directory-prompt prompt dir)) + (default-directory (cdr prompt-dir)) + (read-process-output-max (max read-process-output-max (* 1024 1024)))) + (consult--read + (consult--async-command builder + (consult--grep-format builder) + :file-handler t) ;; allow tramp + :prompt (car prompt-dir) + :lookup #'consult--lookup-member + :state (consult--grep-state) + :initial (consult--async-split-initial initial) + :add-history (consult--async-split-thingatpt 'symbol) + :require-match t + :category 'consult-grep + :group #'consult--grep-group + :history '(:input consult--grep-history) + :sort nil))) + +(defun consult--grep-lookahead-p (&rest cmd) + "Return t if grep CMD supports lookahead." + (with-temp-buffer + (insert "xaxbx") + (eq 0 (apply #'call-process-region (point-min) (point-max) + (car cmd) nil nil nil `(,@(cdr cmd) "^(?=.*b)(?=.*a)"))))) + +(defvar consult--grep-regexp-type nil) +(defun consult--grep-regexp-type (cmd) + "Return regexp type supported by grep CMD." + (or consult--grep-regexp-type + (setq consult--grep-regexp-type + (if (consult--grep-lookahead-p cmd "-P") 'pcre 'extended)))) + +(defun consult--grep-builder (input) + "Build command line given INPUT." + (pcase-let* ((cmd (split-string-and-unquote consult-grep-args)) + (type (consult--grep-regexp-type (car cmd))) + (`(,arg . ,opts) (consult--command-split input)) + (`(,re . ,hl) (funcall consult--regexp-compiler arg type))) + (when re + (list :command + (append cmd + (list (if (eq type 'pcre) "--perl-regexp" "--extended-regexp") + "-e" (consult--join-regexps re type)) + opts) + :highlight hl)))) + +;;;###autoload +(defun consult-grep (&optional dir initial) + "Search for regexp with grep in DIR with INITIAL input. + +The input string is split, the first part of the string (grep input) is +passed to the asynchronous grep process and the second part of the string is +passed to the completion-style filtering. + +The input string is split at a punctuation character, which is given as the +first character of the input string. The format is similar to Perl-style +regular expressions, e.g., /regexp/. Furthermore command line options can be +passed to grep, specified behind --. The overall prompt input has the form +`#async-input -- grep-opts#filter-string'. + +Note that the grep input string is transformed from Emacs regular expressions +to Posix regular expressions. Always enter Emacs regular expressions at the +prompt. `consult-grep' behaves like builtin Emacs search commands, e.g., +Isearch, which take Emacs regular expressions. Furthermore the asynchronous +input split into words, each word must match separately and in any order. See +`consult--regexp-compiler' for the inner workings. In order to disable +transformations of the grep input, adjust `consult--regexp-compiler' +accordingly. + +Here we give a few example inputs: + +#alpha beta : Search for alpha and beta in any order. +#alpha.*beta : Search for alpha before beta. +#\\(alpha\\|beta\\) : Search for alpha or beta (Note Emacs syntax!) +#word -- -C3 : Search for word, include 3 lines as context +#first#second : Search for first, quick filter for second. + +The symbol at point is added to the future history. If `consult-grep' +is called interactively with a prefix argument, the user can specify +the directory to search in. By default the project directory is used +if `consult-project-root-function' is defined and returns non-nil. +Otherwise the `default-directory' is searched." + (interactive "P") + (consult--grep "Grep" #'consult--grep-builder dir initial)) + +;;;;; Command: consult-git-grep + +(defun consult--git-grep-builder (input) + "Build command line given CONFIG and INPUT." + (pcase-let* ((`(,arg . ,opts) (consult--command-split input)) + (`(,re . ,hl) (funcall consult--regexp-compiler arg 'extended))) + (when re + (list :command + (append (split-string-and-unquote consult-git-grep-args) + (cdr (mapcan (lambda (x) (list "--and" "-e" x)) re)) + opts) + :highlight hl)))) + +;;;###autoload +(defun consult-git-grep (&optional dir initial) + "Search for regexp with grep in DIR with INITIAL input. + +See `consult-grep' for more details." + (interactive "P") + (consult--grep "Git-grep" #'consult--git-grep-builder dir initial)) + +;;;;; Command: consult-ripgrep + +(defvar consult--ripgrep-regexp-type nil) +(defun consult--ripgrep-regexp-type (cmd) + "Return regexp type supported by ripgrep CMD." + (or consult--ripgrep-regexp-type + (setq consult--ripgrep-regexp-type + (if (consult--grep-lookahead-p cmd "-P") 'pcre 'extended)))) + +(defun consult--ripgrep-builder (input) + "Build command line given INPUT." + (pcase-let* ((cmd (split-string-and-unquote consult-ripgrep-args)) + (type (consult--ripgrep-regexp-type (car cmd))) + (`(,arg . ,opts) (consult--command-split input)) + (`(,re . ,hl) (funcall consult--regexp-compiler arg type))) + (when re + (list :command + (append cmd + (and (eq type 'pcre) '("-P")) + (list "-e" (consult--join-regexps re type)) + opts) + :highlight hl)))) + +;;;###autoload +(defun consult-ripgrep (&optional dir initial) + "Search for regexp with rg in DIR with INITIAL input. + +See `consult-grep' for more details." + (interactive "P") + (consult--grep "Ripgrep" #'consult--ripgrep-builder dir initial)) + +;;;;; Command: consult-find + +(defun consult--find (prompt builder initial) + "Run find in current directory. + +The function returns the selected file. +The filename at point is added to the future history. + +BUILDER is the command builder. +PROMPT is the prompt. +INITIAL is inital input." + (consult--read + (consult--async-command builder + (consult--async-map (lambda (x) (string-remove-prefix "./" x))) + (consult--async-highlight builder) + :file-handler t) ;; allow tramp + :prompt prompt + :sort nil + :require-match t + :initial (consult--async-split-initial initial) + :add-history (consult--async-split-thingatpt 'filename) + :category 'file + :history '(:input consult--find-history))) + +(defvar consult--find-regexp-type nil) +(defun consult--find-regexp-type (cmd) + "Return regexp type supported by find CMD." + (or consult--find-regexp-type + (setq consult--find-regexp-type + (if (eq 0 (call-process-shell-command + (concat cmd " -regextype emacs -version"))) + 'emacs 'basic)))) + +(defun consult--find-builder (input) + "Build command line given INPUT." + (pcase-let* ((cmd (split-string-and-unquote consult-find-args)) + (type (consult--find-regexp-type (car cmd))) + (`(,arg . ,opts) (consult--command-split input)) + (`(,re . ,hl) (funcall consult--regexp-compiler arg type))) + (when re + (list :command + (append cmd + (cdr (mapcan + (lambda (x) + `("-and" "-iregex" + ,(format ".*%s.*" + ;; HACK Replace non-capturing groups with capturing groups. + ;; GNU find does not support non-capturing groups. + (replace-regexp-in-string + "\\\\(\\?:" "\\(" x 'fixedcase 'literal)))) + re)) + opts) + :highlight hl)))) + +;;;###autoload +(defun consult-find (&optional dir initial) + "Search for regexp with find in DIR with INITIAL input. + +The find process is started asynchronously, similar to `consult-grep'. +See `consult-grep' for more details regarding the asynchronous search." + (interactive "P") + (let* ((prompt-dir (consult--directory-prompt "Find" dir)) + (default-directory (cdr prompt-dir))) + (find-file (consult--find (car prompt-dir) #'consult--find-builder initial)))) + +;;;;; Command: consult-locate + +(defun consult--locate-builder (input) + "Build command line given INPUT." + (pcase-let* ((`(,arg . ,opts) (consult--command-split input)) + (`(,re . ,hl) (funcall consult--regexp-compiler arg 'basic))) + (when re + (list :command + (append (split-string-and-unquote consult-locate-args) + (list (consult--join-regexps re 'basic)) + opts) + :highlight hl)))) + +;;;###autoload +(defun consult-locate (&optional initial) + "Search for regexp with locate with INITIAL input. + +The locate process is started asynchronously, similar to `consult-grep'. +See `consult-grep' for more details regarding the asynchronous search." + (interactive) + (find-file (consult--find "Locate: " #'consult--locate-builder initial))) + +;;;;; Command: consult-man + +(defun consult--man-builder (input) + "Build command line given CONFIG and INPUT." + (pcase-let ((`(,arg . ,opts) (consult--command-split input))) + (unless (string-blank-p arg) + (list :command (append (split-string-and-unquote consult-man-args) + (list arg) opts) + :highlight (cdr (consult--default-regexp-compiler input 'basic)))))) + +(defun consult--man-format (lines) + "Format man candidates from LINES." + (let ((candidates)) + (save-match-data + (dolist (str lines) + (when (string-match "\\`\\(.*?\\([^ ]+\\) *(\\([^,)]+\\)[^)]*).*?\\) +- +\\(.*\\)\\'" str) + (let ((names (match-string 1 str)) + (name (match-string 2 str)) + (section (match-string 3 str)) + (desc (match-string 4 str))) + (add-face-text-property 0 (length names) 'consult-file nil names) + (push (cons + (format "%s - %s" names desc) + (concat section " " name)) + candidates))))) + (nreverse candidates))) + +;;;###autoload +(defun consult-man (&optional initial) + "Search for regexp with man with INITIAL input. + +The man process is started asynchronously, similar to `consult-grep'. +See `consult-grep' for more details regarding the asynchronous search." + (interactive) + (man (consult--read + (consult--async-command #'consult--man-builder + (consult--async-transform consult--man-format) + (consult--async-highlight #'consult--man-builder)) + :prompt "Manual entry: " + :require-match t + :lookup #'consult--lookup-cdr + :initial (consult--async-split-initial initial) + :add-history (consult--async-split-thingatpt 'symbol) + :history '(:input consult--man-history)))) + +;;;; Preview at point in completions buffers + +(define-minor-mode consult-preview-at-point-mode + "Preview minor mode for *Completions* buffers. +When moving around in the *Completions* buffer, the candidate at point is +automatically previewed." + :init-value nil :group 'consult + (if consult-preview-at-point-mode + (add-hook 'post-command-hook #'consult-preview-at-point nil 'local) + (remove-hook 'post-command-hook #'consult-preview-at-point 'local))) + +(defun consult-preview-at-point () + "Preview candidate at point in *Completions* buffer." + (interactive) + (when-let* ((win (active-minibuffer-window)) + (buf (window-buffer win)) + (fun (buffer-local-value 'consult--preview-function buf))) + (funcall fun))) + +;;;; Integration with the default completion system + +(defun consult--default-completion-mb-candidate () + "Return current minibuffer candidate from default completion system or Icomplete." + (when (and (minibufferp) + (eq completing-read-function #'completing-read-default)) + (let ((content (minibuffer-contents-no-properties))) + ;; When the current minibuffer content matches a candidate, return it! + (if (test-completion content + minibuffer-completion-table + minibuffer-completion-predicate) + content + ;; Return the full first candidate of the sorted completion list. + (when-let ((completions (completion-all-sorted-completions))) + (concat + (substring content 0 (or (cdr (last completions)) 0)) + (car completions))))))) + +(defun consult--default-completion-list-candidate () + "Return current candidate at point from completions buffer." + (let (beg end) + (when (and + (derived-mode-p 'completion-list-mode) + ;; Logic taken from `choose-completion'. + ;; TODO Upstream a `completion-list-get-candidate' function. + (cond + ((and (not (eobp)) (get-text-property (point) 'mouse-face)) + (setq end (point) beg (1+ (point)))) + ((and (not (bobp)) (get-text-property (1- (point)) 'mouse-face)) + (setq end (1- (point)) beg (point))))) + (setq beg (previous-single-property-change beg 'mouse-face) + end (or (next-single-property-change end 'mouse-face) (point-max))) + (buffer-substring-no-properties beg end)))) + +;; Announce now that consult has been loaded +(provide 'consult) + +;;;; Integration with other completion systems + +(with-eval-after-load 'icomplete (require 'consult-icomplete)) +(with-eval-after-load 'selectrum (require 'consult-selectrum)) +(with-eval-after-load 'vertico (require 'consult-vertico)) + +;;; consult.el ends here diff --git a/elpa/consult-0.14/consult.elc b/elpa/consult-0.14/consult.elc Binary files differ. diff --git a/elpa/consult-0.14/consult.info b/elpa/consult-0.14/consult.info @@ -0,0 +1,1476 @@ +This is consult.info, produced by makeinfo version 6.7 from +consult.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Consult: (consult). Useful commands built on completing-read. +END-INFO-DIR-ENTRY + + +File: consult.info, Node: Top, Next: Introduction, Up: (dir) + +consult.el - Consulting completing-read +*************************************** + +* Menu: + +* Introduction:: Why Consult? +* Available commands:: Navigation, search, editing commands and more +* Special features:: Enhancements over built-in ‘completing-read’ +* Configuration:: Example configuration and customization variables +* Recommended packages:: Related packages recommended for installation +* Bug reports:: How to create reproducible bug reports +* Contributions:: Feature requests and pull requests +* Acknowledgments:: Contributors and Sources of Inspiration +* Indices:: Indices of concepts and functions + +— The Detailed Node Listing — + +Available commands + +* Virtual Buffers:: Buffers, bookmarks and recent files +* Editing:: Commands useful for editing +* Register:: Searching through registers and fast access +* Navigation:: Mark rings, outlines and imenu +* Search:: Line search, grep and file search +* Grep and Find:: Searching through the filesystem +* Compilation:: Jumping to references and compilation errors +* Histories:: Navigating histories +* Modes:: Toggling minor modes and executing commands +* Org Mode:: Org-specific commands +* Miscellaneous:: Various other useful commands + +Special features + +* Live previews:: Preview the currently selected candidate +* Narrowing and grouping:: Restricting the completion to a candidate group +* Asynchronous search:: Filtering asynchronously generated candidate lists +* Multiple sources:: Combining candidates from different sources +* Embark integration:: Actions, Grep/Occur-buffer export + +Configuration + +* Use-package example:: Configuration example based on use-package +* Custom variables:: Short description of all customization settings +* Fine-tuning:: Fine-grained configuration for special requirements + +Indices + +* Function index:: List of all Consult commands +* Concept index:: List of all Consult-specific concepts + + + +File: consult.info, Node: Introduction, Next: Available commands, Prev: Top, Up: Top + +1 Introduction +************** + +Consult provides practical commands based on the Emacs completion +function completing-read +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Completion.html). +Completion allows you to quickly select an item from a list of +candidates. Consult offers in particular an advanced buffer switching +command ‘consult-buffer’ to switch between buffers and recently opened +files. Furthermore Consult provides multiple search commands, an +asynchronous ‘consult-grep’ and ‘consult-ripgrep’, and ‘consult-line’, +which resembles Swiper (https://github.com/abo-abo/swiper#swiper). Some +of the Consult commands are enhanced versions of built-in Emacs +commands. For example the command ‘consult-imenu’ presents a flat list +of the Imenu with *note live preview: Live previews, *note grouping and +narrowing: Narrowing and grouping. Please take a look at the *note full +list of commands: Available commands. + + Consult is fully compatible with completion systems based on the +standard Emacs ‘completing-read’ API, notably the default completion +system, Vertico (https://github.com/minad/vertico), Icomplete +(https://www.gnu.org/software/emacs/manual/html_node/emacs/Icomplete.html)/Icomplete-vertical +(https://github.com/oantolin/icomplete-vertical), Selectrum +(https://github.com/raxod502/selectrum), Embark +(https://github.com/oantolin/embark/) and Mct +(https://github.com/protesilaos/mct). + + This package keeps the completion system specifics to a minimum. The +ability of the Consult commands to work well with arbitrary completion +systems is one of the main advantages of the package. Consult fits well +into existing setups and it helps you to create a full completion +environment out of small and independent components. Note that, if you +use Ivy (https://github.com/abo-abo/swiper#ivy) or Helm +(https://github.com/emacs-helm/helm), you probably don’t need Consult, +since both packages bring their own Consult-like functionality. + + You can combine the complementary packages Marginalia +(https://github.com/minad/marginalia/), Embark +(https://github.com/oantolin/embark/) and Orderless +(https://github.com/oantolin/orderless) with Consult. Marginalia +enriches the completion display with annotations, e.g., documentation +strings or file information. The versatile Embark package provides +local actions, comparable to a context menu. These actions operate on +the selected candidate in the minibuffer or at point in normal buffers. +For example, when selecting from a list of files, Embark offers an +action to delete the file. Additionally Embark offers a completion +system by itself through its live-updating collect buffer. The section +*note Embark integration:: documents in greater detail how Consult and +Embark work together. + + +File: consult.info, Node: Available commands, Next: Special features, Prev: Introduction, Up: Top + +2 Available commands +******************** + +Most Consult commands follow the meaningful naming scheme +‘consult-<thing>’. Many commands implement a little known but +convenient Emacs feature called "future history", which guesses what +input the user wants. At a command prompt type ‘M-n’ and typically +Consult will insert the symbol or thing at point into the input. + + *TIP:* If you have Marginalia (https://github.com/minad/marginalia) +annotators activated, type ‘M-x ^consult’ to see all Consult commands +with their abbreviated description. Alternatively, type ‘C-h a +^consult’ to get an overview of all Consult variables and functions with +their descriptions. + +* Menu: + +* Virtual Buffers:: Buffers, bookmarks and recent files +* Editing:: Commands useful for editing +* Register:: Searching through registers and fast access +* Navigation:: Mark rings, outlines and imenu +* Search:: Line search, grep and file search +* Grep and Find:: Searching through the filesystem +* Compilation:: Jumping to references and compilation errors +* Histories:: Navigating histories +* Modes:: Toggling minor modes and executing commands +* Org Mode:: Org-specific commands +* Miscellaneous:: Various other useful commands + + +File: consult.info, Node: Virtual Buffers, Next: Editing, Up: Available commands + +2.1 Virtual Buffers +=================== + + • ‘consult-buffer’ (‘-other-window’, ‘-other-frame’): Enhanced + version of ‘switch-to-buffer’ with support for virtual buffers. + Supports live preview of buffers and narrowing to the virtual + buffer types. You can type ‘f SPC’ in order to narrow to recent + files. Press ‘SPC’ to show ephemeral buffers. Supported narrowing + keys: + • b Buffers + • f Files (Requires ‘recentf-mode’) + • m Bookmarks + • p Project (Requires configuration of the + ‘consult-project-root-function’ as shown in the *note example + configuration: Use-package example.). + • Arbitrary *note other sources: Multiple sources. configured in + ‘consult-buffer-sources’. + • ‘consult-bookmark’: Select or create bookmark. To select bookmarks + you might use the ‘consult-buffer’ as an alternative, which can + include a bookmark virtual buffer source. Note that + ‘consult-bookmark’ supports preview of bookmarks and narrowing. + • ‘consult-recent-file’: Select from recent files with preview. You + might prefer the powerful ‘consult-buffer’ instead, which can + include recent files as a virtual buffer source. The + ‘recentf-mode’ enables tracking of recent files. + + +File: consult.info, Node: Editing, Next: Register, Prev: Virtual Buffers, Up: Available commands + +2.2 Editing +=========== + + • ‘consult-yank-from-kill-ring’: Enhanced version of ‘yank’ to select + an item from the ‘kill-ring’. The selected text previewed as + overlay in the buffer. + • ‘consult-yank-pop’: Enhanced version of ‘yank-pop’ with + DWIM-behavior, which either replaces the last ‘yank’ by cycling + through the ‘kill-ring’, or if there has not been a last ‘yank’ + consults the ‘kill-ring’. The selected text previewed as overlay + in the buffer. + • ‘consult-yank-replace’: Like ‘consult-yank-pop’, but always + replaces the last ‘yank’ with an item from the ‘kill-ring’. + • ‘consult-kmacro’: Select macro from the macro ring and execute it. + + +File: consult.info, Node: Register, Next: Navigation, Prev: Editing, Up: Available commands + +2.3 Register +============ + + • ‘consult-register’: Select from list of registers. The command + supports narrowing to register types and preview of marker + positions. This command is useful to search the register contents. + For quick access use the commands ‘consult-register-load’, + ‘consult-register-store’ or the built-in Emacs register commands. + • ‘consult-register-format’: Set ‘register-preview-function’ to this + function for an enhanced register formatting. See the *note + example configuration: Use-package example. + • ‘consult-register-window’: Replace ‘register-preview’ with this + function for a better register window. See the *note example + configuration: Use-package example. + • ‘consult-register-load’: Utility command to quickly load a + register. The command either jumps to the register value or + inserts it. + • ‘consult-register-store’: Improved UI to store registers depending + on the current context with an action menu. With an active region, + store/append/prepend the contents, optionally deleting the region + when a prefix argument is given. With a numeric prefix argument, + store/add the number. Otherwise store point, frameset, window or + kmacro. Usage examples: + • ‘M-' x’: If no region is active, store point in register ‘x’. + If a region is active, store the region in register ‘x’. + • ‘M-' M-w x’: Store window configuration in register ‘x’. + • ‘C-u 100 M-' x’: Store number in register ‘x’. + + +File: consult.info, Node: Navigation, Next: Search, Prev: Register, Up: Available commands + +2.4 Navigation +============== + + • ‘consult-goto-line’: Jump to line number enhanced with live + preview. This is a drop-in replacement for ‘goto-line’. + • ‘consult-mark’: Jump to a marker in the ‘mark-ring’. Supports live + preview and recursive editing. + • ‘consult-global-mark’: Jump to a marker in the ‘global-mark-ring’. + Supports live preview and recursive editing. + • ‘consult-outline’: Jump to a heading of the outline. Supports + narrowing to a heading level, live preview and recursive editing. + • ‘consult-imenu’: Jump to imenu item in the current buffer. + Supports live preview, recursive editing and narrowing. + • ‘consult-imenu-multi’: Jump to imenu item in project buffers, with + the same major mode as the current buffer. Supports live preview, + recursive editing and narrowing. This feature has been inspired by + imenu-anywhere (https://github.com/vspinu/imenu-anywhere). + + +File: consult.info, Node: Search, Next: Grep and Find, Prev: Navigation, Up: Available commands + +2.5 Search +========== + + • ‘consult-line’: Enter search string and select from matching lines. + Supports live preview and recursive editing. The symbol at point + and the recent Isearch string are added to the "future history" and + can be accessed by pressing ‘M-n’. When ‘consult-line’ is bound to + the ‘isearch-mode-map’ and is invoked during a running Isearch, it + will use the current Isearch string. + • ‘consult-line-multi’: Search across multiple buffers. By default + search across project buffers. If invoked with a prefix argument + search across all buffers. Behaves like ‘consult-line’. + • ‘consult-multi-occur’: Replacement for ‘multi-occur’ which uses + ‘completing-read-multiple’. + • ‘consult-keep-lines’: Replacement for ‘keep/flush-lines’ which uses + the current completion style for filtering the buffer. The + function updates the buffer while typing. In particular + ‘consult-keep-lines’ can narrow down an exported Embark collect + buffer further, relying on the same completion filtering as + ‘completing-read’. If the input begins with the negation operator, + i.e., ‘! SPC’, the filter matches the complement. If a region is + active, the region restricts the filtering. + • ‘consult-focus-lines’: Temporarily hide lines by filtering them + using the current completion style. Call with ‘C-u’ prefix + argument in order to show the hidden lines again. If the input + begins with the negation operator, i.e., ‘! SPC’, the filter + matches the complement. In contrast to ‘consult-keep-lines’ this + function does not edit the buffer. If a region is active, the + region restricts the filtering. + + +File: consult.info, Node: Grep and Find, Next: Compilation, Prev: Search, Up: Available commands + +2.6 Grep and Find +================= + + • ‘consult-grep’, ‘consult-ripgrep’, ‘consult-git-grep’: Search for + regular expression in files. Consult invokes Grep asynchronously, + while you enter the search term. After at least + ‘consult-async-min-input’ characters, the search gets started. + Consult splits the input string into two parts, if the first + character is a punctuation character, like ‘#’. For example + ‘#regexps#filter-string’, is split at the second ‘#’. The string + ‘regexps’ is passed to Grep. Note that Consult transforms Emacs + regular expressions to expressions understand by the search + program. Always use Emacs regular expressions at the prompt. If + you enter multiple regular expressions separated by space only + lines matching all regular expressions are shown. In order to + match space literally, escape the space with a backslash. The + ‘filter-string’ is passed to the _fast_ Emacs filtering to further + narrow down the list of matches. This is particularly useful if + you are using an advanced completion style like orderless. + ‘consult-grep’ supports preview. If the + ‘consult-project-root-function’ is *note configured: Use-package + example. and returns non-nil, ‘consult-grep’ searches the current + project directory. Otherwise the ‘default-directory’ is searched. + If ‘consult-grep’ is invoked with prefix argument ‘C-u M-s g’, you + can specify the directory manually. + • ‘consult-find’, ‘consult-locate’: Find file by matching the path + against a regexp. Like for ‘consult-grep,’ either the project root + or the current directory is the root directory for the search. The + input string is treated similarly to ‘consult-grep’, where the + first part is passed to find, and the second part is used for Emacs + filtering. + + +File: consult.info, Node: Compilation, Next: Histories, Prev: Grep and Find, Up: Available commands + +2.7 Compilation +=============== + + • ‘consult-compile-error’: Jump to a compilation error. Supports + live preview narrowing and recursive editing. + • ‘consult-flymake’: Jump to flymake diagnostic. Supports live + preview and recursive editing. The command supports narrowing. + Press ‘e SPC’, ‘w SPC’, ‘n SPC’ to only show errors, warnings and + notes respectively. + • ‘consult-flycheck’: Jump to flycheck error, similar to + ‘consult-flymake’. This command requires the installation of the + additional ‘consult-flycheck’ package since the main ‘consult’ + package only depends on Emacs core components. + • ‘consult-xref’: Integration with xref. This function can be set as + as ‘xref-show-xrefs-function’ and ‘xref-show-definitions-function’. + + +File: consult.info, Node: Histories, Next: Modes, Prev: Compilation, Up: Available commands + +2.8 Histories +============= + + • ‘consult-complex-command’: Select a command from the + ‘command-history’. This command is a ‘completing-read’ version of + ‘repeat-complex-command’ and is also a replacement for the + ‘command-history’ command from chistory.el. + • ‘consult-history’: Insert a string from the current buffer history. + You can invoke this command from the minibuffer. In that case + ‘consult-history’ uses the history stored in the + ‘minibuffer-history-variable’. + • ‘consult-isearch-history’: During an Isearch session, this command + picks a search string from history and continues the search with + the newly selected string. Outside of Isearch, the command allows + you to pick a string from the history and starts a new Isearch. + ‘consult-isearch-history’ acts as a drop-in replacement for + ‘isearch-edit-string’. + + +File: consult.info, Node: Modes, Next: Org Mode, Prev: Histories, Up: Available commands + +2.9 Modes +========= + + • ‘consult-minor-mode-menu’: Enable/disable minor mode. Supports + narrowing to on/off/local/global modes by pressing ‘i/o/l/g SPC’ + respectively. + • ‘consult-mode-command’: Run a command from the currently active + minor or major modes. Supports narrowing to + local-minor/global-minor/major mode via the keys ‘l/g/m’. + + +File: consult.info, Node: Org Mode, Next: Miscellaneous, Prev: Modes, Up: Available commands + +2.10 Org Mode +============= + + • ‘consult-org-heading’: Similar to ‘consult-outline’, for Org + buffers. Supports narrowing by heading level, priority and TODO + state, as well as live preview and recursive editing. + • ‘consult-org-agenda’: Jump to an agenda heading. Supports + narrowing by heading level, priority and TODO state, as well as + live preview and recursive editing. + + +File: consult.info, Node: Miscellaneous, Prev: Org Mode, Up: Available commands + +2.11 Miscellaneous +================== + + • ‘consult-apropos’: Replacement for ‘apropos’ with completion. As a + better alternative, you can run ‘embark-export’ from commands like + ‘M-x’ or ‘describe-symbol’. + • ‘consult-man’: Find Unix man page, via Unix ‘apropos’ or ‘man -k’. + ‘consult-man’ opens the selected man page using the Emacs ‘man’ + command. + • ‘consult-file-externally’: Select a file and open it externally, + e.g. using ‘xdg-open’ on Linux. + • ‘consult-theme’: Select a theme and disable all currently enabled + themes. Supports live preview of the theme while scrolling through + the candidates. + • ‘consult-preview-at-point’ and ‘consult-preview-at-point-mode’: + Command and minor mode which previews the candidate at point in the + ‘*Completions*’ buffer. This is mainly relevant if you use the + default ‘*Completions*’ UI or if you want to enable preview in + Embark Collect buffers. + • ‘consult-completion-in-region’: This function can be set as + ‘completion-in-region-function’. Then the minibuffer completion UI + will be used for ‘completion-at-point’. This function is + particularly useful in combination with Vertico or Icomplete, since + these UIs do not provide their own ‘completion-in-region-function’. + Selectrum provides its own function similar to + ‘consult-completion-in-region’. If you use the default + ‘*Completions*’ UI, note that ‘consult-completion-in-region’ is not + useful. + ;; Use `consult-completion-in-region' if Vertico is enabled. + ;; Otherwise use the default `completion--in-region' function. + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + Instead of ‘consult-completion-in-region’, you may prefer to see + the completions directly in the buffer as a small popup. In that + case, I recommend either the Corfu (https://github.com/minad/corfu) + or the Company (https://github.com/company-mode/company-mode) + package. There is a technical caveat of + ‘consult-completion-in-region’ in combination with Lsp-mode or + Eglot. The Lsp server relies on the input at point, in order to + generate refined candidate strings. Since the completion is + transferred from the original buffer to the minibuffer, the server + does not receive the updated input. Lsp completion should work + with Corfu or Company though, which perform the completion directly + in the original buffer. + • ‘consult-completing-read-multiple’: Enhanced drop-in replacement + for ‘completing-read-multiple’ which works better for long + candidates. You can select/deselect multiple candidates by + pressing ‘RET’. Afterwards the selections are confirmed by + pressing ‘RET’ again. + + +File: consult.info, Node: Special features, Next: Configuration, Prev: Available commands, Up: Top + +3 Special features +****************** + +Consult enhances ‘completing-read’ with live previews of candidates, +additional narrowing capabilities to candidate groups and asynchronously +generated candidate lists. The internal ‘consult--read’ function, which +is used by most Consult commands, is a thin wrapper around +‘completing-read’ and provides the special functionality. In order to +support multiple candidate sources there exists the high-level function +‘consult--multi’. The architecture of Consult allows it to work with +different completion systems in the backend, while still offering +advanced features. + +* Menu: + +* Live previews:: Preview the currently selected candidate +* Narrowing and grouping:: Restricting the completion to a candidate group +* Asynchronous search:: Filtering asynchronously generated candidate lists +* Multiple sources:: Combining candidates from different sources +* Embark integration:: Actions, Grep/Occur-buffer export + + +File: consult.info, Node: Live previews, Next: Narrowing and grouping, Up: Special features + +3.1 Live previews +================= + +Some Consult commands support live previews. For example when you +scroll through the items of ‘consult-line’, the buffer will scroll to +the corresponding position. It is possible to jump back and forth +between the minibuffer and the buffer to perform recursive editing while +the search is ongoing. + + Consult enables previews by default. You can disable them by +adjusting the ‘consult-preview-key’ variable. Furthermore it is +possible to specify keybindings which trigger the preview manually as +shown in the *note example configuration: Use-package example. The +default setting of ‘consult-preview-key’ is ‘any’ which means that +Consult triggers the preview _immediately_ on any key press when the +selected candidate changes. You can configure each command individually +with its own ‘:preview-key’. The following settings are possible: + + • Automatic and immediate ‘'any’ + • Automatic and delayed ‘(list :debounce 0.5 'any)’ + • Manual and immediate ‘(kbd "M-.")’ + • Manual and delayed ‘(list :debounce 0.5 (kbd "M-."))’ + • Disabled ‘nil’ + + A safe recommendation is to leave automatic immediate previews +enabled in general and disable the automatic preview only for commands, +where the preview may be expensive due to file loading. + + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-recent-file consult--source-project-recent-file consult--source-bookmark + :preview-key (kbd "M-.")) + + In this case one may wonder what the difference is between using an +Embark action on the current candidate in comparison to a manually +triggered preview. The main difference is that the files opened by +manual preview are closed again after the completion session. +Furthermore during preview some functionality is disabled to improve the +performance, see for example ‘consult-preview-excluded-hooks’. Files +larger than ‘consult-preview-raw-size’ are previewed literally without +syntax highlighting and without changing the major mode. + + Delaying the preview is particularly useful for ‘consult-theme’, +since the theme preview is a little bit slow. The delay can result in a +smoother UI. + + ;; Preview on any key press, but delay 0.5s + (consult-customize consult-theme :preview-key '(:debounce 0.5 any)) + ;; Preview immediately on M-., on up/down after 0.5s, on any other key after 1s + (consult-customize consult-theme + :preview-key + (list (kbd "M-.") + :debounce 0.5 (kbd "<up>") (kbd "<down>") + :debounce 1 'any)) + + +File: consult.info, Node: Narrowing and grouping, Next: Asynchronous search, Prev: Live previews, Up: Special features + +3.2 Narrowing and grouping +========================== + +Consult has special support for candidate groups. If the completion UI +supports the grouping functionality, the UI separates the groups with +thin lines and shows group titles. Grouping is useful if the list of +candidates consists of candidates of multiple types or candidates from +*note multiple sources: Multiple sources, like the ‘consult-buffer’ +command, which shows both buffers and recently opened files. Note that +you can disable the group titles by setting the ‘:group’ property of the +corresponding command to nil using the ‘consult-customize’ macro. + + By entering a narrowing prefix or by pressing a narrowing key it is +possible to restrict the completion candidates to a certain candidate +group. When you use the ‘consult-buffer’ command, you can enter the +prefix ‘b SPC’ to restrict list of candidates to buffers only. If you +press ‘DEL’ afterwards, the full candidate list will be shown again. +Furthermore a narrowing prefix key and a widening key can be configured +which can be pressed to achieve the same effect, see the configuration +variables ‘consult-narrow-key’ and ‘consult-widen-key’. + + After pressing ‘consult-narrow-key’, the possible narrowing keys can +be shown by pressing ‘C-h’. When pressing ‘C-h’ after some prefix key, +the ‘prefix-help-command’ is invoked, which shows the keybinding help +window by default. As a more compact alternative, there is the +‘consult-narrow-help’ command which can be bound to a key, for example +‘?’ or ‘C-h’ in the ‘consult-narrow-map’, as shown in the *note example +configuration: Use-package example. If which-key +(https://github.com/justbur/emacs-which-key) is installed, the narrowing +keys are automatically shown in the which-key window after pressing the +‘consult-narrow-key’. + + +File: consult.info, Node: Asynchronous search, Next: Multiple sources, Prev: Narrowing and grouping, Up: Special features + +3.3 Asynchronous search +======================= + +Consult has support for asynchronous generation of candidate lists. +This feature is used for search commands like ‘consult-grep’, where the +list of matches is generated dynamically while the user is typing a +regular expression. The grep process is executed in the background. +When modifying the regular expression, the background process is +terminated and a new process is started with the modified regular +expression. + + The matches, which have been found, can then be narrowed using the +installed Emacs completion-style. This can be powerful if you are using +for example the ‘orderless’ completion style. + + This two-level filtering is possible by splitting the input string. +Part of the input string is treated as input to grep and part of the +input is used for filtering. There are multiple splitting styles +available, configured in ‘consult-async-split-styles-alist’: ‘nil’, +‘comma’, ‘semicolon’ and ‘perl’. The default splitting style is +configured with the variable ‘consult-async-split-style’. + + With the ‘comma’ and ‘semicolon’ splitting styles, the first word +before the comma or semicolon is passed to grep, the remaining string is +used for filtering. The ‘nil’ splitting style does not perform any +splitting, the whole input is passed to grep. + + The ‘perl’ splitting style splits the input string at a punctuation +character, using a similar syntax as Perl regular expressions. + + Examples: + + • ‘#defun’: Search for "defun" using grep. + • ‘#consult embark’: Search for both "consult" and "embark" using + grep in any order. + • ‘#first.*second’: Search for "first" followed by "second" using + grep. + • ‘#\(consult\|embark\)’: Search for "consult" or "embark" using + grep. Note the usage of Emacs-style regular expressions. + • ‘#defun#consult’: Search for "defun" using grep, filter with the + word "consult". + • ‘/defun/consult’: It is also possible to use other punctuation + characters. + • ‘#to#’: Force searching for "to" using grep, since the grep pattern + must be longer than ‘consult-async-min-input’ characters by + default. + • ‘#defun -- --invert-match#’: Pass argument ‘--invert-match’ to + grep. + + Asynchronous processes like ‘find’ and ‘grep’ create an error log +buffer ‘_*consult-async*’ (note the leading space), which is useful for +troubleshooting. The prompt has a small indicator showing the process +status: + + • ‘:’ the usual prompt colon, before input is provided. + • ‘*’ with warning face, the process is running. + • ‘:’ with success face, success, process exited with an error code + of zero. + • ‘!’ with error face, failure, process exited with a nonzero error + code. + • ‘;’ with error face, interrupted, for example if more input is + provided. + + +File: consult.info, Node: Multiple sources, Next: Embark integration, Prev: Asynchronous search, Up: Special features + +3.4 Multiple sources +==================== + +Multiple synchronous candidate sources can be combined. This feature is +used by the ‘consult-buffer’ command to present buffer-like candidates +in a single menu for quick access. By default ‘consult-buffer’ includes +buffers, bookmarks, recent files and project-specific buffers and files. +It is possible to configure the list of sources via the +‘consult-buffer-sources’ variable. Arbitrary custom sources can be +defined. + + As an example, the bookmark source is defined as follows: + + (defvar consult--source-bookmark + `(:name "Bookmark" + :narrow ?m + :category bookmark + :face consult-bookmark + :history bookmark-history + :items ,#'bookmark-all-names + :action ,#'consult--bookmark-action)) + + Required source fields: + • ‘:category’ Completion category. + • ‘:items’ List of strings to select from or function returning list + of strings. A list of cons cells is not supported. + + Optional source fields: + • ‘:name’ Name of the source, used for narrowing, group titles and + annotations. + • ‘:narrow’ Narrowing character or ‘(character . string)’ pair. + • ‘:preview-key’ Preview key or keys which trigger preview. + • ‘:enabled’ Function which must return t if the source is enabled. + • ‘:hidden’ When t candidates of this source are hidden by default. + • ‘:face’ Face used for highlighting the candidates. + • ‘:annotate’ Annotation function called for each candidate, returns + string. + • ‘:history’ Name of history variable to add selected candidate. + • ‘:default’ Must be t if the first item of the source is the default + value. + • ‘:action’ Action function called with the selected candidate. + • ‘:state’ State constructor for the source, must return the state + function. + • Other source fields can be added specifically to the use case. + + The ‘:state’ and ‘:action’ fields of the sources deserve a longer +explanation. The ‘:action’ function takes a single argument and is only +called after selection with the selected candidate, if the selection has +not been aborted. This functionality is provided for convenience and +easy definition of sources. The ‘:state’ field is more complicated and +general. The ‘:state’ function is a constructor function without +arguments, which can perform some setup necessary for the preview. It +must return a closure with two arguments: The first argument is the +candidate string, the second argument is the restore flag. The state +function is called during preview, if a preview key has been pressed, +with the selected candidate or nil and the restore argument being nil. +Furthermore the state function is always called after selection with the +selected candidate or nil. The state function is called with nil for +the candidate if for example the selection process has been aborted or +if the original preview state should be restored during preview. The +restore flag is t for the final call. The final call happens even if +preview is disabled. For this reason you can also use the final call to +the state function in a similar way as ‘:action’. You probably only +want to specify both ‘:state’ and ‘:action’ if ‘:state’ is purely +responsible for preview and ‘:action’ is then responsible for the real +action after selection. + + In order to avoid slowness, ‘consult-buffer’ only preview buffers by +default. Loading recent files, bookmarks or views can result in +expensive operations. However it is possible to configure the bookmark +and file sources to also perform preview. + + (consult-customize + consult--source-recent-file consult--source-project-recent-file consult--source-bookmark + :preview-key (kbd "M-.")) + + Sources can be added directly to the ‘consult-buffer-source’ list for +convenience. For example views can be added to the list of virtual +buffers from a library like <https://github.com/minad/bookmark-view/>. + + ;; Configure new bookmark-view source + (add-to-list 'consult-buffer-sources + (list :name "View" + :narrow ?v + :category 'bookmark + :face 'font-lock-keyword-face + :history 'bookmark-view-history + :action #'consult--bookmark-action + :items #'bookmark-view-names) + 'append) + + ;; Modify bookmark source, such that views are hidden + (setq consult--source-bookmark + (plist-put + consult--source-bookmark :items + (lambda () + (bookmark-maybe-load-default-file) + (mapcar #'car + (seq-remove (lambda (x) + (eq #'bookmark-view-handler + (alist-get 'handler (cdr x)))) + bookmark-alist))))) + + Other useful sources allow the creation of terminal and eshell +buffers if they do not exist yet. + + (defun mode-buffer-exists-p (mode) + (seq-some (lambda (buf) + (provided-mode-derived-p + (buffer-local-value 'major-mode buf) + mode)) + (buffer-list))) + + (defvar eshell-source + `(:category 'consult-new + :face 'font-lock-constant-face + :action ,(lambda (_) (eshell)) + :items + ,(lambda () + (unless (mode-buffer-exists-p 'eshell-mode) + '("*eshell* (new)"))))) + + (defvar term-source + `(:category 'consult-new + :face 'font-lock-constant-face + :action + ,(lambda (_) + (ansi-term (or (getenv "SHELL") "/bin/sh"))) + :items + ,(lambda () + (unless (mode-buffer-exists-p 'term-mode) + '("*ansi-term* (new)"))))) + + (add-to-list 'consult-buffer-sources 'eshell-source 'append) + (add-to-list 'consult-buffer-sources 'term-source 'append) + + For more details, see the documentation of ‘consult-buffer’ and of +the internal ‘consult--multi’ API. The ‘consult--multi’ function can be +used to create new multi-source commands, but is part of the internal +API as of now, since some details may still change. + + +File: consult.info, Node: Embark integration, Prev: Multiple sources, Up: Special features + +3.5 Embark integration +====================== + +*NOTE*: Install the ‘embark-consult’ package from MELPA, which provides +Consult-specific Embark actions and the Occur buffer export. + + Embark is a versatile package which offers context dependent actions, +comparable to a context menu. See the Embark manual +(https://github.com/oantolin/embark) for an extensive description of its +capabilities. + + Actions are commands which can operate on the currently selected +candidate (or target in Embark terminology). When completing files, for +example the ‘delete-file’ command is offered. With Embark you can +execute arbitrary commands on the currently selected candidate via +‘M-x’. + + Furthermore Embark provides the ‘embark-collect-snapshot’ command, +which collects candidates and presents them in an Embark collect buffer, +where further actions can be applied to them. A related feature is the +‘embark-export’ command, which exports candidate lists to a buffer of a +special type. For example in the case of file completion, a Dired +buffer is opened. + + In the context of Consult, particularly exciting is the possibility +to export the matching lines from ‘consult-line’, ‘consult-outline’, +‘consult-mark’ and ‘consult-global-mark’. The matching lines are +exported to an Occur buffer where they can be edited via the +‘occur-edit-mode’ (press key ‘e’). Similarly, Embark supports exporting +the matches found by ‘consult-grep’, ‘consult-ripgrep’ and +‘consult-git-grep’ to a Grep buffer, where the matches across files can +be edited, if the wgrep (https://github.com/mhayashi1120/Emacs-wgrep) +package is installed. These three workflows are symmetric. + + • ‘consult-line’ -> ‘embark-export’ to ‘occur-mode’ buffer -> + ‘occur-edit-mode’ for editing of matches in buffer. + • ‘consult-grep’ -> ‘embark-export’ to ‘grep-mode’ buffer -> ‘wgrep’ + for editing of all matches. + • ‘consult-find’ -> ‘embark-export’ to ‘dired-mode’ buffer -> + ‘wdired-change-to-wdired-mode’ for editing. + + +File: consult.info, Node: Configuration, Next: Recommended packages, Prev: Special features, Up: Top + +4 Configuration +*************** + +Consult can be installed from ELPA +(http://elpa.gnu.org/packages/consult.html) or MELPA +(https://melpa.org/#/consult) via the Emacs built-in package manager. +Alternatively it can be directly installed from the development +repository via other non-standard package managers. + + There is the Consult wiki (https://github.com/minad/consult/wiki), +where additional configuration examples can be contributed. + + *IMPORTANT:* It is strongly recommended that you enable lexical +binding +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html) +in your configuration. Consult uses a functional programming style, +relying on lambdas and lexical closures. For this reason many +Consult-related snippets require lexical binding. + +* Menu: + +* Use-package example:: Configuration example based on use-package +* Custom variables:: Short description of all customization settings +* Fine-tuning:: Fine-grained configuration for special requirements + + +File: consult.info, Node: Use-package example, Next: Custom variables, Up: Configuration + +4.1 Use-package example +======================= + +The Consult package only provides commands and does not add any +keybindings or modes. Therefore the package is non-intrusive but +requires a little setup effort. In order to use the Consult commands, +it is advised to add keybindings for commands which are accessed often. +Rarely used commands can be invoked via ‘M-x’. Feel free to only bind +the commands you consider useful to your workflow. The configuration +shown here relies on the ‘use-package’ macro, which is a convenient tool +to manage package configurations. + + *NOTE:* There is the Consult wiki +(https://github.com/minad/consult/wiki), where you can contribute +additional configuration examples. + + ;; Example configuration for Consult + (use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings (mode-specific-map) + ("C-c h" . consult-history) + ("C-c m" . consult-mode-command) + ("C-c k" . consult-kmacro) + ;; C-x bindings (ctl-x-map) + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ("<help> a" . consult-apropos) ;; orig. apropos-command + ;; M-g bindings (goto-map) + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings (search-map) + ("M-s d" . consult-find) + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s m" . consult-multi-occur) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi)) ;; needed by consult-line to detect isearch + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. You may want to also + ;; enable `consult-preview-at-point-mode` in Embark Collect buffers. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Optionally replace `completing-read-multiple' with an enhanced version. + (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key (kbd "M-.")) + ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>"))) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme + :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-recent-file consult--source-project-recent-file consult--source-bookmark + :preview-key (kbd "M-.")) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; (kbd "C-+") + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; Optionally configure a function which returns the project root directory. + ;; There are multiple reasonable alternatives to chose from. + ;;;; 1. project.el (project-roots) + (setq consult-project-root-function + (lambda () + (when-let (project (project-current)) + (car (project-roots project))))) + ;;;; 2. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-root-function #'projectile-project-root) + ;;;; 3. vc.el (vc-root-dir) + ;; (setq consult-project-root-function #'vc-root-dir) + ;;;; 4. locate-dominating-file + ;; (setq consult-project-root-function (lambda () (locate-dominating-file "." ".git"))) + ) + + +File: consult.info, Node: Custom variables, Next: Fine-tuning, Prev: Use-package example, Up: Configuration + +4.2 Custom variables +==================== + +*TIP:* If you have Marginalia (https://github.com/minad/marginalia) +installed, type ‘M-x customize-variable RET ^consult’ to see all +Consult-specific customizable variables with their current values and +abbreviated description. Alternatively, type ‘C-h a ^consult’ to get an +overview of all Consult variables and functions with their descriptions. + +Variable Description +------------------------------------------------------------------------------------------- +consult-after-jump-hook Functions to call after jumping to a location +consult-async-input-debounce Input debounce for asynchronous commands +consult-async-input-throttle Input throttle for asynchronous commands +consult-async-min-input Minimum numbers of letters needed for async process +consult-async-refresh-delay Refresh delay for asynchronous commands +consult-async-split-style Splitting style used for async commands +consult-async-split-styles-alist Available splitting styles used for async commands +consult-bookmark-narrow Narrowing configuration for ‘consult-bookmark’ +consult-buffer-filter Filter for ‘consult-buffer’ +consult-buffer-sources List of virtual buffer sources +consult-crm-prefix Prefix string for CRM candidates +consult-find-args Command line arguments for find +consult-fontify-max-size Buffers larger than this limit are not fontified +consult-fontify-preserve Preserve fontification for line-based commands. +consult-git-grep-args Command line arguments for git-grep +consult-goto-line-numbers Show line numbers for ‘consult-goto-line’ +consult-grep-max-columns Maximal number of columns of the matching lines +consult-grep-args Command line arguments for grep +consult-imenu-config Mode-specific configuration for ‘consult-imenu’ +consult-line-numbers-widen Show absolute line numbers when narrowing is active. +consult-line-point-placement Placement of the point used by ‘consult-line’ +consult-line-start-from-top Start the ‘consult-line’ search from the top +consult-locate-args Command line arguments for locate +consult-man-args Command line arguments for man +consult-mode-command-filter Filter for ‘consult-mode-command’ +consult-mode-histories Mode-specific history variables +consult-narrow-key Narrowing prefix key during completion +consult-preview-key Keys which triggers preview +consult-preview-excluded-hooks List of ‘find-file’ hooks to avoid during preview +consult-preview-max-count Maximum number of files to keep open during preview +consult-preview-max-size Files larger than this size are not previewed +consult-preview-raw-size Files larger than this size are previewed in raw form +consult-project-root-function Function which returns current project root +consult-recent-file-filter Filter for ‘consult-recent-file’ +consult-register-narrow Narrowing configuration for ‘consult-register’ +consult-ripgrep-args Command line arguments for ripgrep +consult-themes List of themes to be presented for selection +consult-widen-key Widening key during completion + + +File: consult.info, Node: Fine-tuning, Prev: Custom variables, Up: Configuration + +4.3 Fine-tuning of individual commands +====================================== + +*NOTE:* Consult supports fine-grained customization of individual +commands. This configuration feature exists for experienced users with +special requirements. There is the Consult wiki +(https://github.com/minad/consult/wiki), where we collect further +configuration examples. + + Commands and buffer sources allow flexible, individual customization +by using the ‘consult-customize’ macro. You can override any option +passed to the internal ‘consult--read’ API. The Consult wiki +(https://github.com/minad/consult/wiki) already contains a numerous +useful configuration examples. Note that since ‘consult--read’ is part +of the internal API, options could be removed, replaced or renamed in +future versions of the package. + + Useful options are: + • ‘:prompt’ set the prompt string + • ‘:preview-key’ set the preview key, default is + ‘consult-preview-key’ + • ‘:initial’ set the initial input + • ‘:default’ set the default value + • ‘:history’ set the history variable symbol + • ‘:add-history’ add items to the future history, for example symbol + at point + • ‘:sort’ enable or disable sorting + • ‘:group’ set to nil to disable candidate grouping and titles. + • ‘:inherit-input-method’ set to non-nil to inherit the input method. + + (consult-customize + ;; Disable preview for `consult-theme' completely. + consult-theme :preview-key nil + ;; Set preview for `consult-buffer' to key `M-.' + consult-buffer :preview-key (kbd "M-.") + ;; For `consult-line' change the prompt and specify multiple preview + ;; keybindings. Note that you should bind <S-up> and <S-down> in the + ;; `minibuffer-local-completion-map' or `vertico-map' to the commands which + ;; select the previous or next candidate. + consult-line :prompt "Search: " + :preview-key (list (kbd "<S-down>") (kbd "<S-up>"))) + + Generally it is possible to modify commands for your individual needs +by the following techniques: + + 1. Use ‘consult-customize’ in order to change the command or source + settings. + 2. Create your own wrapper function which passes modified arguments to + the Consult functions. + 3. Create your own buffer *note multi sources: Multiple sources. for + ‘consult-buffer’. + 4. Create advices to modify some internal behavior. + 5. Write or propose a patch. + + +File: consult.info, Node: Recommended packages, Next: Bug reports, Prev: Configuration, Up: Top + +5 Recommended packages +********************** + +I use and recommend this combination of packages: + + • consult: This package + • vertico (https://github.com/minad/vertico): Fast and minimal + vertical completion system + • marginalia (https://github.com/minad/marginalia): Annotations for + the completion candidates + • embark and embark-consult (https://github.com/oantolin/embark): + Action commands, which can act on the completion candidates + • orderless (https://github.com/oantolin/orderless): Completion style + which offers flexible candidate filtering + + There exist many other fine completion UIs beside Vertico, which are +supported by Consult. Give them a try and find out which interaction +model fits best for you! + + • selectrum by Radon Rosborough + (https://github.com/raxod502/selectrum): Alternative vertical + completion system. + • icomplete-vertical by Omar Antolín Camarena + (https://github.com/oantolin/icomplete-vertical): Vertical + completion system based on Icomplete. Icomplete-vertical is only + needed for Emacs 27, built-in on Emacs 28. + • embark by Omar Antolín Camarena + (https://github.com/oantolin/embark): Completion based on live + updating Embark collect buffer. + • mct by Protesilaos Stavrou (https://gitlab.com/protesilaos/mct): + Minibuffer and Completions in Tandem, which builds on the default + completion UI. + + You can integrated Consult with special programs or with other +packages in the wider Emacs ecosystem. You may want to install some of +theses packages depending on your preferences and requirements. + + • consult-company (https://github.com/mohkale/consult-company): + Completion at point using the company backends. + • consult-dir (https://github.com/karthink/consult-dir): Directory + jumper using Consult multi sources. + • consult-eglot (https://github.com/mohkale/consult-eglot): + Integration with eglot (lsp client). + • consult-flycheck (https://github.com/minad/consult-flycheck): + Provides the ‘consult-flycheck’ command. + • consult-lsp (https://github.com/gagbo/consult-lsp): Integration + with ‘lsp-mode’ (lsp client). + • consult-notmuch (https://codeberg.org/jao/consult-notmuch): Access + the Notmuch (https://notmuchmail.org/) email system using Consult. + • consult-spotify (https://codeberg.org/jao/espotify): Access the + Spotify API and control your local music player. + • consult-projectile (https://gitlab.com/OlMon/consult-projectile/): + Projectile integration, buffer sources for Projectile. + • consult-recoll (https://codeberg.org/jao/consult-recoll): Access + the Recoll (https://www.lesbonscomptes.com/recoll/) desktop + full-text search using Consult. + • consult-yasnippet (https://github.com/mohkale/consult-yasnippet): + Integration with yasnippet. + • affe (https://github.com/minad/affe): Asynchronous Fuzzy Finder for + Emacs (uses Consult under the hood). + + Not directly related to Consult, but maybe still of interest are the +following packages. These packages should work well with Consult, +follow a similar spirit or offer functionality based on +‘completing-read’. + + • corfu (https://github.com/minad/corfu): Completion systems for + ‘completion-at-point’ using small popups (Alternative to company + (https://github.com/company-mode/company-mode)). + • cape (https://github.com/minad/cape): Completion At Point + Extensions, which can be used with ‘consult-completion-in-region’ + and Corfu (https://github.com/minad/corfu). + • bookmark-view (https://github.com/minad/bookmark-view): Store + window configuration as bookmarks, possible integration with + ‘consult-buffer’. + • citar (https://github.com/bdarcus/citar): Versatile package for + citation insertion and bibliography management. + • flyspell-correct (https://github.com/d12frosted/flyspell-correct): + Apply spelling corrections by selecting via ‘completing-read’. + • wgrep (https://github.com/mhayashi1120/Emacs-wgrep): Editing of + grep buffers, use together with ‘consult-grep’ via ‘embark-export’. + • all-the-icons-completion + (https://github.com/iyefrat/all-the-icons-completion): Icons for + the completion UI. + + Note that all packages are independent and can be exchanged with +alternative components, since there exist no hard dependencies. +Furthermore it is possible to get started with only default completion +and Consult and add more components later to the mix. For example you +can omit Marginalia if you don’t need annotations. I highly recommend +the Embark package, but in order to familarize yourself with the other +components, you can first start without it - or you could even start +with Embark right away and add the other components later on. + + +File: consult.info, Node: Bug reports, Next: Contributions, Prev: Recommended packages, Up: Top + +6 Bug reports +************* + +If you find a bug or suspect that there is a problem with Consult, +please carry out the following steps: + + 1. *Update all the relevant packages to the newest version*. This + includes Consult, Vertico, Mct, Selectrum, Icomplete-vertical, + Marginalia, Embark, Orderless and Prescient in case you are using + any of those packages. + 2. Either use the default completion UI or ensure that exactly one of + ‘vertico-mode’, ‘selectrum-mode’, ‘mct-mode’, or ‘icomplete-mode’ + is enabled. Furthermore ‘ivy-mode’ and ‘helm-mode’ must be + disabled. + 3. Ensure that the ‘completion-styles’ variable is properly + configured. Try to set ‘completion-styles’ to a list including + ‘substring’ or ‘orderless’. + 4. Try to reproduce the issue by starting a bare bone Emacs instance + with ‘emacs -Q’ on the command line. Execute the following minimal + code snippets in the scratch buffer. This way we can exclude side + effects due to configuration settings. If other packages are + relevant to reproduce the issue, include them in the minimal + configuration snippet. + + Minimal setup with Vertico for ‘emacs -Q’: + (package-initialize) + (require 'consult) + (require 'vertico) + (vertico-mode) + (setq completion-styles '(substring)) + + Minimal setup with the default completion system for ‘emacs -Q’: + (package-initialize) + (require 'consult) + (setq completion-styles '(substring)) + + Please provide the necessary important information with your bug +report: + + • The minimal configuration snippet used to reproduce the issue. + • Your completion UI (Default completion, Vertico, Mct, Selectrum or + Icomplete). + • The full stack trace in case the bug triggers an exception. + • Your Emacs version, since bugs may be fixed or introduced in newer + versions. + • Your operating system, since Emacs behavior varies between Linux, + Mac and Windows. + • The package manager, e.g., straight.el or package.el, used to + install the Emacs packages, in order to exclude update issues. Did + you install Consult as part of the Doom or Spacemacs Emacs + distributions? + • If you are using Evil or other packages which change Emacs + fundamentally, since Consult does not provide Evil integration out + of the box. + + When evaluating Consult-related code snippets you should enable +lexical binding +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html). +Consult often uses a functional programming style, relying on lambdas +and lexical closures. + + The Selectrum repository provides a set of scripts +(https://github.com/raxod502/selectrum/tree/master/test) which allow +experimenting with multiple package combinations of completion systems +and Consult. After cloning the repository, you can execute the scripts +with ‘cd selectrum/test; ./run.sh <package-combo.el>’. The scripts do +not modify your existing Emacs configuration, but create a separate +Emacs configuration in ‘/tmp’. + + +File: consult.info, Node: Contributions, Next: Acknowledgments, Prev: Bug reports, Up: Top + +7 Contributions +*************** + +Consult is a community effort, please participate in the discussions. +Contributions are welcome, but you may want to discuss potential +contributions first. Since this package is part of GNU ELPA +(http://elpa.gnu.org/packages/consult.html) contributions require a +copyright assignment to the FSF. + + If you have a proposal, take a look at the Consult issue tracker +(https://github.com/consult/issues) and the Consult wishlist +(https://github.com/minad/consult/issues/6). There have been many prior +feature discussions. Please search through the issue tracker, maybe +your issue or feature request has already been discussed. You can +contribute to the Consult wiki (https://github.com/minad/consult/wiki), +in case you want to share small configuration or command snippets. + + +File: consult.info, Node: Acknowledgments, Next: Indices, Prev: Contributions, Up: Top + +8 Acknowledgments +***************** + +You probably guessed from the name that this package took inspiration +from Counsel (https://github.com/abo-abo/swiper#counsel) by Oleh Krehel. +Some of the Consult commands originated in the Counsel package or the +Selectrum wiki +(https://github.com/raxod502/selectrum/wiki/Useful-Commands). The +commands have been rewritten and greatly enhanced in comparison to the +original versions. + + Code contributions: + • Omar Antolín Camarena (https://github.com/oantolin/) + • Sergey Kostyaev (https://github.com/s-kostyaev/) + • okamsn (https://github.com/okamsn/) + • Clemens Radermacher (https://github.com/clemera/) + • Tom Fitzhenry (https://github.com/tomfitzhenry/) + • jakanakaevangeli (https://github.com/jakanakaevangeli) + • Iñigo Serna (https://hg.serna.eu) + • Adam Spiers (https://github.com/aspiers/) + • Omar Polo (https://github.com/omar-polo) + • Augusto Stoffel (https://github.com/astoff) + • Fox Kiester (https://github.com/noctuid) + • Tecosaur (https://github.com/tecosaur) + • Mohamed Abdelnour (https://github.com/mohamed-abdelnour) + • Sylvain Rousseau (https://github.com/thisirs) + + Advice and useful discussions: + • Clemens Radermacher (https://github.com/clemera/) + • Omar Antolín Camarena (https://github.com/oantolin/) + • Protesilaos Stavrou (https://gitlab.com/protesilaos/) + • Steve Purcell (https://github.com/purcell/) + • Adam Porter (https://github.com/alphapapa/) + • Manuel Uberti (https://github.com/manuel-uberti/) + • Tom Fitzhenry (https://github.com/tomfitzhenry/) + • Howard Melman (https://github.com/hmelman/) + • Stefan Monnier (https://github.com/monnier/) + • Dmitry Gutov (https://github.com/dgutov/) + • Itai Y. Efrat (https://github.com/iyefrat) + • Bruce d’Arcus (https://github.com/bdarcus) + + Authors of supplementary ‘consult-*’ packages: + + • Jose A Ortega Ruiz (https://codeberg.org/jao/) (consult-notmuch + (https://codeberg.org/jao/consult-notmuch), consult-recoll + (https://codeberg.org/jao/consult-recoll), consult-spotify + (https://codeberg.org/jao/espotify)) + • Gerry Agbobada (https://github.com/gagbo/) (consult-lsp + (https://github.com/gagbo/consult-lsp)) + • Karthik Chikmagalur (https://github.com/karthink) (consult-dir + (https://github.com/karthink/consult-dir)) + • Mohsin Kaleem (https://github.com/mohkale) (consult-company + (https://github.com/mohkale/consult-company), consult-eglot + (https://github.com/mohkale/consult-eglot), consult-yasnippet + (https://github.com/mohkale/consult-yasnippet)) + • Marco Pawłowski (https://gitlab.com/OlMon) (consult-projectile + (https://gitlab.com/OlMon/consult-projectile)) + + +File: consult.info, Node: Indices, Prev: Acknowledgments, Up: Top + +9 Indices +********* + +* Menu: + +* Function index:: List of all Consult commands +* Concept index:: List of all Consult-specific concepts + + +File: consult.info, Node: Function index, Next: Concept index, Up: Indices + +9.1 Function index +================== + + +* Menu: + +* consult-apropos: Miscellaneous. (line 6) +* consult-bookmark: Virtual Buffers. (line 6) +* consult-buffer: Virtual Buffers. (line 6) +* consult-buffer-other-frame: Virtual Buffers. (line 6) +* consult-buffer-other-window: Virtual Buffers. (line 6) +* consult-compile-error: Compilation. (line 6) +* consult-completing-read-multiple: Miscellaneous. (line 6) +* consult-completion-in-region: Miscellaneous. (line 6) +* consult-complex-command: Histories. (line 6) +* consult-file-externally: Miscellaneous. (line 6) +* consult-find: Grep and Find. (line 6) +* consult-flycheck: Compilation. (line 6) +* consult-flymake: Compilation. (line 6) +* consult-focus-lines: Search. (line 6) +* consult-git-grep: Grep and Find. (line 6) +* consult-global-mark: Navigation. (line 6) +* consult-goto-line: Navigation. (line 6) +* consult-grep: Grep and Find. (line 6) +* consult-history: Histories. (line 6) +* consult-imenu: Navigation. (line 6) +* consult-imenu-multi: Navigation. (line 6) +* consult-isearch-history: Histories. (line 6) +* consult-keep-lines: Search. (line 6) +* consult-kmacro: Editing. (line 6) +* consult-line: Search. (line 6) +* consult-line-multi: Search. (line 6) +* consult-locate: Grep and Find. (line 6) +* consult-man: Miscellaneous. (line 6) +* consult-mark: Navigation. (line 6) +* consult-minor-mode-menu: Modes. (line 6) +* consult-mode-command: Modes. (line 6) +* consult-multi-occur: Search. (line 6) +* consult-org-agenda: Org Mode. (line 6) +* consult-org-heading: Org Mode. (line 6) +* consult-outline: Navigation. (line 6) +* consult-preview-at-point: Miscellaneous. (line 6) +* consult-preview-at-point-mode: Miscellaneous. (line 6) +* consult-recent-file: Virtual Buffers. (line 6) +* consult-register: Register. (line 6) +* consult-register-format: Register. (line 6) +* consult-register-load: Register. (line 6) +* consult-register-store: Register. (line 6) +* consult-register-window: Register. (line 6) +* consult-ripgrep: Grep and Find. (line 6) +* consult-theme: Miscellaneous. (line 6) +* consult-xref: Compilation. (line 6) +* consult-yank-from-kill-ring: Editing. (line 6) +* consult-yank-pop: Editing. (line 6) +* consult-yank-replace: Editing. (line 6) + + +File: consult.info, Node: Concept index, Prev: Function index, Up: Indices + +9.2 Concept index +================= + + +* Menu: + +* asynchronous search: Asynchronous search. (line 6) +* commands: Available commands. (line 6) +* compilation errors: Compilation. (line 6) +* customization: Custom variables. (line 6) +* editing: Editing. (line 6) +* embark: Embark integration. (line 6) +* find: Grep and Find. (line 6) +* grep: Grep and Find. (line 6) +* history: Histories. (line 6) +* introduction: Introduction. (line 6) +* locate: Grep and Find. (line 6) +* major mode: Modes. (line 6) +* minor mode: Modes. (line 6) +* multiple sources: Multiple sources. (line 6) +* narrowing: Narrowing and grouping. + (line 6) +* navigation: Navigation. (line 6) +* preview: Live previews. (line 6) +* register: Register. (line 6) +* search: Search. (line 6) +* use-package: Use-package example. (line 6) +* virtual buffers: Virtual Buffers. (line 6) + + + +Tag Table: +Node: Top205 +Node: Introduction2603 +Node: Available commands5503 +Node: Virtual Buffers7031 +Node: Editing8479 +Node: Register9333 +Node: Navigation11043 +Node: Search12124 +Node: Grep and Find14015 +Node: Compilation16066 +Node: Histories17012 +Node: Modes18041 +Node: Org Mode18519 +Node: Miscellaneous19034 +Node: Special features22233 +Node: Live previews23360 +Node: Narrowing and grouping26210 +Node: Asynchronous search28211 +Node: Multiple sources31291 +Node: Embark integration37838 +Node: Configuration40040 +Node: Use-package example41178 +Node: Custom variables48131 +Node: Fine-tuning51721 +Node: Recommended packages54284 +Node: Bug reports59261 +Node: Contributions62472 +Node: Acknowledgments63379 +Node: Indices66238 +Node: Function index66474 +Node: Concept index70193 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/consult-0.14/dir b/elpa/consult-0.14/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Consult: (consult). Useful commands built on completing-read. diff --git a/elpa/corfu-0.17.signed b/elpa/corfu-0.17.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2021-12-31T11:05:02+0100 using RSA +\ No newline at end of file diff --git a/elpa/corfu-0.17/LICENSE b/elpa/corfu-0.17/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/elpa/corfu-0.17/README.org b/elpa/corfu-0.17/README.org @@ -0,0 +1,227 @@ +#+title: corfu.el - Completion Overlay Region FUnction +#+author: Daniel Mendler +#+language: en +#+export_file_name: corfu.texi +#+texinfo_dir_category: Emacs +#+texinfo_dir_title: Corfu: (corfu). +#+texinfo_dir_desc: Completion Overlay Region FUnction + +#+html: <a href="https://www.gnu.org/software/emacs/"><img alt="GNU Emacs" src="https://github.com/minad/corfu/blob/screenshots/emacs.svg?raw=true"/></a> +#+html: <a href="http://elpa.gnu.org/packages/corfu.html"><img alt="GNU ELPA" src="https://elpa.gnu.org/packages/corfu.svg"/></a> +#+html: <a href="http://elpa.gnu.org/devel/corfu.html"><img alt="GNU-devel ELPA" src="https://elpa.gnu.org/devel/corfu.svg"/></a> + +* Introduction + + Corfu enhances the default completion in region function with a completion + overlay. The current candidates are shown in a popup below or above the point. + Corfu is the minimalistic ~completion-in-region~ counterpart of the [[https://github.com/minad/vertico][Vertico]] + minibuffer UI. + + Corfu is a minimal package, which relies on the Emacs completion facilities and + concentrates on providing a polished completion UI. Completions are either + provided by commands like ~dabbrev-completion~ or by pluggable backends + (~completion-at-point-functions~, Capfs). Most programming language major modes + implement a Capf. Furthermore the language server packages, [[https://github.com/joaotavora/eglot][Eglot]] and [[https://github.com/emacs-lsp/lsp-mode][Lsp-mode]], + both use Capfs which talk to the LSP server to retrieve the completions. + + Corfu does not include custom completion backends. In contrast, the complex + Company package includes custom completion backends, which deviate from the + Emacs completion infrastructure. The Emacs built-in Capfs are mostly + sufficient, but a few additional Capfs and completion functions are provided + by the [[https://github.com/minad/cape][Cape]] package. + + *NOTE*: Corfu uses child frames to show the popup. For now Corfu falls back to + the default setting of the ~completion-in-region-function~ on non-graphical + displays. You may want to use ~consult-completion-in-region~. + + [[https://github.com/minad/corfu/blob/screenshots/light.png?raw=true]] + + [[https://github.com/minad/corfu/blob/screenshots/dark.png?raw=true]] + +* Features + + - Timer-based auto-completions (/off/ by default, set ~corfu-auto~). + - Popup display with scrollbar indicator and arrow key navigation. + - The popup can be summoned explicitly by pressing =TAB= at any time. + - The current candidate is inserted with =TAB= and selected with =RET=. + - Candidates sorting by prefix, string length and alphabetically. + - The selected candidate is previewed (configuable via ~corfu-preview-current~). + - The selected candidate automatically committed on further input by default + (configurable via ~corfu-commit-predicate~). + - The [[https://github.com/oantolin/orderless][Orderless]] completion style is supported. The filter string can contain + arbitrary characters, including spaces, if ~corfu-quit-at-boundary~ is nil. + - Deferred completion style highlighting for performance. + - Jumping to location/documentation of current candidate. + - Show candidate documentation/signature string in the echo area. + - Deprecated candidates are crossed out in the display. + - Support for annotations (~annotation-function~, ~affixation-function~). + - Icons can be provided by an external package via margin formatter functions. + +* Installation and Configuration + + Corfu is available from [[http://elpa.gnu.org/packages/corfu.html][GNU ELPA]], such that it can be installed directly via + ~package-install~. After installation, the global minor mode can be enabled with + =M-x corfu-global-mode=. In order to configure Corfu and other packages in your + init.el, you may want to use ~use-package~. + + Corfu is highly flexible and customizable via ~corfu-*~ customization variables. + For filtering I recommend to give Orderless completion a try, which is + different from the familiar prefix TAB completion. Corfu can be used with the + default completion styles, the use of Orderless is not a necessity. See also + the [[https://github.com/minad/corfu/wiki][Corfu Wiki]] for additional configuration tips. In particular the Lsp-mode + configuration is documented in the Wiki. + + Here is an example configuration: + + #+begin_src emacs-lisp + (use-package corfu + ;; Optional customizations + ;; :custom + ;; (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + ;; (corfu-auto t) ;; Enable auto completion + ;; (corfu-commit-predicate nil) ;; Do not commit selected candidates on next input + ;; (corfu-quit-at-boundary t) ;; Automatically quit at word boundary + ;; (corfu-quit-no-match t) ;; Automatically quit if there is no match + ;; (corfu-preview-current nil) ;; Disable current candidate preview + ;; (corfu-preselect-first nil) ;; Disable candidate preselection + ;; (corfu-echo-documentation nil) ;; Disable documentation in the echo area + ;; (corfu-scroll-margin 5) ;; Use scroll margin + + ;; You may want to enable Corfu only for certain modes. + ;; :hook ((prog-mode . corfu-mode) + ;; (shell-mode . corfu-mode) + ;; (eshell-mode . corfu-mode)) + + ;; Recommended: Enable Corfu globally. + ;; This is recommended since dabbrev can be used globally (M-/). + :init + (corfu-global-mode)) + + ;; Optionally use the `orderless' completion style. See `+orderless-dispatch' + ;; in the Consult wiki for an advanced Orderless style dispatcher. + ;; Enable `partial-completion' for files to allow path expansion. + ;; You may prefer to use `initials' instead of `partial-completion'. + (use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless) + completion-category-defaults nil + completion-category-overrides '((file (styles . (partial-completion)))))) + + ;; Use dabbrev with Corfu! + (use-package dabbrev + ;; Swap M-/ and C-M-/ + :bind (("M-/" . dabbrev-completion) + ("C-M-/" . dabbrev-expand))) + + ;; A few more useful configurations... + (use-package emacs + :init + ;; TAB cycle if there are only few candidates + (setq completion-cycle-threshold 3) + + ;; Emacs 28: Hide commands in M-x which do not apply to the current mode. + ;; Corfu commands are hidden, since they are not supposed to be used via M-x. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable indentation+completion using the TAB key. + ;; `completion-at-point' is often bound to M-TAB. + (setq tab-always-indent 'complete)) + #+end_src + + See also the [[https://github.com/minad/corfu/wiki][Corfu Wiki]] for additional configuration tips. For more general + documentation read the chapter about completion in the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion.html][Emacs manual]]. If you + want to create your own Capfs, you can find documentation about completion in + the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html][Elisp manual]]. + +** TAB-and-Go completion + +You may be interested in configuring Corfu in TAB-and-Go style. Pressing TAB +moves to the next candidate and further input will then commit the selection. + +#+begin_src emacs-lisp + (use-package corfu + ;; TAB-and-Go customizations + :custom + (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + (corfu-preselect-first nil) ;; Disable candidate preselection + + ;; Use TAB for cycling, default is `corfu-complete'. + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + + :init + (corfu-global-mode)) +#+end_src + +* Key bindings + + Corfu uses a transient keymap ~corfu-map~ which is active while the popup is shown. + The keymap defines the following remappings and bindings: + + - ~beginning-of-buffer~ -> ~corfu-first~ + - ~end-of-buffer~ -> ~corfu-last~ + - ~scroll-down-command~ -> ~corfu-scroll-down~ + - ~scroll-up-command~ -> ~corfu-scroll-up~ + - ~next-line~, =down=, =M-n= -> ~corfu-next~ + - ~previous-line~, =up=, =M-p= -> ~corfu-previous~ + - ~completion-at-point~, =TAB= -> ~corfu-complete~ + - =RET= -> ~corfu-insert~ + - =M-g= -> ~corfu-show-location~ + - =M-h= -> ~corfu-show-documentation~ + - =C-g= -> ~corfu-quit~ + - ~keyboard-escape-quit~ -> ~corfu-reset~ + +* Complementary packages + + Corfu works well together with all packages providing code completion via the + ~completion-at-point-functions~. Many modes and packages already provide a Capf + out of the box. Nevertheless you may want to look into complementary packages + to enhance your setup. + + - [[https://github.com/oantolin/orderless][Orderless]]: Cofu supports completion styles, + including the advanced [[https://github.com/oantolin/orderless][Orderless]] completion style, where the filtering + expressions are separated by spaces (see ~corfu-quit-at-boundary~). + + - [[https://github.com/minad/cape][Cape]]: I collect additional Capf backends and =completion-in-region= commands + in my [[https://github.com/minad/cape][Cape]] package. The package provides a file path, a dabbrev completion + backend and a backend which allows you to enter unicode characters in the + form of TeX commands. Cape provides an adapter to reuse Company backends in + Corfu. Furthermore the function ~cape-super-capf~ can merge/groups multiple + Capfs, such that the candidates of multiple Capfs are displayed together at + the same time. + + - [[https://github.com/jdtsmith/kind-icon][kind-icon]]: Icons are supported by Corfu via an external package. For example + the [[https://github.com/jdtsmith/kind-icon][kind-icon]] package provides beautifully styled SVG icons based on + monochromatic icon sets like material design. + + - [[https://github.com/galeo/corfu-doc][corfu-doc]]: The corfu-doc package by @galeo allows you to display the candidate + documentation in a popup next to the Corfu popup, similar to + =company-quickhelp=. /Note that the corfu-doc package is new and still work in + progress./ + + - [[https://github.com/minad/vertico][Vertico]]: You may also want to look into my [[https://github.com/minad/vertico][Vertico]] package. Vertico is the + minibuffer completion counterpart of Corfu. + +* Caveats + + Corfu is robust in most scenarios. There are a few known technical caveats. + + - Corfu uses child frames to show the popup. For now Corfu falls back to the + default setting of the ~completion-in-region-function~ on non-graphical + displays. You may want to use ~consult-completion-in-region~. + + - Corfu does not sort by history, since ~completion-at-point~ does not + maintain a history (See branch =history= for a possible solution). + +* Contributions + + Since this package is part of [[http://elpa.gnu.org/packages/corfu.html][GNU ELPA]] contributions require a copyright + assignment to the FSF. diff --git a/elpa/corfu-0.17/corfu-autoloads.el b/elpa/corfu-0.17/corfu-autoloads.el @@ -0,0 +1,60 @@ +;;; corfu-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "corfu" "corfu.el" (0 0 0 0)) +;;; Generated autoloads from corfu.el + +(autoload 'corfu-mode "corfu" "\ +Completion Overlay Region FUnction + +If called interactively, enable Corfu mode if ARG is positive, +and disable it if ARG is zero or negative. If called from Lisp, +also enable the mode if ARG is omitted or nil, and toggle it if +ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(put 'corfu-global-mode 'globalized-minor-mode t) + +(defvar corfu-global-mode nil "\ +Non-nil if Corfu-Global mode is enabled. +See the `corfu-global-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `corfu-global-mode'.") + +(custom-autoload 'corfu-global-mode "corfu" nil) + +(autoload 'corfu-global-mode "corfu" "\ +Toggle Corfu mode in all buffers. +With prefix ARG, enable Corfu-Global mode if ARG is positive; +otherwise, disable it. If called from Lisp, enable the mode if +ARG is omitted or nil. + +Corfu mode is enabled in all buffers where +`corfu--on' would do it. +See `corfu-mode' for more information on Corfu mode. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "corfu" '("corfu-"))) + +;;;*** + +;;;### (autoloads nil nil ("corfu-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; corfu-autoloads.el ends here diff --git a/elpa/corfu-0.17/corfu-pkg.el b/elpa/corfu-0.17/corfu-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from corfu.el -*- no-byte-compile: t -*- +(define-package "corfu" "0.17" "Completion Overlay Region FUnction" '((emacs "27.1")) :authors '(("Daniel Mendler" . "mail@daniel-mendler.de")) :maintainer '("Daniel Mendler" . "mail@daniel-mendler.de") :url "https://github.com/minad/corfu") diff --git a/elpa/corfu-0.17/corfu.el b/elpa/corfu-0.17/corfu.el @@ -0,0 +1,1214 @@ +;;; corfu.el --- Completion Overlay Region FUnction -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.17 +;; Package-Requires: ((emacs "27.1")) +;; Homepage: https://github.com/minad/corfu + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Corfu enhances the default completion in region function with a +;; completion overlay. The current candidates are shown in a popup +;; below or above the point. Corfu can be considered the minimalistic +;; completion-in-region counterpart of Vertico. + +;;; Code: + +(require 'seq) +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) + +(defgroup corfu nil + "Completion Overlay Region FUnction." + :group 'convenience + :prefix "corfu-") + +(defcustom corfu-count 10 + "Maximal number of candidates to show." + :type 'integer) + +(defcustom corfu-scroll-margin 2 + "Number of lines at the top and bottom when scrolling. +The value should lie between 0 and corfu-count/2." + :type 'integer) + +(defcustom corfu-min-width 15 + "Popup minimum width in characters." + :type 'integer) + +(defcustom corfu-max-width 100 + "Popup maximum width in characters." + :type 'integer) + +(defcustom corfu-cycle nil + "Enable cycling for `corfu-next' and `corfu-previous'." + :type 'boolean) + +(defcustom corfu-continue-commands + ;; nil is undefined command + '(nil ignore completion-at-point universal-argument universal-argument-more digit-argument + "\\`corfu-" "\\`scroll-other-window") + "Continue Corfu completion after executing these commands." + :type '(repeat (choice regexp symbol))) + +(defcustom corfu-commit-predicate #'corfu-candidate-previewed-p + "Automatically commit if the predicate returns t." + :type '(choice (const nil) function)) + +(defcustom corfu-preview-current t + "Preview currently selected candidate." + :type 'boolean) + +(defcustom corfu-preselect-first t + "Preselect first candidate." + :type 'boolean) + +(defcustom corfu-quit-at-boundary nil + "Automatically quit at completion field/word boundary. +If automatic quitting is disabled, Orderless filter strings with spaces +are allowed." + :type 'boolean) + +(defcustom corfu-quit-no-match 1.0 + "Automatically quit if no matching candidate is found. +If a floating point number, quit on no match only if the auto-started +completion began less than that number of seconds ago." + :type '(choice boolean float)) + +(defcustom corfu-excluded-modes nil + "List of modes excluded by `corfu-global-mode'." + :type '(repeat symbol)) + +(defcustom corfu-left-margin-width 0.5 + "Width of the left margin in units of the character width." + :type 'float) + +(defcustom corfu-right-margin-width 0.5 + "Width of the right margin in units of the character width." + :type 'float) + +(defcustom corfu-bar-width 0.2 + "Width of the bar in units of the character width." + :type 'float) + +(defcustom corfu-echo-documentation 0.5 + "Show documentation string in the echo area after that number of seconds." + :type '(choice boolean float)) + +(defcustom corfu-margin-formatters nil + "Registry for margin formatter functions. +Each function of the list is called with the completion metadata as +argument until an appropriate formatter is found. The function should +return a formatter function, which takes the candidate string and must +return a string, possibly an icon." + :type 'hook) + +(defcustom corfu-sort-function #'corfu-sort-length-alpha + "Default sorting function, used if no `display-sort-function' is specified." + :type `(choice + (const :tag "No sorting" nil) + (const :tag "By length and alpha" ,#'corfu-sort-length-alpha) + (function :tag "Custom function"))) + +(defcustom corfu-auto-prefix 3 + "Minimum length of prefix for auto completion. +The completion backend can override this with +:company-prefix-length." + :type 'integer) + +(defcustom corfu-auto-delay 0.2 + "Delay for auto completion." + :type 'float) + +(defcustom corfu-auto-commands + '("self-insert-command\\'" + c-electric-colon c-electric-lt-gt c-electric-slash c-scope-operator) + "Commands which initiate auto completion." + :type '(repeat (choice regexp symbol))) + +(defcustom corfu-auto nil + "Enable auto completion." + :type 'boolean) + +(defgroup corfu-faces nil + "Faces used by Corfu." + :group 'corfu + :group 'faces) + +(defface corfu-default + '((((class color) (min-colors 88) (background dark)) :background "#191a1b") + (((class color) (min-colors 88) (background light)) :background "#f0f0f0") + (t :background "gray")) + "Default face used for the popup, in particular the background and foreground color.") + +(defface corfu-current + '((((class color) (min-colors 88) (background dark)) + :background "#00415e" :foreground "white") + (((class color) (min-colors 88) (background light)) + :background "#c0efff" :foreground "black") + (t :background "blue" :foreground "white")) + "Face used to highlight the currently selected candidate.") + +(defface corfu-bar + '((((class color) (min-colors 88) (background dark)) :background "#a8a8a8") + (((class color) (min-colors 88) (background light)) :background "#505050") + (t :background "gray")) + "The background color is used for the scrollbar indicator.") + +(defface corfu-border + '((((class color) (min-colors 88) (background dark)) :background "#323232") + (((class color) (min-colors 88) (background light)) :background "#d7d7d7") + (t :background "gray")) + "The background color used for the thin border.") + +(defface corfu-echo + '((t :inherit completions-annotations)) + "Face used for echo area messages.") + +(defface corfu-annotations + '((t :inherit completions-annotations)) + "Face used for annotations.") + +(defface corfu-deprecated + '((t :inherit shadow :strike-through t)) + "Face used for deprecated candidates.") + +(defvar corfu-map + (let ((map (make-sparse-keymap))) + (define-key map [remap beginning-of-buffer] #'corfu-first) + (define-key map [remap end-of-buffer] #'corfu-last) + (define-key map [remap scroll-down-command] #'corfu-scroll-down) + (define-key map [remap scroll-up-command] #'corfu-scroll-up) + (define-key map [remap next-line] #'corfu-next) + (define-key map [remap previous-line] #'corfu-previous) + (define-key map [remap completion-at-point] #'corfu-complete) + (define-key map [down] #'corfu-next) + (define-key map [up] #'corfu-previous) + (define-key map [remap keyboard-escape-quit] #'corfu-reset) + ;; XXX [tab] is bound because of org-mode + ;; The binding should be removed from org-mode-map. + (define-key map [tab] #'corfu-complete) + (define-key map "\en" #'corfu-next) + (define-key map "\ep" #'corfu-previous) + (define-key map "\C-g" #'corfu-quit) + (define-key map "\r" #'corfu-insert) + (define-key map "\t" #'corfu-complete) + (define-key map "\eg" #'corfu-show-location) + (define-key map "\eh" #'corfu-show-documentation) + map) + "Corfu keymap used when popup is shown.") + +(defvar corfu--auto-timer nil + "Auto completion timer.") + +(defvar-local corfu--candidates nil + "List of candidates.") + +(defvar-local corfu--metadata nil + "Completion metadata.") + +(defvar-local corfu--base 0 + "Size of the base string, which is concatenated with the candidate.") + +(defvar-local corfu--total 0 + "Length of the candidate list `corfu--candidates'.") + +(defvar-local corfu--highlight #'identity + "Deferred candidate highlighting function.") + +(defvar-local corfu--index -1 + "Index of current candidate or negative for prompt selection.") + +(defvar-local corfu--preselect -1 + "Index of preselected candidate, negative for prompt selection.") + +(defvar-local corfu--scroll 0 + "Scroll position.") + +(defvar-local corfu--input nil + "Cons of last prompt contents and point or t.") + +(defvar-local corfu--preview-ov nil + "Current candidate overlay.") + +(defvar-local corfu--extra nil + "Extra completion properties.") + +(defvar-local corfu--change-group nil + "Undo change group.") + +(defvar-local corfu--auto-start nil + "Auto completion start time.") + +(defvar-local corfu--echo-timer nil + "Echo area message timer.") + +(defvar-local corfu--echo-message nil + "Last echo message.") + +(defvar corfu--frame nil + "Popup frame.") + +(defconst corfu--state-vars + '(corfu--base + corfu--candidates + corfu--highlight + corfu--index + corfu--preselect + corfu--scroll + corfu--input + corfu--total + corfu--preview-ov + corfu--extra + corfu--auto-start + corfu--echo-timer + corfu--echo-message + corfu--change-group + corfu--metadata) + "Buffer-local state variables used by Corfu.") + +(defvar corfu--frame-parameters + '((no-accept-focus . t) + (no-focus-on-map . t) + (min-width . t) + (min-height . t) + (width . 0) + (height . 0) + (border-width . 0) + (child-frame-border-width . 1) + (left-fringe . 0) + (right-fringe . 0) + (vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil) + (menu-bar-lines . 0) + (tool-bar-lines . 0) + (tab-bar-lines . 0) + (no-other-frame . t) + (no-other-window . t) + (no-delete-other-windows . t) + (unsplittable . t) + (undecorated . t) + (cursor-type . nil) + (visibility . nil) + (no-special-glyphs . t) + (desktop-dont-save . t)) + "Default child frame parameters.") + +(defvar corfu--buffer-parameters + '((mode-line-format . nil) + (header-line-format . nil) + (tab-line-format . nil) + (tab-bar-format . nil) ;; Emacs 28 tab-bar-format + (frame-title-format . "") + (truncate-lines . t) + (cursor-in-non-selected-windows . nil) + (cursor-type . nil) + (show-trailing-whitespace . nil) + (display-line-numbers . nil) + (left-fringe-width . nil) + (right-fringe-width . nil) + (left-margin-width . 0) + (right-margin-width . 0) + (fringes-outside-margins . 0) + (buffer-read-only . t)) + "Default child frame buffer parameters.") + +(defvar corfu--mouse-ignore-map + (let ((map (make-sparse-keymap))) + (dotimes (i 7) + (dolist (k '(mouse down-mouse drag-mouse double-mouse triple-mouse)) + (define-key map (vector (intern (format "%s-%s" k (1+ i)))) #'ignore))) + map) + "Ignore all mouse clicks.") + +(defun corfu--popup-redirect-focus () + "Redirect focus from popup." + (redirect-frame-focus corfu--frame (frame-parent corfu--frame))) + +(defun corfu--make-buffer (content) + "Create corfu buffer with CONTENT." + (let ((fr face-remapping-alist) + (buffer (get-buffer-create " *corfu*"))) + (with-current-buffer buffer + ;;; XXX HACK install redirect focus hook + (add-hook 'pre-command-hook #'corfu--popup-redirect-focus nil 'local) + ;;; XXX HACK install mouse ignore map + (use-local-map corfu--mouse-ignore-map) + (dolist (var corfu--buffer-parameters) + (set (make-local-variable (car var)) (cdr var))) + (setq-local face-remapping-alist (copy-tree fr)) + (cl-pushnew 'corfu-default (alist-get 'default face-remapping-alist)) + (let ((inhibit-modification-hooks t) + (inhibit-read-only t)) + (erase-buffer) + (insert content) + (goto-char (point-min)))) + buffer)) + +;; Function adapted from posframe.el by tumashu +(defun corfu--make-frame (x y width height content) + "Show child frame at X/Y with WIDTH/HEIGHT and CONTENT." + (let* ((window-min-height 1) + (window-min-width 1) + (x-gtk-resize-child-frames + (let ((case-fold-search t)) + (and + ;; XXX HACK to fix resizing on gtk3/gnome taken from posframe.el + ;; More information: + ;; * https://github.com/minad/corfu/issues/17 + ;; * https://gitlab.gnome.org/GNOME/mutter/-/issues/840 + ;; * https://lists.gnu.org/archive/html/emacs-devel/2020-02/msg00001.html + (string-match-p "gtk3" system-configuration-features) + (string-match-p "gnome\\|cinnamon" (or (getenv "XDG_CURRENT_DESKTOP") + (getenv "DESKTOP_SESSION") "")) + 'resize-mode))) + (after-make-frame-functions) + (edge (window-inside-pixel-edges)) + (lh (default-line-height)) + (border (alist-get 'child-frame-border-width corfu--frame-parameters)) + (x (max border (min (+ (car edge) x (- border)) + (- (frame-pixel-width) width)))) + (yb (+ (cadr edge) (window-tab-line-height) y lh)) + (y (if (> (+ yb height lh lh) (frame-pixel-height)) + (- yb height lh 1) + yb)) + (buffer (corfu--make-buffer content))) + (unless (and (frame-live-p corfu--frame) + (eq (frame-parent corfu--frame) (window-frame))) + (when corfu--frame (delete-frame corfu--frame)) + (setq corfu--frame (make-frame + `((parent-frame . ,(window-frame)) + (minibuffer . ,(minibuffer-window (window-frame))) + (line-spacing . ,line-spacing) + ;; Set `internal-border-width' for Emacs 27 + (internal-border-width . ,border) + ,@corfu--frame-parameters)))) + ;; XXX HACK Setting the same frame-parameter/face-background is not a nop (BUG!). + ;; Check explicitly before applying the setting. + ;; Without the check, the frame flickers on Mac. + ;; XXX HACK We have to apply the face background before adjusting the frame parameter, + ;; otherwise the border is not updated (BUG!). + (let* ((face (if (facep 'child-frame-border) 'child-frame-border 'internal-border)) + (new (face-attribute 'corfu-border :background nil 'default))) + (unless (equal (face-attribute face :background corfu--frame 'default) new) + (set-face-background face new corfu--frame))) + (let ((new (face-attribute 'corfu-default :background nil 'default))) + (unless (equal (frame-parameter corfu--frame 'background-color) new) + (set-frame-parameter corfu--frame 'background-color new))) + (let ((win (frame-root-window corfu--frame))) + (set-window-buffer win buffer) + ;; Mark window as dedicated to prevent frame reuse (#60) + (set-window-dedicated-p win t)) + ;; XXX HACK Make the frame invisible before moving the popup in order to avoid flicker. + (unless (eq (cdr (frame-position corfu--frame)) y) + (make-frame-invisible corfu--frame)) + (set-frame-position corfu--frame x y) + (set-frame-size corfu--frame width height t) + (make-frame-visible corfu--frame))) + +(defun corfu--popup-show (pos off width lines &optional curr lo bar) + "Show LINES as popup at POS - OFF. +WIDTH is the width of the popup. +The current candidate CURR is highlighted. +A scroll bar is displayed from LO to LO+BAR." + (let* ((ch (default-line-height)) + (cw (default-font-width)) + (lm (ceiling (* cw corfu-left-margin-width))) + (rm (ceiling (* cw corfu-right-margin-width))) + (bw (ceiling (min rm (* cw corfu-bar-width)))) + (lmargin (and (> lm 0) (propertize " " 'display `(space :width (,lm))))) + (rmargin (and (> rm 0) (propertize " " 'display `(space :align-to right)))) + (sbar (when (> bw 0) + (concat (propertize " " 'display `(space :align-to (- right (,rm)))) + (propertize " " 'display `(space :width (,(- rm bw)))) + (propertize " " 'face 'corfu-bar 'display `(space :width (,bw)))))) + (row 0) + (pos (posn-x-y (posn-at-point pos))) + (x (or (car pos) 0)) + (y (or (cdr pos) 0))) + (corfu--make-frame + (- x lm (* cw off)) y + (+ (* width cw) lm rm) (* (length lines) ch) + (mapconcat (lambda (line) + (let ((str (concat lmargin line + (if (and lo (<= lo row (+ lo bar))) sbar rmargin)))) + (when (eq row curr) + (add-face-text-property + 0 (length str) 'corfu-current 'append str)) + (setq row (1+ row)) + str)) + lines "\n")))) + +(defun corfu--popup-hide () + "Hide Corfu popup." + (when (frame-live-p corfu--frame) + (make-frame-invisible corfu--frame) + (with-current-buffer (window-buffer (frame-root-window corfu--frame)) + (let ((inhibit-read-only t)) + (erase-buffer))))) + +(defun corfu--move-to-front (elem list) + "Move ELEM to front of LIST." + (if-let (found (member elem list)) + (let ((head (list (car found)))) + (nconc head (delq (setcar found nil) list))) + list)) + +;; bug#47711: Deferred highlighting for `completion-all-completions' +;; XXX There is one complication: `completion--twq-all' already adds `completions-common-part'. +(defun corfu--all-completions (&rest args) + "Compute all completions for ARGS with deferred highlighting." + (cl-letf* ((orig-pcm (symbol-function #'completion-pcm--hilit-commonality)) + (orig-flex (symbol-function #'completion-flex-all-completions)) + ((symbol-function #'completion-flex-all-completions) + (lambda (&rest args) + ;; Unfortunately for flex we have to undo the deferred highlighting, since flex uses + ;; the completion-score for sorting, which is applied during highlighting. + (cl-letf (((symbol-function #'completion-pcm--hilit-commonality) orig-pcm)) + (apply orig-flex args)))) + ;; Defer the following highlighting functions + (hl #'identity) + ((symbol-function #'completion-hilit-commonality) + (lambda (cands prefix &optional base) + (setq hl (lambda (x) (nconc (completion-hilit-commonality x prefix base) nil))) + (and cands (nconc cands base)))) + ((symbol-function #'completion-pcm--hilit-commonality) + (lambda (pattern cands) + (setq hl (lambda (x) + ;; `completion-pcm--hilit-commonality' sometimes throws an internal error + ;; for example when entering "/sudo:://u". + (condition-case nil + (completion-pcm--hilit-commonality pattern x) + (t x)))) + cands))) + ;; Only advise orderless after it has been loaded to avoid load order issues + (if (and (fboundp 'orderless-highlight-matches) (fboundp 'orderless-pattern-compiler)) + (cl-letf (((symbol-function 'orderless-highlight-matches) + (lambda (pattern cands) + (let ((regexps (orderless-pattern-compiler pattern))) + (setq hl (lambda (x) (orderless-highlight-matches regexps x)))) + cands))) + (cons (apply #'completion-all-completions args) hl)) + (cons (apply #'completion-all-completions args) hl)))) + +(defun corfu--sort-predicate (x y) + "Sorting predicate which compares X and Y." + (or (< (length x) (length y)) (and (= (length x) (length y)) (string< x y)))) + +(defun corfu-sort-length-alpha (list) + "Sort LIST by length and alphabetically." + (sort list #'corfu--sort-predicate)) + +(defmacro corfu--partition! (list form) + "Evaluate FORM for every element and partition LIST." + (let ((head1 (make-symbol "head1")) + (head2 (make-symbol "head2")) + (tail1 (make-symbol "tail1")) + (tail2 (make-symbol "tail2"))) + `(let* ((,head1 (cons nil nil)) + (,head2 (cons nil nil)) + (,tail1 ,head1) + (,tail2 ,head2)) + (while ,list + (if (let ((it (car ,list))) ,form) + (progn + (setcdr ,tail1 ,list) + (pop ,tail1)) + (setcdr ,tail2 ,list) + (pop ,tail2)) + (pop ,list)) + (setcdr ,tail1 (cdr ,head2)) + (setcdr ,tail2 nil) + (setq ,list (cdr ,head1))))) + +(defun corfu--move-prefix-candidates-to-front (field candidates) + "Move CANDIDATES which match prefix of FIELD to the beginning." + (let* ((word (replace-regexp-in-string " .*" "" field)) + (len (length word))) + (corfu--partition! candidates + (and (>= (length it) len) + (eq t (compare-strings word 0 len it 0 len)))))) + +(defun corfu--filter-files (files) + "Filter FILES by `completion-ignored-extensions'." + (let ((re (concat "\\(?:\\(?:\\`\\|/\\)\\.\\.?/\\|" + (regexp-opt completion-ignored-extensions) + "\\)\\'"))) + (or (seq-remove (lambda (x) (string-match-p re x)) files) files))) + +(defun corfu--sort-function () + "Return the sorting function." + (or (corfu--metadata-get 'display-sort-function) corfu-sort-function)) + +(defun corfu--recompute-candidates (str pt table pred) + "Recompute candidates from STR, PT, TABLE and PRED." + (pcase-let* ((before (substring str 0 pt)) + (after (substring str pt)) + (corfu--metadata (completion-metadata before table pred)) + ;; bug#47678: `completion-boundaries` fails for `partial-completion` + ;; if the cursor is moved between the slashes of "~//". + ;; See also vertico.el which has the same issue. + (bounds (or (condition-case nil + (completion-boundaries before table pred after) + (t (cons 0 (length after)))))) + (field (substring str (car bounds) (+ pt (cdr bounds)))) + (completing-file (eq (corfu--metadata-get 'category) 'file)) + (`(,all . ,hl) (corfu--all-completions str table pred pt corfu--metadata)) + (base (or (when-let (z (last all)) (prog1 (cdr z) (setcdr z nil))) 0))) + ;; Filter the ignored file extensions. We cannot use modified predicate for this filtering, + ;; since this breaks the special casing in the `completion-file-name-table' for `file-exists-p' + ;; and `file-directory-p'. + (when completing-file (setq all (corfu--filter-files all))) + (setq all (delete-consecutive-dups (funcall (or (corfu--sort-function) #'identity) all))) + (setq all (corfu--move-prefix-candidates-to-front field all)) + (when (and completing-file (not (string-suffix-p "/" field))) + (setq all (corfu--move-to-front (concat field "/") all))) + (setq all (corfu--move-to-front field all)) + (list base all (length all) hl corfu--metadata + ;; Select the prompt when the input is a valid completion + ;; and if it is not equal to the first candidate. + (if (or (not corfu-preselect-first) (not all) + (and (not (equal field (car all))) + (not (and completing-file (equal (concat field "/") (car all)))) + (test-completion str table pred))) + -1 0)))) + +(defun corfu--update-candidates (str pt table pred) + "Update candidates from STR, PT, TABLE and PRED." + ;; Redisplay such that the input becomes immediately visible before the + ;; expensive candidate recomputation is performed (Issue #48). See also + ;; corresponding vertico#89. + (redisplay) + (pcase (while-no-input (corfu--recompute-candidates str pt table pred)) + ('nil (keyboard-quit)) + (`(,base ,candidates ,total ,hl ,metadata ,preselect) + (setq corfu--input (cons str pt) + corfu--candidates candidates + corfu--base base + corfu--total total + corfu--preselect preselect + corfu--index preselect + corfu--highlight hl + corfu--metadata metadata)))) + +(defun corfu--match-symbol-p (pattern sym) + "Return non-nil if SYM is matching an element of the PATTERN list." + (and (symbolp sym) + (cl-loop for x in pattern + thereis (if (symbolp x) + (eq sym x) + (string-match-p x (symbol-name sym)))))) + +(defun corfu-quit () + "Quit Corfu completion." + (interactive) + (completion-in-region-mode -1)) + +(defun corfu-reset () + "Reset Corfu completion. +This command can be executed multiple times by hammering the ESC key. If a +candidate is selected, unselect the candidate. Otherwise reset the input. If +there hasn't been any input, then quit." + (interactive) + (if (/= corfu--index corfu--preselect) + (progn + (corfu--goto -1) + (setq this-command #'corfu-first)) + ;; Cancel all changes and start new change group. + (cancel-change-group corfu--change-group) + (activate-change-group (setq corfu--change-group (prepare-change-group))) + (when (eq last-command #'corfu-reset) (corfu-quit)))) + +(defun corfu--affixate (cands) + "Annotate CANDS with annotation function." + (setq cands + (if-let (aff (or (corfu--metadata-get 'affixation-function) + (plist-get corfu--extra :affixation-function))) + (funcall aff cands) + (if-let (ann (or (corfu--metadata-get 'annotation-function) + (plist-get corfu--extra :annotation-function))) + (cl-loop for cand in cands collect + (let ((suffix (or (funcall ann cand) ""))) + (list cand "" + ;; The default completion UI adds the `completions-annotations' face + ;; if no other faces are present. We use a custom `corfu-annotations' + ;; face to allow further styling which fits better for popups. + (if (text-property-not-all 0 (length suffix) 'face nil suffix) + suffix + (propertize suffix 'face 'corfu-annotations))))) + (cl-loop for cand in cands collect (list cand "" ""))))) + (let* ((dep (plist-get corfu--extra :company-deprecated)) + (completion-extra-properties corfu--extra) + (mf (run-hook-with-args-until-success 'corfu-margin-formatters corfu--metadata))) + (cl-loop for x in cands for (c . _) = x do + (when mf + (setf (cadr x) (funcall mf c))) + (when (and dep (funcall dep c)) + (setcar x (setq c (substring c))) + (add-face-text-property 0 (length c) 'corfu-deprecated 'append c))) + (cons mf cands))) + +(defun corfu--metadata-get (prop) + "Return PROP from completion metadata." + ;; Note: Do not use `completion-metadata-get' in order to avoid Marginalia. + ;; The Marginalia annotators are too heavy for the Corfu popup! + (cdr (assq prop corfu--metadata))) + +(defun corfu--format-candidates (cands) + "Format annotated CANDS." + (setq cands + (cl-loop for c in cands collect + (cl-loop for s in c collect + (replace-regexp-in-string "[ \t]*\n[ \t]*" " " s)))) + (let* ((cw (cl-loop for x in cands maximize (string-width (car x)))) + (pw (cl-loop for x in cands maximize (string-width (cadr x)))) + (sw (cl-loop for x in cands maximize (string-width (caddr x)))) + (width (+ pw cw sw))) + (when (< width corfu-min-width) + (setq cw (+ cw (- corfu-min-width width)) + width corfu-min-width)) + ;; -4 because of margins and some additional safety + (setq width (min width corfu-max-width (- (frame-width) 4))) + (list pw width + (cl-loop for (cand prefix suffix) in cands collect + (truncate-string-to-width + (concat prefix + (make-string (- pw (string-width prefix)) ?\s) + cand + (when (/= sw 0) + (make-string (+ (- cw (string-width cand)) + (- sw (string-width suffix))) + ?\s)) + suffix) + width))))) + +(defun corfu--update-scroll () + "Update scroll position." + (let ((off (max (min corfu-scroll-margin (/ corfu-count 2)) 0)) + (corr (if (= corfu-scroll-margin (/ corfu-count 2)) (1- (mod corfu-count 2)) 0))) + (setq corfu--scroll (min (max 0 (- corfu--total corfu-count)) + (max 0 (+ corfu--index off 1 (- corfu-count)) + (min (- corfu--index off corr) corfu--scroll)))))) + +(defun corfu--candidates-popup (pos) + "Show candidates popup at POS." + (corfu--update-scroll) + (pcase-let* ((last (min (+ corfu--scroll corfu-count) corfu--total)) + (bar (ceiling (* corfu-count corfu-count) corfu--total)) + (lo (min (- corfu-count bar 1) (floor (* corfu-count corfu--scroll) corfu--total))) + (`(,mf . ,acands) (corfu--affixate (funcall corfu--highlight + (seq-subseq corfu--candidates corfu--scroll last)))) + (`(,pw ,width ,fcands) (corfu--format-candidates acands)) + ;; Disable the left margin if a margin formatter is active. + (corfu-left-margin-width (if mf 0 corfu-left-margin-width))) + ;; Nonlinearity at the end and the beginning + (when (/= corfu--scroll 0) + (setq lo (max 1 lo))) + (when (/= last corfu--total) + (setq lo (min (- corfu-count bar 2) lo))) + (corfu--popup-show (+ pos corfu--base) pw width fcands (- corfu--index corfu--scroll) + (and (> corfu--total corfu-count) lo) bar))) + +(defun corfu--preview-current (beg end str) + "Show current candidate as overlay given BEG, END and STR." + (when-let (cand (and corfu-preview-current (>= corfu--index 0) + (/= corfu--index corfu--preselect) + (nth corfu--index corfu--candidates))) + (setq corfu--preview-ov (make-overlay beg end nil t t)) + (overlay-put corfu--preview-ov 'priority 1000) + (overlay-put corfu--preview-ov 'window (selected-window)) + (overlay-put corfu--preview-ov + (if (= beg end) 'after-string 'display) + (concat (substring str 0 corfu--base) cand)))) + +(defun corfu--echo-refresh () + "Refresh echo message to prevent flicker during redisplay." + (when corfu--echo-timer + (cancel-timer corfu--echo-timer) + (setq corfu--echo-timer nil)) + (when corfu--echo-message + (corfu--echo-show corfu--echo-message))) + +(defun corfu--echo-show (msg) + "Show MSG in echo area." + (let ((message-log-max nil)) + (setq corfu--echo-message msg) + (message "%s" (if (text-property-not-all 0 (length msg) 'face nil msg) + msg + (propertize msg 'face 'corfu-echo))))) + +(defun corfu--echo-documentation () + "Show documentation string of current candidate in echo area." + (when corfu-echo-documentation + (if-let* ((fun (plist-get corfu--extra :company-docsig)) + (cand (and (>= corfu--index 0) (nth corfu--index corfu--candidates))) + (doc (funcall fun cand))) + (if (or (eq corfu-echo-documentation t) corfu--echo-message) + (corfu--echo-show doc) + (setq corfu--echo-timer (run-at-time corfu-echo-documentation + nil #'corfu--echo-show doc))) + (when corfu--echo-message + (corfu--echo-show ""))))) + +(defun corfu--update () + "Refresh Corfu UI." + (pcase-let* ((`(,beg ,end ,table ,pred) completion-in-region--data) + (pt (- (point) beg)) + (str (buffer-substring-no-properties beg end)) + (initializing (not corfu--input)) + (continue (or (/= beg end) + (corfu--match-symbol-p corfu-continue-commands + this-command)))) + (corfu--echo-refresh) + (cond + ;; XXX Guard against errors during candidate generation. + ;; Turn off completion immediately if there are errors + ;; For example dabbrev throws error "No dynamic expansion ... found". + ;; TODO Report this as a bug? Are completion tables supposed to throw errors? + ((condition-case err + ;; Only recompute when input changed and when input is non-empty + (when (and continue (not (equal corfu--input (cons str pt)))) + (corfu--update-candidates str pt table pred) + nil) + (error (corfu-quit) + (message "Corfu completion error: %s" (error-message-string err))))) + ;; 1) Initializing, no candidates => Quit + ((and initializing (not corfu--candidates)) + (corfu-quit)) + ;; 2) Single matching candidate and no further completion is possible + ((and (not (equal str "")) + (equal corfu--candidates (list str)) + (not (consp (completion-try-completion str table pred pt corfu--metadata)))) + (corfu--done str (if initializing 'exact 'finished))) + ;; 3) There exist candidates + ;; & Input is non-empty or continue command + ;; => Show candidates popup + ((and corfu--candidates continue) + (corfu--candidates-popup beg) + (corfu--echo-documentation) + (corfu--preview-current beg end str)) + ;; 4) There are no candidates & corfu-quit-no-match => Confirmation popup + ((not (or corfu--candidates + ;; When `corfu-quit-no-match' is a number of seconds and the auto completion wasn't + ;; initiated too long ago, quit directly without showing the "No match" popup. + (if (and corfu--auto-start (numberp corfu-quit-no-match)) + (< (- (float-time) corfu--auto-start) corfu-quit-no-match) + (eq t corfu-quit-no-match)))) + (corfu--popup-show beg 0 8 '(#("No match" 0 8 (face italic))))) + (t (corfu-quit))))) + +(defun corfu--pre-command () + "Insert selected candidate unless command is marked to continue completion." + (add-hook 'window-configuration-change-hook #'corfu-quit) + (when corfu--preview-ov + (delete-overlay corfu--preview-ov) + (setq corfu--preview-ov nil)) + (when (and corfu-commit-predicate + (not (corfu--match-symbol-p corfu-continue-commands this-command)) + (funcall corfu-commit-predicate)) + (corfu--insert 'exact))) + +(defun corfu-candidate-previewed-p () + "Return t if a candidate is selected and previewed." + (and corfu-preview-current (/= corfu--index corfu--preselect))) + +(defun corfu--post-command () + "Refresh Corfu after last command." + (remove-hook 'window-configuration-change-hook #'corfu-quit) + (or (pcase completion-in-region--data + (`(,beg ,end . ,_) + (when (let ((pt (point))) + (and (eq (marker-buffer beg) (current-buffer)) + (<= beg pt end) + (save-excursion + (goto-char beg) + (<= (line-beginning-position) pt (line-end-position))) + (or (not corfu-quit-at-boundary) + (funcall completion-in-region-mode--predicate)))) + (corfu--update) + t))) + (corfu-quit))) + +(defun corfu--goto (index) + "Go to candidate with INDEX." + (setq corfu--index (max corfu--preselect (min index (1- corfu--total))) + ;; Reset auto start in order to disable the `corfu-quit-no-match' timer + corfu--auto-start nil)) + +(defun corfu-next (&optional n) + "Go forward N candidates." + (interactive "p") + (let ((index (+ corfu--index (or n 1)))) + (corfu--goto + (cond + ((not corfu-cycle) index) + ((= corfu--total 0) -1) + ((< corfu--preselect 0) (1- (mod (1+ index) (1+ corfu--total)))) + (t (mod index corfu--total)))))) + +(defun corfu-previous (&optional n) + "Go backward N candidates." + (interactive "p") + (corfu-next (- (or n 1)))) + +(defun corfu-scroll-down (&optional n) + "Go back by N pages." + (interactive "p") + (corfu--goto (max 0 (- corfu--index (* (or n 1) corfu-count))))) + +(defun corfu-scroll-up (&optional n) + "Go forward by N pages." + (interactive "p") + (corfu-scroll-down (- (or n 1)))) + +(defun corfu-first () + "Go to first candidate, or to the prompt when the first candidate is selected." + (interactive) + (corfu--goto (if (> corfu--index 0) 0 -1))) + +(defun corfu-last () + "Go to last candidate." + (interactive) + (corfu--goto (1- corfu--total))) + +(defun corfu--restore-on-next-command () + "Restore window configuration before next command." + (let ((config (current-window-configuration)) + (other other-window-scroll-buffer) + (restore (make-symbol "corfu--restore"))) + (fset restore + (lambda () + (setq other-window-scroll-buffer other) + (unless (memq this-command '(scroll-other-window scroll-other-window-down)) + (when (memq this-command '(corfu-quit corfu-reset)) + (setq this-command #'ignore)) + (remove-hook 'pre-command-hook restore) + (set-window-configuration config)))) + (add-hook 'pre-command-hook restore))) + +;; Company support, taken from `company.el', see `company-show-doc-buffer'. +(defun corfu-show-documentation () + "Show documentation of current candidate." + (interactive) + (when (< corfu--index 0) + (user-error "No candidate selected")) + (if-let* ((fun (plist-get corfu--extra :company-doc-buffer)) + (res (funcall fun (nth corfu--index corfu--candidates)))) + (let ((buf (or (car-safe res) res))) + (corfu--restore-on-next-command) + (setq other-window-scroll-buffer (get-buffer buf)) + (set-window-start (display-buffer buf t) (or (cdr-safe res) (point-min)))) + (user-error "No documentation available"))) + +;; Company support, taken from `company.el', see `company-show-location'. +(defun corfu-show-location () + "Show location of current candidate." + (interactive) + (when (< corfu--index 0) + (user-error "No candidate selected")) + (if-let* ((fun (plist-get corfu--extra :company-location)) + (loc (funcall fun (nth corfu--index corfu--candidates)))) + (let ((buf (or (and (bufferp (car loc)) (car loc)) (find-file-noselect (car loc) t)))) + (corfu--restore-on-next-command) + (setq other-window-scroll-buffer buf) + (with-selected-window (display-buffer buf t) + (save-restriction + (widen) + (if (bufferp (car loc)) + (goto-char (cdr loc)) + (goto-char (point-min)) + (forward-line (1- (cdr loc)))) + (set-window-start nil (point))))) + (user-error "No candidate location available"))) + +(defun corfu-complete () + "Try to complete current input." + (interactive) + (pcase-let ((`(,beg ,end ,table ,pred) completion-in-region--data)) + (if completion-cycling + ;; Proceed with cycling + (let ((completion-extra-properties corfu--extra)) + (corfu--completion-in-region beg end table pred)) + (if (>= corfu--index 0) + ;; Continue completion with selected candidate + (corfu--insert nil) + ;; Try to complete the current input string + (let* ((pt (max 0 (- (point) beg))) + (str (buffer-substring-no-properties beg end)) + (metadata (completion-metadata (substring str 0 pt) table pred))) + (pcase (completion-try-completion str table pred pt metadata) + (`(,newstr . ,newpt) + (completion--replace beg end newstr) + (goto-char (+ beg newpt)))))) + ;; No further completion is possible and the current string is a valid + ;; match, exit with status 'finished. + (let* ((pt (max 0 (- (point) beg))) + (str (buffer-substring-no-properties beg end)) + (metadata (completion-metadata (substring str 0 pt) table pred))) + (when (and (not (consp (completion-try-completion str table pred pt metadata))) + (test-completion str table pred)) + (corfu--done str 'finished)))))) + +(defun corfu--insert (status) + "Insert current candidate, exit with STATUS if non-nil." + (pcase-let* ((`(,beg ,end ,table ,pred) completion-in-region--data) + (str (buffer-substring-no-properties beg end))) + ;; Replace if candidate is selected or if current input is not valid completion. + ;; For example str can be a valid path, e.g., ~/dir/. + (when (or (>= corfu--index 0) (equal str "") + (not (test-completion str table pred))) + ;; XXX There is a small bug here, depending on interpretation. + ;; When completing "~/emacs/master/li|/calc" where "|" is the + ;; cursor, then the candidate only includes the prefix + ;; "~/emacs/master/lisp/", but not the suffix "/calc". Default + ;; completion has the same problem when selecting in the + ;; *Completions* buffer. See bug#48356. + (setq str (concat (substring str 0 corfu--base) + (substring-no-properties (nth (max 0 corfu--index) corfu--candidates)))) + (completion--replace beg end str) + (corfu--goto -1)) ;; Reset selection, but continue completion. + (when status (corfu--done str status)))) ;; Exit with status + +(defun corfu--done (str status) + "Call the `:exit-function' with STR and STATUS and exit completion." + (let ((exit (plist-get corfu--extra :exit-function))) + ;; For successfull completions, amalgamate undo operations, + ;; such that completion can be undone in a single step. + (undo-amalgamate-change-group corfu--change-group) + (corfu-quit) + ;; XXX Is the :exit-function handling sufficient? + (when exit (funcall exit str status)))) + +(defun corfu-insert () + "Insert current candidate." + (interactive) + (if (> corfu--total 0) + (corfu--insert 'finished) + (corfu-quit))) + +(defun corfu--setup () + "Setup Corfu completion state." + (setq corfu--extra completion-extra-properties) + (activate-change-group (setq corfu--change-group (prepare-change-group))) + (setcdr (assq #'completion-in-region-mode minor-mode-overriding-map-alist) corfu-map) + (add-hook 'pre-command-hook #'corfu--pre-command nil 'local) + (add-hook 'post-command-hook #'corfu--post-command nil 'local) + ;; Disable default post-command handling, since we have our own + ;; checks in `corfu--post-command'. + (remove-hook 'post-command-hook #'completion-in-region--postch) + (let ((sym (make-symbol "corfu--teardown")) + (buf (current-buffer))) + (fset sym (lambda () + ;; Ensure that the teardown runs in the correct buffer, if still alive. + (unless completion-in-region-mode + (remove-hook 'completion-in-region-mode-hook sym) + (with-current-buffer (if (buffer-live-p buf) buf (current-buffer)) + (corfu--teardown))))) + (add-hook 'completion-in-region-mode-hook sym))) + +(defun corfu--teardown () + "Teardown Corfu." + ;; Redisplay such that the input becomes immediately visible before the popup + ;; hiding, which is slow (Issue #48). See also corresponding vertico#89. + (redisplay) + (corfu--popup-hide) + (remove-hook 'window-configuration-change-hook #'corfu-quit) + (remove-hook 'pre-command-hook #'corfu--pre-command 'local) + (remove-hook 'post-command-hook #'corfu--post-command 'local) + (when corfu--preview-ov (delete-overlay corfu--preview-ov)) + (when corfu--echo-timer (cancel-timer corfu--echo-timer)) + (when corfu--echo-message (corfu--echo-show "")) + (accept-change-group corfu--change-group) + (mapc #'kill-local-variable corfu--state-vars)) + +(defun corfu--completion-message (msg) + "Print completion MSG, do not hang like `completion--message'." + (when (and completion-show-inline-help + (member msg '("No match" "Sole completion"))) + (message msg))) + +(defun corfu--all-sorted-completions (&optional beg end) + "Compute all sorted completions for string between BEG and END." + (or completion-all-sorted-completions + (pcase-let ((`(,base ,all . ,_) (corfu--recompute-candidates + (buffer-substring-no-properties beg end) + (max 0 (- (point) beg)) + minibuffer-completion-table + minibuffer-completion-predicate))) + (when all + (completion--cache-all-sorted-completions + beg end (nconc all base)))))) + +(defun corfu--completion-in-region (&rest args) + "Corfu completion in region function passing ARGS to `completion--in-region'." + (barf-if-buffer-read-only) + (if (not (display-graphic-p)) + ;; XXX Warning this can result in an endless loop when `completion-in-region-function' + ;; is set *globally* to `corfu--completion-in-region'. This should never happen. + (apply (default-value 'completion-in-region-function) args) + ;; Restart the completion. This can happen for example if C-M-/ + ;; (`dabbrev-completion') is pressed while the Corfu popup is already open. + (when (and completion-in-region-mode (not completion-cycling)) + (corfu-quit)) + (prog1 + (cl-letf* ((completion-auto-help nil) + ;; Set the predicate to ensure that `completion-in-region-mode' is enabled. + (completion-in-region-mode-predicate + (or completion-in-region-mode-predicate (lambda () t))) + ;; Overwrite to avoid hanging. + ((symbol-function #'completion--message) + #'corfu--completion-message) + ;; Overwrite for performance and consistency. + ((symbol-function #'completion-all-sorted-completions) + #'corfu--all-sorted-completions)) + (apply #'completion--in-region args)) + (when (and completion-in-region-mode + ;; Do not show Corfu when "trivially" cycling, i.e., + ;; when the completion is finished after the candidate. + (not (and completion-cycling + (pcase-let* ((`(,beg ,end ,table ,pred) completion-in-region--data) + (pt (max 0 (- (point) beg))) + (str (buffer-substring-no-properties beg end)) + (before (substring str 0 pt)) + (after (substring str pt))) + (equal (completion-boundaries before table pred after) '(0 . 0)))))) + (corfu--setup))))) + +(defun corfu--auto-complete (buffer) + "Initiate auto completion after delay in BUFFER." + (setq corfu--auto-timer nil) + (when (and (not completion-in-region-mode) + (eq (current-buffer) buffer)) + (pcase (while-no-input ;; Interruptible capf query + (run-hook-wrapped 'completion-at-point-functions #'corfu--capf-wrapper)) + ((and `(,fun ,beg ,end ,table . ,plist) + (guard (integer-or-marker-p beg)) + (guard (<= beg (point) end)) + (guard + (let ((len (or (plist-get plist :company-prefix-length) (- (point) beg)))) + (or (eq len t) (>= len corfu-auto-prefix))))) + (let ((completion-extra-properties plist) + (completion-in-region-mode-predicate + (lambda () (eq beg (car-safe (funcall fun)))))) + (setq completion-in-region--data `(,(copy-marker beg) ,(copy-marker end t) + ,table ,(plist-get plist :predicate)) + corfu--auto-start (float-time)) + (undo-boundary) ;; Necessary to support `corfu-reset' + (completion-in-region-mode 1) + (corfu--setup) + (corfu--update)))))) + +(defun corfu--auto-post-command () + "Post command hook which initiates auto completion." + (when corfu--auto-timer + (cancel-timer corfu--auto-timer) + (setq corfu--auto-timer nil)) + (when (and (not completion-in-region-mode) + (corfu--match-symbol-p corfu-auto-commands this-command) + (display-graphic-p)) + ;; NOTE: Do not use idle timer since this leads to unacceptable slowdowns, + ;; in particular if flyspell-mode is enabled. + (setq corfu--auto-timer (run-at-time corfu-auto-delay nil + #'corfu--auto-complete + (current-buffer))))) + +;;;###autoload +(define-minor-mode corfu-mode + "Completion Overlay Region FUnction" + :global nil :group 'corfu + (cond + (corfu-mode + ;; FIXME: Install advice which fixes `completion--capf-wrapper', such that + ;; it respects the completion styles for non-exclusive capfs. See FIXME in + ;; the `completion--capf-wrapper' function in minibuffer.el, where the + ;; issue has been mentioned. We never uninstall this advice since the + ;; advice is active *globally*. + (advice-add #'completion--capf-wrapper :around #'corfu--capf-wrapper-advice) + (advice-add #'eldoc-display-message-no-interference-p :before-while #'corfu--allow-eldoc) + (and corfu-auto (add-hook 'post-command-hook #'corfu--auto-post-command nil 'local)) + (setq-local completion-in-region-function #'corfu--completion-in-region)) + (t + (remove-hook 'post-command-hook #'corfu--auto-post-command 'local) + (kill-local-variable 'completion-in-region-function)))) + +(defun corfu--capf-wrapper (fun) + "Wrapper for `completion-at-point' FUN. +Determines if the capf is applicable at the current position." + (pcase + ;; bug#50470: Fix Capfs which illegally modify the buffer or which + ;; illegally call `completion-in-region'. The workaround here has been + ;; proposed @jakanakaevangeli in bug#50470 and is used in + ;; @jakanakaevangeli's capf-autosuggest package. + (catch 'corfu--illegal-completion-in-region + (condition-case nil + (let ((buffer-read-only t) + (inhibit-read-only nil) + (completion-in-region-function + (lambda (beg end coll pred) + (throw 'corfu--illegal-completion-in-region + (list beg end coll :predicate pred))))) + (funcall fun)) + (buffer-read-only nil))) + ((and res `(,beg ,end ,table . ,plist)) + (and (integer-or-marker-p beg) ;; Valid capf result + (<= beg (point) end) ;; Sanity checking + ;; For non-exclusive capfs, check for valid completion. + (or (not (eq 'no (plist-get plist :exclusive))) + (let* ((str (buffer-substring-no-properties beg end)) + (pt (- (point) beg)) + (pred (plist-get plist :predicate)) + (md (completion-metadata (substring str 0 pt) table pred))) + ;; We use `completion-try-completion' to check if there are + ;; completions. The upstream `completion--capf-wrapper' uses + ;; `try-completion' which is incorrect since it only checks for + ;; prefix completions. + (completion-try-completion str table pred pt md))) + (cons fun res))))) + +(defun corfu--capf-wrapper-advice (orig fun which) + "Around advice for `completion--capf-wrapper'. +The ORIG function takes the FUN and WHICH arguments." + (if corfu-mode (corfu--capf-wrapper fun) (funcall orig fun which))) + +;;;###autoload +(define-globalized-minor-mode corfu-global-mode corfu-mode corfu--on :group 'corfu) + +(defun corfu--on () + "Turn `corfu-mode' on." + (unless (or noninteractive + (eq (aref (buffer-name) 0) ?\s) + (memq major-mode corfu-excluded-modes)) + (corfu-mode 1))) + +(defun corfu--allow-eldoc () + "Return non-nil if Corfu is currently not active." + (not (and corfu-mode completion-in-region-mode))) + +;; Emacs 28: Do not show Corfu commands with M-X +(dolist (sym '(corfu-next corfu-previous corfu-first corfu-last corfu-quit corfu-reset + corfu-complete corfu-insert corfu-scroll-up corfu-scroll-down + corfu-show-location corfu-show-documentation)) + (put sym 'completion-predicate #'ignore)) + +(provide 'corfu) +;;; corfu.el ends here diff --git a/elpa/corfu-0.17/corfu.elc b/elpa/corfu-0.17/corfu.elc Binary files differ. diff --git a/elpa/corfu-0.17/corfu.info b/elpa/corfu-0.17/corfu.info @@ -0,0 +1,327 @@ +This is corfu.info, produced by makeinfo version 6.7 from corfu.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Corfu: (corfu). Completion Overlay Region FUnction. +END-INFO-DIR-ENTRY + + +File: corfu.info, Node: Top, Next: Introduction, Up: (dir) + +corfu.el - Completion Overlay Region FUnction +********************************************* + +* Menu: + +* Introduction:: +* Features:: +* Installation and Configuration:: +* Key bindings:: +* Complementary packages:: +* Caveats:: +* Contributions:: + +— The Detailed Node Listing — + +Installation and Configuration + +* TAB-and-Go completion:: + + + +File: corfu.info, Node: Introduction, Next: Features, Prev: Top, Up: Top + +1 Introduction +************** + +Corfu enhances the default completion in region function with a +completion overlay. The current candidates are shown in a popup below +or above the point. Corfu is the minimalistic ‘completion-in-region’ +counterpart of the Vertico (https://github.com/minad/vertico) minibuffer +UI. + + Corfu is a minimal package, which relies on the Emacs completion +facilities and concentrates on providing a polished completion UI. +Completions are either provided by commands like ‘dabbrev-completion’ or +by pluggable backends (‘completion-at-point-functions’, Capfs). Most +programming language major modes implement a Capf. Furthermore the +language server packages, Eglot (https://github.com/joaotavora/eglot) +and Lsp-mode (https://github.com/emacs-lsp/lsp-mode), both use Capfs +which talk to the LSP server to retrieve the completions. + + Corfu does not include custom completion backends. In contrast, the +complex Company package includes custom completion backends, which +deviate from the Emacs completion infrastructure. The Emacs built-in +Capfs are mostly sufficient, but a few additional Capfs and completion +functions are provided by the Cape (https://github.com/minad/cape) +package. + + *NOTE*: Corfu uses child frames to show the popup. For now Corfu +falls back to the default setting of the ‘completion-in-region-function’ +on non-graphical displays. You may want to use +‘consult-completion-in-region’. + + <https://github.com/minad/corfu/blob/screenshots/light.png?raw=true> + + <https://github.com/minad/corfu/blob/screenshots/dark.png?raw=true> + + +File: corfu.info, Node: Features, Next: Installation and Configuration, Prev: Introduction, Up: Top + +2 Features +********** + + • Timer-based auto-completions (_off_ by default, set ‘corfu-auto’). + • Popup display with scrollbar indicator and arrow key navigation. + • The popup can be summoned explicitly by pressing ‘TAB’ at any time. + • The current candidate is inserted with ‘TAB’ and selected with + ‘RET’. + • Candidates sorting by prefix, string length and alphabetically. + • The selected candidate is previewed (configuable via + ‘corfu-preview-current’). + • The selected candidate automatically committed on further input by + default (configurable via ‘corfu-commit-predicate’). + • The Orderless (https://github.com/oantolin/orderless) completion + style is supported. The filter string can contain arbitrary + characters, including spaces, if ‘corfu-quit-at-boundary’ is nil. + • Deferred completion style highlighting for performance. + • Jumping to location/documentation of current candidate. + • Show candidate documentation/signature string in the echo area. + • Deprecated candidates are crossed out in the display. + • Support for annotations (‘annotation-function’, + ‘affixation-function’). + • Icons can be provided by an external package via margin formatter + functions. + + +File: corfu.info, Node: Installation and Configuration, Next: Key bindings, Prev: Features, Up: Top + +3 Installation and Configuration +******************************** + +Corfu is available from GNU ELPA +(http://elpa.gnu.org/packages/corfu.html), such that it can be installed +directly via ‘package-install’. After installation, the global minor +mode can be enabled with ‘M-x corfu-global-mode’. In order to configure +Corfu and other packages in your init.el, you may want to use +‘use-package’. + + Corfu is highly flexible and customizable via ‘corfu-*’ customization +variables. For filtering I recommend to give Orderless completion a +try, which is different from the familiar prefix TAB completion. Corfu +can be used with the default completion styles, the use of Orderless is +not a necessity. See also the Corfu Wiki +(https://github.com/minad/corfu/wiki) for additional configuration tips. +In particular the Lsp-mode configuration is documented in the Wiki. + + Here is an example configuration: + + (use-package corfu + ;; Optional customizations + ;; :custom + ;; (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + ;; (corfu-auto t) ;; Enable auto completion + ;; (corfu-commit-predicate nil) ;; Do not commit selected candidates on next input + ;; (corfu-quit-at-boundary t) ;; Automatically quit at word boundary + ;; (corfu-quit-no-match t) ;; Automatically quit if there is no match + ;; (corfu-preview-current nil) ;; Disable current candidate preview + ;; (corfu-preselect-first nil) ;; Disable candidate preselection + ;; (corfu-echo-documentation nil) ;; Disable documentation in the echo area + ;; (corfu-scroll-margin 5) ;; Use scroll margin + + ;; You may want to enable Corfu only for certain modes. + ;; :hook ((prog-mode . corfu-mode) + ;; (shell-mode . corfu-mode) + ;; (eshell-mode . corfu-mode)) + + ;; Recommended: Enable Corfu globally. + ;; This is recommended since dabbrev can be used globally (M-/). + :init + (corfu-global-mode)) + + ;; Optionally use the `orderless' completion style. See `+orderless-dispatch' + ;; in the Consult wiki for an advanced Orderless style dispatcher. + ;; Enable `partial-completion' for files to allow path expansion. + ;; You may prefer to use `initials' instead of `partial-completion'. + (use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless) + completion-category-defaults nil + completion-category-overrides '((file (styles . (partial-completion)))))) + + ;; Use dabbrev with Corfu! + (use-package dabbrev + ;; Swap M-/ and C-M-/ + :bind (("M-/" . dabbrev-completion) + ("C-M-/" . dabbrev-expand))) + + ;; A few more useful configurations... + (use-package emacs + :init + ;; TAB cycle if there are only few candidates + (setq completion-cycle-threshold 3) + + ;; Emacs 28: Hide commands in M-x which do not apply to the current mode. + ;; Corfu commands are hidden, since they are not supposed to be used via M-x. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable indentation+completion using the TAB key. + ;; `completion-at-point' is often bound to M-TAB. + (setq tab-always-indent 'complete)) + + See also the Corfu Wiki (https://github.com/minad/corfu/wiki) for +additional configuration tips. For more general documentation read the +chapter about completion in the Emacs manual +(https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion.html). +If you want to create your own Capfs, you can find documentation about +completion in the Elisp manual +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html). + +* Menu: + +* TAB-and-Go completion:: + + +File: corfu.info, Node: TAB-and-Go completion, Up: Installation and Configuration + +3.1 TAB-and-Go completion +========================= + +You may be interested in configuring Corfu in TAB-and-Go style. +Pressing TAB moves to the next candidate and further input will then +commit the selection. + + (use-package corfu + ;; TAB-and-Go customizations + :custom + (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + (corfu-preselect-first nil) ;; Disable candidate preselection + + ;; Use TAB for cycling, default is `corfu-complete'. + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + + :init + (corfu-global-mode)) + + +File: corfu.info, Node: Key bindings, Next: Complementary packages, Prev: Installation and Configuration, Up: Top + +4 Key bindings +************** + +Corfu uses a transient keymap ‘corfu-map’ which is active while the +popup is shown. The keymap defines the following remappings and +bindings: + + • ‘beginning-of-buffer’ -> ‘corfu-first’ + • ‘end-of-buffer’ -> ‘corfu-last’ + • ‘scroll-down-command’ -> ‘corfu-scroll-down’ + • ‘scroll-up-command’ -> ‘corfu-scroll-up’ + • ‘next-line’, ‘down’, ‘M-n’ -> ‘corfu-next’ + • ‘previous-line’, ‘up’, ‘M-p’ -> ‘corfu-previous’ + • ‘completion-at-point’, ‘TAB’ -> ‘corfu-complete’ + • ‘RET’ -> ‘corfu-insert’ + • ‘M-g’ -> ‘corfu-show-location’ + • ‘M-h’ -> ‘corfu-show-documentation’ + • ‘C-g’ -> ‘corfu-quit’ + • ‘keyboard-escape-quit’ -> ‘corfu-reset’ + + +File: corfu.info, Node: Complementary packages, Next: Caveats, Prev: Key bindings, Up: Top + +5 Complementary packages +************************ + +Corfu works well together with all packages providing code completion +via the ‘completion-at-point-functions’. Many modes and packages +already provide a Capf out of the box. Nevertheless you may want to +look into complementary packages to enhance your setup. + + • Orderless (https://github.com/oantolin/orderless): Cofu supports + completion styles, including the advanced Orderless + (https://github.com/oantolin/orderless) completion style, where the + filtering expressions are separated by spaces (see + ‘corfu-quit-at-boundary’). + + • Cape (https://github.com/minad/cape): I collect additional Capf + backends and ‘completion-in-region’ commands in my Cape + (https://github.com/minad/cape) package. The package provides a + file path, a dabbrev completion backend and a backend which allows + you to enter unicode characters in the form of TeX commands. Cape + provides an adapter to reuse Company backends in Corfu. + Furthermore the function ‘cape-super-capf’ can merge/groups + multiple Capfs, such that the candidates of multiple Capfs are + displayed together at the same time. + + • kind-icon (https://github.com/jdtsmith/kind-icon): Icons are + supported by Corfu via an external package. For example the + kind-icon (https://github.com/jdtsmith/kind-icon) package provides + beautifully styled SVG icons based on monochromatic icon sets like + material design. + + • corfu-doc (https://github.com/galeo/corfu-doc): The corfu-doc + package by @galeo allows you to display the candidate documentation + in a popup next to the Corfu popup, similar to ‘company-quickhelp’. + _Note that the corfu-doc package is new and still work in + progress._ + + • Vertico (https://github.com/minad/vertico): You may also want to + look into my Vertico (https://github.com/minad/vertico) package. + Vertico is the minibuffer completion counterpart of Corfu. + + +File: corfu.info, Node: Caveats, Next: Contributions, Prev: Complementary packages, Up: Top + +6 Caveats +********* + +Corfu is robust in most scenarios. There are a few known technical +caveats. + + • Corfu uses child frames to show the popup. For now Corfu falls + back to the default setting of the ‘completion-in-region-function’ + on non-graphical displays. You may want to use + ‘consult-completion-in-region’. + + • Corfu does not sort by history, since ‘completion-at-point’ does + not maintain a history (See branch ‘history’ for a possible + solution). + + +File: corfu.info, Node: Contributions, Prev: Caveats, Up: Top + +7 Contributions +*************** + +Since this package is part of GNU ELPA +(http://elpa.gnu.org/packages/corfu.html) contributions require a +copyright assignment to the FSF. + + + +Tag Table: +Node: Top195 +Node: Introduction597 +Node: Features2280 +Node: Installation and Configuration3684 +Node: TAB-and-Go completion7847 +Node: Key bindings8657 +Node: Complementary packages9609 +Node: Caveats11717 +Node: Contributions12319 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/corfu-0.17/dir b/elpa/corfu-0.17/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Corfu: (corfu). Completion Overlay Region FUnction. diff --git a/elpa/marginalia-0.11.signed b/elpa/marginalia-0.11.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2021-12-31T11:05:02+0100 using RSA +\ No newline at end of file diff --git a/elpa/marginalia-0.11/LICENSE b/elpa/marginalia-0.11/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/elpa/marginalia-0.11/README.org b/elpa/marginalia-0.11/README.org @@ -0,0 +1,209 @@ +#+title: marginalia.el - Marginalia in the minibuffer +#+author: Omar Antolín Camarena, Daniel Mendler +#+language: en +#+export_file_name: marginalia.texi +#+texinfo_dir_category: Emacs +#+texinfo_dir_title: Marginalia: (marginalia). +#+texinfo_dir_desc: Marginalia in the minibuffer + +#+html: <a href="https://www.gnu.org/software/emacs/"><img alt="GNU Emacs" src="https://github.com/minad/corfu/blob/screenshots/emacs.svg?raw=true"/></a> +#+html: <a href="http://elpa.gnu.org/packages/marginalia.html"><img alt="GNU ELPA" src="https://elpa.gnu.org/packages/marginalia.svg"/></a> +#+html: <a href="http://elpa.gnu.org/devel/marginalia.html"><img alt="GNU-devel ELPA" src="https://elpa.gnu.org/devel/marginalia.svg"/></a> +#+html: <a href="https://melpa.org/#/marginalia"><img alt="MELPA" src="https://melpa.org/packages/marginalia-badge.svg"/></a> +#+html: <a href="https://stable.melpa.org/#/marginalia"><img alt="MELPA Stable" src="https://stable.melpa.org/packages/marginalia-badge.svg"/></a> + +* Introduction + +#+html: <img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/Marginalia_%285095211566%29.jpg" align="right" width="30%"> + +This package provides =marginalia-mode= which adds marginalia to the +minibuffer completions. +[[https://en.wikipedia.org/wiki/Marginalia][Marginalia]] are marks or +annotations placed at the margin of the page of a book or in this case +helpful colorful annotations placed at the margin of the minibuffer for +your completion candidates. Marginalia can only add annotations to be +displayed with the completion candidates. It cannot modify the +appearance of the candidates themselves, which are shown as supplied by +the original commands. + +The annotations are added based on the completion category. For example +=find-file= reports the =file= category and =M-x= reports the =command= category. You +can cycle between more or less detailed annotators or even disable the annotator +with command =marginalia-cycle=. + +#+html: <img src="https://github.com/minad/marginalia/blob/main/marginalia-mode.png?raw=true"> + +* Configuration + +It is recommended to use Marginalia together with either the [[https://github.com/raxod502/selectrum][Selectrum]], [[https://github.com/minad/vertico][Vertico]] +or the [[https://github.com/oantolin/icomplete-vertical][Icomplete-vertical]] completion system. Furthermore Marginalia can be +combined with [[https://github.com/oantolin/embark][Embark]] for action support and [[https://github.com/minad/consult][Consult]], which provides many useful +commands. + +#+begin_src emacs-lisp +;; Enable richer annotations using the Marginalia package +(use-package marginalia + ;; Either bind `marginalia-cycle` globally or only in the minibuffer + :bind (("M-A" . marginalia-cycle) + :map minibuffer-local-map + ("M-A" . marginalia-cycle)) + + ;; The :init configuration is always executed (Not lazy!) + :init + + ;; Must be in the :init section of use-package such that the mode gets + ;; enabled right away. Note that this forces loading the package. + (marginalia-mode)) +#+end_src + +* Information shown by the annotators + +In general, to learn more about what different annotations mean, a good starting +point is to look at ~marginalia-annotator-registry~, and follow up to the +annotation function of the category you are interested in. + +For example the annotations for elisp symbols include their symbol class - v for +variable, f for function, c for command, etc. For more information on what the +different classifications mean, see the docstring of ~marginalia--symbol-class~. + +* Adding custom annotators or classifiers + +*IMPORTANT NOTICE FOR PACKAGE AUTHORS*: The intention of the Marginalia package is +to give the user means to overwrite completion categories and to add custom +annotators for existing commands in their user configuration. Marginalia is a +user facing package and is not intended to be used as a library. Therefore +Marginalia does not expose library functions as part of its public API. If you +add your own completion commands to your package we recommend to specify an +=annotation-function= or an =affixation-function=, avoiding the Marginalia +dependency this way. The =annotation-function= is documented in the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html][Elisp manual]]. +There is an exception to our recommendation: If you want to implement +annotations for an existing package =hypothetical.el=, which does not have +annotations and where annotations cannot be added, then the creation of a +=marginalia-hypothetical.el= package is a good idea, since Marginalia provides the +facilities to enhance existing commands from the outside. If you have questions +feel free to ask on the Marginalia issue tracker! + +Commands that support minibuffer completion use a completion table of all the +available candidates. Candidates are associated with a *category* such as =command=, +=file=, =face=, or =variable= depending on what the candidates are. Based on the +category of the candidates, Marginalia selects an *annotator* to generate +annotations for display for each candidate. + +Unfortunately, not all commands (including Emacs' builtin ones) specify the +category of their candidates. To compensate for this shortcoming, Marginalia +hooks into the emacs completion framework and runs the *classifiers* listed in the +variable =marginalia-classifiers=, which use the command's prompt or other +properties of the candidates to specify the completion category. + +For example, the =marginalia-classify-by-prompt= classifier checks the minibuffer +prompt against regexps listed in the =marginalia-prompt-categories= alist to +determine a category. The following is already included but would be a way to +assign the category =face= to all candidates from commands with prompts that +include the word "face". + +#+begin_src emacs-lisp + (add-to-list 'marginalia-prompt-categories '("\\<face\\>" . face)) +#+end_src + +The =marginalia-classify-by-command-name= classifier uses the alist +=marginalia-command-categories= to specify the completion category based on the +command name. This is particularily useful if the prompt classifier yields a +false positive. + +Completion categories are also important for [[https://github.com/oantolin/embark][Embark]], which associates actions +based on the completion category and benefits from Marginalia's classifiers. + +Once the category of the candidates is known, Marginalia looks in the +=marginalia-annotator-registry= to find the associated annotator to use. An +annotator is a function that takes a completion candidate string as an argument +and returns an annotation string to be displayed after the candidate in the +minibuffer. More than one annotator can be assigned to each each category, +displaying more, less or different information. Use the =marginalia-cycle= command +to cycle between the annotations of different annotators defined for the current +category. + +Here's an example of a basic face annotator: + +#+begin_src emacs-lisp + (defun my-face-annotator (cand) + (when-let (sym (intern-soft cand)) + (concat (propertize " " 'display '(space :align-to center)) + (propertize "The quick brown fox jumps over the lazy dog" 'face sym)))) +#+end_src + +Look at Marginalia's various annotators for examples of formating annotations. +In particular, the helper function =marginalia--fields= can be used to format +information into columns. + +After defining a new annotator, associate it with a category in the annotator +registry as follows: + +#+begin_src emacs-lisp + (add-to-list 'marginalia-annotator-registry + '(face my-face-annotator marginalia-annotate-face builtin none)) +#+end_src + +This makes the =my-face-annotator= the first of four annotators for the face +category. The others are the annotator provided by Marginalia +(=marginalia-annotate-face=), the =builtin= annotator as defined by Emacs and the +=none= annotator, which disables the annotations. With this setting, after +invoking =M-x describe-face RET= you can cycle between all of these annotators +using =marginalia-cycle=. + +* Disabling annotators, builtin or lightweight annotators + +Marginalia activates rich annotators by default. Depending on your preference +you may want to use the builtin annotators or even no annotators by default and +only activate the annotators on demand by invoking ~marginalia-cycle~. + +In order to use the builtin annotators by default, you can use the following +command. Replace =builtin= by =none= to disable annotators by default. + +#+begin_src emacs-lisp + (defun marginalia-use-builtin () + (interactive) + (mapc + (lambda (x) + (setcdr x (cons 'builtin (remq 'builtin (cdr x))))) + marginalia-annotator-registry)) +#+end_src + +If a completion category supports two annotators, you can toggle between +those using this command. + +#+begin_src emacs-lisp + (defun marginalia-toggle () + (interactive) + (mapc + (lambda (x) + (setcdr x (append (reverse (remq 'none + (remq 'builtin (cdr x)))) + '(builtin none)))) + marginalia-annotator-registry)) +#+end_src + +After cycling the annotators you may want to automatically save the +configuration. This can be achieved using an advice which calls +~customize-save-variable~. + +#+begin_src emacs-lisp + (advice-add #'marginalia-cycle :after + (lambda () + (let ((inhibit-message t)) + (customize-save-variable 'marginalia-annotator-registry + marginalia-annotator-registry)))) +#+end_src + +In order to disable an annotator permanently, the ~marginalia-annotator-registry~ +can be modified. For example if you prefer to never see file annotations, you +can delete all file annotators from the registry. + +#+begin_src emacs-lisp + (setq marginalia-annotator-registry + (assq-delete-all 'file marginalia-annotator-registry)) +#+end_src + +* Contributions + +Since this package is part of [[http://elpa.gnu.org/packages/marginalia.html][GNU ELPA]] contributions require a copyright +assignment to the FSF. diff --git a/elpa/marginalia-0.11/dir b/elpa/marginalia-0.11/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Marginalia: (marginalia). Marginalia in the minibuffer. diff --git a/elpa/marginalia-0.11/marginalia-autoloads.el b/elpa/marginalia-0.11/marginalia-autoloads.el @@ -0,0 +1,49 @@ +;;; marginalia-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "marginalia" "marginalia.el" (0 0 0 0)) +;;; Generated autoloads from marginalia.el + +(defvar marginalia-mode nil "\ +Non-nil if Marginalia mode is enabled. +See the `marginalia-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `marginalia-mode'.") + +(custom-autoload 'marginalia-mode "marginalia" nil) + +(autoload 'marginalia-mode "marginalia" "\ +Annotate completion candidates with richer information. + +If called interactively, enable Marginalia mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(autoload 'marginalia-cycle "marginalia" "\ +Cycle between annotators in `marginalia-annotator-registry'." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "marginalia" '("marginalia-"))) + +;;;*** + +;;;### (autoloads nil nil ("marginalia-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; marginalia-autoloads.el ends here diff --git a/elpa/marginalia-0.11/marginalia-mode.png b/elpa/marginalia-0.11/marginalia-mode.png Binary files differ. diff --git a/elpa/marginalia-0.11/marginalia-pkg.el b/elpa/marginalia-0.11/marginalia-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from marginalia.el -*- no-byte-compile: t -*- +(define-package "marginalia" "0.11" "Enrich existing commands with completion annotations" '((emacs "26.1")) :authors '(("Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler" . "mail@daniel-mendler.de")) :maintainer '("Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler" . "mail@daniel-mendler.de") :url "https://github.com/minad/marginalia") diff --git a/elpa/marginalia-0.11/marginalia.el b/elpa/marginalia-0.11/marginalia.el @@ -0,0 +1,1131 @@ +;;; marginalia.el --- Enrich existing commands with completion annotations -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Omar Antolín Camarena <omar@matem.unam.mx>, Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2020 +;; Version: 0.11 +;; Package-Requires: ((emacs "26.1")) +;; Homepage: https://github.com/minad/marginalia + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Enrich existing commands with completion annotations + +;;; Code: + +(eval-when-compile + (require 'subr-x) + (require 'cl-lib)) + +;;;; Customization + +(defgroup marginalia nil + "Enrich existing commands with completion annotations." + :group 'convenience + :group 'minibuffer + :prefix "marginalia-") + +(defcustom marginalia-truncate-width 80 + "Maximum truncation width of annotation fields. + +This value is adjusted depending on the `window-width'." + :type 'integer) + +(defcustom marginalia-separator-threshold 160 + "Use wider separator for window widths larger than this value." + :type 'integer) + +;; See https://github.com/minad/marginalia/issues/42 for the discussion +;; regarding the alignment. +(defcustom marginalia-align-offset nil + "Additional offset at the right margin used by `marginalia--align'. + +This value should be set to nil to enable auto-configuration. +It can also be set to an integer value of 1 or larger to force an offset." + :type '(choice (const nil) integer)) + +(defcustom marginalia-margin-min 8 + "Minimum whitespace margin at the right side." + :type 'integer) + +(defcustom marginalia-margin-threshold 200 + "Use whitespace margin for window widths larger than this value." + :type 'integer) + +(defcustom marginalia-max-relative-age (* 60 60 24 14) + "Maximum relative age in seconds displayed by the file annotator. + +Set to `most-positive-fixnum' to always use a relative age, or 0 to never show +a relative age." + :type 'integer) + +(defcustom marginalia-annotator-registry + (mapcar + (lambda (x) (append x '(builtin none))) + '((command marginalia-annotate-command marginalia-annotate-binding) + (embark-keybinding marginalia-annotate-embark-keybinding) + (customize-group marginalia-annotate-customize-group) + (variable marginalia-annotate-variable) + (function marginalia-annotate-function) + (face marginalia-annotate-face) + (color marginalia-annotate-color) + (unicode-name marginalia-annotate-char) + (minor-mode marginalia-annotate-minor-mode) + (symbol marginalia-annotate-symbol) + (environment-variable marginalia-annotate-environment-variable) + (input-method marginalia-annotate-input-method) + (coding-system marginalia-annotate-coding-system) + (charset marginalia-annotate-charset) + (package marginalia-annotate-package) + (imenu marginalia-annotate-imenu) + (bookmark marginalia-annotate-bookmark) + (file marginalia-annotate-file) + (project-file marginalia-annotate-project-file) + (buffer marginalia-annotate-buffer) + (multi-category marginalia-annotate-multi-category) + ;; TODO: `consult-multi' has been obsoleted by `multi-category'. Remove! + (consult-multi marginalia-annotate-multi-category))) + "Annotator function registry. +Associates completion categories with annotation functions. +Each annotation function must return a string, +which is appended to the completion candidate." + :type '(alist :key-type symbol :value-type (repeat symbol))) + +(defcustom marginalia-classifiers + '(marginalia-classify-by-command-name + marginalia-classify-original-category + marginalia-classify-by-prompt + marginalia-classify-symbol) + "List of functions to determine current completion category. +Each function should take no arguments and return a symbol +indicating the category, or nil to indicate it could not +determine it." + :type 'hook) + +(defcustom marginalia-prompt-categories + '(("\\<customize group\\>" . customize-group) + ("\\<M-x\\>" . command) + ("\\<package\\>" . package) + ("\\<bookmark\\>" . bookmark) + ("\\<color\\>" . color) + ("\\<face\\>" . face) + ("\\<environment variable\\>" . environment-variable) + ("\\<function\\>" . function) + ("\\<variable\\>" . variable) + ("\\<input method\\>" . input-method) + ("\\<charset\\>" . charset) + ("\\<coding system\\>" . coding-system) + ("\\<minor mode\\>" . minor-mode) + ("\\<kill-ring\\>" . kill-ring) + ("\\<[Ll]ibrary\\>" . library)) + "Associates regexps to match against minibuffer prompts with categories." + :type '(alist :key-type regexp :value-type symbol)) + +(defcustom marginalia-censor-variables + '("pass") + "The values of variables matching any of these regular expressions is not shown." + :type '(repeat (choice symbol regexp))) + +(defcustom marginalia-command-categories + '((imenu . imenu)) + "Associate commands with a completion category." + :type '(alist :key-type symbol :value-type symbol)) + +(defcustom marginalia-bookmark-type-transformers + (let ((words (regexp-opt '("handle" "handler" "jump" "bookmark")))) + `((,(format "-+%s-+" words) . "-") + (,(format "\\`%s-+" words) . "") + (,(format "-%s\\'" words) . "") + ("\\`default\\'" . "File") + (".*" . ,#'capitalize))) + "List of bookmark type transformers." + :type '(alist :key-type regexp :value-type (choice string function))) + +(defgroup marginalia-faces nil + "Faces used by `marginalia-mode'." + :group 'marginalia + :group 'faces) + +(defface marginalia-key + '((t :inherit font-lock-keyword-face)) + "Face used to highlight keys.") + +(defface marginalia-type + '((t :inherit marginalia-key)) + "Face used to highlight types.") + +(defface marginalia-char + '((t :inherit marginalia-key)) + "Face used to highlight character annotations.") + +(defface marginalia-lighter + '((t :inherit marginalia-size)) + "Face used to highlight minor mode lighters.") + +(defface marginalia-on + '((t :inherit success)) + "Face used to signal enabled modes.") + +(defface marginalia-off + '((t :inherit error)) + "Face used to signal disabled modes.") + +(defface marginalia-documentation + '((t :inherit completions-annotations)) + "Face used to highlight documentation strings.") + +(defface marginalia-value + '((t :inherit marginalia-key)) + "Face used to highlight general variable values.") + +(defface marginalia-null + '((t :inherit font-lock-comment-face)) + "Face used to highlight null or unbound variable values.") + +(defface marginalia-true + '((t :inherit font-lock-builtin-face)) + "Face used to highlight true variable values.") + +(defface marginalia-function + '((t :inherit font-lock-function-name-face)) + "Face used to highlight function symbols.") + +(defface marginalia-symbol + '((t :inherit font-lock-type-face)) + "Face used to highlight general symbols.") + +(defface marginalia-list + '((t :inherit font-lock-constant-face)) + "Face used to highlight list expressions.") + +(defface marginalia-mode + '((t :inherit marginalia-key)) + "Face used to highlight buffer major modes.") + +(defface marginalia-date + '((t :inherit marginalia-key)) + "Face used to highlight dates.") + +(defface marginalia-version + '((t :inherit marginalia-number)) + "Face used to highlight package versions.") + +(defface marginalia-archive + '((t :inherit warning)) + "Face used to highlight package archives.") + +(defface marginalia-installed + '((t :inherit success)) + "Face used to highlight the status of packages.") + +(defface marginalia-size + '((t :inherit marginalia-number)) + "Face used to highlight sizes.") + +(defface marginalia-number + '((t :inherit font-lock-constant-face)) + "Face used to highlight numeric values.") + +(defface marginalia-string + '((t :inherit font-lock-string-face)) + "Face used to highlight string values.") + +(defface marginalia-modified + '((t :inherit font-lock-negation-char-face)) + "Face used to highlight buffer modification indicators.") + +(defface marginalia-file-name + '((t :inherit marginalia-documentation)) + "Face used to highlight file names.") + +(defface marginalia-file-owner + '((t :inherit font-lock-preprocessor-face)) + "Face used to highlight file owner and group names.") + +(defface marginalia-file-priv-no + '((t :inherit shadow)) + "Face used to highlight the no file privilege attribute.") + +(defface marginalia-file-priv-dir + '((t :inherit font-lock-keyword-face)) + "Face used to highlight the dir file privilege attribute.") + +(defface marginalia-file-priv-link + '((t :inherit font-lock-keyword-face)) + "Face used to highlight the link file privilege attribute.") + +(defface marginalia-file-priv-read + '((t :inherit font-lock-type-face)) + "Face used to highlight the read file privilege attribute.") + +(defface marginalia-file-priv-write + '((t :inherit font-lock-builtin-face)) + "Face used to highlight the write file privilege attribute.") + +(defface marginalia-file-priv-exec + '((t :inherit font-lock-function-name-face)) + "Face used to highlight the exec file privilege attribute.") + +(defface marginalia-file-priv-other + '((t :inherit font-lock-constant-face)) + "Face used to highlight some other file privilege attribute.") + +(defface marginalia-file-priv-rare + '((t :inherit font-lock-variable-name-face)) + "Face used to highlight a rare file privilege attribute.") + +;;;; Pre-declarations for external packages + +(defvar bookmark-alist) +(declare-function bookmark-get-handler "bookmark") +(declare-function bookmark-get-filename "bookmark") +(declare-function bookmark-get-front-context-string "bookmark") + +(defvar package--builtins) +(defvar package-archive-contents) +(declare-function package--from-builtin "package") +(declare-function package-desc-archive "package") +(declare-function package-desc-status "package") +(declare-function package-desc-summary "package") +(declare-function package-desc-version "package") +(declare-function package-version-join "package") +(declare-function project-current "project") + +(declare-function color-rgb-to-hex "color") +(declare-function color-rgb-to-hsl "color") +(declare-function color-hsl-to-rgb "color") + +(declare-function selectrum--get-full "ext:selectrum") + +;;;; Marginalia mode + +(defvar marginalia--fontified-file-modes nil + "List of fontified file modes.") + +(defvar-local marginalia--cache nil + "The cache, pair of list and hashtable.") + +(defvar marginalia--cache-size 100 + "Size of the cache, set to 0 to disable the cache. +Disabling the cache is useful on non-incremental UIs like default completion or +for performance profiling of the annotators.") + +(defvar marginalia--separator " " + "Field separator.") + +(defvar marginalia--margin 0 + "Right margin.") + +(defvar-local marginalia--command nil + "Last command symbol saved in order to allow annotations.") + +(defvar-local marginalia--base-position 0 + "Last completion base position saved to get full file paths.") + +(defvar marginalia--metadata nil + "Completion metadata from the current completion.") + +(defun marginalia--truncate (str width) + "Truncate string STR to WIDTH." + (when-let (pos (string-match-p "\n" str)) + (setq str (substring str 0 pos))) + (if (< width 0) + (nreverse (truncate-string-to-width (reverse str) (- width) 0 ?\s t)) + (truncate-string-to-width str width 0 ?\s t))) + +(defun marginalia--align (str) + "Align STR at the right margin." + (unless (string-blank-p str) + (concat " " + (propertize + " " + 'display + `(space :align-to (- right ,marginalia--margin ,(string-width str)))) + str))) + +(cl-defmacro marginalia--field (field &key truncate format face width) + "Format FIELD as a string according to some options. + +TRUNCATE is the truncation width. +FORMAT is a format string. This must be used if the field value is not a string. +FACE is the name of the face, with which the field should be propertized. +WIDTH is the format width. This can be specified as alternative to FORMAT." + (cl-assert (not (and width format))) + (when width + (setq field `(or ,field "") + format (format "%%%ds" (- width)))) + (setq field (if format + `(format ,format ,field) + `(or ,field ""))) + (when truncate (setq field `(marginalia--truncate ,field ,truncate))) + (when face (setq field `(propertize ,field 'face ,face))) + field) + +(defmacro marginalia--fields (&rest fields) + "Format annotation FIELDS as a string with separators in between." + `(marginalia--align (concat ,@(cdr (mapcan (lambda (field) + (list 'marginalia--separator `(marginalia--field ,@field))) + fields))))) + +(defun marginalia--documentation (str) + "Format documentation string STR." + (when str + (marginalia--fields + (str :truncate marginalia-truncate-width :face 'marginalia-documentation)))) + +(defun marginalia-annotate-binding (cand) + "Annotate command CAND with keybinding." + (when-let* ((sym (intern-soft cand)) + (key (and (commandp sym) (where-is-internal sym nil 'first-only)))) + (format #(" (%s)" 1 5 (face marginalia-key)) (key-description key)))) + +(defun marginalia--annotator (cat) + "Return annotation function for category CAT." + (pcase (car (alist-get cat marginalia-annotator-registry)) + ('none (lambda (_) nil)) + ('builtin nil) + (fun fun))) + +(defun marginalia-annotate-multi-category (cand) + "Annotate multi-category CAND with the buffer class." + (if-let* ((multi (or (get-text-property 0 'multi-category cand) + ;; TODO: `consult-multi' has been obsoleted by `multi-category'. Remove! + (get-text-property 0 'consult-multi cand))) + (annotate (marginalia--annotator (car multi)))) + ;; Use the Marginalia annotator corresponding to the multi category. + (funcall annotate (cdr multi)) + ;; Apply the original annotation function on the original candidate, if there is one. + ;; NOTE: Use `alist-get' instead of `completion-metadata-get' to bypass our + ;; `marginalia--completion-metadata-get' advice! + (when-let (annotate (alist-get 'annotation-function marginalia--metadata)) + (funcall annotate cand)))) + +(defconst marginalia--advice-regexp + (rx bos + (1+ (seq (? "This function has ") + (or ":before" ":after" ":around" ":override" + ":before-while" ":before-until" ":after-while" + ":after-until" ":filter-args" ":filter-return") + " advice: " (0+ nonl) "\n")) + "\n") + "Regexp to match lines about advice in function documentation strings.") + +;; Taken from advice--make-docstring, is this robust? +(defun marginalia--advised (fun) + "Return t if function FUN is advised." + (let ((flist (indirect-function fun))) + (advice--p (if (eq 'macro (car-safe flist)) (cdr flist) flist)))) + +;; Symbol class characters from Emacs 28 `help--symbol-completion-table-affixation' +;; ! and * are our additions +(defun marginalia--symbol-class (s) + "Return symbol class characters for symbol S. + +Function: +f function +c command +C interactive-only command +m macro +M special-form +p pure +s side-effect-free +@ autoloaded +! advised +- obsolete + +Variable: +u custom (U modified compared to global value) +v variable +l local (L modified compared to default value) +- obsolete + +Other: +a face +t cl-type" + (format + "%-6s" + (concat + (when (fboundp s) + (concat + (cond + ((get s 'pure) "p") + ((get s 'side-effect-free) "s")) + (cond + ((commandp s) (if (get s 'interactive-only) "C" "c")) + ((macrop (symbol-function s)) "m") + ((special-form-p (symbol-function s)) "M") + (t "f")) + (and (autoloadp (symbol-function s)) "@") + (and (marginalia--advised s) "!") + (and (get s 'byte-obsolete-info) "-"))) + (when (boundp s) + (concat + (when (local-variable-if-set-p s) + (if (ignore-errors + (not (equal (symbol-value s) + (default-value s)))) + "L" "l")) + (if (custom-variable-p s) + (if (ignore-errors + (not (equal + (symbol-value s) + (eval (car (get s 'standard-value)))))) + "U" "u") + "v") + (and (get s 'byte-obsolete-variable) "-"))) + (and (facep s) "a") + (and (fboundp 'cl-find-class) (cl-find-class s) "t")))) + +(defun marginalia--function-doc (sym) + "Documentation string of function SYM." + (when-let (str (ignore-errors (documentation sym))) + (save-match-data + (if (string-match marginalia--advice-regexp str) + (substring str (match-end 0)) + str)))) + +;; Derived from elisp-get-fnsym-args-string +(defun marginalia--function-args (sym) + "Return function arguments for SYM." + (let ((tmp)) + (elisp-function-argstring + (cond + ((listp (setq tmp (gethash (indirect-function sym) + advertised-signature-table t))) + tmp) + ((setq tmp (help-split-fundoc + (ignore-errors (documentation sym t)) + sym)) + (substitute-command-keys (car tmp))) + ((setq tmp (help-function-arglist sym)) + (and + (if (and (stringp tmp) + (string-match-p "Arg list not available" tmp)) + ;; A shorter text fits better into the + ;; limited Marginalia space. + "[autoload]" + tmp))))))) + +(defun marginalia-annotate-symbol (cand) + "Annotate symbol CAND with its documentation string." + (when-let (sym (intern-soft cand)) + (concat + (marginalia-annotate-binding cand) + (marginalia--fields + ((marginalia--symbol-class sym) :face 'marginalia-type) + ((cond + ((fboundp sym) (marginalia--function-doc sym)) + ((facep sym) (documentation-property sym 'face-documentation)) + (t (documentation-property sym 'variable-documentation))) + :truncate marginalia-truncate-width :face 'marginalia-documentation))))) + +(defun marginalia-annotate-command (cand) + "Annotate command CAND with its documentation string. +Similar to `marginalia-annotate-symbol', but does not show symbol class." + (when-let (sym (intern-soft cand)) + (concat + (marginalia-annotate-binding cand) + (marginalia--documentation (marginalia--function-doc sym))))) + +(defun marginalia-annotate-embark-keybinding (cand) + "Annotate Embark keybinding CAND with its documentation string. +Similar to `marginalia-annotate-command', but does not show the +keybinding since CAND includes it." + (when-let (cmd (get-text-property 0 'embark-command cand)) + (marginalia--documentation (marginalia--function-doc cmd)))) + +(defun marginalia-annotate-imenu (cand) + "Annotate imenu CAND with its documentation string." + (when (derived-mode-p 'emacs-lisp-mode) + ;; Strip until the last whitespace in order to support flat imenu + (marginalia-annotate-symbol (replace-regexp-in-string "^.* " "" cand)))) + +(defun marginalia-annotate-function (cand) + "Annotate function CAND with its documentation string." + (when-let (sym (intern-soft cand)) + (when (fboundp sym) + (concat + (marginalia-annotate-binding cand) + (marginalia--fields + ((marginalia--symbol-class sym) :face 'marginalia-type) + ((marginalia--function-args sym) :face 'marginalia-value + :truncate (/ marginalia-truncate-width 2)) + ((marginalia--function-doc sym) :truncate marginalia-truncate-width + :face 'marginalia-documentation)))))) + +(defun marginalia--variable-value (sym) + "Return the variable value of SYM as string." + (cond + ((not (boundp sym)) + (propertize "#<unbound>" 'face 'marginalia-null)) + ((and marginalia-censor-variables + (let ((name (symbol-name sym))) + (cl-loop for r in marginalia-censor-variables + thereis (if (symbolp r) + (eq r sym) + (string-match-p r name))))) + (propertize "*****" 'face 'marginalia-null)) + (t (let ((val (symbol-value sym))) + (pcase val + ('nil (propertize "nil" 'face 'marginalia-null)) + ('t (propertize "t" 'face 'marginalia-true)) + ((pred keymapp) (propertize "#<keymap>" 'face 'marginalia-value)) + ((pred bool-vector-p) (propertize "#<bool-vector>" 'face 'marginalia-value)) + ((pred hash-table-p) (propertize "#<hash-table>" 'face 'marginalia-value)) + ((pred syntax-table-p) (propertize "#<syntax-table>" 'face 'marginalia-value)) + ;; Emacs BUG: abbrev-table-p throws an error + ((guard (ignore-errors (abbrev-table-p val))) (propertize "#<abbrev-table>" 'face 'marginalia-value)) + ((pred char-table-p) (propertize "#<char-table>" 'face 'marginalia-value)) + ((pred byte-code-function-p) (propertize "#<byte-code-function>" 'face 'marginalia-function)) + ((and (pred functionp) (pred symbolp)) + ;; NOTE: We are not consistent here, values are generally printed unquoted. But we + ;; make an exception for function symbols to visually distinguish them from symbols. + ;; I am not entirely happy with this, but we should not add quotation to every type. + (format (propertize "#'%s" 'face 'marginalia-function) val)) + ((pred recordp) (format (propertize "#<record %s>" 'face 'marginalia-value) (type-of val))) + ((pred symbolp) (propertize (symbol-name val) 'face 'marginalia-symbol)) + ((pred numberp) (propertize (number-to-string val) 'face 'marginalia-number)) + (_ (let ((print-escape-newlines t) + (print-escape-control-characters t) + (print-escape-multibyte t) + (print-level 10) + (print-length marginalia-truncate-width)) + (propertize + (prin1-to-string + (if (stringp val) + ;; Get rid of string properties to save some of the precious space + (substring-no-properties + val 0 + (min (length val) marginalia-truncate-width)) + val)) + 'face + (cond + ((listp val) 'marginalia-list) + ((stringp val) 'marginalia-string) + (t 'marginalia-value)))))))))) + +(defun marginalia-annotate-variable (cand) + "Annotate variable CAND with its documentation string." + (when-let (sym (intern-soft cand)) + (marginalia--fields + ((marginalia--symbol-class sym) :face 'marginalia-type) + ((marginalia--variable-value sym) :truncate (/ marginalia-truncate-width 2)) + ((documentation-property sym 'variable-documentation) + :truncate marginalia-truncate-width :face 'marginalia-documentation)))) + +(defun marginalia-annotate-environment-variable (cand) + "Annotate environment variable CAND with its current value." + (when-let (val (getenv cand)) + (marginalia--fields + (val :truncate marginalia-truncate-width :face 'marginalia-value)))) + +(defun marginalia-annotate-face (cand) + "Annotate face CAND with its documentation string and face example." + (when-let (sym (intern-soft cand)) + (marginalia--fields + ("abcdefghijklmNOPQRSTUVWXYZ" :face sym) + ((documentation-property sym 'face-documentation) + :truncate marginalia-truncate-width :face 'marginalia-documentation)))) + +(defun marginalia-annotate-color (cand) + "Annotate face CAND with its documentation string and face example." + (when-let (rgb (color-name-to-rgb cand)) + (pcase-let* ((`(,r ,g ,b) rgb) + (`(,h ,s ,l) (apply #'color-rgb-to-hsl rgb)) + (cr (color-rgb-to-hex r 0 0)) + (cg (color-rgb-to-hex 0 g 0)) + (cb (color-rgb-to-hex 0 0 b)) + (ch (apply #'color-rgb-to-hex (color-hsl-to-rgb h 1 0.5))) + (cs (apply #'color-rgb-to-hex (color-hsl-to-rgb h s 0.5))) + (cl (apply #'color-rgb-to-hex (color-hsl-to-rgb 0 0 l)))) + (marginalia--fields + (" " :face `(:background ,(apply #'color-rgb-to-hex rgb))) + ((format "%s%s%s %s" + (propertize "r" 'face `(:background ,cr :foreground ,(readable-foreground-color cr))) + (propertize "g" 'face `(:background ,cg :foreground ,(readable-foreground-color cg))) + (propertize "b" 'face `(:background ,cb :foreground ,(readable-foreground-color cb))) + (color-rgb-to-hex r g b 2))) + ((format "%s%s%s %3s° %3s%% %3s%%" + (propertize "h" 'face `(:background ,ch :foreground ,(readable-foreground-color ch))) + (propertize "s" 'face `(:background ,cs :foreground ,(readable-foreground-color cs))) + (propertize "l" 'face `(:background ,cl :foreground ,(readable-foreground-color cl))) + (round (* 360 h)) + (round (* 100 s)) + (round (* 100 l)))))))) + +(defun marginalia-annotate-char (cand) + "Annotate character CAND with its general character category and character code." + (when-let (char (char-from-name cand t)) + (concat + (format #(" (%c)" 1 5 (face marginalia-char)) char) + (marginalia--fields + (char :format "%06X" :face 'marginalia-number) + ((char-code-property-description + 'general-category + (get-char-code-property char 'general-category)) + :width 30 :face 'marginalia-documentation))))) + +(defun marginalia-annotate-minor-mode (cand) + "Annotate minor-mode CAND with status and documentation string." + (let* ((sym (intern-soft cand)) + (mode (if (and sym (boundp sym)) + sym + (lookup-minor-mode-from-indicator cand))) + (lighter (cdr (assq mode minor-mode-alist))) + (lighter-str (and lighter (string-trim (format-mode-line (cons t lighter)))))) + (concat + (marginalia--fields + ((if (and (boundp mode) (symbol-value mode)) + (propertize "On" 'face 'marginalia-on) + (propertize "Off" 'face 'marginalia-off)) :width 3) + ((if (local-variable-if-set-p mode) "Local" "Global") :width 6 :face 'marginalia-type) + (lighter-str :width 20 :face 'marginalia-lighter) + ((marginalia--function-doc mode) + :truncate marginalia-truncate-width :face 'marginalia-documentation))))) + +(defun marginalia-annotate-package (cand) + "Annotate package CAND with its description summary." + (when-let* ((pkg-alist (and (bound-and-true-p package-alist) package-alist)) + (pkg (intern-soft (replace-regexp-in-string "-[[:digit:]\\.-]+\\'" "" cand))) + ;; taken from `describe-package-1' + (desc (or (car (alist-get pkg pkg-alist)) + (if-let (built-in (assq pkg package--builtins)) + (package--from-builtin built-in) + (car (alist-get pkg package-archive-contents)))))) + (marginalia--fields + ((package-version-join (package-desc-version desc)) :width 16 :face 'marginalia-version) + ((cond + ((package-desc-archive desc) (propertize (package-desc-archive desc) 'face 'marginalia-archive)) + (t (propertize (or (package-desc-status desc) "orphan") 'face 'marginalia-installed))) :width 10) + ((package-desc-summary desc) :truncate marginalia-truncate-width :face 'marginalia-documentation)))) + +(defun marginalia--bookmark-type (bm) + "Return bookmark type string of BM. + +The string is transformed according to `marginalia-bookmark-type-transformers'." + (let ((handler (or (bookmark-get-handler bm) 'bookmark-default-handler))) + ;; Some libraries use lambda handlers instead of symbols. For + ;; example the function `xwidget-webkit-bookmark-make-record' is + ;; affected. I consider this bad style since then the lambda is + ;; persisted. + (when-let (str (and (symbolp handler) (symbol-name handler))) + (dolist (transformer marginalia-bookmark-type-transformers str) + (when (string-match-p (car transformer) str) + (setq str + (if (stringp (cdr transformer)) + (replace-regexp-in-string (car transformer) (cdr transformer) str) + (funcall (cdr transformer) str)))))))) + +(defun marginalia-annotate-bookmark (cand) + "Annotate bookmark CAND with its file name and front context string." + (when-let ((bm (assoc cand bookmark-alist))) + (let ((front (bookmark-get-front-context-string bm))) + (marginalia--fields + ((marginalia--bookmark-type bm) :width 10 :face 'marginalia-type) + ((bookmark-get-filename bm) + :truncate (- (/ marginalia-truncate-width 2)) :face 'marginalia-file-name) + ((if (or (not front) (string= front "")) + "" + (concat (string-trim + (replace-regexp-in-string + "[ \t]+" " " + (replace-regexp-in-string "\n" "\\\\n" front))) "…")) + :truncate (/ marginalia-truncate-width 3) :face 'marginalia-documentation))))) + +(defun marginalia-annotate-customize-group (cand) + "Annotate customization group CAND with its documentation string." + (marginalia--documentation (documentation-property (intern cand) 'group-documentation))) + +(defun marginalia-annotate-input-method (cand) + "Annotate input method CAND with its description." + (marginalia--documentation (nth 4 (assoc cand input-method-alist)))) + +(defun marginalia-annotate-charset (cand) + "Annotate charset CAND with its description." + (marginalia--documentation (charset-description (intern cand)))) + +(defun marginalia-annotate-coding-system (cand) + "Annotate coding system CAND with its description." + (marginalia--documentation (coding-system-doc-string (intern cand)))) + +(defun marginalia--buffer-status (buffer) + "Return the status of BUFFER as a string." + (format-mode-line '((:propertize "%1*%1+%1@" face marginalia-modified) + marginalia--separator + (7 (:propertize "%I" face marginalia-size)) + marginalia--separator + ;; InactiveMinibuffer has 18 letters, but there are longer names. + ;; For example Org-Agenda produces very long mode names. + ;; Therefore we have to truncate. + (20 (-20 (:propertize mode-name face marginalia-mode)))) + nil nil buffer)) + +(defun marginalia--buffer-file (buffer) + "Return the file or process name of BUFFER." + (if-let (proc (get-buffer-process buffer)) + (format "(%s %s) %s" + proc (process-status proc) + (abbreviate-file-name (buffer-local-value 'default-directory buffer))) + (abbreviate-file-name + (or (cond + ;; see ibuffer-buffer-file-name + ((buffer-file-name buffer)) + ((when-let (dir (and (local-variable-p 'dired-directory buffer) + (buffer-local-value 'dired-directory buffer))) + (expand-file-name (if (stringp dir) dir (car dir)) + (buffer-local-value 'default-directory buffer)))) + ((local-variable-p 'list-buffers-directory buffer) + (buffer-local-value 'list-buffers-directory buffer))) + "")))) + +(defun marginalia-annotate-buffer (cand) + "Annotate buffer CAND with modification status, file name and major mode." + (when-let (buffer (get-buffer cand)) + (marginalia--fields + ((marginalia--buffer-status buffer)) + ((marginalia--buffer-file buffer) + :truncate (- (/ marginalia-truncate-width 2)) + :face 'marginalia-file-name)))) + +(defun marginalia--full-candidate (cand) + "Return completion candidate CAND in full. +For some completion tables, the completion candidates offered are +meant to be only a part of the full minibuffer contents. For +example, during file name completion the candidates are one path +component of a full file path." + (if-let (win (active-minibuffer-window)) + (with-current-buffer (window-buffer win) + (if (bound-and-true-p selectrum-is-active) + (selectrum--get-full cand) + (concat (substring (minibuffer-contents-no-properties) + 0 marginalia--base-position) + cand))) + ;; no minibuffer is active, trust that cand already conveys all + ;; necessary information (there's not much else we can do) + cand)) + +(defun marginalia--remote-protocol (path) + "Return the remote protocol of PATH." + (save-match-data + (setq path (substitute-in-file-name path)) + (and (string-match "\\`/\\([^/|:]+\\):" path) + (match-string 1 path)))) + +(defun marginalia--annotate-local-file (cand) + "Annotate local file CAND." + (when-let (attrs (ignore-errors + ;; may throw permission denied errors + (file-attributes (substitute-in-file-name + (marginalia--full-candidate cand)) + 'integer))) + (marginalia--fields + ((marginalia--file-owner attrs) + :width 12 :face 'marginalia-file-owner) + ((marginalia--file-modes attrs)) + ((file-size-human-readable (file-attribute-size attrs)) + :face 'marginalia-size :width -7) + ((marginalia--time (file-attribute-modification-time attrs)) + :face 'marginalia-date :width -12)))) + +(defun marginalia-annotate-file (cand) + "Annotate file CAND with its size, modification time and other attributes. +These annotations are skipped for remote paths." + (if-let (remote (or (marginalia--remote-protocol cand) + (when-let (win (active-minibuffer-window)) + (with-current-buffer (window-buffer win) + (marginalia--remote-protocol (minibuffer-contents-no-properties)))))) + (marginalia--fields (remote :format "*%s*" :face 'marginalia-documentation)) + (marginalia--annotate-local-file cand))) + +(defun marginalia--file-owner (attrs) + "Return file owner given ATTRS." + (let ((uid (file-attribute-user-id attrs)) + (gid (file-attribute-group-id attrs))) + (if (or (/= (user-uid) uid) (/= (group-gid) gid)) + (format "%s:%s" (or (user-login-name uid) uid) (or (group-name gid) gid)) + ""))) + +(defun marginalia--file-modes (attrs) + "Return fontified file modes given the ATTRS." + ;; Without caching this can a be significant portion of the time + ;; `marginalia-annotate-file' takes to execute. Caching improves performance + ;; by about a factor of 20. + (setq attrs (file-attribute-modes attrs)) + (or (car (member attrs marginalia--fontified-file-modes)) + (progn + (setq attrs (substring attrs)) ;; copy because attrs is about to be modified + (dotimes (i (length attrs)) + (put-text-property + i (1+ i) 'face + (pcase (aref attrs i) + (?- 'marginalia-file-priv-no) + (?d 'marginalia-file-priv-dir) + (?l 'marginalia-file-priv-link) + (?r 'marginalia-file-priv-read) + (?w 'marginalia-file-priv-write) + (?x 'marginalia-file-priv-exec) + ((or ?s ?S ?t ?T) 'marginalia-file-priv-other) + (_ 'marginalia-file-priv-rare)) + attrs)) + (push attrs marginalia--fontified-file-modes) + attrs))) + +(defconst marginalia--time-relative + `((100 "sec" 1) + (,(* 60 100) "min" 60.0) + (,(* 3600 30) "hour" 3600.0) + (,(* 3600 24 400) "day" ,(* 3600.0 24.0)) + (nil "year" ,(* 365.25 24 3600))) + "Formatting used by the function `marginalia--time-relative'.") + +;; Taken from `seconds-to-string'. +(defun marginalia--time-relative (time) + "Format TIME as a relative age." + (setq time (float-time (time-since time))) + (if (<= time 0) + "0 secs ago" + (let ((sts marginalia--time-relative) here) + (while (and (car (setq here (pop sts))) (<= (car here) time))) + (setq time (round time (caddr here))) + (format "%s %s%s ago" time (cadr here) (if (= time 1) "" "s"))))) + +(defun marginalia--time-absolute (time) + "Format TIME as an absolute age." + (let ((system-time-locale "C")) + (format-time-string + ;; decoded-time-year is only available on Emacs 27, use nth 5 here. + (if (> (nth 5 (decode-time (current-time))) + (nth 5 (decode-time time))) + " %Y %b %d" + "%b %d %H:%M") + time))) + +(defun marginalia--time (time) + "Format file age TIME, suitably for use in annotations." + (if (< (float-time (time-since time)) marginalia-max-relative-age) + (marginalia--time-relative time) + (marginalia--time-absolute time))) + +(defmacro marginalia--project-root () + "Return project root." + (require 'project) + `(when-let (proj (project-current)) + ,(if (fboundp 'project-root) + '(project-root proj) + '(car (project-roots proj))))) + +(defun marginalia-annotate-project-file (cand) + "Annotate file CAND with its size, modification time and other attributes." + ;; TODO project-find-file can be called from outside all projects in + ;; which case it prompts for a project first; we don't support that + ;; case yet, since there is no current project. + (when-let (root (marginalia--project-root)) + (marginalia-annotate-file (expand-file-name cand root)))) + +(defun marginalia-classify-by-command-name () + "Lookup category for current command." + (and marginalia--command + (alist-get marginalia--command marginalia-command-categories))) + +(defun marginalia-classify-original-category () + "Return original category reported by completion metadata." + ;; NOTE: Use `alist-get' instead of `completion-metadata-get' to bypass our + ;; `marginalia--completion-metadata-get' advice! + (when-let (cat (alist-get 'category marginalia--metadata)) + ;; Ignore Emacs 28 symbol-help category in order to ensure that the + ;; categories are refined to our categories function and variable. + (and (not (eq cat 'symbol-help)) cat))) + +(defun marginalia-classify-symbol () + "Determine if currently completing symbols." + (when-let (mct minibuffer-completion-table) + (when (or (eq mct 'help--symbol-completion-table) + (obarrayp mct) + (and (not (functionp mct)) (consp mct) (symbolp (car mct)))) ; assume list of symbols + 'symbol))) + +(defun marginalia-classify-by-prompt () + "Determine category by matching regexps against the minibuffer prompt. +This runs through the `marginalia-prompt-categories' alist +looking for a regexp that matches the prompt." + (when-let (prompt (minibuffer-prompt)) + (setq prompt + (replace-regexp-in-string "(.*default.*)\\|\\[.*\\]" "" prompt)) + (cl-loop for (regexp . category) in marginalia-prompt-categories + when (string-match-p regexp prompt) + return category))) + +(defmacro marginalia--context (metadata &rest body) + "Setup annotator context with completion METADATA around BODY." + (declare (indent 1)) + (let ((w (make-symbol "w")) + (c (make-symbol "c")) + (o (make-symbol "o"))) + ;; Take the window width of the current window (minibuffer window!) + `(let ((marginalia--metadata ,metadata) + (,c marginalia--cache) + ;; Compute minimum width of windows, which display the minibuffer. + ;; vertico-buffer displays the minibuffer in different windows. We may + ;; want to generalize this and detect other types of completion + ;; buffers, e.g., Embark Collect or the default completion buffer. + (,w (cl-loop for win in (get-buffer-window-list) + minimize (window-width win))) + ;; Compute marginalia-align-offset. If the right-fringe-width is + ;; zero, use an additional offset of 1 by default! See + ;; https://github.com/minad/marginalia/issues/42 for the discussion + ;; regarding the alignment. + (,o (if (eq 0 (nth 1 (window-fringes))) 1 0))) + ;; We generally run the annotators in the original window. + ;; `with-selected-window' is necessary because of `lookup-minor-mode-from-indicator'. + ;; Otherwise it would probably suffice to only change the current buffer. + ;; We need the `selected-window' fallback for Embark Occur. + (with-selected-window (or (minibuffer-selected-window) (selected-window)) + (let ((marginalia--cache ,c) ;; Take the cache from the minibuffer + (marginalia-truncate-width (min (/ ,w 2) marginalia-truncate-width)) + (marginalia--separator (if (>= ,w marginalia-separator-threshold) " " " ")) + (marginalia--margin + (+ (or marginalia-align-offset ,o) + (if (>= ,w (+ marginalia-margin-min marginalia-margin-threshold)) + (- ,w marginalia-margin-threshold) + 0)))) + ,@body))))) + +(defun marginalia--cache-reset () + "Reset the cache." + (when marginalia--cache + (setq marginalia--cache (and (> marginalia--cache-size 0) + (cons nil (make-hash-table :test #'equal + :size marginalia--cache-size)))))) + +(defun marginalia--cached (fun key) + "Cached application of function FUN with KEY. + +The cache keeps around the last `marginalia--cache-size' computed annotations. +The cache is mainly useful when scrolling in completion UIs like Vertico or +Selectrum." + (if marginalia--cache + (let ((ht (cdr marginalia--cache))) + (or (gethash key ht) + (let ((val (funcall fun key))) + (setcar marginalia--cache (cons key (car marginalia--cache))) + (puthash key val ht) + (when (>= (hash-table-count ht) marginalia--cache-size) + (let ((end (last (car marginalia--cache) 2))) + (remhash (cadr end) ht) + (setcdr end nil))) + val))) + (funcall fun key))) + +(defun marginalia--completion-metadata-get (metadata prop) + "Meant as :before-until advice for `completion-metadata-get'. +METADATA is the metadata. +PROP is the property which is looked up." + (pcase prop + ('annotation-function + ;; we do want the advice triggered for completion-metadata-get + (when-let* ((cat (completion-metadata-get metadata 'category)) + (annotate (marginalia--annotator cat))) + (lambda (cand) + (marginalia--context metadata + (marginalia--cached annotate cand))))) + ('affixation-function + ;; We do want the advice triggered for `completion-metadata-get'. + ;; Return wrapper around `annotation-function'. + (when-let* ((cat (completion-metadata-get metadata 'category)) + (annotate (marginalia--annotator cat))) + (lambda (cands) + (marginalia--context metadata + (mapcar (lambda (x) (list x "" (or (marginalia--cached annotate x) ""))) cands))))) + ('category + ;; Find the completion category by trying each of our classifiers. + ;; Store the metadata for `marginalia-classify-original-category'. + (let ((marginalia--metadata metadata)) + (run-hook-with-args-until-success 'marginalia-classifiers))))) + +(defun marginalia--minibuffer-setup () + "Setup the minibuffer for Marginalia. +Remember `this-command' for `marginalia-classify-by-command-name'." + (setq marginalia--cache t marginalia--command this-command) + ;; Reset cache if window size changes, recompute alignment + (add-hook 'window-state-change-hook #'marginalia--cache-reset nil 'local) + (marginalia--cache-reset)) + +(defun marginalia--base-position (completions) + "Record the base position of COMPLETIONS." + ;; NOTE: As a small optimization track the base position only for file completions, + ;; since `marginalia--full-candidate' is only used for files as of now. + (when minibuffer-completing-file-name + (let ((base (or (cdr (last completions)) 0))) + (unless (= marginalia--base-position base) + (marginalia--cache-reset) + (setq marginalia--base-position base)))) + completions) + +;;;###autoload +(define-minor-mode marginalia-mode + "Annotate completion candidates with richer information." + :global t :group 'marginalia + (if marginalia-mode + (progn + ;; Ensure that we remember this-command in order to select the annotation function. + (add-hook 'minibuffer-setup-hook #'marginalia--minibuffer-setup) + ;; Replace the metadata function. + (advice-add #'completion-metadata-get :before-until #'marginalia--completion-metadata-get) + ;; Record completion base position, for marginalia--full-candidate + (advice-add #'completion-all-completions :filter-return #'marginalia--base-position)) + (advice-remove #'completion-all-completions #'marginalia--base-position) + (advice-remove #'completion-metadata-get #'marginalia--completion-metadata-get) + (remove-hook 'minibuffer-setup-hook #'marginalia--minibuffer-setup))) + +;;;###autoload +(defun marginalia-cycle () + "Cycle between annotators in `marginalia-annotator-registry'." + (interactive) + (if-let* ((win (active-minibuffer-window)) + (buf (window-buffer win))) + (with-current-buffer buf + (let* ((pt (max 0 (- (point) (minibuffer-prompt-end)))) + (metadata (completion-metadata (buffer-substring-no-properties + (minibuffer-prompt-end) + (+ (minibuffer-prompt-end) pt)) + minibuffer-completion-table + minibuffer-completion-predicate)) + (cat (completion-metadata-get metadata 'category))) + (unless cat + (user-error "Marginalia: Unknown completion category")) + (setq cat (assq cat marginalia-annotator-registry)) + (unless cat + (user-error "Marginalia: No annotators found")) + (marginalia--cache-reset) + (setcdr cat (append (cddr cat) (list (cadr cat)))) + ;; When the builtin annotator is selected and no builtin function is available, skip to + ;; the next annotator. Note that we cannot use `completion-metadata-get' to access the + ;; metadata since we must bypass the `marginalia--completion-metadata-get' advice. + (when (and (eq (cadr cat) 'builtin) + (not (assq 'annotation-function metadata)) + (not (assq 'affixation-function metadata)) + (not (plist-get completion-extra-properties :annotation-function)) + (not (plist-get completion-extra-properties :affixation-function))) + (setcdr cat (append (cddr cat) (list (cadr cat))))) + (message "Marginalia: Use annotator `%s' for category `%s'" (cadr cat) (car cat)))) + (user-error "Marginalia: No active minibuffer"))) + +(provide 'marginalia) +;;; marginalia.el ends here diff --git a/elpa/marginalia-0.11/marginalia.elc b/elpa/marginalia-0.11/marginalia.elc Binary files differ. diff --git a/elpa/marginalia-0.11/marginalia.info b/elpa/marginalia-0.11/marginalia.info @@ -0,0 +1,257 @@ +This is marginalia.info, produced by makeinfo version 6.7 from +marginalia.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Marginalia: (marginalia). Marginalia in the minibuffer. +END-INFO-DIR-ENTRY + + +File: marginalia.info, Node: Top, Next: Introduction, Up: (dir) + +marginalia.el - Marginalia in the minibuffer +******************************************** + +* Menu: + +* Introduction:: +* Configuration:: +* Information shown by the annotators:: +* Adding custom annotators or classifiers:: +* Disabling annotators, builtin or lightweight annotators: Disabling annotators builtin or lightweight annotators. +* Contributions:: + + +File: marginalia.info, Node: Introduction, Next: Configuration, Prev: Top, Up: Top + +1 Introduction +************** + +This package provides ‘marginalia-mode’ which adds marginalia to the +minibuffer completions. Marginalia +(https://en.wikipedia.org/wiki/Marginalia) are marks or annotations +placed at the margin of the page of a book or in this case helpful +colorful annotations placed at the margin of the minibuffer for your +completion candidates. Marginalia can only add annotations to be +displayed with the completion candidates. It cannot modify the +appearance of the candidates themselves, which are shown as supplied by +the original commands. + + The annotations are added based on the completion category. For +example ‘find-file’ reports the ‘file’ category and ‘M-x’ reports the +‘command’ category. You can cycle between more or less detailed +annotators or even disable the annotator with command +‘marginalia-cycle’. + + +File: marginalia.info, Node: Configuration, Next: Information shown by the annotators, Prev: Introduction, Up: Top + +2 Configuration +*************** + +It is recommended to use Marginalia together with either the Selectrum +(https://github.com/raxod502/selectrum), Vertico +(https://github.com/minad/vertico) or the Icomplete-vertical +(https://github.com/oantolin/icomplete-vertical) completion system. +Furthermore Marginalia can be combined with Embark +(https://github.com/oantolin/embark) for action support and Consult +(https://github.com/minad/consult), which provides many useful commands. + + ;; Enable richer annotations using the Marginalia package + (use-package marginalia + ;; Either bind `marginalia-cycle` globally or only in the minibuffer + :bind (("M-A" . marginalia-cycle) + :map minibuffer-local-map + ("M-A" . marginalia-cycle)) + + ;; The :init configuration is always executed (Not lazy!) + :init + + ;; Must be in the :init section of use-package such that the mode gets + ;; enabled right away. Note that this forces loading the package. + (marginalia-mode)) + + +File: marginalia.info, Node: Information shown by the annotators, Next: Adding custom annotators or classifiers, Prev: Configuration, Up: Top + +3 Information shown by the annotators +************************************* + +In general, to learn more about what different annotations mean, a good +starting point is to look at ‘marginalia-annotator-registry’, and follow +up to the annotation function of the category you are interested in. + + For example the annotations for elisp symbols include their symbol +class - v for variable, f for function, c for command, etc. For more +information on what the different classifications mean, see the +docstring of ‘marginalia--symbol-class’. + + +File: marginalia.info, Node: Adding custom annotators or classifiers, Next: Disabling annotators builtin or lightweight annotators, Prev: Information shown by the annotators, Up: Top + +4 Adding custom annotators or classifiers +***************************************** + +*IMPORTANT NOTICE FOR PACKAGE AUTHORS*: The intention of the Marginalia +package is to give the user means to overwrite completion categories and +to add custom annotators for existing commands in their user +configuration. Marginalia is a user facing package and is not intended +to be used as a library. Therefore Marginalia does not expose library +functions as part of its public API. If you add your own completion +commands to your package we recommend to specify an +‘annotation-function’ or an ‘affixation-function’, avoiding the +Marginalia dependency this way. The ‘annotation-function’ is documented +in the Elisp manual +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html). +There is an exception to our recommendation: If you want to implement +annotations for an existing package ‘hypothetical.el’, which does not +have annotations and where annotations cannot be added, then the +creation of a ‘marginalia-hypothetical.el’ package is a good idea, since +Marginalia provides the facilities to enhance existing commands from the +outside. If you have questions feel free to ask on the Marginalia issue +tracker! + + Commands that support minibuffer completion use a completion table of +all the available candidates. Candidates are associated with a +*category* such as ‘command’, ‘file’, ‘face’, or ‘variable’ depending on +what the candidates are. Based on the category of the candidates, +Marginalia selects an *annotator* to generate annotations for display +for each candidate. + + Unfortunately, not all commands (including Emacs’ builtin ones) +specify the category of their candidates. To compensate for this +shortcoming, Marginalia hooks into the emacs completion framework and +runs the *classifiers* listed in the variable ‘marginalia-classifiers’, +which use the command’s prompt or other properties of the candidates to +specify the completion category. + + For example, the ‘marginalia-classify-by-prompt’ classifier checks +the minibuffer prompt against regexps listed in the +‘marginalia-prompt-categories’ alist to determine a category. The +following is already included but would be a way to assign the category +‘face’ to all candidates from commands with prompts that include the +word "face". + + (add-to-list 'marginalia-prompt-categories '("\\<face\\>" . face)) + + The ‘marginalia-classify-by-command-name’ classifier uses the alist +‘marginalia-command-categories’ to specify the completion category based +on the command name. This is particularily useful if the prompt +classifier yields a false positive. + + Completion categories are also important for Embark +(https://github.com/oantolin/embark), which associates actions based on +the completion category and benefits from Marginalia’s classifiers. + + Once the category of the candidates is known, Marginalia looks in the +‘marginalia-annotator-registry’ to find the associated annotator to use. +An annotator is a function that takes a completion candidate string as +an argument and returns an annotation string to be displayed after the +candidate in the minibuffer. More than one annotator can be assigned to +each each category, displaying more, less or different information. Use +the ‘marginalia-cycle’ command to cycle between the annotations of +different annotators defined for the current category. + + Here’s an example of a basic face annotator: + + (defun my-face-annotator (cand) + (when-let (sym (intern-soft cand)) + (concat (propertize " " 'display '(space :align-to center)) + (propertize "The quick brown fox jumps over the lazy dog" 'face sym)))) + + Look at Marginalia’s various annotators for examples of formating +annotations. In particular, the helper function ‘marginalia--fields’ +can be used to format information into columns. + + After defining a new annotator, associate it with a category in the +annotator registry as follows: + + (add-to-list 'marginalia-annotator-registry + '(face my-face-annotator marginalia-annotate-face builtin none)) + + This makes the ‘my-face-annotator’ the first of four annotators for +the face category. The others are the annotator provided by Marginalia +(‘marginalia-annotate-face’), the ‘builtin’ annotator as defined by +Emacs and the ‘none’ annotator, which disables the annotations. With +this setting, after invoking ‘M-x describe-face RET’ you can cycle +between all of these annotators using ‘marginalia-cycle’. + + +File: marginalia.info, Node: Disabling annotators builtin or lightweight annotators, Next: Contributions, Prev: Adding custom annotators or classifiers, Up: Top + +5 Disabling annotators, builtin or lightweight annotators +********************************************************* + +Marginalia activates rich annotators by default. Depending on your +preference you may want to use the builtin annotators or even no +annotators by default and only activate the annotators on demand by +invoking ‘marginalia-cycle’. + + In order to use the builtin annotators by default, you can use the +following command. Replace ‘builtin’ by ‘none’ to disable annotators by +default. + + (defun marginalia-use-builtin () + (interactive) + (mapc + (lambda (x) + (setcdr x (cons 'builtin (remq 'builtin (cdr x))))) + marginalia-annotator-registry)) + + If a completion category supports two annotators, you can toggle +between those using this command. + + (defun marginalia-toggle () + (interactive) + (mapc + (lambda (x) + (setcdr x (append (reverse (remq 'none + (remq 'builtin (cdr x)))) + '(builtin none)))) + marginalia-annotator-registry)) + + After cycling the annotators you may want to automatically save the +configuration. This can be achieved using an advice which calls +‘customize-save-variable’. + + (advice-add #'marginalia-cycle :after + (lambda () + (let ((inhibit-message t)) + (customize-save-variable 'marginalia-annotator-registry + marginalia-annotator-registry)))) + + In order to disable an annotator permanently, the +‘marginalia-annotator-registry’ can be modified. For example if you +prefer to never see file annotations, you can delete all file annotators +from the registry. + + (setq marginalia-annotator-registry + (assq-delete-all 'file marginalia-annotator-registry)) + + +File: marginalia.info, Node: Contributions, Prev: Disabling annotators builtin or lightweight annotators, Up: Top + +6 Contributions +*************** + +Since this package is part of GNU ELPA +(http://elpa.gnu.org/packages/marginalia.html) contributions require a +copyright assignment to the FSF. + + + +Tag Table: +Node: Top203 +Node: Introduction626 +Node: Configuration1584 +Node: Information shown by the annotators2730 +Node: Adding custom annotators or classifiers3425 +Node: Disabling annotators builtin or lightweight annotators8227 +Node: Contributions10269 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/vertico-0.19.signed b/elpa/vertico-0.19.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-01-07T23:15:02+0100 using RSA +\ No newline at end of file diff --git a/elpa/vertico-0.19/LICENSE b/elpa/vertico-0.19/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/elpa/vertico-0.19/README.org b/elpa/vertico-0.19/README.org @@ -0,0 +1,562 @@ +#+title: vertico.el - VERTical Interactive COmpletion +#+author: Daniel Mendler +#+language: en +#+export_file_name: vertico.texi +#+texinfo_dir_category: Emacs +#+texinfo_dir_title: Vertico: (vertico). +#+texinfo_dir_desc: VERTical Interactive COmpletion. + +#+html: <a href="https://www.gnu.org/software/emacs/"><img alt="GNU Emacs" src="https://github.com/minad/corfu/blob/screenshots/emacs.svg?raw=true"/></a> +#+html: <a href="http://elpa.gnu.org/packages/vertico.html"><img alt="GNU ELPA" src="https://elpa.gnu.org/packages/vertico.svg"/></a> +#+html: <a href="http://elpa.gnu.org/devel/vertico.html"><img alt="GNU-devel ELPA" src="https://elpa.gnu.org/devel/vertico.svg"/></a> +#+html: <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Vertigomovie_restoration.jpg/800px-Vertigomovie_restoration.jpg" align="right" width="30%"> + +* Introduction + + Vertico provides a performant and minimalistic vertical completion UI based on + the default completion system. The main focus of Vertico is to provide a UI + which behaves /correctly/ under all circumstances. By reusing the built-in + facilities system, Vertico achieves /full compatibility/ with built-in Emacs + completion commands and completion tables. Vertico only provides the + completion UI but aims to be highly flexible, extensible and modular. + Additional enhancements are available as [[#extensions][extensions]] or [[#complementary-packages][complementary packages]]. + The code base is small and maintainable. The main ~vertico.el~ package is only + about 600 lines of code without white space and comments. + +* Features + + - Vertical display with arrow key navigation (see the [[#extensions][extensions]] for additional display modes) + - Prompt shows the current candidate index and the total number of candidates + - The current candidate is inserted with =TAB= and selected with =RET= + - Non-existing candidates can be entered by moving the point to the prompt line + - Configurable sorting by history position, length and alphabetically + - Long candidates with newlines are formatted to take up less space + - Deferred completion style highlighting for performance + - Support for annotations (~annotation-function~ and ~affixation-function~) + - Support for grouping and group cycling commands (~group-function~) + + [[https://github.com/minad/vertico/blob/screenshots/vertico-mx.png?raw=true]] + +* Key bindings + + Vertico defines its own local keymap in the minibuffer which is derived from + ~minibuffer-local-map~. The keymap keeps most of the ~fundamental-mode~ + keybindings intact and remaps and binds only a handful of commands. Note in + particular the binding of =TAB= to ~vertico-insert~ and the bindings of + ~vertico-exit/exit-input~. + + - ~beginning-of-buffer~, ~minibuffer-beginning-of-buffer~ -> ~vertico-first~ + - ~end-of-buffer~ -> ~vertico-last~ + - ~scroll-down-command~ -> ~vertico-scroll-down~ + - ~scroll-up-command~ -> ~vertico-scroll-up~ + - ~next-line~, ~next-line-or-history-element~ -> ~vertico-next~ + - ~previous-line~, ~previous-line-or-history-element~ -> ~vertico-previous~ + - ~forward-paragraph~ -> ~vertico-next-group~ + - ~backward-paragraph~ -> ~vertico-previous-group~ + - ~exit-minibuffer~ -> ~vertico-exit~ + - ~kill-ring-save~ -> ~vertico-save~ + - =C-<return>= -> ~vertico-exit-input~ + - =TAB= -> ~vertico-insert~ + +* Configuration + + Vertico is available from [[http://elpa.gnu.org/packages/vertico.html][GNU ELPA]]. You can install it directly via + ~package-install~. After installation, you can activate the global minor mode + with =M-x vertico-mode=. In order to configure Vertico and other packages in + your init.el, you may want to take advantage of ~use-package~. I recommend to + give Orderless completion a try, which is different from the prefix TAB + completion used by the basic default completion system or in shells. Here is + an example configuration: + + #+begin_src emacs-lisp + ;; Enable vertico + (use-package vertico + :init + (vertico-mode) + + ;; Different scroll margin + ;; (setq vertico-scroll-margin 0) + + ;; Show more candidates + ;; (setq vertico-count 20) + + ;; Grow and shrink the Vertico minibuffer + ;; (setq vertico-resize t) + + ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. + ;; (setq vertico-cycle t) + ) + + ;; Optionally use the `orderless' completion style. See + ;; `+orderless-dispatch' in the Consult wiki for an advanced Orderless style + ;; dispatcher. Additionally enable `partial-completion' for file path + ;; expansion. `partial-completion' is important for wildcard support. + ;; Multiple files can be opened at once with `find-file' if you enter a + ;; wildcard. You may also give the `initials' completion style a try. + (use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; A few more useful configurations... + (use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; Alternatively try `consult-completing-read-multiple'. + (defun crm-indicator (args) + (cons (concat "[CRM] " (car args)) (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + #+end_src + + See also the [[https://github.com/minad/vertico/wiki][Vertico Wiki]] for additional configuration tips. For more general + documentation read the chapter about completion in the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion.html][Emacs manual]]. If you + want to create your own completion commands, you can find documentation about + completion in the [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html][Elisp manual]]. + +** Completion styles and TAB completion + + The bindings of the ~minibuffer-local-completion-map~ are not available in + Vertico by default. This means that TAB works differently from what you may + expect from the default Emacs completion system. + + If you prefer to have the default completion commands a key press away you can + add new bindings or even replace the Vertico bindings. Then the default + completion commands behave as usual. For example you can use =M-TAB= to cycle + between candidates if you have set ~completion-cycle-threshold~. + + #+begin_src emacs-lisp + (define-key vertico-map "?" #'minibuffer-completion-help) + (define-key vertico-map (kbd "M-RET") #'minibuffer-force-complete-and-exit) + (define-key vertico-map (kbd "M-TAB") #'minibuffer-complete) + #+end_src + + The ~orderless~ completion style does not support completion of a common prefix + substring, as you may be familiar with from shells or the basic default + completion system. The reason is that the Orderless input string is usually + not a prefix. In order to support completing prefixes you may want to combine + ~orderless~ with ~substring~ in your =completion-styles= configuration. + + #+begin_src emacs-lisp + (setq completion-styles '(substring orderless)) + #+end_src + + Alternatively you can experiment with the built-in completion-styles, e.g., + adding =partial-completion= or =flex=. The =partial-completion= style is important + to add if you want to open multiple files at once with ~find-file~ using + wildcards. In order to open multiple files at once, you have to move to the + prompt and then press =RET=. + + #+begin_src emacs-lisp + (setq completion-styles '(basic substring partial-completion flex)) + #+end_src + + Because Vertico is fully compatible with Emacs default completion + system, further customization of completion behavior can be achieved + by setting the designated Emacs variables. For example, one may wish + to disable case-sensitivity for file and buffer matching when built-in + completion styles are used instead of ~orderless~: + + #+begin_src emacs-lisp + (setq read-file-name-completion-ignore-case t + read-buffer-completion-ignore-case t + completion-ignore-case t) + #+end_src + +** Completion-at-point and completion-in-region + + The =completion-at-point= command is usually bound to =M-TAB= or =TAB=. In case you + want to use Vertico for completion-at-point/completion-in-region, you can use + the function ~consult-completion-in-region~ provided by the Consult package. + + #+begin_src emacs-lisp + ;; Use `consult-completion-in-region' if Vertico is enabled. + ;; Otherwise use the default `completion--in-region' function. + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + #+end_src + + The =completion-in-region-function= setting also affects TAB completion in the + minibuffer when =M-:= (~eval-expression~) is used. + + You may also want to look into my [[https://github.com/minad/corfu][Corfu]] package, which provides a minimal + completion system for =completion-in-region= in a child frame popup. Corfu is + also a narrowly focused package and developed in the same spirit as Vertico. + +** Completing-read-multiple (CRM) + + Consult offers an enhanced =completing-read-multiple= implementation which you + can use with Vertico. + + #+begin_src emacs-lisp + (advice-add #'completing-read-multiple + :override #'consult-completing-read-multiple) + #+end_src + +* Extensions + :properties: + :custom_id: extensions + :end: + + We maintain small extension packages to Vertico in this repository in the + subdirectory [[https://github.com/minad/vertico/tree/main/extensions][extensions/]]. The extensions are installed together with Vertico + if you pull the package from ELPA. The extensions are inactive by default and + can be enabled manually if desired. Furthermore it is possible to install all + of the files separately, both ~vertico.el~ and the ~vertico-*.el~ extensions. + Currently the following extensions come with the Vertico ELPA package: + + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-buffer.el][vertico-buffer]]: =vertico-buffer-mode= to display Vertico in a separate buffer. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-directory.el][vertico-directory]]: Commands for Ido-like directory navigation. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-flat.el][vertico-flat]]: =vertico-flat-mode= to enable a flat, horizontal display. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-grid.el][vertico-grid]]: =vertico-grid-mode= to enable a grid display. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-indexed.el][vertico-indexed]]: =vertico-indexed-mode= to select indexed candidates with prefix arguments. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-mouse.el][vertico-mouse]]: =vertico-mouse-mode= to support for scrolling and candidate selection. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-multiform.el][vertico-multiform]]: Configure Vertico modes per command or completion category. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-quick.el][vertico-quick]]: Commands to select using Avy-style quick keys. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-repeat.el][vertico-repeat]]: The command =vertico-repeat= repeats the last completion session. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-reverse.el][vertico-reverse]]: =vertico-reverse-mode= to reverse the display. + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-unobtrusive.el][vertico-unobtrusive]]: =vertico-unobtrusive-mode= displays only the topmost candidate. + + With these extensions it is possible to adapt Vertico such that it matches + your preference or behaves similar to other familiar UIs. For example, the + combination =vertico-flat= plus =vertico-directory= resembles Ido in look and + feel. For an interface similar to Helm, the extension =vertico-buffer= allows + you to configure freely where the completion buffer opens, instead of growing + the minibuffer. Furthermore =vertico-buffer= will adjust the number of displayed + candidates according to the buffer height. + + Configuration example for =vertico-directory=: + + #+begin_src emacs-lisp + ;; Configure directory extension. + (use-package vertico-directory + :after vertico + :ensure nil + ;; More convenient directory navigation commands + :bind (:map 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)) + #+end_src + +** Configure Vertico per command or completion category + +[[https://github.com/minad/vertico/blob/screenshots/vertico-ripgrep.png?raw=true]] + +Vertico offers the =vertico-multiform-mode= which allows you to configure Vertico +per command or per completion category. The =vertico-buffer-mode= enables a +Helm-like buffer display, which takes more space but also displays more +candidates. This verbose display mode is useful for commands like ~consult-imenu~ +or ~consult-outline~ since the buffer display allows you to get a better overview +over the entire current buffer. But for other commands you want to keep using +the default Vertico display. ~vertico-multiform-mode~ solves this configuration +problem! + +#+begin_src emacs-lisp + ;; Enable vertico-multiform + (vertico-multiform-mode) + + ;; Configure the display per command. + ;; Use a buffer with indices for imenu + ;; and a flat (Ido-like) menu for M-x. + (setq vertico-multiform-commands + '((consult-imenu buffer indexed) + (execute-extended-command unobtrusive))) + + ;; Configure the display per completion category. + ;; Use the grid display for files and a buffer + ;; for the consult-grep commands. + (setq vertico-multiform-categories + '((file grid) + (consult-grep buffer))) +#+end_src + +You can use your own functions or even lambdas to configure the completion +behavior per command or per completion category. The function must have the +calling convention of a mode, i.e., it takes a single argument, which is either +1 to turn on the mode and -1 to turn off the mode. + +#+begin_src emacs-lisp + ;; Configure `consult-outline' as a scaled down TOC in a separate buffer + (setq vertico-multiform-commands + `((consult-outline buffer ,(lambda (_) (text-scale-set -1))))) +#+end_src + +Furthermore you can tune buffer-local settings per command or category. + +#+begin_src emacs-lisp + ;; Change the default sorting function + (setq vertico-multiform-commands + '((describe-symbol (vertico-sort-function . vertico-sort-alpha)))) + + (setq vertico-multiform-categories + '((symbol (vertico-sort-function . vertico-sort-alpha)) + (file (vertico-sort-function . sort-directories-first)))) + + ;; Sort directories before files + (defun sort-directories-first (files) + (setq files (vertico-sort-history-length-alpha files)) + (nconc (seq-filter (lambda (x) (string-suffix-p "/" x)) files) + (seq-remove (lambda (x) (string-suffix-p "/" x)) files))) +#+end_src + +Combining these features allows us to fine-tune the completion display even more +by adjusting the ~vertico-buffer-display-action~. We can for example reuse the +current window for commands of the ~consult-grep~ category (~consult-grep~, +~consult-git-grep~ and ~consult-ripgrep~). Note that this configuration is +incompatible with Consult preview, since the previewed buffer is usually shown +in exactly this window. Nevertheless this snippet demonstrates the flexibility +of the configuration system. + +#+begin_src emacs-lisp + ;; Configure the buffer display and the buffer display action + (setq vertico-multiform-categories + '((consult-grep + buffer + (vertico-buffer-display-action . (display-buffer-same-window))))) + + ;; Disable preview for consult-grep commands + (consult-customize consult-ripgrep consult-git-grep consult-grep :preview-key nil) +#+end_src + +As another example, the following code uses ~vertico-flat~ and ~vertico-cycle~ to +emulate ~(ido-mode 'buffer)~, i.e., Ido when it is enabled only for completion of +buffer names. ~vertico-cycle~ set to ~t~ is necessary here to prevent completion +candidates from disappearing when they scroll off-screen to the left. + +#+begin_src emacs-lisp + (setq vertico-multiform-categories + '((buffer flat (vertico-cycle . t)))) +#+end_src + +* Complementary packages + :properties: + :custom_id: complementary-packages + :end: + + Vertico integrates well with complementary packages, which enrich the + completion UI. These packages are fully supported: + + - [[https://github.com/minad/marginalia][Marginalia]]: Rich annotations in the minibuffer + - [[https://github.com/minad/consult][Consult]]: Useful search and navigation commands + - [[https://github.com/oantolin/embark][Embark]]: Minibuffer actions and context menu + - [[https://github.com/oantolin/orderless][Orderless]]: Advanced completion style + + In order to get accustomed with the package ecosystem, I recommed the + following quick start approach: + + 1. Start with plain Emacs (~emacs -Q~). + 2. Install and enable Vertico to get incremental minibuffer completion. + 3. Install Orderless and/or configure the built-in completion styles + for more flexible minibuffer filtering. + 4. Install Marginalia if you like rich minibuffer annotations. + 5. Install Embark and add two keybindings for ~embark-dwim~ and ~embark-act~. + I am using the mnemonic keybindings =M-.= and =C-.= since these commands allow + you to act on the object at point or in the minibuffer. + 6. Install Consult if you want additional featureful completion commands, + e.g, the buffer switcher ~consult-buffer~ with preview or the line-based + search ~consult-line~. + 7. Install Embark-Consult and Wgrep for export from =consult-line= to =occur-mode= + buffers and from =consult-grep= to editable =grep-mode= buffers. + 8. Fine tune Vertico with [[#extensions][extensions]]. + + The ecosystem is modular. You don't have to use all of these components. Use + only the ones you like and the ones which fit well into your setup. The + steps 1. to 4. introduce no new commands over plain Emacs. Step 5. introduces + the new commands ~embark-act~ and ~embark-dwim~. In step 6. you get the Consult + commands, some offer new functionality not present in Emacs already (e.g., + ~consult-line~) and some are substitutes (e.g., ~consult-buffer~ for + ~switch-to-buffer~). + +* Child frames and Popups + +An often requested feature is the ability to display the completions in a child +frame popup. Personally I am critical of using child frames for minibuffer +completion. From my experience it introduces more problems than it solves. Most +importantly child frames hide the content of the underlying buffer. Furthermore +child frames do not play well together with changing windows and entering +recursive minibuffer sessions. On top, child frames can feel slow and sometimes +flicker. A better alternative is the ~vertico-buffer~ display which can even be +configured individually per command using ~vertico-multiform~. On the plus side of +child frames, the completion display appears at the center of the screen, where +your eyes are focused. Please give the following packages a try and judge for +yourself. + +- [[https://github.com/muffinmad/emacs-mini-frame][mini-frame]]: Display the entire minibuffer in a child frame. +- [[https://github.com/minad/mini-popup][mini-popup]]: Slightly simpler alternative to mini-frame. +- [[https://github.com/tumashu/vertico-posframe][vertico-posframe]]: Display only the Vertico minibuffer in a child frame using + the posframe library. + +* Alternatives + + There are many alternative completion UIs, each UI with its own advantages and + disadvantages. + + Vertico aims to be 100% compliant with all Emacs commands and achieves that + with a minimal code base, relying purely on ~completing-read~ while avoiding to + invent its own APIs. Inventing a custom API as Helm or Ivy is explicitly + avoided in order to increase flexibility and package reuse. Due to its small + code base and reuse of the Emacs built-in facilities, bugs and compatibility + issues are less likely to occur in comparison to completion UIs or full + completion systems, which reimplement a lot of functionality. + + Since Vertico only provides the UI, you may want to combine it with some of + the complementary packages, to give a full-featured completion experience + similar to Helm or Ivy. Overall the packages in the spirit of Vertico have a + different style than Helm or Ivy. The idea is to have smaller independent + components, which one can add and understand step by step. Each component + focuses on its niche and tries to be as non-intrusive as possible. Vertico + targets users interested in crafting their Emacs precisely to their liking - + completion plays an integral part in how the users interacts with Emacs. + + There are other interactive completion UIs, which follow a similar philosophy: + + - [[https://github.com/raxod502/selectrum][Selectrum]]: Selectrum has a similar UI as Vertico, since it directly inspired + Vertico. The Selectrum code base is more complex. Unfortunately Selectrum is + not fully compatible with every Emacs completion command ([[https://github.com/raxod502/selectrum/issues/481][Issue #481]]), since + it uses its own filtering infrastructure, which deviates from the standard + Emacs completion facilities. Vertico additionally has the ability to cycle + over candidates, offers commands for grouping support and comes with a rich + set of [[#extensions][extensions]]. + - [[https://github.com/oantolin/icomplete-vertical][Icomplete-vertical]]: This package enhances the Emacs builtin Icomplete with a + vertical display. In contrast to Vertico, Icomplete rotates the candidates + such that the current candidate always appears at the top. From my + perspective, candidate rotation feels a bit less intuitive than the UI of + Vertico or Selectrum. Note that Emacs 28 offers a built-in + ~icomplete-vertical-mode~. + - [[https://gitlab.com/protesilaos/mct][Mct]]: Minibuffer and Completions in Tandem. Mct reuses the default ~*Completions*~ + buffer and enhances it with automatic updates and additional keybindings, to + select a candidate and move between minibuffer and completions buffer. Mct + is great if you prefer an unobtrusive UI since it can be configured to open + only when requested. Furthermore since Mct uses a fully functional buffer + you can reuse all your familar buffer commands inside the completions + buffer. The main distinction to Vertico's approach is that ~*Completions*~ + buffer displays all matching candidates. On the one hand this is good since + it allows you to interact with all the candidates and jump around with + Isearch or Avy. On the other hand it necessarily causes a slowdown in + comparison to Vertico, which only displays a subset of candidates. Mct + supports completion in region via its ~mct-region-mode~. + +* Problematic completion commands + + Vertico is robust in most scenarios. However some completion commands make + certain assumptions about the completion styles and the completion UI. Some of + these assumptions may not hold in Vertico or other UIs and require minor + workarounds. + +** ~org-refile~ + + ~org-refile~ uses ~org-olpath-completing-read~ to complete the outline path + in steps, when ~org-refile-use-outline-path~ is non-nil. + + Unfortunately the implementation of this Org completion table assumes that + the ~basic~ completion style is used. The table is incompatible with completion + styles like ~substring~, ~flex~ or ~orderless~. In order to fix the issue at the + root, the completion table should make use of completion boundaries similar + to the built-in file completion table. In your user configuration you can + prioritize ~basic~ before ~orderless:~ + + #+begin_src emacs-lisp + ;; Alternative 1: Use the basic completion style + (setq org-refile-use-outline-path 'file + org-outline-path-complete-in-steps t) + (advice-add #'org-olpath-completing-read :around + (lambda (&rest args) + (minibuffer-with-setup-hook + (lambda () (setq-local completion-styles '(basic))) + (apply args)))) + #+end_src + + Alternatively you may want to disable the outline path completion in steps. + The completion on the full path can be quicker since the input string matches + directly against substrings of the full path, which is useful with Orderless. + However the list of possible completions becomes much more cluttered. + + #+begin_src emacs-lisp + ;; Alternative 2: Complete full paths + (setq org-refile-use-outline-path 'file + org-outline-path-complete-in-steps nil) + #+end_src + +** ~tmm-menubar~ + + The text menu bar works well with Vertico but always shows a =*Completions*= + buffer, which is unwanted if you use the Vertico UI. This completion buffer + can be disabled as follows. + + #+begin_src emacs-lisp + (advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions) + #+end_src + +** ~ffap-menu~ + + The command ~ffap-menu~ shows the ==*Completions*= buffer by default like + ~tmm-menubar~, which is unnecessary with Vertico. This completion buffer can be + disabled as follows. + + #+begin_src emacs-lisp + (advice-add #'ffap-menu-ask :around (lambda (&rest args) + (cl-letf (((symbol-function #'minibuffer-completion-help) + #'ignore)) + (apply args)))) + #+end_src + +** Tramp hostname completion + + In combination with Orderless, hostnames are not made available for + completion after entering =/ssh:=. In order to avoid this problem, the =basic= + completion style should be specified for the file completion category. + + #+begin_src emacs-lisp + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic partial-completion)))) + #+end_src + + For users who are familiar with the =completion-style= machinery: You may also + define a custom completion style which sets in only for remote files! + + #+begin_src emacs-lisp + (defun basic-remote-try-completion (string table pred point) + (and (vertico--remote-p string) + (completion-basic-try-completion string table pred point))) + (defun basic-remote-all-completions (string table pred point) + (and (vertico--remote-p string) + (completion-basic-all-completions string table pred point))) + (add-to-list + 'completion-styles-alist + '(basic-remote basic-remote-try-completion basic-remote-all-completions nil)) + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic-remote partial-completion)))) + #+end_src + +* Contributions + + Since this package is part of [[http://elpa.gnu.org/packages/vertico.html][GNU ELPA]] contributions require a copyright + assignment to the FSF. diff --git a/elpa/vertico-0.19/dir b/elpa/vertico-0.19/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Vertico: (vertico). VERTical Interactive COmpletion. diff --git a/elpa/vertico-0.19/vertico-autoloads.el b/elpa/vertico-0.19/vertico-autoloads.el @@ -0,0 +1,321 @@ +;;; vertico-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "vertico" "vertico.el" (0 0 0 0)) +;;; Generated autoloads from vertico.el + +(defvar vertico-mode nil "\ +Non-nil if Vertico mode is enabled. +See the `vertico-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-mode'.") + +(custom-autoload 'vertico-mode "vertico" nil) + +(autoload 'vertico-mode "vertico" "\ +VERTical Interactive COmpletion. + +If called interactively, enable Vertico mode if ARG is positive, +and disable it if ARG is zero or negative. If called from Lisp, +also enable the mode if ARG is omitted or nil, and toggle it if +ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico" '("vertico-"))) + +;;;*** + +;;;### (autoloads nil "vertico-buffer" "vertico-buffer.el" (0 0 0 +;;;;;; 0)) +;;; Generated autoloads from vertico-buffer.el + +(defvar vertico-buffer-mode nil "\ +Non-nil if Vertico-Buffer mode is enabled. +See the `vertico-buffer-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-buffer-mode'.") + +(custom-autoload 'vertico-buffer-mode "vertico-buffer" nil) + +(autoload 'vertico-buffer-mode "vertico-buffer" "\ +Display Vertico in a buffer instead of the minibuffer. + +If called interactively, enable Vertico-Buffer mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-buffer" '("vertico-buffer-"))) + +;;;*** + +;;;### (autoloads nil "vertico-directory" "vertico-directory.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from vertico-directory.el + +(autoload 'vertico-directory-enter "vertico-directory" "\ +Enter directory or exit completion with current candidate." t nil) + +(autoload 'vertico-directory-up "vertico-directory" "\ +Delete directory before point." t nil) + +(autoload 'vertico-directory-delete-char "vertico-directory" "\ +Delete directory or char before point." t nil) + +(autoload 'vertico-directory-delete-word "vertico-directory" "\ +Delete directory or word before point." t nil) + +(autoload 'vertico-directory-tidy "vertico-directory" "\ +Tidy shadowed file name, see `rfn-eshadow-overlay'." nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-directory" '("vertico-directory--completing-file-p"))) + +;;;*** + +;;;### (autoloads nil "vertico-flat" "vertico-flat.el" (0 0 0 0)) +;;; Generated autoloads from vertico-flat.el + +(defvar vertico-flat-mode nil "\ +Non-nil if Vertico-Flat mode is enabled. +See the `vertico-flat-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-flat-mode'.") + +(custom-autoload 'vertico-flat-mode "vertico-flat" nil) + +(autoload 'vertico-flat-mode "vertico-flat" "\ +Flat, horizontal display for Vertico. + +If called interactively, enable Vertico-Flat mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-flat" '("vertico-flat-"))) + +;;;*** + +;;;### (autoloads nil "vertico-grid" "vertico-grid.el" (0 0 0 0)) +;;; Generated autoloads from vertico-grid.el + +(defvar vertico-grid-mode nil "\ +Non-nil if Vertico-Grid mode is enabled. +See the `vertico-grid-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-grid-mode'.") + +(custom-autoload 'vertico-grid-mode "vertico-grid" nil) + +(autoload 'vertico-grid-mode "vertico-grid" "\ +Grid display for Vertico. + +If called interactively, enable Vertico-Grid mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-grid" '("vertico-grid-"))) + +;;;*** + +;;;### (autoloads nil "vertico-indexed" "vertico-indexed.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from vertico-indexed.el + +(defvar vertico-indexed-mode nil "\ +Non-nil if Vertico-Indexed mode is enabled. +See the `vertico-indexed-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-indexed-mode'.") + +(custom-autoload 'vertico-indexed-mode "vertico-indexed" nil) + +(autoload 'vertico-indexed-mode "vertico-indexed" "\ +Prefix candidates with indices. + +If called interactively, enable Vertico-Indexed mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-indexed" '("vertico-indexed--"))) + +;;;*** + +;;;### (autoloads nil "vertico-mouse" "vertico-mouse.el" (0 0 0 0)) +;;; Generated autoloads from vertico-mouse.el + +(defvar vertico-mouse-mode nil "\ +Non-nil if Vertico-Mouse mode is enabled. +See the `vertico-mouse-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-mouse-mode'.") + +(custom-autoload 'vertico-mouse-mode "vertico-mouse" nil) + +(autoload 'vertico-mouse-mode "vertico-mouse" "\ +Mouse support for Vertico. + +If called interactively, enable Vertico-Mouse mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-mouse" '("vertico-mouse--"))) + +;;;*** + +;;;### (autoloads nil "vertico-multiform" "vertico-multiform.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from vertico-multiform.el + +(defvar vertico-multiform-mode nil "\ +Non-nil if Vertico-Multiform mode is enabled. +See the `vertico-multiform-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-multiform-mode'.") + +(custom-autoload 'vertico-multiform-mode "vertico-multiform" nil) + +(autoload 'vertico-multiform-mode "vertico-multiform" "\ +Configure Vertico in various forms per command. + +If called interactively, enable Vertico-Multiform mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-multiform" '("vertico-multiform-"))) + +;;;*** + +;;;### (autoloads nil "vertico-quick" "vertico-quick.el" (0 0 0 0)) +;;; Generated autoloads from vertico-quick.el + +(autoload 'vertico-quick-jump "vertico-quick" "\ +Jump to candidate using quick keys." t nil) + +(autoload 'vertico-quick-exit "vertico-quick" "\ +Exit with candidate using quick keys." t nil) + +(autoload 'vertico-quick-insert "vertico-quick" "\ +Insert candidate using quick keys." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-quick" '("vertico-quick"))) + +;;;*** + +;;;### (autoloads nil "vertico-repeat" "vertico-repeat.el" (0 0 0 +;;;;;; 0)) +;;; Generated autoloads from vertico-repeat.el + +(autoload 'vertico-repeat "vertico-repeat" "\ +Repeat last Vertico completion session." t nil) + +(autoload 'vertico-repeat-save "vertico-repeat" "\ +Save Vertico status for `vertico-repeat'. +This function must be registered as `minibuffer-setup-hook'." nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-repeat" '("vertico-repeat--"))) + +;;;*** + +;;;### (autoloads nil "vertico-reverse" "vertico-reverse.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from vertico-reverse.el + +(defvar vertico-reverse-mode nil "\ +Non-nil if Vertico-Reverse mode is enabled. +See the `vertico-reverse-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-reverse-mode'.") + +(custom-autoload 'vertico-reverse-mode "vertico-reverse" nil) + +(autoload 'vertico-reverse-mode "vertico-reverse" "\ +Reverse the Vertico display. + +If called interactively, enable Vertico-Reverse mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-reverse" '("vertico-reverse-"))) + +;;;*** + +;;;### (autoloads nil "vertico-unobtrusive" "vertico-unobtrusive.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from vertico-unobtrusive.el + +(defvar vertico-unobtrusive-mode nil "\ +Non-nil if Vertico-Unobtrusive mode is enabled. +See the `vertico-unobtrusive-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-unobtrusive-mode'.") + +(custom-autoload 'vertico-unobtrusive-mode "vertico-unobtrusive" nil) + +(autoload 'vertico-unobtrusive-mode "vertico-unobtrusive" "\ +Unobtrusive display for Vertico. + +If called interactively, enable Vertico-Unobtrusive mode if ARG +is positive, and disable it if ARG is zero or negative. If +called from Lisp, also enable the mode if ARG is omitted or nil, +and toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-unobtrusive" '("vertico-unobtrusive--orig-count"))) + +;;;*** + +;;;### (autoloads nil nil ("vertico-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; vertico-autoloads.el ends here diff --git a/elpa/vertico-0.19/vertico-buffer.el b/elpa/vertico-0.19/vertico-buffer.el @@ -0,0 +1,155 @@ +;;; vertico-buffer.el --- Display Vertico in a buffer instead of the minibuffer -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which displays Vertico in a +;; buffer instead of the minibuffer. The buffer display can be enabled +;; by the `vertico-buffer-mode'. + +;;; Code: + +(require 'vertico) + +(defvar-local vertico-buffer--window nil) + +(defcustom vertico-buffer-hide-prompt t + "Hide prompt in the minibuffer." + :group 'vertico + :type 'boolean) + +(defcustom vertico-buffer-display-action + '(display-buffer-reuse-window) + "Display action for the Vertico buffer." + :group 'vertico + :type `(choice + (const :tag "Reuse some window" + (display-buffer-reuse-window)) + (const :tag "Below target buffer" + (display-buffer-below-selected + (window-height . ,(+ 3 vertico-count)))) + (const :tag "Bottom of frame" + (display-buffer-at-bottom + (window-height . ,(+ 3 vertico-count)))) + (const :tag "Side window on the right" + (display-buffer-in-side-window + (side . right) + (window-width . 0.3))) + (const :tag "Side window on the left" + (display-buffer-in-side-window + (side . left) + (window-width . 0.3))) + (const :tag "Side window at the top" + (display-buffer-in-side-window + (window-height . ,(+ 3 vertico-count)) + (side . top))) + (const :tag "Side window at the bottom" + (display-buffer-in-side-window + (window-height . ,(+ 3 vertico-count)) + (side . bottom))) + (sexp :tag "Other"))) + +(defun vertico-buffer--redisplay (win) + "Redisplay window WIN." + (when-let (mbwin (active-minibuffer-window)) + (when (eq (window-buffer mbwin) (current-buffer)) + (let ((old cursor-in-non-selected-windows) + (new (and (eq (selected-window) mbwin) 'box))) + (unless (eq new old) + (setq-local cursor-in-non-selected-windows new) + (force-mode-line-update t))) + (when (eq win vertico-buffer--window) + (setq-local truncate-lines (< (window-point vertico-buffer--window) + (* 0.8 (window-width vertico-buffer--window)))) + (set-window-point vertico-buffer--window (point)) + (when vertico-buffer-hide-prompt + (window-resize mbwin (- (window-pixel-height mbwin)) nil nil 'pixelwise) + (set-window-vscroll mbwin 100)))))) + +(defun vertico-buffer--setup () + "Setup buffer display." + (add-hook 'pre-redisplay-functions 'vertico-buffer--redisplay nil 'local) + (let ((action vertico-buffer-display-action) + (temp (generate-new-buffer "*vertico*"))) + (setq vertico-buffer--window + ;; Temporarily select the original window such that `display-buffer-same-window' works. + (with-minibuffer-selected-window (display-buffer temp action))) + (set-window-buffer vertico-buffer--window (current-buffer)) + (kill-buffer temp)) + (let ((sym (make-symbol "vertico-buffer--destroy")) + (depth (recursion-depth)) + (now (window-parameter vertico-buffer--window 'no-other-window)) + (ndow (window-parameter vertico-buffer--window 'no-delete-other-windows))) + (fset sym (lambda () + (when (= depth (recursion-depth)) + (with-selected-window (active-minibuffer-window) + (when (window-live-p vertico-buffer--window) + (set-window-parameter vertico-buffer--window 'no-other-window now) + (set-window-parameter vertico-buffer--window 'no-delete-other-windows ndow)) + (when vertico-buffer-hide-prompt + (set-window-vscroll nil 0)) + (remove-hook 'minibuffer-exit-hook sym))))) + ;; NOTE: We cannot use a buffer-local minibuffer-exit-hook here. + ;; The hook will not be called when abnormally exiting the minibuffer + ;; from another buffer via `keyboard-escape-quit'. + (add-hook 'minibuffer-exit-hook sym) + (set-window-parameter vertico-buffer--window 'no-other-window t) + (set-window-parameter vertico-buffer--window 'no-delete-other-windows t) + (overlay-put vertico--candidates-ov 'window vertico-buffer--window) + (when (and vertico-buffer-hide-prompt vertico--count-ov) + (overlay-put vertico--count-ov 'window vertico-buffer--window)) + (setq-local show-trailing-whitespace nil + truncate-lines t + face-remapping-alist + (copy-tree `((mode-line-inactive mode-line) + ,@face-remapping-alist)) + mode-line-format + (list (format " %s " + (propertize + (format (if (< depth 2) "*%s*" "*%s [%s]*") + (replace-regexp-in-string + ":? *\\'" "" + (minibuffer-prompt)) + depth) + 'face 'mode-line-buffer-id))) + cursor-in-non-selected-windows 'box + vertico-count (- (/ (window-pixel-height vertico-buffer--window) + (default-line-height)) 2)))) + +;;;###autoload +(define-minor-mode vertico-buffer-mode + "Display Vertico in a buffer instead of the minibuffer." + :global t :group 'vertico + (cond + (vertico-buffer-mode + (advice-add #'vertico--setup :after #'vertico-buffer--setup) + (advice-add #'vertico--resize-window :override #'ignore)) + (t + (advice-remove #'vertico--setup #'vertico-buffer--setup) + (advice-remove #'vertico--resize-window #'ignore)))) + +(provide 'vertico-buffer) +;;; vertico-buffer.el ends here diff --git a/elpa/vertico-0.19/vertico-buffer.elc b/elpa/vertico-0.19/vertico-buffer.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-directory.el b/elpa/vertico-0.19/vertico-directory.el @@ -0,0 +1,117 @@ +;;; vertico-directory.el --- Ido-like direction navigation for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which provides Ido-like +;; directory navigation commands. The commands can be bound in the +;; `vertico-map'. Furthermore a cleanup function for shadowed file paths +;; is provided. +;; +;; (define-key vertico-map "\r" #'vertico-directory-enter) +;; (define-key vertico-map "\d" #'vertico-directory-delete-char) +;; (define-key vertico-map "\M-\d" #'vertico-directory-delete-word) +;; (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy) + +;;; Code: + +(require 'vertico) + +(defun vertico-directory--completing-file-p () + "Return non-nil when completing file names." + (eq 'file + (completion-metadata-get + (completion-metadata + (buffer-substring (minibuffer-prompt-end) + (max (minibuffer-prompt-end) (point))) + minibuffer-completion-table + minibuffer-completion-predicate) + 'category))) + +;;;###autoload +(defun vertico-directory-enter () + "Enter directory or exit completion with current candidate." + (interactive) + (if (and (>= vertico--index 0) + (let ((cand (vertico--candidate))) + (or (string-suffix-p "/" cand) + (and (vertico--remote-p cand) + (string-suffix-p ":" cand)))) + (vertico-directory--completing-file-p)) + (vertico-insert) + (vertico-exit))) + +;;;###autoload +(defun vertico-directory-up () + "Delete directory before point." + (interactive) + (when (and (> (point) (minibuffer-prompt-end)) + (eq (char-before) ?/) + (vertico-directory--completing-file-p)) + (let ((path (buffer-substring (minibuffer-prompt-end) (point)))) + (when (string-match-p "\\`~[^/]*/\\'" path) + (delete-minibuffer-contents) + (insert (expand-file-name path)))) + (save-excursion + (goto-char (1- (point))) + (when (search-backward "/" (minibuffer-prompt-end) t) + (delete-region (1+ (point)) (point-max)) + t)))) + +;;;###autoload +(defun vertico-directory-delete-char () + "Delete directory or char before point." + (interactive) + (unless (vertico-directory-up) + (call-interactively #'backward-delete-char))) + +;;;###autoload +(defun vertico-directory-delete-word () + "Delete directory or word before point." + (interactive) + (unless (vertico-directory-up) + (let ((pt (point))) + (forward-word -1) + (delete-region pt (point))))) + +;;;###autoload +(defun vertico-directory-tidy () + "Tidy shadowed file name, see `rfn-eshadow-overlay'." + (when (and (eq this-command #'self-insert-command) + (bound-and-true-p rfn-eshadow-overlay) + (overlay-buffer rfn-eshadow-overlay) + (= (point) (point-max)) + (or (>= (- (point) (overlay-end rfn-eshadow-overlay)) 2) + (eq ?/ (char-before (- (point) 2))))) + (delete-region (overlay-start rfn-eshadow-overlay) (overlay-end rfn-eshadow-overlay)))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-directory-up vertico-directory-enter + vertico-directory-delete-char vertico-directory-delete-word)) + (put sym 'completion-predicate #'vertico--command-p)) + +(provide 'vertico-directory) +;;; vertico-directory.el ends here diff --git a/elpa/vertico-0.19/vertico-directory.elc b/elpa/vertico-0.19/vertico-directory.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-flat.el b/elpa/vertico-0.19/vertico-flat.el @@ -0,0 +1,143 @@ +;;; vertico-flat.el --- Flat, horizontal display for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension providing a horizontal display. +;; +;; The mode can be enabled globally or via `vertico-multiform-mode' per +;; command or completion category. Alternatively the flat display can be +;; toggled temporarily if `vertico-multiform-mode' is enabled: +;; +;; (define-key vertico-map "\M-F" #'vertico-multiform-flat) +;; +;; The flat display can be made to look like `ido-mode' by setting +;; `vertico-cycle' to t. See also the `vertico-flat-format' +;; configuration variable for further tweaks. + +;;; Code: + +(require 'vertico) + +(defcustom vertico-flat-max-lines 1 + "Maximal number of lines to use." + :type 'integer + :group 'vertico) + +(defcustom vertico-flat-format + '(:left #("{" 0 1 (face minibuffer-prompt)) + :separator #(" | " 0 3 (face minibuffer-prompt)) + :right #("}" 0 1 (face minibuffer-prompt)) + :ellipsis #("…" 0 1 (face minibuffer-prompt)) + :only-match #("[%s]" 0 1 (face minibuffer-prompt) + 1 3 (face success) 3 4 (face minibuffer-prompt)) + :no-match "[No match]") + "Formatting strings." + :type 'plist + :group 'vertico) + +(defvar vertico-flat-map + (let ((map (make-sparse-keymap))) + (define-key map [remap left-char] #'vertico-previous) + (define-key map [remap right-char] #'vertico-next) + map) + "Additional keymap activated in flat mode.") + +(defun vertico-flat--display-candidates (candidates) + "Display CANDIDATES horizontally." + (setq-local truncate-lines nil + resize-mini-windows t) + (move-overlay vertico--candidates-ov (point-max) (point-max)) + (overlay-put + vertico--candidates-ov 'after-string + (concat #(" " 0 1 (cursor t)) + (cond + ((and (not candidates) (plist-get vertico-flat-format :no-match))) + ((and (= vertico--total 1) + (when-let (fmt (plist-get vertico-flat-format :only-match)) + (format fmt (substring-no-properties (car candidates)))))) + (t (concat (plist-get vertico-flat-format :left) + (string-join candidates (plist-get vertico-flat-format :separator)) + (plist-get vertico-flat-format :right))))))) + +(defun vertico-flat--arrange-candidates () + "Arrange candidates." + (let* ((index (max 0 vertico--index)) (count vertico-count) + (candidates (nthcdr vertico--index vertico--candidates)) + (width (- (* vertico-flat-max-lines (- (window-width) 4)) + (length (plist-get vertico-flat-format :left)) + (length (plist-get vertico-flat-format :separator)) + (length (plist-get vertico-flat-format :right)) + (length (plist-get vertico-flat-format :ellipsis)) + (car (posn-col-row (posn-at-point (1- (point-max))))))) + (result) (wrapped)) + (while (and candidates (not (eq wrapped (car candidates))) + (> width 0) (> count 0)) + (let ((cand (car candidates))) + (setq cand (car (funcall vertico--highlight-function (list cand)))) + (when (string-match-p "\n" cand) + (setq cand (vertico--truncate-multiline cand width))) + (setq cand (string-trim + (replace-regexp-in-string + "[ \t]+" + (lambda (x) (apply #'propertize " " (text-properties-at 0 x))) + (vertico--format-candidate cand "" "" index vertico--index)))) + (setq index (1+ index) + count (1- count) + width (- width (string-width cand) (length (plist-get vertico-flat-format :separator)))) + (when (or (not result) (> width 0)) + (push cand result)) + (pop candidates) + (when (and vertico-cycle (not candidates)) + (setq candidates vertico--candidates index 0 + wrapped (nth vertico--index vertico--candidates))))) + (when (if wrapped + (> vertico--total (- vertico-count count)) + (and (/= vertico--total 0) (/= index vertico--total))) + (push (plist-get vertico-flat-format :ellipsis) result)) + (nreverse result))) + +;;;###autoload +(define-minor-mode vertico-flat-mode + "Flat, horizontal display for Vertico." + :global t :group 'vertico + ;; Shrink current minibuffer window + (when-let (win (active-minibuffer-window)) + (window-resize win (- (window-pixel-height win)) nil nil 'pixelwise)) + (cond + (vertico-flat-mode + (unless (eq (cadr vertico-map) vertico-flat-map) + (setcdr vertico-map (cons vertico-flat-map (cdr vertico-map)))) + (advice-add #'vertico--arrange-candidates :override #'vertico-flat--arrange-candidates) + (advice-add #'vertico--display-candidates :override #'vertico-flat--display-candidates)) + (t + (when (eq (cadr vertico-map) vertico-flat-map) + (setcdr vertico-map (cddr vertico-map))) + (advice-remove #'vertico--arrange-candidates #'vertico-flat--arrange-candidates) + (advice-remove #'vertico--display-candidates #'vertico-flat--display-candidates)))) + +(provide 'vertico-flat) +;;; vertico-flat.el ends here diff --git a/elpa/vertico-0.19/vertico-flat.elc b/elpa/vertico-0.19/vertico-flat.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-grid.el b/elpa/vertico-0.19/vertico-grid.el @@ -0,0 +1,165 @@ +;;; vertico-grid.el --- Grid display for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension providing a grid display. +;; +;; The mode can be enabled globally or via `vertico-multiform-mode' per +;; command or completion category. Alternatively the grid display can be +;; toggled temporarily if `vertico-multiform-mode' is enabled: +;; +;; (define-key vertico-map "\M-G" #'vertico-multiform-grid) + +;;; Code: + +(require 'vertico) +(eval-when-compile + (require 'cl-lib)) + +(defcustom vertico-grid-max-columns 8 + "Maximal number of grid columns." + :type 'integer + :group 'vertico) + +(defcustom vertico-grid-separator + #(" | " 2 3 (display (space :width (1)) face (:inverse-video t))) + "Separator between columns." + :type 'string + :group 'vertico) + +(defcustom vertico-grid-rows 6 + "Number of grid rows." + :type 'integer + :group 'vertico) + +(defcustom vertico-grid-lookahead 200 + "Number of candidates to lookahead for column number computation. +When scrolling beyond this limit, candidates may be truncated." + :type 'integer + :group 'vertico) + +(defvar vertico-grid-map + (let ((map (make-sparse-keymap))) + (define-key map [remap left-char] #'vertico-grid-left) + (define-key map [remap right-char] #'vertico-grid-right) + map) + "Additional keymap activated in grid mode.") + +(defvar-local vertico-grid--columns 1 + "Current number of grid columns.") + +(defun vertico-grid--arrange-candidates () + "Arrange candidates." + (when (<= vertico--index 0) + (let ((cand vertico--candidates) (w 1) (n 0)) + (while (and cand (< n vertico-grid-lookahead)) + (setq w (max w (length (car cand))) n (1+ n)) + (pop cand)) + (setq vertico-grid--columns + (max 1 (min vertico-grid-max-columns + (floor (window-width) (+ w (length vertico-grid-separator)))))))) + (let* ((sep (length vertico-grid-separator)) + (count (* vertico-count vertico-grid--columns)) + (start (* count (floor (max 0 vertico--index) count))) + (width (- (/ (window-width) vertico-grid--columns) sep)) + (cands + (seq-map-indexed (lambda (cand index) + (cl-incf index start) + (when (string-match-p "\n" cand) + (setq cand (vertico--truncate-multiline cand width))) + (truncate-string-to-width + (string-trim + (replace-regexp-in-string + "[ \t]+" + (lambda (x) (apply #'propertize " " (text-properties-at 0 x))) + (vertico--format-candidate cand "" "" index start))) + width)) + (funcall vertico--highlight-function + (seq-subseq vertico--candidates start + (min (+ start count) + vertico--total))))) + (width (make-vector vertico-grid--columns 0))) + (dotimes (col vertico-grid--columns) + (dotimes (row vertico-count) + (aset width col (max + (aref width col) + (string-width (or (nth (+ row (* col vertico-count)) cands) "")))))) + (dotimes (col (1- vertico-grid--columns)) + (cl-incf (aref width (1+ col)) (+ (aref width col) sep))) + (cl-loop for row from 0 to (1- (min vertico-count vertico--total)) collect + (let ((line (list "\n"))) + (cl-loop for col from (1- vertico-grid--columns) downto 0 do + (when-let (cand (nth (+ row (* col vertico-count)) cands)) + (push cand line) + (when (> col 0) + (push vertico-grid-separator line) + (push (propertize " " 'display + `(space :align-to (+ left ,(aref width (1- col))))) line)))) + (string-join line))))) + +(defun vertico-grid-left (&optional n) + "Move N columns to the left in the grid." + (interactive "p") + (vertico-grid-right (- (or n 1)))) + +(defun vertico-grid-right (&optional n) + "Move N columns to the right in the grid." + (interactive "p") + (let* ((page (* vertico-count vertico-grid--columns)) + (p (/ vertico--index page)) + (q (mod vertico--index page)) + (x (/ q vertico-count)) + (y (mod q vertico-count)) + (z (+ (* p page) (* vertico-grid--columns y) x (or n 1)))) + (setq x (mod z vertico-grid--columns) + y (/ z vertico-grid--columns)) + (vertico--goto (+ (* x vertico-count) (mod y vertico-count) + (* (/ y vertico-count) page))))) + +;;;###autoload +(define-minor-mode vertico-grid-mode + "Grid display for Vertico." + :global t :group 'vertico + ;; Shrink current minibuffer window + (when-let (win (active-minibuffer-window)) + (window-resize win (- (window-pixel-height win)) nil nil 'pixelwise)) + (cond + (vertico-grid-mode + (unless (eq (cadr vertico-map) vertico-grid-map) + (setcdr vertico-map (cons vertico-grid-map (cdr vertico-map)))) + (advice-add #'vertico--arrange-candidates :override #'vertico-grid--arrange-candidates)) + (t + (when (eq (cadr vertico-map) vertico-grid-map) + (setcdr vertico-map (cddr vertico-map))) + (advice-remove #'vertico--arrange-candidates #'vertico-grid--arrange-candidates)))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-grid-left vertico-grid-right)) + (put sym 'completion-predicate #'vertico--command-p)) + +(provide 'vertico-grid) +;;; vertico-grid.el ends here diff --git a/elpa/vertico-0.19/vertico-grid.elc b/elpa/vertico-0.19/vertico-grid.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-indexed.el b/elpa/vertico-0.19/vertico-indexed.el @@ -0,0 +1,83 @@ +;;; vertico-indexed.el --- Select indexed candidates -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which prefixes candidates with +;; indices and allows you to select with prefix arguments. + +;;; Code: + +(require 'vertico) + +(defface vertico-indexed + '((t :height 0.75 :inherit font-lock-comment-face)) + "Face used for the candidate index prefix." + :group 'vertico-faces) + +(defvar vertico-indexed--commands + '(vertico-insert vertico-exit vertico-directory-enter)) +(defvar-local vertico-indexed--min 0) +(defvar-local vertico-indexed--max 0) + +(defun vertico-indexed--format-candidate (orig cand prefix suffix index start) + "Format candidate, see `vertico--format-candidate' for arguments." + (setq vertico-indexed--min start vertico-indexed--max index) + (funcall orig cand + (concat (propertize (format + (format "%%%ds " (if (> vertico-count 10) 2 1)) + (- index start)) + 'face 'vertico-indexed) + prefix) + suffix index start)) + +(defun vertico-indexed--handle-prefix (orig &rest args) + "Handle prefix argument before calling ORIG function with ARGS." + (if (and current-prefix-arg (called-interactively-p t)) + (let ((vertico--index (+ vertico-indexed--min (prefix-numeric-value current-prefix-arg)))) + (if (or (< vertico--index vertico-indexed--min) + (> vertico--index vertico-indexed--max) + (= vertico--total 0)) + (minibuffer-message "Out of range") + (funcall orig))) + (apply orig args))) + +;;;###autoload +(define-minor-mode vertico-indexed-mode + "Prefix candidates with indices." + :global t :group 'vertico + (cond + (vertico-indexed-mode + (advice-add #'vertico--format-candidate :around #'vertico-indexed--format-candidate) + (dolist (cmd vertico-indexed--commands) + (advice-add cmd :around #'vertico-indexed--handle-prefix))) + (t + (advice-remove #'vertico--format-candidate #'vertico-indexed--format-candidate) + (dolist (cmd vertico-indexed--commands) + (advice-remove cmd #'vertico-indexed--handle-prefix))))) + +(provide 'vertico-indexed) +;;; vertico-indexed.el ends here diff --git a/elpa/vertico-0.19/vertico-indexed.elc b/elpa/vertico-0.19/vertico-indexed.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-mouse.el b/elpa/vertico-0.19/vertico-mouse.el @@ -0,0 +1,95 @@ +;;; vertico-mouse.el --- Mouse support for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which adds mouse support. + +;;; Code: + +(require 'vertico) + +(defface vertico-mouse + '((t :inherit highlight)) + "Face used for mouse highlighting." + :group 'vertico-faces) + +(defun vertico-mouse--candidate-map (index) + "Return keymap for candidate with INDEX." + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] (lambda () + (interactive) + (with-selected-window (active-minibuffer-window) + (let ((vertico--index index)) + (vertico-exit))))) + (define-key map [mouse-3] (lambda () + (interactive) + (with-selected-window (active-minibuffer-window) + (let ((vertico--index index)) + (vertico-insert))))) + map)) + +(defun vertico-mouse--format-candidate (orig cand prefix suffix index start) + "Format candidate, see `vertico--format-candidate' for arguments." + (setq cand (funcall orig cand prefix suffix index start)) + (when (equal suffix "") + (setq cand (concat (substring cand 0 -1) + (propertize " " 'display '(space :align-to right)) + "\n")) + (when (= index vertico--index) + (add-face-text-property 0 (length cand) 'vertico-current 'append cand))) + (add-text-properties 0 (1- (length cand)) + `(mouse-face vertico-mouse keymap ,(vertico-mouse--candidate-map index)) + cand) + cand) + +(defun vertico-mouse--scroll-up (n) + "Scroll up by N lines." + (vertico--goto (max 0 (+ vertico--index n)))) + +(defun vertico-mouse--scroll-down (n) + "Scroll down by N lines." + (vertico-mouse--scroll-up (- n))) + +(defun vertico-mouse--setup () + "Setup mouse scrolling." + (setq-local mwheel-scroll-up-function #'vertico-mouse--scroll-up + mwheel-scroll-down-function #'vertico-mouse--scroll-down)) + +;;;###autoload +(define-minor-mode vertico-mouse-mode + "Mouse support for Vertico." + :global t :group 'vertico + (cond + (vertico-mouse-mode + (advice-add #'vertico--format-candidate :around #'vertico-mouse--format-candidate) + (advice-add #'vertico--setup :after #'vertico-mouse--setup)) + (t + (advice-remove #'vertico--format-candidate #'vertico-mouse--format-candidate) + (advice-remove #'vertico--setup #'vertico-mouse--setup)))) + +(provide 'vertico-mouse) +;;; vertico-mouse.el ends here diff --git a/elpa/vertico-0.19/vertico-mouse.elc b/elpa/vertico-0.19/vertico-mouse.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-multiform.el b/elpa/vertico-0.19/vertico-multiform.el @@ -0,0 +1,211 @@ +;;; vertico-multiform.el --- Configure Vertico in different forms per command -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension for fine tuning the Vertico +;; display and other minibuffer modes per command or completion +;; category. For some commands you may want to use the `vertico-buffer' +;; display and for completion categories like file you prefer the +;; `vertico-grid-mode'. +;; +;; Example: +;; +;; (setq vertico-multiform-commands +;; '((consult-line buffer) +;; (consult-imenu reverse buffer) +;; (execute-extended-command flat))) +;; +;; (setq vertico-multiform-categories +;; '((file buffer grid)) +;; (imenu (:not indexed mouse)) +;; (symbol (vertico-sort-function . vertico-sort-alpha)))) +;; +;; (vertico-multiform-mode) +;; +;; Temporary toggling between the different display modes is +;; possible. Bind the following commands: +;; +;; (define-key vertico-map "\M-G" #'vertico-multiform-grid) +;; (define-key vertico-map "\M-F" #'vertico-multiform-flat) +;; (define-key vertico-map "\M-R" #'vertico-multiform-reverse) +;; (define-key vertico-map "\M-U" #'vertico-multiform-unobtrusive) +;; +;;; Code: + +(require 'vertico) +(eval-when-compile + (require 'cl-lib)) + +(defcustom vertico-multiform-commands nil + "Alist of commands/regexps and list of settings to turn on per command. +Takes precedence over `vertico-multiform-categories'. A setting can +either be a mode symbol, a function, an inverted mode symbol or +function, or a cons cell of variable name and value." + :group 'vertico + :type '(alist :key-type (choice symbol regexp (const t)) :value-type (repeat sexp))) + +(defcustom vertico-multiform-categories nil + "Alist of categories/regexps and list of settings to turn on per category. +See `vertico-multiform-commands' on details about the settings. +Has lower precedence than `vertico-multiform-commands'." + :group 'vertico + :type '(alist :key-type (choice symbol regexp (const t)) :value-type (repeat sexp))) + +(defvar vertico-multiform--stack nil) + +(defun vertico-multiform--toggle (arg) + "Toggle modes from stack depending on ARG." + (when-let ((win (active-minibuffer-window)) + (modes (car vertico-multiform--stack))) + (when (> arg 0) (setq modes (reverse modes))) + (with-selected-window win + (dolist (m modes) + (if (eq (car-safe m) :not) + (funcall (cdr m) (- arg)) + (funcall m arg)))))) + +(defun vertico-multiform--lookup (key list) + "Lookup symbolic KEY in LIST. +The keys in LIST can be symbols or regexps." + (and (symbolp key) + (seq-find (lambda (x) + (cond + ((eq (car x) t)) + ((symbolp (car x)) (eq key (car x))) + ((string-match-p (car x) (symbol-name key))))) + list))) + +(defun vertico-multiform--setup () + "Enable modes at minibuffer setup." + (let ((cat (completion-metadata-get + (completion-metadata + (buffer-substring (minibuffer-prompt-end) + (max (minibuffer-prompt-end) (point))) + minibuffer-completion-table + minibuffer-completion-predicate) + 'category)) + (exit (make-symbol "vertico-multiform--exit")) + (depth (recursion-depth)) + (modes nil)) + (fset exit (lambda () + (when (= depth (recursion-depth)) + (remove-hook 'minibuffer-exit-hook exit) + (vertico-multiform--toggle -1) + (pop vertico-multiform--stack)))) + (add-hook 'minibuffer-exit-hook exit) + (dolist (x (cdr (or (vertico-multiform--lookup this-command vertico-multiform-commands) + (vertico-multiform--lookup cat vertico-multiform-categories)))) + (pcase x + (`(:not . ,fs) + (dolist (f fs) + (let ((sym (and (symbolp f) (intern-soft (format "vertico-%s-mode" f))))) + (push (cons :not (if (and sym (fboundp sym)) sym f)) modes)))) + ((or (pred functionp) (pred symbolp)) + (let ((sym (and (symbolp x) (intern-soft (format "vertico-%s-mode" x))))) + (push (if (and sym (fboundp sym)) sym x) modes))) + (`(,k . ,v) (set (make-local-variable k) v)) + (_ (error "Invalid multiform setting %S" x)))) + (push modes vertico-multiform--stack) + (vertico-multiform--toggle 1) + (vertico--setup))) + +(defun vertico-multiform--advice (&rest app) + "Override advice for `vertico--advice' switching modes on and off. +APP is the original function call." + (unwind-protect + (progn + (vertico-multiform--toggle -1) + (minibuffer-with-setup-hook #'vertico-multiform--setup + (apply app))) + (vertico-multiform--toggle 1))) + +;;;###autoload +(define-minor-mode vertico-multiform-mode + "Configure Vertico in various forms per command." + :global t :group 'vertico + (when (/= (recursion-depth) 0) + (warn "vertico-multiform must not be toggled from recursive minibuffers")) + (when vertico-multiform--stack + (warn "vertico-multiform state is inconsistent") + (setq vertico-multiform--stack nil)) + (if vertico-multiform-mode + (advice-add #'vertico--advice :override #'vertico-multiform--advice) + (advice-remove #'vertico--advice #'vertico-multiform--advice))) + +(defun vertico-multiform--ensure () + "Ensure that multiform mode is enabled." + (unless (minibufferp) + (user-error "`%s' must be called inside the minibuffer" this-command)) + (unless vertico-multiform-mode + (user-error "`vertico-multiform-mode' is not enabled"))) + +(defun vertico-multiform--temporary-mode (mode arg) + "Enable or disable MODE temporarily in minibuffer given ARG. +ARG can be nil, t, -1, 1 or toggle." + (unless (minibufferp) + (user-error "`%s' must be called inside the minibuffer" this-command)) + (unless vertico-multiform-mode + (user-error "`vertico-multiform-mode' is not enabled")) + (setq arg (pcase arg + ('toggle (not (and (boundp mode) (symbol-value mode)))) + ((or 'nil 't) arg) + (_ (> arg 0)))) + (unless (eq arg (and (boundp mode) (symbol-value mode))) + (funcall mode (if arg 1 -1)) + (let ((modes (car vertico-multiform--stack)) + (not-mode (cons :not mode))) + (when arg + (cl-rotatef not-mode mode)) + (if (member mode modes) + (setcar vertico-multiform--stack (remove mode modes)) + (push not-mode (car vertico-multiform--stack)))))) + +(defun vertico-multiform--display-toggle (mode) + "Toggle display MODE temporarily in minibuffer." + (let ((arg (not (and (boundp mode) (symbol-value mode))))) + (dolist (m '(vertico-unobtrusive-mode vertico-flat-mode + vertico-grid-mode vertico-reverse-mode)) + (vertico-multiform--temporary-mode m -1)) + (when arg (vertico-multiform--temporary-mode mode 1)))) + +(defmacro vertico-multiform--define-display-toggle (name) + "Define toggle for display mode NAME." + (let ((sym (intern (format "vertico-multiform-%s" name)))) + `(progn + (defun ,sym () + ,(format "Toggle the %s display." name) + (interactive) + (vertico-multiform--display-toggle ',(intern (format "vertico-%s-mode" name)))) + (put ',sym 'completion-predicate #'vertico--command-p)))) + +(vertico-multiform--define-display-toggle grid) +(vertico-multiform--define-display-toggle flat) +(vertico-multiform--define-display-toggle reverse) +(vertico-multiform--define-display-toggle unobtrusive) + +(provide 'vertico-multiform) +;;; vertico-multiform.el ends here diff --git a/elpa/vertico-0.19/vertico-multiform.elc b/elpa/vertico-0.19/vertico-multiform.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-pkg.el b/elpa/vertico-0.19/vertico-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from vertico.el -*- no-byte-compile: t -*- +(define-package "vertico" "0.19" "VERTical Interactive COmpletion" '((emacs "27.1")) :authors '(("Daniel Mendler" . "mail@daniel-mendler.de")) :maintainer '("Daniel Mendler" . "mail@daniel-mendler.de") :url "https://github.com/minad/vertico") diff --git a/elpa/vertico-0.19/vertico-quick.el b/elpa/vertico-0.19/vertico-quick.el @@ -0,0 +1,140 @@ +;;; vertico-quick.el --- Quick keys for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which provides quick keys. +;; (define-key vertico-map "\M-q" #'vertico-quick-insert) +;; (define-key vertico-map "\C-q" #'vertico-quick-exit) + +;;; Code: + +(require 'vertico) +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) + +(defface vertico-quick1 + '((((class color) (min-colors 88) (background dark)) + :background "#7042a2" :weight bold :foreground "white") + (((class color) (min-colors 88) (background light)) + :weight bold :background "#d5baff" :foreground "black") + (t :background "magenta" :foreground "white")) + "Face used for the first quick key." + :group 'vertico-faces) + +(defface vertico-quick2 + '((((class color) (min-colors 88) (background dark)) + :background "#004065" :weight bold :foreground "white") + (((class color) (min-colors 88) (background light)) + :weight bold :background "#8ae4f2" :foreground "black") + (t :background "blue" :foreground "white")) + "Face used for the second quick key." + :group 'vertico-faces) + +(defcustom vertico-quick1 "asdfgh" + "Single level quick keys." + :type 'string + :group 'vertico) + +(defcustom vertico-quick2 "jkl" + "Two level quick keys." + :type 'string + :group 'vertico) + +(defvar-local vertico-quick--list nil) +(defvar-local vertico-quick--first nil) + +(defun vertico-quick--format-candidate (orig cand prefix suffix index start) + "Format candidate, see `vertico--format-candidate' for arguments." + (let* ((fst (length vertico-quick1)) + (snd (length vertico-quick2)) + (len (+ fst snd)) + (idx (- index start)) + (keys (if (>= idx fst) + (let ((first (elt vertico-quick2 (mod (/ (- idx fst) len) snd))) + (second (elt (concat vertico-quick1 vertico-quick2) (mod (- idx fst) len)))) + (cond + ((eq first vertico-quick--first) + (push (cons second index) vertico-quick--list) + (concat " " (propertize (char-to-string second) 'face 'vertico-quick1))) + (vertico-quick--first " ") + (t + (push (cons first (list first)) vertico-quick--list) + (concat (propertize (char-to-string first) 'face 'vertico-quick1) + (propertize (char-to-string second) 'face 'vertico-quick2))))) + (let ((first (elt vertico-quick1 (mod idx fst)))) + (if vertico-quick--first + " " + (push (cons first index) vertico-quick--list) + (concat (propertize (char-to-string first) 'face 'vertico-quick1) " ")))))) + (if (bound-and-true-p vertico-flat-mode) + (setq keys (replace-regexp-in-string " " "" keys) + cand (string-trim cand) + cand (substring cand (min (length cand) (length keys)))) + (setq keys (concat keys (make-string (max 1 (- (length prefix) 2)) ?\s)))) + (funcall orig cand keys suffix index start))) + +(defun vertico-quick--read (&optional first) + "Read quick key given FIRST pressed key." + (cl-letf (((symbol-function #'vertico--format-candidate) + (apply-partially #'vertico-quick--format-candidate + (symbol-function #'vertico--format-candidate))) + (vertico-quick--first first) + (vertico-quick--list)) + (vertico--exhibit) + (alist-get (read-key) vertico-quick--list))) + +;;;###autoload +(defun vertico-quick-jump () + "Jump to candidate using quick keys." + (interactive) + (if (= vertico--total 0) + (and (minibuffer-message "No match") nil) + (let ((idx (vertico-quick--read))) + (when (consp idx) (setq idx (vertico-quick--read (car idx)))) + (when idx (setq vertico--index idx))))) + +;;;###autoload +(defun vertico-quick-exit () + "Exit with candidate using quick keys." + (interactive) + (when (vertico-quick-jump) + (vertico-exit))) + +;;;###autoload +(defun vertico-quick-insert () + "Insert candidate using quick keys." + (interactive) + (when (vertico-quick-jump) + (vertico-insert))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-quick-jump vertico-quick-exit vertico-quick-insert)) + (put sym 'completion-predicate #'vertico--command-p)) + +(provide 'vertico-quick) +;;; vertico-quick.el ends here diff --git a/elpa/vertico-0.19/vertico-quick.elc b/elpa/vertico-0.19/vertico-quick.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-repeat.el b/elpa/vertico-0.19/vertico-repeat.el @@ -0,0 +1,96 @@ +;;; vertico-repeat.el --- Repeat the last Vertico session -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which enables repetition of the +;; last Vertico session via the `vertico-repeat' command. +;; +;; (global-set-key "\M-r" #'vertico-repeat) +;; +;; It is necessary to register a minibuffer setup hook, which saves the +;; Vertico state for repetition. +;; +;; (add-hook 'minibuffer-setup-hook #'vertico-repeat-save) + +;;; Code: + +(require 'vertico) + +(defvar-local vertico-repeat--restore nil) +(defvar vertico-repeat--input nil) +(defvar vertico-repeat--command nil) +(defvar vertico-repeat--candidate nil) + +(defun vertico-repeat--save-input () + "Save current minibuffer content for `vertico-repeat'." + (setq vertico-repeat--input (minibuffer-contents))) + +(defun vertico-repeat--save-candidate () + "Save currently selected candidate for `vertico-repeat'." + (setq vertico-repeat--candidate + (and vertico--lock-candidate + (>= vertico--index 0) + (nth vertico--index vertico--candidates)))) + +(defun vertico-repeat--restore () + "Restore Vertico status for `vertico-repeat'." + (setq vertico-repeat--restore t) + (delete-minibuffer-contents) + (insert vertico-repeat--input) + (when vertico-repeat--candidate + (run-at-time 0 nil + (lambda () + (when-let (idx (seq-position vertico--candidates vertico-repeat--candidate)) + (setq vertico--index idx + vertico--lock-candidate t) + (vertico--exhibit)))))) + +;;;###autoload +(defun vertico-repeat () + "Repeat last Vertico completion session." + (interactive) + (unless vertico-repeat--command + (user-error "No repeatable Vertico session")) + (minibuffer-with-setup-hook + #'vertico-repeat--restore + (command-execute (setq this-command vertico-repeat--command)))) + +;;;###autoload +(defun vertico-repeat-save () + "Save Vertico status for `vertico-repeat'. +This function must be registered as `minibuffer-setup-hook'." + (when vertico--input + (unless vertico-repeat--restore + (setq vertico-repeat--command this-command + vertico-repeat--input "" + vertico-repeat--candidate nil + vertico-repeat--restore nil)) + (add-hook 'post-command-hook #'vertico-repeat--save-input nil 'local) + (add-hook 'minibuffer-exit-hook #'vertico-repeat--save-candidate nil 'local))) + +(provide 'vertico-repeat) +;;; vertico-repeat.el ends here diff --git a/elpa/vertico-0.19/vertico-repeat.elc b/elpa/vertico-0.19/vertico-repeat.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-reverse.el b/elpa/vertico-0.19/vertico-reverse.el @@ -0,0 +1,82 @@ +;;; vertico-reverse.el --- Reverse the Vertico display -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which reverses the list of candidates. + +;;; Code: + +(require 'vertico) + +(defvar vertico-reverse-map + (let ((map (make-sparse-keymap))) + (define-key map [remap beginning-of-buffer] #'vertico-last) + (define-key map [remap minibuffer-beginning-of-buffer] #'vertico-last) + (define-key map [remap end-of-buffer] #'vertico-first) + (define-key map [remap scroll-down-command] #'vertico-scroll-up) + (define-key map [remap scroll-up-command] #'vertico-scroll-down) + (define-key map [remap next-line] #'vertico-previous) + (define-key map [remap previous-line] #'vertico-next) + (define-key map [remap next-line-or-history-element] #'vertico-previous) + (define-key map [remap previous-line-or-history-element] #'vertico-next) + (define-key map [remap backward-paragraph] #'vertico-next-group) + (define-key map [remap forward-paragraph] #'vertico-previous-group) + map) + "Additional keymap activated in reverse mode.") + +(defun vertico-reverse--display-candidates (lines) + "Display LINES in reverse." + (move-overlay vertico--candidates-ov (point-min) (point-min)) + (setq lines (nreverse lines)) + (unless (eq vertico-resize t) + (setq lines (nconc (make-list (max 0 (- vertico-count (length lines))) "\n") lines))) + (let ((string (apply #'concat lines))) + (add-face-text-property 0 (length string) 'default 'append string) + (overlay-put vertico--candidates-ov 'before-string string) + (overlay-put vertico--candidates-ov 'after-string nil)) + (vertico--resize-window (length lines))) + +;;;###autoload +(define-minor-mode vertico-reverse-mode + "Reverse the Vertico display." + :global t :group 'vertico + ;; Reset overlays + (dolist (buf (buffer-list)) + (when-let (ov (buffer-local-value 'vertico--candidates-ov buf)) + (overlay-put ov 'before-string nil))) + (cond + (vertico-reverse-mode + (unless (eq (cadr vertico-map) vertico-reverse-map) + (setcdr vertico-map (cons vertico-reverse-map (cdr vertico-map)))) + (advice-add #'vertico--display-candidates :override #'vertico-reverse--display-candidates)) + (t + (when (eq (cadr vertico-map) vertico-reverse-map) + (setcdr vertico-map (cddr vertico-map))) + (advice-remove #'vertico--display-candidates #'vertico-reverse--display-candidates)))) + +(provide 'vertico-reverse) +;;; vertico-reverse.el ends here diff --git a/elpa/vertico-0.19/vertico-reverse.elc b/elpa/vertico-0.19/vertico-reverse.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico-unobtrusive.el b/elpa/vertico-0.19/vertico-unobtrusive.el @@ -0,0 +1,75 @@ +;;; vertico-unobtrusive.el --- Unobtrusive display for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.19")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension providing a unobtrusive display. +;; The unobtrusive display only shows the topmost candidate and nothing +;; else, it is a simple derivative of `vertico-flat-mode'. +;; +;; The mode can be enabled globally or via `vertico-multiform-mode' per +;; command or completion category. Alternatively the unobtrusive display +;; can be toggled temporarily if `vertico-multiform-mode' is enabled: +;; +;; (define-key vertico-map "\M-U" #'vertico-multiform-unobtrusive) + +;;; Code: + +(require 'vertico-flat) + +(defvar vertico-unobtrusive--orig-count nil) +(defvar vertico-unobtrusive--orig-count-format nil) + +;;;###autoload +(define-minor-mode vertico-unobtrusive-mode + "Unobtrusive display for Vertico." + :global t :group 'vertico + (cond + (vertico-unobtrusive-mode + (unless vertico-unobtrusive--orig-count + (push '(vertico-current . default) (default-value 'face-remapping-alist)) + (setq vertico-unobtrusive--orig-count vertico-count + vertico-unobtrusive--orig-count-format vertico-count-format + vertico-count 1 + vertico-count-format nil + vertico-flat-format `(:separator nil :ellipsis nil ,@vertico-flat-format))) + (advice-add #'vertico--setup :before #'redisplay) + (vertico-flat-mode 1)) + (t + (when vertico-unobtrusive--orig-count + (setq-default face-remapping-alist + (remove '(vertico-current . default) + (default-value 'face-remapping-alist))) + (setq vertico-count vertico-unobtrusive--orig-count + vertico-count-format vertico-unobtrusive--orig-count-format + vertico-flat-format (nthcdr 4 vertico-flat-format) + vertico-unobtrusive--orig-count nil)) + (advice-remove #'vertico--setup #'redisplay) + (vertico-flat-mode -1))) + (setq vertico-flat-mode nil)) + +(provide 'vertico-unobtrusive) +;;; vertico-unobtrusive.el ends here diff --git a/elpa/vertico-0.19/vertico-unobtrusive.elc b/elpa/vertico-0.19/vertico-unobtrusive.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico.el b/elpa/vertico-0.19/vertico.el @@ -0,0 +1,789 @@ +;;; vertico.el --- VERTical Interactive COmpletion -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.19 +;; Package-Requires: ((emacs "27.1")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Vertico provides a performant and minimalistic vertical completion UI +;; based on the default completion system. By reusing the built-in +;; facilities, Vertico achieves full compatibility with built-in Emacs +;; completion commands and completion tables. + +;;; Code: + +(require 'seq) +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) + +(defgroup vertico nil + "VERTical Interactive COmpletion." + :group 'convenience + :group 'minibuffer + :prefix "vertico-") + +(defcustom vertico-count-format (cons "%-6s " "%s/%s") + "Format string used for the candidate count." + :type '(choice (const :tag "No candidate count" nil) (cons string string))) + +(defcustom vertico-group-format + (concat #(" " 0 4 (face vertico-group-separator)) + #(" %s " 0 4 (face vertico-group-title)) + #(" " 0 1 (face vertico-group-separator display (space :align-to right)))) + "Format string used for the group title." + :type '(choice (const :tag "No group titles" nil) string)) + +(defcustom vertico-count 10 + "Maximal number of candidates to show." + :type 'integer) + +(defcustom vertico-scroll-margin 2 + "Number of lines at the top and bottom when scrolling. +The value should lie between 0 and vertico-count/2." + :type 'integer) + +(defcustom vertico-resize resize-mini-windows + "How to resize the Vertico minibuffer window. +See `resize-mini-windows' for documentation." + :type '(choice (const :tag "Fixed" nil) + (const :tag "Shrink and grow" t) + (const :tag "Grow-only" grow-only))) + +(defcustom vertico-cycle nil + "Enable cycling for `vertico-next' and `vertico-previous'." + :type 'boolean) + +(defcustom vertico-multiline + (cons #("⤶" 0 1 (face vertico-multiline)) #("…" 0 1 (face vertico-multiline))) + "Replacements for multiline strings." + :type '(cons (string :tag "Newline") (string :tag "Truncation"))) + +(defcustom vertico-sort-function #'vertico-sort-history-length-alpha + "Default sorting function, used if no `display-sort-function' is specified." + :type `(choice + (const :tag "No sorting" nil) + (const :tag "By history, length and alpha" ,#'vertico-sort-history-length-alpha) + (const :tag "By history and alpha" ,#'vertico-sort-history-alpha) + (const :tag "By length and alpha" ,#'vertico-sort-length-alpha) + (const :tag "Alphabetically" ,#'vertico-sort-alpha) + (function :tag "Custom function"))) + +(defgroup vertico-faces nil + "Faces used by Vertico." + :group 'vertico + :group 'faces) + +(defface vertico-multiline '((t :inherit shadow)) + "Face used to highlight multiline replacement characters.") + +(defface vertico-group-title '((t :inherit shadow :slant italic)) + "Face used for the title text of the candidate group headlines.") + +(defface vertico-group-separator '((t :inherit shadow :strike-through t)) + "Face used for the separator lines of the candidate groups.") + +(defface vertico-current '((t :inherit highlight :extend t)) + "Face used to highlight the currently selected candidate.") + +(defvar vertico-map + (let ((map (make-composed-keymap nil minibuffer-local-map))) + (define-key map [remap beginning-of-buffer] #'vertico-first) + (define-key map [remap minibuffer-beginning-of-buffer] #'vertico-first) + (define-key map [remap end-of-buffer] #'vertico-last) + (define-key map [remap scroll-down-command] #'vertico-scroll-down) + (define-key map [remap scroll-up-command] #'vertico-scroll-up) + (define-key map [remap next-line] #'vertico-next) + (define-key map [remap previous-line] #'vertico-previous) + (define-key map [remap next-line-or-history-element] #'vertico-next) + (define-key map [remap previous-line-or-history-element] #'vertico-previous) + (define-key map [remap backward-paragraph] #'vertico-previous-group) + (define-key map [remap forward-paragraph] #'vertico-next-group) + (define-key map [remap exit-minibuffer] #'vertico-exit) + (define-key map [remap kill-ring-save] #'vertico-save) + (define-key map [C-return] #'vertico-exit-input) + (define-key map "\t" #'vertico-insert) + map) + "Vertico minibuffer keymap derived from `minibuffer-local-map'.") + +(defvar-local vertico--highlight-function #'identity + "Deferred candidate highlighting function.") + +(defvar-local vertico--history-hash nil + "History hash table.") + +(defvar-local vertico--history-base nil + "Base prefix of `vertico--history-hash'.") + +(defvar-local vertico--candidates-ov nil + "Overlay showing the candidates.") + +(defvar-local vertico--count-ov nil + "Overlay showing the number of candidates.") + +(defvar-local vertico--index -1 + "Index of current candidate or negative for prompt selection.") + +(defvar-local vertico--scroll 0 + "Scroll position.") + +(defvar-local vertico--input nil + "Cons of last minibuffer contents and point or t.") + +(defvar-local vertico--candidates nil + "List of candidates.") + +(defvar-local vertico--metadata nil + "Completion metadata.") + +(defvar-local vertico--base 0 + "Size of the base string, which is concatenated with the candidate.") + +(defvar-local vertico--total 0 + "Length of the candidate list `vertico--candidates'.") + +(defvar-local vertico--lock-candidate nil + "Lock-in current candidate.") + +(defvar-local vertico--lock-groups nil + "Lock-in current group order.") + +(defvar-local vertico--all-groups nil + "List of all group titles.") + +(defvar-local vertico--groups nil + "List of current group titles.") + +(defvar-local vertico--default-missing nil + "Default candidate is missing from candidates list.") + +(defun vertico--history-hash () + "Recompute history hash table and return it." + (or vertico--history-hash + (let* ((base vertico--history-base) + (base-size (length base)) + ;; History disabled if `minibuffer-history-variable' eq `t'. + (hist (and (not (eq minibuffer-history-variable t)) + (symbol-value minibuffer-history-variable))) + (hash (make-hash-table :test #'equal :size (length hist)))) + (if (= base-size 0) + ;; Put history elements into the hash + (cl-loop for elem in hist for index from 0 do + (unless (gethash elem hash) + (puthash elem index hash))) + ;; Drop base string from history elements, before putting them into the hash + (cl-loop for elem in hist for index from 0 do + (when (and (>= (length elem) base-size) + (eq t (compare-strings base 0 base-size elem 0 base-size))) + (setq elem (substring elem base-size)) + (unless (gethash elem hash) + (puthash elem index hash))))) + (setq vertico--history-hash hash)))) + +(defun vertico--length-string< (x y) + "Sorting predicate which compares X and Y first by length then by `string<'." + (or (< (length x) (length y)) (and (= (length x) (length y)) (string< x y)))) + +(defun vertico--sort-decorated (list) + "Sort decorated LIST and remove decorations." + (setq list (sort list #'car-less-than-car)) + (cl-loop for item on list do (setcar item (cdar item))) + list) + +(defmacro vertico--define-sort (by bsize bindex bpred pred) + "Generate optimized sorting function. +The function is configured by BY, BSIZE, BINDEX, BPRED and PRED." + `(defun ,(intern (mapconcat #'symbol-name `(vertico sort ,@by) "-")) (candidates) + ,(concat "Sort candidates by " (mapconcat #'symbol-name by ", ") ".") + (let* ((buckets (make-vector ,bsize nil)) + ,@(and (eq (car by) 'history) '((hhash (vertico--history-hash)) (hcands)))) + (dolist (% candidates) + ,(if (eq (car by) 'history) + ;; Find recent candidates or fill buckets + `(if-let (idx (gethash % hhash)) + (push (cons idx %) hcands) + (let ((idx (min ,(1- bsize) ,bindex))) + (aset buckets idx (cons % (aref buckets idx))))) + ;; Fill buckets + `(let ((idx (min ,(1- bsize) ,bindex))) + (aset buckets idx (cons % (aref buckets idx)))))) + (nconc ,@(and (eq (car by) 'history) '((vertico--sort-decorated hcands))) + (mapcan (lambda (bucket) (sort bucket #',bpred)) + (nbutlast (append buckets nil))) + ;; Last bucket needs special treatment + (sort (aref buckets ,(1- bsize)) #',pred))))) + +(vertico--define-sort (history length alpha) 32 (length %) string< vertico--length-string<) +(vertico--define-sort (history alpha) 32 (if (eq % "") 0 (/ (aref % 0) 4)) string< string<) +(vertico--define-sort (length alpha) 32 (length %) string< vertico--length-string<) +(vertico--define-sort (alpha) 32 (if (eq % "") 0 (/ (aref % 0) 4)) string< string<) + +(defun vertico--affixate (cands) + "Annotate CANDS with annotation function." + (if-let (aff (or (vertico--metadata-get 'affixation-function) + (plist-get completion-extra-properties :affixation-function))) + (funcall aff cands) + (if-let (ann (or (vertico--metadata-get 'annotation-function) + (plist-get completion-extra-properties :annotation-function))) + (cl-loop for cand in cands collect + (let ((suffix (or (funcall ann cand) ""))) + (list cand "" + ;; The default completion UI adds the `completions-annotations' face + ;; if no other faces are present. + (if (text-property-not-all 0 (length suffix) 'face nil suffix) + suffix + (propertize suffix 'face 'completions-annotations))))) + (cl-loop for cand in cands collect (list cand "" ""))))) + +(defun vertico--move-to-front (elem list) + "Move ELEM to front of LIST." + (if-let (found (member elem list)) + (let ((head (list (car found)))) + (nconc head (delq (setcar found nil) list))) + list)) + +;; bug#47711: Deferred highlighting for `completion-all-completions' +;; XXX There is one complication: `completion--twq-all' already adds `completions-common-part'. +;; See below `vertico--candidate'. +(defun vertico--all-completions (&rest args) + "Compute all completions for ARGS with deferred highlighting." + (cl-letf* ((orig-pcm (symbol-function #'completion-pcm--hilit-commonality)) + (orig-flex (symbol-function #'completion-flex-all-completions)) + ((symbol-function #'completion-flex-all-completions) + (lambda (&rest args) + ;; Unfortunately for flex we have to undo the deferred highlighting, since flex uses + ;; the completion-score for sorting, which is applied during highlighting. + (cl-letf (((symbol-function #'completion-pcm--hilit-commonality) orig-pcm)) + (apply orig-flex args)))) + ;; Defer the following highlighting functions + (hl #'identity) + ((symbol-function #'completion-hilit-commonality) + (lambda (cands prefix &optional base) + (setq hl (lambda (x) (nconc (completion-hilit-commonality x prefix base) nil))) + (and cands (nconc cands base)))) + ((symbol-function #'completion-pcm--hilit-commonality) + (lambda (pattern cands) + (setq hl (lambda (x) + ;; `completion-pcm--hilit-commonality' sometimes throws an internal error + ;; for example when entering "/sudo:://u". + (condition-case nil + (completion-pcm--hilit-commonality pattern x) + (t x)))) + cands))) + ;; Only advise orderless after it has been loaded to avoid load order issues + (if (and (fboundp 'orderless-highlight-matches) (fboundp 'orderless-pattern-compiler)) + (cl-letf (((symbol-function 'orderless-highlight-matches) + (lambda (pattern cands) + (let ((regexps (orderless-pattern-compiler pattern))) + (setq hl (lambda (x) (orderless-highlight-matches regexps x)))) + cands))) + (cons (apply #'completion-all-completions args) hl)) + (cons (apply #'completion-all-completions args) hl)))) + +(defun vertico--metadata-get (prop) + "Return PROP from completion metadata." + (completion-metadata-get vertico--metadata prop)) + +(defun vertico--sort-function () + "Return the sorting function." + (or (vertico--metadata-get 'display-sort-function) vertico-sort-function)) + +(defun vertico--filter-files (files) + "Filter FILES by `completion-ignored-extensions'." + (let ((re (concat "\\(?:\\(?:\\`\\|/\\)\\.\\.?/\\|" + (regexp-opt completion-ignored-extensions) + "\\)\\'"))) + (or (seq-remove (lambda (x) (string-match-p re x)) files) files))) + +(defun vertico--recompute-candidates (pt content) + "Recompute candidates given PT and CONTENT." + (pcase-let* ((before (substring content 0 pt)) + (after (substring content pt)) + ;; bug#47678: `completion-boundaries` fails for `partial-completion` + ;; if the cursor is moved between the slashes of "~//". + ;; See also marginalia.el which has the same issue. + (bounds (or (condition-case nil + (completion-boundaries before + minibuffer-completion-table + minibuffer-completion-predicate + after) + (t (cons 0 (length after)))))) + (field (substring content (car bounds) (+ pt (cdr bounds)))) + ;; `minibuffer-completing-file-name' has been obsoleted by the completion category + (completing-file (eq 'file (vertico--metadata-get 'category))) + (`(,all . ,hl) (vertico--all-completions content + minibuffer-completion-table + minibuffer-completion-predicate + pt vertico--metadata)) + (base (or (when-let (z (last all)) (prog1 (cdr z) (setcdr z nil))) 0)) + (base-str (substring content 0 base)) + (def (or (car-safe minibuffer-default) minibuffer-default)) + (groups)) + ;; Reset the history hash table + (unless (equal base-str vertico--history-base) + (setq vertico--history-base base-str vertico--history-hash nil)) + ;; Filter the ignored file extensions. We cannot use modified predicate for this filtering, + ;; since this breaks the special casing in the `completion-file-name-table' for `file-exists-p' + ;; and `file-directory-p'. + (when completing-file + (setq all (vertico--filter-files all))) + ;; Sort using the `display-sort-function' or the Vertico sort functions + (setq all (delete-consecutive-dups (funcall (or (vertico--sort-function) #'identity) all))) + ;; Move special candidates: "field" appears at the top, before "field/", before default value + (when (stringp def) + (setq all (vertico--move-to-front def all))) + (when (and completing-file (not (string-suffix-p "/" field))) + (setq all (vertico--move-to-front (concat field "/") all))) + (setq all (vertico--move-to-front field all)) + (when-let (group-fun (and all (vertico--metadata-get 'group-function))) + (setq groups (vertico--group-by group-fun all) all (car groups))) + (list base (length all) + ;; Default value is missing from collection + (and def (equal content "") (not (member def all))) + ;; Find position of old candidate in the new list. + (when vertico--lock-candidate + (if (< vertico--index 0) + vertico--index + (seq-position all (nth vertico--index vertico--candidates)))) + all (cadr groups) (or (caddr groups) vertico--all-groups) hl))) + +(defun vertico--cycle (list n) + "Rotate LIST to position N." + (nconc (copy-sequence (nthcdr n list)) (seq-take list n))) + +(defun vertico--group-by (fun elems) + "Group ELEMS by FUN." + (let ((ht (make-hash-table :test #'equal)) titles groups) + ;; Build hash table of groups + (while elems + (let* ((title (funcall fun (car elems) nil)) + (group (gethash title ht))) + (if group + (setcdr group (setcdr (cdr group) elems)) ;; Append to tail of group + (puthash title (cons elems elems) ht) ;; New group element (head . tail) + (push title titles)) + (pop elems))) + (setq titles (nreverse titles)) + ;; Cycle groups if `vertico--lock-groups' is set + (when-let (group (and vertico--lock-groups + (seq-find (lambda (group) (gethash group ht)) + vertico--all-groups))) + (setq titles (vertico--cycle titles (seq-position titles group)))) + ;; Build group list + (dolist (title titles) + (push (gethash title ht) groups)) + ;; Unlink last tail + (setcdr (cdar groups) nil) + (setq groups (nreverse groups)) + ;; Link groups + (let ((link groups)) + (while (cdr link) + (setcdr (cdar link) (caadr link)) + (pop link))) + ;; Check if new groups are found + (dolist (group vertico--all-groups) + (remhash group ht)) + (list (caar groups) titles + (if (hash-table-empty-p ht) vertico--all-groups titles)))) + +(defun vertico--remote-p (path) + "Return t if PATH is a remote path." + (string-match-p "\\`/[^/|:]+:" (substitute-in-file-name path))) + +(defun vertico--update-candidates (pt content) + "Preprocess candidates given PT and CONTENT." + ;; Redisplay the minibuffer such that the input becomes immediately + ;; visible before the expensive candidate recomputation is performed (Issue #89). + ;; Do not redisplay during initialization, since this leads to flicker. + (when (consp vertico--input) (redisplay)) + (let ((metadata (completion-metadata (substring content 0 pt) + minibuffer-completion-table + minibuffer-completion-predicate))) + (pcase + (let ((vertico--metadata metadata)) + ;; If Tramp is used, do not compute the candidates in an interruptible fashion, + ;; since this will break the Tramp password and user name prompts (See #23). + (if (and (eq 'file (vertico--metadata-get 'category)) + (or (vertico--remote-p content) (vertico--remote-p default-directory))) + (vertico--recompute-candidates pt content) + (let ((non-essential t)) + (while-no-input (vertico--recompute-candidates pt content))))) + ('nil (abort-recursive-edit)) + (`(,base ,total ,def-missing ,index ,candidates ,groups ,all-groups ,hl) + (setq vertico--input (cons content pt) + vertico--index index + vertico--base base + vertico--total total + vertico--highlight-function hl + vertico--groups groups + vertico--all-groups all-groups + vertico--candidates candidates + vertico--default-missing def-missing + vertico--metadata metadata) + ;; If the current index is nil, compute new index. Select the prompt: + ;; * If there are no candidates + ;; * If the default is missing from the candidate list. + ;; * For matching content, as long as the full content after the boundary is empty, + ;; including content after point. + (unless vertico--index + (setq vertico--lock-candidate nil + vertico--index + (if (or vertico--default-missing + (= 0 vertico--total) + (and (= base (length content)) + (test-completion content minibuffer-completion-table + minibuffer-completion-predicate))) + -1 0))))))) + +(defun vertico--display-string (str) + "Return display STR without display and invisible properties." + (let ((end (length str)) (pos 0) chunks) + (while (< pos end) + (let ((nextd (next-single-property-change pos 'display str end)) + (display (get-text-property pos 'display str))) + (if (stringp display) + (progn (push display chunks) (setq pos nextd)) + (while (< pos nextd) + (let ((nexti (next-single-property-change pos 'invisible str nextd))) + (unless (get-text-property pos 'invisible str) + (unless (and (= pos 0) (= nexti end)) ;; full string -> avoid allocation + (push (substring str pos nexti) chunks))) + (setq pos nexti)))))) + (if chunks (apply #'concat (nreverse chunks)) str))) + +(defun vertico--truncate-multiline (cand max-width) + "Truncate multiline CAND to MAX-WIDTH." + (truncate-string-to-width + (thread-last cand + (replace-regexp-in-string "[\t ]+" " ") + (replace-regexp-in-string "[\t\n ]*\n[\t\n ]*" (car vertico-multiline)) + (replace-regexp-in-string "\\`[\t\n ]+\\|[\t\n ]+\\'" "")) + max-width 0 nil (cdr vertico-multiline))) + +(defun vertico--format-candidate (cand prefix suffix index _start) + "Format CAND given PREFIX, SUFFIX and INDEX." + (setq cand (vertico--display-string (concat prefix cand suffix "\n"))) + (when (= index vertico--index) + (add-face-text-property 0 (length cand) 'vertico-current 'append cand)) + cand) + +(defun vertico--update-scroll () + "Update scroll position." + (let ((off (max (min vertico-scroll-margin (/ vertico-count 2)) 0)) + (corr (if (= vertico-scroll-margin (/ vertico-count 2)) (1- (mod vertico-count 2)) 0))) + (setq vertico--scroll (min (max 0 (- vertico--total vertico-count)) + (max 0 (+ vertico--index off 1 (- vertico-count)) + (min (- vertico--index off corr) vertico--scroll)))))) + +(defun vertico--format-group-title (title cand) + "Format group TITLE given the current CAND." + (when (string-prefix-p title cand) + ;; Highlight title if title is a prefix of the candidate + (setq title (substring (car (funcall vertico--highlight-function + (list (propertize cand 'face 'vertico-group-title)))) + 0 (length title))) + (vertico--remove-face 0 (length title) 'completions-first-difference title)) + (format (concat vertico-group-format "\n") title)) + +(defun vertico--arrange-candidates () + "Arrange candidates." + (vertico--update-scroll) + (let ((curr-line 0) lines) + ;; Compute group titles + (let* (title (index vertico--scroll) + (group-fun (and vertico-group-format (vertico--metadata-get 'group-function))) + (candidates + (thread-last (seq-subseq vertico--candidates index + (min (+ index vertico-count) vertico--total)) + (funcall vertico--highlight-function) + (vertico--affixate)))) + (dolist (cand candidates) + (let ((str (car cand))) + (when-let (new-title (and group-fun (funcall group-fun str nil))) + (unless (equal title new-title) + (setq title new-title) + (push (vertico--format-group-title title str) lines)) + (setcar cand (funcall group-fun str 'transform)))) + (when (= index vertico--index) + (setq curr-line (length lines))) + (push (cons index cand) lines) + (setq index (1+ index)))) + ;; Drop excess lines + (setq lines (nreverse lines)) + (cl-loop for count from (length lines) above vertico-count do + (if (< curr-line (/ count 2)) + (nbutlast lines) + (setq curr-line (1- curr-line) lines (cdr lines)))) + ;; Format candidates + (let ((max-width (- (window-width) 4)) start) + (cl-loop for line on lines do + (pcase (car line) + (`(,index ,cand ,prefix ,suffix) + (setq start (or start index)) + (when (string-match-p "\n" cand) + (setq cand (vertico--truncate-multiline cand max-width))) + (setcar line (vertico--format-candidate cand prefix suffix index start)))))) + lines)) + +(defun vertico--display-candidates (lines) + "Update candidates overlay `vertico--candidates-ov' with LINES." + (move-overlay vertico--candidates-ov (point-max) (point-max)) + (overlay-put vertico--candidates-ov 'after-string + (apply #'concat #(" " 0 1 (cursor t)) (and lines "\n") lines)) + (vertico--resize-window (length lines))) + +(defun vertico--resize-window (height) + "Resize active minibuffer window to HEIGHT." + (setq-local truncate-lines (< (point) (* 0.8 (window-width))) + resize-mini-windows 'grow-only + max-mini-window-height 1.0) + (unless (frame-root-window-p (active-minibuffer-window)) + (unless vertico-resize + (setq height (max height vertico-count))) + (let* ((window-resize-pixelwise t) + (dp (- (max (cdr (window-text-pixel-size)) + (* (default-line-height) (1+ height))) + (window-pixel-height)))) + (when (or (and (> dp 0) (/= height 0)) + (and (< dp 0) (eq vertico-resize t))) + (window-resize nil dp nil nil 'pixelwise))))) + +(defun vertico--format-count () + "Format the count string." + (format (car vertico-count-format) + (format (cdr vertico-count-format) + (cond ((>= vertico--index 0) (1+ vertico--index)) + ((vertico--allow-prompt-selection-p) "*") + (t "!")) + vertico--total))) + +(defun vertico--display-count () + "Update count overlay `vertico--count-ov'." + (move-overlay vertico--count-ov (point-min) (point-min)) + (overlay-put vertico--count-ov 'before-string + (if vertico-count-format (vertico--format-count) ""))) + +(defun vertico--prompt-selection () + "Highlight the prompt if selected." + (let ((inhibit-modification-hooks t)) + (if (and (< vertico--index 0) (vertico--allow-prompt-selection-p)) + (add-face-text-property (minibuffer-prompt-end) (point-max) 'vertico-current 'append) + (vertico--remove-face (minibuffer-prompt-end) (point-max) 'vertico-current)))) + +(defun vertico--remove-face (beg end face &optional obj) + "Remove FACE between BEG and END from OBJ." + (while (< beg end) + (let ((next (next-single-property-change beg 'face obj end))) + (when-let (val (get-text-property beg 'face obj)) + (put-text-property beg next 'face (remq face (if (listp val) val (list val))) obj)) + (setq beg next)))) + +(defun vertico--exhibit () + "Exhibit completion UI." + (let* ((buffer-undo-list t) ;; Overlays affect point position and undo list! + (pt (max 0 (- (point) (minibuffer-prompt-end)))) + (content (minibuffer-contents))) + (unless (or (input-pending-p) (equal vertico--input (cons content pt))) + (vertico--update-candidates pt content)) + (vertico--prompt-selection) + (vertico--display-count) + (vertico--display-candidates (vertico--arrange-candidates)))) + +(defun vertico--allow-prompt-selection-p () + "Return t if prompt can be selected." + (or vertico--default-missing + (memq minibuffer--require-match '(nil confirm confirm-after-completion)))) + +(defun vertico--goto (index) + "Go to candidate with INDEX." + (let ((prompt (vertico--allow-prompt-selection-p))) + (setq vertico--index + (max (if (or prompt (= 0 vertico--total)) -1 0) + (min index (1- vertico--total))) + vertico--lock-candidate (or (>= vertico--index 0) prompt)))) + +(defun vertico-first () + "Go to first candidate, or to the prompt when the first candidate is selected." + (interactive) + (vertico--goto (if (> vertico--index 0) 0 -1))) + +(defun vertico-last () + "Go to last candidate." + (interactive) + (vertico--goto (1- vertico--total))) + +(defun vertico-scroll-down (&optional n) + "Go back by N pages." + (interactive "p") + (vertico--goto (max 0 (- vertico--index (* (or n 1) vertico-count))))) + +(defun vertico-scroll-up (&optional n) + "Go forward by N pages." + (interactive "p") + (vertico-scroll-down (- (or n 1)))) + +(defun vertico-next (&optional n) + "Go forward N candidates." + (interactive "p") + (let ((index (+ vertico--index (or n 1)))) + (vertico--goto + (cond + ((not vertico-cycle) index) + ((= vertico--total 0) -1) + ((vertico--allow-prompt-selection-p) (1- (mod (1+ index) (1+ vertico--total)))) + (t (mod index vertico--total)))))) + +(defun vertico-previous (&optional n) + "Go backward N candidates." + (interactive "p") + (vertico-next (- (or n 1)))) + +(defun vertico--match-p (input) + "Return t if INPUT is a valid match." + (or (memq minibuffer--require-match '(nil confirm-after-completion)) + (equal "" input) ;; The questionable null completion + (test-completion input + minibuffer-completion-table + minibuffer-completion-predicate) + (if (eq minibuffer--require-match 'confirm) + (eq (ignore-errors (read-char "Confirm")) 13) + (and (message "Match required") nil)))) + +(defun vertico-exit (&optional arg) + "Exit minibuffer with current candidate or input if prefix ARG is given." + (interactive "P") + (unless arg (vertico-insert)) + (when (vertico--match-p (minibuffer-contents-no-properties)) + (exit-minibuffer))) + +(defun vertico-next-group (&optional n) + "Cycle N groups forward. +When the prefix argument is 0, the group order is reset." + (interactive "p") + (when (cdr vertico--groups) + (if (eq n 0) + (setq vertico--groups nil + vertico--all-groups nil + vertico--lock-groups nil) + (setq vertico--groups + (vertico--cycle vertico--groups + (let ((len (length vertico--groups))) + (- len (mod (- (or n 1)) len)))) + vertico--all-groups + (vertico--cycle vertico--all-groups + (seq-position vertico--all-groups + (car vertico--groups))) + vertico--lock-groups t)) + (setq vertico--lock-candidate nil + vertico--input nil))) + +(defun vertico-previous-group (&optional n) + "Cycle N groups backward. +When the prefix argument is 0, the group order is reset." + (interactive "p") + (vertico-next-group (- (or n 1)))) + +(defun vertico-exit-input () + "Exit minibuffer with input." + (interactive) + (vertico-exit t)) + +(defun vertico-save () + "Save current candidate to kill ring." + (interactive) + (if (or (use-region-p) (not transient-mark-mode)) + (call-interactively #'kill-ring-save) + (kill-new (vertico--candidate)))) + +(defun vertico-insert () + "Insert current candidate in minibuffer." + (interactive) + ;; XXX There is a small bug here, depending on interpretation. When + ;; completing "~/emacs/master/li|/calc" where "|" is the cursor, + ;; then the returned candidate only includes the prefix + ;; "~/emacs/master/lisp/", but not the suffix "/calc". Default + ;; completion has the same problem when selecting in the + ;; *Completions* buffer. See bug#48356. + (when-let (cand (and (>= vertico--index 0) (vertico--candidate))) + (delete-minibuffer-contents) + (insert cand))) + +(defun vertico--candidate (&optional hl) + "Return current candidate string with optional highlighting if HL is non-nil." + (let ((content (substring (or (car-safe vertico--input) (minibuffer-contents))))) + (cond + ((>= vertico--index 0) + (let ((cand (substring (nth vertico--index vertico--candidates)))) + ;; XXX Drop the completions-common-part face which is added by `completion--twq-all'. + ;; This is a hack in Emacs and should better be fixed in Emacs itself, the corresponding + ;; code is already marked with a FIXME. Should this be reported as a bug? + (vertico--remove-face 0 (length cand) 'completions-common-part cand) + (concat (substring content 0 vertico--base) + (if hl (car (funcall vertico--highlight-function (list cand))) cand)))) + ((and (equal content "") (or (car-safe minibuffer-default) minibuffer-default))) + (t (vertico--remove-face 0 (length content) 'vertico-current content) ;; Remove prompt face + content)))) + +(defun vertico--setup () + "Setup completion UI." + (setq vertico--input t + vertico--candidates-ov (make-overlay (point-max) (point-max) nil t t) + vertico--count-ov (make-overlay (point-min) (point-min) nil t t)) + ;; Set priority for compatibility with `minibuffer-depth-indicate-mode' + (overlay-put vertico--count-ov 'priority 1) + (setq-local completion-auto-help nil + completion-show-inline-help nil) + (use-local-map vertico-map) + ;; Use -90 to ensure that the exhibit hook runs early such that the + ;; candidates are available for Consult preview. It works, but besides + ;; that I'dont have a specific reason for this particular value. + (add-hook 'post-command-hook #'vertico--exhibit -90 'local)) + +(defun vertico--advice (&rest args) + "Advice for completion function, receiving ARGS." + (minibuffer-with-setup-hook #'vertico--setup (apply args))) + +;;;###autoload +(define-minor-mode vertico-mode + "VERTical Interactive COmpletion." + :global t :group 'vertico + (if vertico-mode + (progn + (advice-add #'completing-read-default :around #'vertico--advice) + (advice-add #'completing-read-multiple :around #'vertico--advice)) + (advice-remove #'completing-read-default #'vertico--advice) + (advice-remove #'completing-read-multiple #'vertico--advice))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-next vertico-next-group vertico-previous vertico-previous-group + vertico-scroll-down vertico-scroll-up vertico-exit vertico-insert + vertico-exit-input vertico-save vertico-first vertico-last)) + (put sym 'completion-predicate #'vertico--command-p)) + +(defun vertico--command-p (_sym buffer) + "Return non-nil if Vertico is active in BUFFER." + (buffer-local-value 'vertico--input buffer)) + +(provide 'vertico) +;;; vertico.el ends here diff --git a/elpa/vertico-0.19/vertico.elc b/elpa/vertico-0.19/vertico.elc Binary files differ. diff --git a/elpa/vertico-0.19/vertico.info b/elpa/vertico-0.19/vertico.info @@ -0,0 +1,748 @@ +This is vertico.info, produced by makeinfo version 6.7 from +vertico.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Vertico: (vertico). VERTical Interactive COmpletion. +END-INFO-DIR-ENTRY + + +File: vertico.info, Node: Top, Next: Introduction, Up: (dir) + +vertico.el - VERTical Interactive COmpletion +******************************************** + +* Menu: + +* Introduction:: +* Features:: +* Key bindings:: +* Configuration:: +* Extensions:: +* Complementary packages:: +* Child frames and Popups:: +* Alternatives:: +* Problematic completion commands:: +* Contributions:: + +— The Detailed Node Listing — + +Configuration + +* Completion styles and TAB completion:: +* Completion-at-point and completion-in-region:: +* Completing-read-multiple (CRM):: + +Extensions + +* Configure Vertico per command or completion category:: + +Problematic completion commands + +* org-refile:: +* tmm-menubar:: +* ffap-menu:: +* Tramp hostname completion:: + + + +File: vertico.info, Node: Introduction, Next: Features, Prev: Top, Up: Top + +1 Introduction +************** + +Vertico provides a performant and minimalistic vertical completion UI +based on the default completion system. The main focus of Vertico is to +provide a UI which behaves _correctly_ under all circumstances. By +reusing the built-in facilities system, Vertico achieves _full +compatibility_ with built-in Emacs completion commands and completion +tables. Vertico only provides the completion UI but aims to be highly +flexible, extensible and modular. Additional enhancements are available +as *note extensions: Extensions. or *note complementary packages: +Complementary packages. The code base is small and maintainable. The +main ‘vertico.el’ package is only about 600 lines of code without white +space and comments. + + +File: vertico.info, Node: Features, Next: Key bindings, Prev: Introduction, Up: Top + +2 Features +********** + + • Vertical display with arrow key navigation (see the *note + extensions: Extensions. for additional display modes) + • Prompt shows the current candidate index and the total number of + candidates + • The current candidate is inserted with ‘TAB’ and selected with + ‘RET’ + • Non-existing candidates can be entered by moving the point to the + prompt line + • Configurable sorting by history position, length and alphabetically + • Long candidates with newlines are formatted to take up less space + • Deferred completion style highlighting for performance + • Support for annotations (‘annotation-function’ and + ‘affixation-function’) + • Support for grouping and group cycling commands (‘group-function’) + + <https://github.com/minad/vertico/blob/screenshots/vertico-mx.png?raw=true> + + +File: vertico.info, Node: Key bindings, Next: Configuration, Prev: Features, Up: Top + +3 Key bindings +************** + +Vertico defines its own local keymap in the minibuffer which is derived +from ‘minibuffer-local-map’. The keymap keeps most of the +‘fundamental-mode’ keybindings intact and remaps and binds only a +handful of commands. Note in particular the binding of ‘TAB’ to +‘vertico-insert’ and the bindings of ‘vertico-exit/exit-input’. + + • ‘beginning-of-buffer’, ‘minibuffer-beginning-of-buffer’ -> + ‘vertico-first’ + • ‘end-of-buffer’ -> ‘vertico-last’ + • ‘scroll-down-command’ -> ‘vertico-scroll-down’ + • ‘scroll-up-command’ -> ‘vertico-scroll-up’ + • ‘next-line’, ‘next-line-or-history-element’ -> ‘vertico-next’ + • ‘previous-line’, ‘previous-line-or-history-element’ -> + ‘vertico-previous’ + • ‘forward-paragraph’ -> ‘vertico-next-group’ + • ‘backward-paragraph’ -> ‘vertico-previous-group’ + • ‘exit-minibuffer’ -> ‘vertico-exit’ + • ‘kill-ring-save’ -> ‘vertico-save’ + • ‘C-<return>’ -> ‘vertico-exit-input’ + • ‘TAB’ -> ‘vertico-insert’ + + +File: vertico.info, Node: Configuration, Next: Extensions, Prev: Key bindings, Up: Top + +4 Configuration +*************** + +Vertico is available from GNU ELPA +(http://elpa.gnu.org/packages/vertico.html). You can install it +directly via ‘package-install’. After installation, you can activate +the global minor mode with ‘M-x vertico-mode’. In order to configure +Vertico and other packages in your init.el, you may want to take +advantage of ‘use-package’. I recommend to give Orderless completion a +try, which is different from the prefix TAB completion used by the basic +default completion system or in shells. Here is an example +configuration: + + ;; Enable vertico + (use-package vertico + :init + (vertico-mode) + + ;; Different scroll margin + ;; (setq vertico-scroll-margin 0) + + ;; Show more candidates + ;; (setq vertico-count 20) + + ;; Grow and shrink the Vertico minibuffer + ;; (setq vertico-resize t) + + ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. + ;; (setq vertico-cycle t) + ) + + ;; Optionally use the `orderless' completion style. See + ;; `+orderless-dispatch' in the Consult wiki for an advanced Orderless style + ;; dispatcher. Additionally enable `partial-completion' for file path + ;; expansion. `partial-completion' is important for wildcard support. + ;; Multiple files can be opened at once with `find-file' if you enter a + ;; wildcard. You may also give the `initials' completion style a try. + (use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; A few more useful configurations... + (use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; Alternatively try `consult-completing-read-multiple'. + (defun crm-indicator (args) + (cons (concat "[CRM] " (car args)) (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + + See also the Vertico Wiki (https://github.com/minad/vertico/wiki) for +additional configuration tips. For more general documentation read the +chapter about completion in the Emacs manual +(https://www.gnu.org/software/emacs/manual/html_node/emacs/Completion.html). +If you want to create your own completion commands, you can find +documentation about completion in the Elisp manual +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Completion.html). + +* Menu: + +* Completion styles and TAB completion:: +* Completion-at-point and completion-in-region:: +* Completing-read-multiple (CRM):: + + +File: vertico.info, Node: Completion styles and TAB completion, Next: Completion-at-point and completion-in-region, Up: Configuration + +4.1 Completion styles and TAB completion +======================================== + +The bindings of the ‘minibuffer-local-completion-map’ are not available +in Vertico by default. This means that TAB works differently from what +you may expect from the default Emacs completion system. + + If you prefer to have the default completion commands a key press +away you can add new bindings or even replace the Vertico bindings. +Then the default completion commands behave as usual. For example you +can use ‘M-TAB’ to cycle between candidates if you have set +‘completion-cycle-threshold’. + + (define-key vertico-map "?" #'minibuffer-completion-help) + (define-key vertico-map (kbd "M-RET") #'minibuffer-force-complete-and-exit) + (define-key vertico-map (kbd "M-TAB") #'minibuffer-complete) + + The ‘orderless’ completion style does not support completion of a +common prefix substring, as you may be familiar with from shells or the +basic default completion system. The reason is that the Orderless input +string is usually not a prefix. In order to support completing prefixes +you may want to combine ‘orderless’ with ‘substring’ in your +‘completion-styles’ configuration. + + (setq completion-styles '(substring orderless)) + + Alternatively you can experiment with the built-in completion-styles, +e.g., adding ‘partial-completion’ or ‘flex’. The ‘partial-completion’ +style is important to add if you want to open multiple files at once +with ‘find-file’ using wildcards. In order to open multiple files at +once, you have to move to the prompt and then press ‘RET’. + + (setq completion-styles '(basic substring partial-completion flex)) + + Because Vertico is fully compatible with Emacs default completion +system, further customization of completion behavior can be achieved by +setting the designated Emacs variables. For example, one may wish to +disable case-sensitivity for file and buffer matching when built-in +completion styles are used instead of ‘orderless’: + + (setq read-file-name-completion-ignore-case t + read-buffer-completion-ignore-case t + completion-ignore-case t) + + +File: vertico.info, Node: Completion-at-point and completion-in-region, Next: Completing-read-multiple (CRM), Prev: Completion styles and TAB completion, Up: Configuration + +4.2 Completion-at-point and completion-in-region +================================================ + +The ‘completion-at-point’ command is usually bound to ‘M-TAB’ or ‘TAB’. +In case you want to use Vertico for +completion-at-point/completion-in-region, you can use the function +‘consult-completion-in-region’ provided by the Consult package. + + ;; Use `consult-completion-in-region' if Vertico is enabled. + ;; Otherwise use the default `completion--in-region' function. + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + + The ‘completion-in-region-function’ setting also affects TAB +completion in the minibuffer when ‘M-:’ (‘eval-expression’) is used. + + You may also want to look into my Corfu +(https://github.com/minad/corfu) package, which provides a minimal +completion system for ‘completion-in-region’ in a child frame popup. +Corfu is also a narrowly focused package and developed in the same +spirit as Vertico. + + +File: vertico.info, Node: Completing-read-multiple (CRM), Prev: Completion-at-point and completion-in-region, Up: Configuration + +4.3 Completing-read-multiple (CRM) +================================== + +Consult offers an enhanced ‘completing-read-multiple’ implementation +which you can use with Vertico. + + (advice-add #'completing-read-multiple + :override #'consult-completing-read-multiple) + + +File: vertico.info, Node: Extensions, Next: Complementary packages, Prev: Configuration, Up: Top + +5 Extensions +************ + +We maintain small extension packages to Vertico in this repository in +the subdirectory extensions/ +(https://github.com/minad/vertico/tree/main/extensions). The extensions +are installed together with Vertico if you pull the package from ELPA. +The extensions are inactive by default and can be enabled manually if +desired. Furthermore it is possible to install all of the files +separately, both ‘vertico.el’ and the ‘vertico-*.el’ extensions. +Currently the following extensions come with the Vertico ELPA package: + + • vertico-buffer + (https://github.com/minad/vertico/blob/main/extensions/vertico-buffer.el): + ‘vertico-buffer-mode’ to display Vertico in a separate buffer. + • vertico-directory + (https://github.com/minad/vertico/blob/main/extensions/vertico-directory.el): + Commands for Ido-like directory navigation. + • vertico-flat + (https://github.com/minad/vertico/blob/main/extensions/vertico-flat.el): + ‘vertico-flat-mode’ to enable a flat, horizontal display. + • vertico-grid + (https://github.com/minad/vertico/blob/main/extensions/vertico-grid.el): + ‘vertico-grid-mode’ to enable a grid display. + • vertico-indexed + (https://github.com/minad/vertico/blob/main/extensions/vertico-indexed.el): + ‘vertico-indexed-mode’ to select indexed candidates with prefix + arguments. + • vertico-mouse + (https://github.com/minad/vertico/blob/main/extensions/vertico-mouse.el): + ‘vertico-mouse-mode’ to support for scrolling and candidate + selection. + • vertico-multiform + (https://github.com/minad/vertico/blob/main/extensions/vertico-multiform.el): + Configure Vertico modes per command or completion category. + • vertico-quick + (https://github.com/minad/vertico/blob/main/extensions/vertico-quick.el): + Commands to select using Avy-style quick keys. + • vertico-repeat + (https://github.com/minad/vertico/blob/main/extensions/vertico-repeat.el): + The command ‘vertico-repeat’ repeats the last completion session. + • vertico-reverse + (https://github.com/minad/vertico/blob/main/extensions/vertico-reverse.el): + ‘vertico-reverse-mode’ to reverse the display. + • vertico-unobtrusive + (https://github.com/minad/vertico/blob/main/extensions/vertico-unobtrusive.el): + ‘vertico-unobtrusive-mode’ displays only the topmost candidate. + + With these extensions it is possible to adapt Vertico such that it +matches your preference or behaves similar to other familiar UIs. For +example, the combination ‘vertico-flat’ plus ‘vertico-directory’ +resembles Ido in look and feel. For an interface similar to Helm, the +extension ‘vertico-buffer’ allows you to configure freely where the +completion buffer opens, instead of growing the minibuffer. Furthermore +‘vertico-buffer’ will adjust the number of displayed candidates +according to the buffer height. + + Configuration example for ‘vertico-directory’: + + ;; Configure directory extension. + (use-package vertico-directory + :after vertico + :ensure nil + ;; More convenient directory navigation commands + :bind (:map 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)) + +* Menu: + +* Configure Vertico per command or completion category:: + + +File: vertico.info, Node: Configure Vertico per command or completion category, Up: Extensions + +5.1 Configure Vertico per command or completion category +======================================================== + +<https://github.com/minad/vertico/blob/screenshots/vertico-ripgrep.png?raw=true> + + Vertico offers the ‘vertico-multiform-mode’ which allows you to +configure Vertico per command or per completion category. The +‘vertico-buffer-mode’ enables a Helm-like buffer display, which takes +more space but also displays more candidates. This verbose display mode +is useful for commands like ‘consult-imenu’ or ‘consult-outline’ since +the buffer display allows you to get a better overview over the entire +current buffer. But for other commands you want to keep using the +default Vertico display. ‘vertico-multiform-mode’ solves this +configuration problem! + + ;; Enable vertico-multiform + (vertico-multiform-mode) + + ;; Configure the display per command. + ;; Use a buffer with indices for imenu + ;; and a flat (Ido-like) menu for M-x. + (setq vertico-multiform-commands + '((consult-imenu buffer indexed) + (execute-extended-command unobtrusive))) + + ;; Configure the display per completion category. + ;; Use the grid display for files and a buffer + ;; for the consult-grep commands. + (setq vertico-multiform-categories + '((file grid) + (consult-grep buffer))) + + You can use your own functions or even lambdas to configure the +completion behavior per command or per completion category. The +function must have the calling convention of a mode, i.e., it takes a +single argument, which is either 1 to turn on the mode and -1 to turn +off the mode. + + ;; Configure `consult-outline' as a scaled down TOC in a separate buffer + (setq vertico-multiform-commands + `((consult-outline buffer ,(lambda (_) (text-scale-set -1))))) + + Furthermore you can tune buffer-local settings per command or +category. + + ;; Change the default sorting function + (setq vertico-multiform-commands + '((describe-symbol (vertico-sort-function . vertico-sort-alpha)))) + + (setq vertico-multiform-categories + '((symbol (vertico-sort-function . vertico-sort-alpha)) + (file (vertico-sort-function . sort-directories-first)))) + + ;; Sort directories before files + (defun sort-directories-first (files) + (setq files (vertico-sort-history-length-alpha files)) + (nconc (seq-filter (lambda (x) (string-suffix-p "/" x)) files) + (seq-remove (lambda (x) (string-suffix-p "/" x)) files))) + + Combining these features allows us to fine-tune the completion +display even more by adjusting the ‘vertico-buffer-display-action’. We +can for example reuse the current window for commands of the +‘consult-grep’ category (‘consult-grep’, ‘consult-git-grep’ and +‘consult-ripgrep’). Note that this configuration is incompatible with +Consult preview, since the previewed buffer is usually shown in exactly +this window. Nevertheless this snippet demonstrates the flexibility of +the configuration system. + + ;; Configure the buffer display and the buffer display action + (setq vertico-multiform-categories + '((consult-grep + buffer + (vertico-buffer-display-action . (display-buffer-same-window))))) + + ;; Disable preview for consult-grep commands + (consult-customize consult-ripgrep consult-git-grep consult-grep :preview-key nil) + + As another example, the following code uses ‘vertico-flat’ and +‘vertico-cycle’ to emulate ‘(ido-mode 'buffer)’, i.e., Ido when it is +enabled only for completion of buffer names. ‘vertico-cycle’ set to ‘t’ +is necessary here to prevent completion candidates from disappearing +when they scroll off-screen to the left. + + (setq vertico-multiform-categories + '((buffer flat (vertico-cycle . t)))) + + +File: vertico.info, Node: Complementary packages, Next: Child frames and Popups, Prev: Extensions, Up: Top + +6 Complementary packages +************************ + +Vertico integrates well with complementary packages, which enrich the +completion UI. These packages are fully supported: + + • Marginalia (https://github.com/minad/marginalia): Rich annotations + in the minibuffer + • Consult (https://github.com/minad/consult): Useful search and + navigation commands + • Embark (https://github.com/oantolin/embark): Minibuffer actions and + context menu + • Orderless (https://github.com/oantolin/orderless): Advanced + completion style + + In order to get accustomed with the package ecosystem, I recommed the +following quick start approach: + + 1. Start with plain Emacs (‘emacs -Q’). + 2. Install and enable Vertico to get incremental minibuffer + completion. + 3. Install Orderless and/or configure the built-in completion styles + for more flexible minibuffer filtering. + 4. Install Marginalia if you like rich minibuffer annotations. + 5. Install Embark and add two keybindings for ‘embark-dwim’ and + ‘embark-act’. I am using the mnemonic keybindings ‘M-.’ and ‘C-.’ + since these commands allow you to act on the object at point or in + the minibuffer. + 6. Install Consult if you want additional featureful completion + commands, e.g, the buffer switcher ‘consult-buffer’ with preview or + the line-based search ‘consult-line’. + 7. Install Embark-Consult and Wgrep for export from ‘consult-line’ to + ‘occur-mode’ buffers and from ‘consult-grep’ to editable + ‘grep-mode’ buffers. + 8. Fine tune Vertico with *note extensions: Extensions. + + The ecosystem is modular. You don’t have to use all of these +components. Use only the ones you like and the ones which fit well into +your setup. The steps 1. to 4. introduce no new commands over plain +Emacs. Step 5. introduces the new commands ‘embark-act’ and +‘embark-dwim’. In step 6. you get the Consult commands, some offer new +functionality not present in Emacs already (e.g., ‘consult-line’) and +some are substitutes (e.g., ‘consult-buffer’ for ‘switch-to-buffer’). + + +File: vertico.info, Node: Child frames and Popups, Next: Alternatives, Prev: Complementary packages, Up: Top + +7 Child frames and Popups +************************* + +An often requested feature is the ability to display the completions in +a child frame popup. Personally I am critical of using child frames for +minibuffer completion. From my experience it introduces more problems +than it solves. Most importantly child frames hide the content of the +underlying buffer. Furthermore child frames do not play well together +with changing windows and entering recursive minibuffer sessions. On +top, child frames can feel slow and sometimes flicker. A better +alternative is the ‘vertico-buffer’ display which can even be configured +individually per command using ‘vertico-multiform’. On the plus side of +child frames, the completion display appears at the center of the +screen, where your eyes are focused. Please give the following packages +a try and judge for yourself. + + • mini-frame (https://github.com/muffinmad/emacs-mini-frame): Display + the entire minibuffer in a child frame. + • mini-popup (https://github.com/minad/mini-popup): Slightly simpler + alternative to mini-frame. + • vertico-posframe (https://github.com/tumashu/vertico-posframe): + Display only the Vertico minibuffer in a child frame using the + posframe library. + + +File: vertico.info, Node: Alternatives, Next: Problematic completion commands, Prev: Child frames and Popups, Up: Top + +8 Alternatives +************** + +There are many alternative completion UIs, each UI with its own +advantages and disadvantages. + + Vertico aims to be 100% compliant with all Emacs commands and +achieves that with a minimal code base, relying purely on +‘completing-read’ while avoiding to invent its own APIs. Inventing a +custom API as Helm or Ivy is explicitly avoided in order to increase +flexibility and package reuse. Due to its small code base and reuse of +the Emacs built-in facilities, bugs and compatibility issues are less +likely to occur in comparison to completion UIs or full completion +systems, which reimplement a lot of functionality. + + Since Vertico only provides the UI, you may want to combine it with +some of the complementary packages, to give a full-featured completion +experience similar to Helm or Ivy. Overall the packages in the spirit +of Vertico have a different style than Helm or Ivy. The idea is to have +smaller independent components, which one can add and understand step by +step. Each component focuses on its niche and tries to be as +non-intrusive as possible. Vertico targets users interested in crafting +their Emacs precisely to their liking - completion plays an integral +part in how the users interacts with Emacs. + + There are other interactive completion UIs, which follow a similar +philosophy: + + • Selectrum (https://github.com/raxod502/selectrum): Selectrum has a + similar UI as Vertico, since it directly inspired Vertico. The + Selectrum code base is more complex. Unfortunately Selectrum is + not fully compatible with every Emacs completion command (Issue + #481 (https://github.com/raxod502/selectrum/issues/481)), since it + uses its own filtering infrastructure, which deviates from the + standard Emacs completion facilities. Vertico additionally has the + ability to cycle over candidates, offers commands for grouping + support and comes with a rich set of *note extensions: Extensions. + • Icomplete-vertical + (https://github.com/oantolin/icomplete-vertical): This package + enhances the Emacs builtin Icomplete with a vertical display. In + contrast to Vertico, Icomplete rotates the candidates such that the + current candidate always appears at the top. From my perspective, + candidate rotation feels a bit less intuitive than the UI of + Vertico or Selectrum. Note that Emacs 28 offers a built-in + ‘icomplete-vertical-mode’. + • Mct (https://gitlab.com/protesilaos/mct): Minibuffer and + Completions in Tandem. Mct reuses the default ‘*Completions*’ + buffer and enhances it with automatic updates and additional + keybindings, to select a candidate and move between minibuffer and + completions buffer. Mct is great if you prefer an unobtrusive UI + since it can be configured to open only when requested. + Furthermore since Mct uses a fully functional buffer you can reuse + all your familar buffer commands inside the completions buffer. + The main distinction to Vertico’s approach is that ‘*Completions*’ + buffer displays all matching candidates. On the one hand this is + good since it allows you to interact with all the candidates and + jump around with Isearch or Avy. On the other hand it necessarily + causes a slowdown in comparison to Vertico, which only displays a + subset of candidates. Mct supports completion in region via its + ‘mct-region-mode’. + + +File: vertico.info, Node: Problematic completion commands, Next: Contributions, Prev: Alternatives, Up: Top + +9 Problematic completion commands +********************************* + +Vertico is robust in most scenarios. However some completion commands +make certain assumptions about the completion styles and the completion +UI. Some of these assumptions may not hold in Vertico or other UIs and +require minor workarounds. + +* Menu: + +* org-refile:: +* tmm-menubar:: +* ffap-menu:: +* Tramp hostname completion:: + + +File: vertico.info, Node: org-refile, Next: tmm-menubar, Up: Problematic completion commands + +9.1 ‘org-refile’ +================ + +‘org-refile’ uses ‘org-olpath-completing-read’ to complete the outline +path in steps, when ‘org-refile-use-outline-path’ is non-nil. + + Unfortunately the implementation of this Org completion table assumes +that the ‘basic’ completion style is used. The table is incompatible +with completion styles like ‘substring’, ‘flex’ or ‘orderless’. In +order to fix the issue at the root, the completion table should make use +of completion boundaries similar to the built-in file completion table. +In your user configuration you can prioritize ‘basic’ before +‘orderless:’ + + ;; Alternative 1: Use the basic completion style + (setq org-refile-use-outline-path 'file + org-outline-path-complete-in-steps t) + (advice-add #'org-olpath-completing-read :around + (lambda (&rest args) + (minibuffer-with-setup-hook + (lambda () (setq-local completion-styles '(basic))) + (apply args)))) + + Alternatively you may want to disable the outline path completion in +steps. The completion on the full path can be quicker since the input +string matches directly against substrings of the full path, which is +useful with Orderless. However the list of possible completions becomes +much more cluttered. + + ;; Alternative 2: Complete full paths + (setq org-refile-use-outline-path 'file + org-outline-path-complete-in-steps nil) + + +File: vertico.info, Node: tmm-menubar, Next: ffap-menu, Prev: org-refile, Up: Problematic completion commands + +9.2 ‘tmm-menubar’ +================= + +The text menu bar works well with Vertico but always shows a +‘*Completions*’ buffer, which is unwanted if you use the Vertico UI. +This completion buffer can be disabled as follows. + + (advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions) + + +File: vertico.info, Node: ffap-menu, Next: Tramp hostname completion, Prev: tmm-menubar, Up: Problematic completion commands + +9.3 ‘ffap-menu’ +=============== + +The command ‘ffap-menu’ shows the ‘=*Completions*’ buffer by default +like ‘tmm-menubar’, which is unnecessary with Vertico. This completion +buffer can be disabled as follows. + + (advice-add #'ffap-menu-ask :around (lambda (&rest args) + (cl-letf (((symbol-function #'minibuffer-completion-help) + #'ignore)) + (apply args)))) + + +File: vertico.info, Node: Tramp hostname completion, Prev: ffap-menu, Up: Problematic completion commands + +9.4 Tramp hostname completion +============================= + +In combination with Orderless, hostnames are not made available for +completion after entering ‘/ssh:’. In order to avoid this problem, the +‘basic’ completion style should be specified for the file completion +category. + + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic partial-completion)))) + + For users who are familiar with the ‘completion-style’ machinery: You +may also define a custom completion style which sets in only for remote +files! + + (defun basic-remote-try-completion (string table pred point) + (and (vertico--remote-p string) + (completion-basic-try-completion string table pred point))) + (defun basic-remote-all-completions (string table pred point) + (and (vertico--remote-p string) + (completion-basic-all-completions string table pred point))) + (add-to-list + 'completion-styles-alist + '(basic-remote basic-remote-try-completion basic-remote-all-completions nil)) + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic-remote partial-completion)))) + + +File: vertico.info, Node: Contributions, Prev: Problematic completion commands, Up: Top + +10 Contributions +**************** + +Since this package is part of GNU ELPA +(http://elpa.gnu.org/packages/vertico.html) contributions require a +copyright assignment to the FSF. + + + +Tag Table: +Node: Top196 +Node: Introduction926 +Node: Features1761 +Node: Key bindings2729 +Node: Configuration3964 +Node: Completion styles and TAB completion7627 +Node: Completion-at-point and completion-in-region9937 +Node: Completing-read-multiple (CRM)11262 +Node: Extensions11681 +Node: Configure Vertico per command or completion category15344 +Node: Complementary packages19321 +Node: Child frames and Popups21574 +Node: Alternatives22949 +Node: Problematic completion commands26538 +Node: org-refile27050 +Node: tmm-menubar28637 +Node: ffap-menu29054 +Node: Tramp hostname completion29687 +Node: Contributions30999 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/vertico-posframe-0.5.1.signed b/elpa/vertico-posframe-0.5.1.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-01-12T11:05:06+0100 using RSA +\ No newline at end of file diff --git a/elpa/vertico-posframe-0.5.1/LICENSE b/elpa/vertico-posframe-0.5.1/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff --git a/elpa/vertico-posframe-0.5.1/README.org b/elpa/vertico-posframe-0.5.1/README.org @@ -0,0 +1,26 @@ +#+TITLE: README of vertico-posframe + +** What is vertico-posframe + +vertico-posframe is an vertico extension, which lets vertico use +posframe to show its candidate menu. + +NOTE: vertico-posframe requires Emacs 26 and do not support mouse +click. + +** How to enable vertico-posframe +#+BEGIN_EXAMPLE +(require 'vertico-posframe) +(vertico-posframe-mode 1) +#+END_EXAMPLE + +** Tips +*** How to show fringe to vertico-posframe +#+BEGIN_EXAMPLE +(setq vertico-posframe-parameters + '((left-fringe . 8) + (right-fringe . 8))) +#+END_EXAMPLE + +By the way, User can set *any* parameters of vertico-posframe with +the help of `vertico-posframe-parameters'. diff --git a/elpa/vertico-posframe-0.5.1/vertico-posframe-autoloads.el b/elpa/vertico-posframe-0.5.1/vertico-posframe-autoloads.el @@ -0,0 +1,50 @@ +;;; vertico-posframe-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "vertico-posframe" "vertico-posframe.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from vertico-posframe.el + +(autoload 'vertico-posframe-cleanup "vertico-posframe" "\ +Remove frames and buffers used for vertico-posframe." t nil) + +(defvar vertico-posframe-mode nil "\ +Non-nil if Vertico-Posframe mode is enabled. +See the `vertico-posframe-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-posframe-mode'.") + +(custom-autoload 'vertico-posframe-mode "vertico-posframe" nil) + +(autoload 'vertico-posframe-mode "vertico-posframe" "\ +Display Vertico in posframe instead of the minibuffer. + +If called interactively, enable Vertico-Posframe mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-posframe" '("vertico-posframe-"))) + +;;;*** + +;;;### (autoloads nil nil ("vertico-posframe-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; vertico-posframe-autoloads.el ends here diff --git a/elpa/vertico-posframe-0.5.1/vertico-posframe-pkg.el b/elpa/vertico-posframe-0.5.1/vertico-posframe-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from vertico-posframe.el -*- no-byte-compile: t -*- +(define-package "vertico-posframe" "0.5.1" "Using posframe to show Vertico" '((emacs "26.0") (posframe "1.1.4") (vertico "0.13.0")) :commit "7a75271fdaf593e6f491a953b511d2540553b532" :authors '(("Feng Shu" . "tumashu@163.com")) :maintainer '("Feng Shu" . "tumashu@163.com") :keywords '("abbrev" "convenience" "matching" "vertico") :url "https://github.com/tumashu/vertico-posframe") diff --git a/elpa/vertico-posframe-0.5.1/vertico-posframe.el b/elpa/vertico-posframe-0.5.1/vertico-posframe.el @@ -0,0 +1,310 @@ +;;; vertico-posframe.el --- Using posframe to show Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Feng Shu <tumashu@163.com> +;; Maintainer: Feng Shu <tumashu@163.com> +;; URL: https://github.com/tumashu/vertico-posframe +;; Version: 0.5.1 +;; Keywords: abbrev, convenience, matching, vertico +;; Package-Requires: ((emacs "26.0") (posframe "1.1.4") (vertico "0.13.0")) + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + + +;;; Commentary: +;; * vertico-posframe README :README: + +;; ** What is vertico-posframe + +;; vertico-posframe is an vertico extension, which lets vertico use posframe to show +;; its candidate menu. + +;; NOTE: vertico-posframe requires Emacs 26 and do not support mouse +;; click. + +;; ** How to enable vertico-posframe +;; #+BEGIN_EXAMPLE +;; (require 'vertico-posframe) +;; (vertico-posframe-mode 1) +;; #+END_EXAMPLE + +;; ** Tips + +;; *** How to show fringe to vertico-posframe +;; #+BEGIN_EXAMPLE +;; (setq vertico-posframe-parameters +;; '((left-fringe . 8) +;; (right-fringe . 8))) +;; #+END_EXAMPLE + +;; By the way, User can set *any* parameters of vertico-posframe with +;; the help of `vertico-posframe-parameters'. + +;;; Code: +;; * vertico-posframe's code +(require 'posframe) +(require 'vertico) + +(defgroup vertico-posframe nil + "Using posframe to show vertico." + :group 'vertico-posframe) + +(defcustom vertico-posframe-font nil + "The font used by vertico-posframe. +When nil, Using current frame's font as fallback." + :type 'string) + +(defcustom vertico-posframe-width nil + "The width of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-height nil + "The height of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-min-width nil + "The min width of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-min-height nil + "The min height of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-poshandler #'posframe-poshandler-frame-center + "The posframe poshandler used by vertico-posframe." + :type 'function) + +(defcustom vertico-posframe-refposhandler #'vertico-posframe-refposhandler-default + "The refposhandler used by vertico-posframe. + +NOTE: This variable is very useful to EXWM users." + :type 'function) + +(defcustom vertico-posframe-size-function #'vertico-posframe-get-size + "The function which is used to deal with posframe's size." + :type 'function) + +(defcustom vertico-posframe-border-width 2 + "The border width used by vertico-posframe. +When 0, no border is showed." + :type 'number) + +(defcustom vertico-posframe-parameters nil + "The frame parameters used by vertico-posframe." + :type 'string) + +(defcustom vertico-posframe-show-minibuffer-rules + (list "^eval-*") + "A list of rule showed minibuffer. + +a rule can be a regexp or a function. + +1. when rule is a regexp and it match `this-command'. +2. when rule is a function and it return t. +3. when rule is a symbol, its value is t. + +minibuffer will not be hided by minibuffer-cover." + :type '(repeat (choice string function))) + +(defface vertico-posframe + '((t (:inherit default))) + "Face used by the vertico-posframe." + :group 'vertico-posframe) + +(defface vertico-posframe-border + '((t (:inherit default :background "gray50"))) + "Face used by the vertico-posframe's border when minibuffer-depth = 1." + :group 'vertico-posframe) + +(defface vertico-posframe-border-2 + '((t (:inherit default :background "red"))) + "Face used by the vertico-posframe's border when minibuffer-depth = 2." + :group 'vertico-posframe) + +(defface vertico-posframe-border-3 + '((t (:inherit default :background "green"))) + "Face used by the vertico-posframe's border when minibuffer-depth = 3." + :group 'vertico-posframe) + +(defface vertico-posframe-border-4 + '((t (:inherit default :background "blue"))) + "Face used by the vertico-posframe's border when minibuffer-depth = 4." + :group 'vertico-posframe) + +(defface vertico-posframe-border-fallback + '((t (:inherit default :background "yellow"))) + "Face used by the vertico-posframe's border when find no face." + :group 'vertico-posframe) + +(defvar vertico-posframe--buffer nil) + +;; Fix warn +(defvar exwm--connection) +(defvar exwm-workspace--workareas) +(defvar exwm-workspace-current-index) + +(defun vertico-posframe-refposhandler-default (&optional frame) + "The default posframe refposhandler used by vertico-posframe. +Optional argument FRAME ." + (cond + ;; EXWM environment + ((bound-and-true-p exwm--connection) + (or (ignore-errors + (let ((info (elt exwm-workspace--workareas + exwm-workspace-current-index))) + (cons (elt info 0) + (elt info 1)))) + ;; Need user install xwininfo. + (ignore-errors + (posframe-refposhandler-xwininfo frame)) + ;; Fallback, this value will incorrect sometime, for example: user + ;; have panel. + (cons 0 0))) + (t nil))) + +(defun vertico-posframe-hidehandler (_) + "Hidehandler used by vertico-posframe." + (not (minibufferp))) + +(defun vertico-posframe-get-size () + "The default functon used by `vertico-posframe-size-function'." + (list + :height vertico-posframe-height + :width vertico-posframe-width + :min-height (or vertico-posframe-min-height + (let ((height (+ vertico-count 1))) + (min height (or vertico-posframe-height height)))) + :min-width (or vertico-posframe-min-width + (let ((width (round (* (frame-width) 0.62)))) + (min width (or vertico-posframe-width width)))))) + +(defun vertico-posframe--display (_lines) + "Display LINES in posframe." + (let ((point (point))) + (setq vertico-posframe--buffer (current-buffer)) + (setq-local max-mini-window-height 1) + (vertico-posframe--handle-minibuffer-window) + (with-selected-window (vertico-posframe-last-window) + (vertico-posframe--show vertico-posframe--buffer point)))) + +(defun vertico-posframe--show (buffer window-point) + "`posframe-show' of vertico-posframe. + +BUFFER will be showed by `posframe-show'. After `posframe-show' +is called, window-point will be set to WINDOW-POINT." + (let ((posframe (apply #'posframe-show + buffer + :font vertico-posframe-font + :poshandler vertico-posframe-poshandler + :background-color (face-attribute 'vertico-posframe :background nil t) + :foreground-color (face-attribute 'vertico-posframe :foreground nil t) + :border-width vertico-posframe-border-width + :border-color (vertico-posframe--get-border-color) + :override-parameters vertico-posframe-parameters + :refposhandler vertico-posframe-refposhandler + :hidehandler #'vertico-posframe-hidehandler + :lines-truncate t + (funcall vertico-posframe-size-function)))) + ;; NOTE: `posframe-show' will force set window-point to 0, so we + ;; need reset it again after `posframe-show'. + (when (numberp window-point) + (let ((window (frame-root-window posframe))) + (when (window-live-p window) + (set-window-point window window-point)))) + ;; NOTE: posframe will hide cursor, so we need let it show again. + (with-current-buffer buffer + (setq-local cursor-type t) + (setq-local cursor-in-non-selected-windows 'box)))) + +(defun vertico-posframe--get-border-color () + "Get color of vertico-posframe border." + (face-attribute + (let* ((n (minibuffer-depth)) + (face (intern (format "vertico-posframe-border-%s" n))) + (face-fallback 'vertico-posframe-border-fallback)) + (if (= n 1) + 'vertico-posframe-border + (if (facep face) + face + face-fallback))) + :background)) + +(defun vertico-posframe--show-minibuffer-p () + "Test show minibuffer or not." + (cl-some + (lambda (rule) + (cond ((functionp rule) + (funcall rule)) + ((and rule (stringp rule)) + (string-match-p rule (symbol-name this-command))) + ((symbolp rule) + (symbol-value rule)) + (t nil))) + vertico-posframe-show-minibuffer-rules)) + +(defun vertico-posframe--handle-minibuffer-window () + "Handle minibuffer window." + (let ((show-minibuffer-p (vertico-posframe--show-minibuffer-p)) + (minibuffer-window (active-minibuffer-window))) + (window-resize minibuffer-window + (- (window-pixel-height minibuffer-window)) + nil nil 'pixelwise) + (set-window-vscroll minibuffer-window 100) + (when show-minibuffer-p + (set-window-vscroll minibuffer-window 0)))) + +(defun vertico-posframe-last-window () + "Get the last actived window before active minibuffer." + (let ((window (minibuffer-selected-window))) + (or (if (window-live-p window) + window + (next-window)) + (selected-window)))) + +(defun vertico-posframe--minibuffer-exit-hook () + "The function used by `minibuffer-exit-hook'." + (setq-local max-mini-window-height 1.0) + (when (posframe-workable-p) + (posframe-hide vertico-posframe--buffer))) + +(defun vertico-posframe--setup () + "Setup minibuffer overlay, which pushes the minibuffer content down." + (add-hook 'minibuffer-exit-hook #'vertico-posframe--minibuffer-exit-hook nil 'local)) + +;;;###autoload +(defun vertico-posframe-cleanup () + "Remove frames and buffers used for vertico-posframe." + (interactive) + (when vertico-posframe--buffer + (posframe-delete vertico-posframe--buffer))) + +;;;###autoload +(define-minor-mode vertico-posframe-mode + "Display Vertico in posframe instead of the minibuffer." + :global t + (cond + (vertico-posframe-mode + (advice-add #'vertico--display-candidates :after #'vertico-posframe--display) + (advice-add #'vertico--setup :after #'vertico-posframe--setup) + (advice-add #'vertico--resize-window :override #'ignore)) + (t + (advice-remove #'vertico--display-candidates #'vertico-posframe--display) + (advice-remove #'vertico--setup #'vertico-posframe--setup) + (advice-remove #'vertico--resize-window #'ignore)))) + +(provide 'vertico-posframe) +;;; vertico-posframe.el ends here diff --git a/elpa/vertico-posframe-0.5.1/vertico-posframe.elc b/elpa/vertico-posframe-0.5.1/vertico-posframe.elc Binary files differ.