dotemacs

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

commit b3f8f12795f8f37eb90b9accec404cffa7420959
parent 9d2857fda5998b9bd628596018d05a7dc2dfd32a
Author: Lukas Henkel <lh@entf.net>
Date:   Fri,  8 Apr 2022 22:11:38 +0200

Disable automatic preselection

I feel like it's too intrusive. Having to C-g every time I want to
write something that does not complete to anything gets annoying fast...

Diffstat:
Delpa/corfu-0.20.signed | 2--
Delpa/corfu-0.20/README.org | 466-------------------------------------------------------------------------------
Delpa/corfu-0.20/corfu-autoloads.el | 60------------------------------------------------------------
Delpa/corfu-0.20/corfu-pkg.el | 2--
Delpa/corfu-0.20/corfu.el | 1278-------------------------------------------------------------------------------
Delpa/corfu-0.20/corfu.info | 611-------------------------------------------------------------------------------
Aelpa/corfu-0.21.signed | 2++
Relpa/corfu-0.20/LICENSE -> elpa/corfu-0.21/LICENSE | 0
Aelpa/corfu-0.21/README.org | 476+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.21/corfu-autoloads.el | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.21/corfu-pkg.el | 2++
Aelpa/corfu-0.21/corfu.el | 1272+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/corfu-0.21/corfu.info | 621+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Relpa/corfu-0.20/dir -> elpa/corfu-0.21/dir | 0
Minit.el | 1+
15 files changed, 2446 insertions(+), 2419 deletions(-)

diff --git a/elpa/corfu-0.20.signed b/elpa/corfu-0.20.signed @@ -1 +0,0 @@ -Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-03-08T23:05:02+0100 using RSA -\ No newline at end of file diff --git a/elpa/corfu-0.20/README.org b/elpa/corfu-0.20/README.org @@ -1,466 +0,0 @@ -#+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 completion at point with a small completion popup. 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 small 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]], use Capfs which talk to the LSP server to retrieve the completions. - Corfu does not include its own completion backends. The Emacs built-in Capfs - and the Capfs provided by other programming language packages are usually - sufficient. A few additional Capfs and completion utilities 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. - - [[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 (configurable via ~corfu-preview-current~). - - The selected candidate automatically committed on further input by default. - (configurable via ~corfu-preview-current~). - - The [[https://github.com/oantolin/orderless][Orderless]] completion style is supported. The filter string can contain - arbitrary characters, after inserting a space via =M-SPC= (configurable via - ~corfu-quit-at-boundary~ and ~corfu-separator~). - - Deferred completion style highlighting for performance. - - Jumping to location/documentation of current candidate. - - Support for candidate annotations and documentation in the echo area. - - Deprecated candidates are crossed out in the display. - - 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, - such that you can adapt it precisely to your requirements. However in order to - quickly try out the Corfu completion package, it should be sufficient to - activate ~corfu-global-mode~. Then you experiment with manual completion for - example in an Elisp buffer or in an Eshell or Shell buffer. For auto - completion, set ~corfu-auto=t~ before turning on ~corfu-global-mode~. - - If you start to configure the package more deeply, I recommend to give the - Orderless completion style a try for filtering. Orderless completion 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-separator ?\s) ;; Orderless field separator - ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary - ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match - ;; (corfu-preview-current nil) ;; Disable current candidate preview - ;; (corfu-preselect-first nil) ;; Disable candidate preselection - ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches - ;; (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]]. - -** Auto completion - - Auto completion is disabled by default, but can be enabled by setting - ~corfu-auto=t~. Furthermore you may want to configure Corfu to quit completion - eagerly, such that the completion popup stays out of your way when it - appeared unexpectedly. - - #+begin_src emacs-lisp - ;; Enable auto completion and configure quitting - (setq corfu-auto t - corfu-quit-no-match 'separator) ;; or t - #+end_src - - In general, I recommend to experiment a bit with the various settings and key - bindings to find a configuration which works for you. There is no one size - fits all solution. Some people like auto completion, some like manual - completion, some want to cycle with TAB and some with the arrow keys... - -** Completing with Corfu in the minibuffer - -Corfu can be used for completion in the minibuffer, since it relies on child -frames to display the candidates. By default, ~corfu-global-mode~ does not -activate ~corfu-mode~ in the minibuffer, to avoid interference with specialised -minibuffer completion UIs like Vertico or Mct. However you may still want to -enable Corfu completion for commands like ~M-:~ (~eval-expression~) or ~M-!~ -(~shell-command~), which read from the minibuffer. Activate ~corfu-mode~ only if -~completion-at-point~ is bound in the minibuffer-local keymap to achieve this -effect. - -#+begin_src emacs-lisp - (defun corfu-enable-in-minibuffer () - "Enable Corfu in the minibuffer if `completion-at-point' is bound." - (when (where-is-internal #'completion-at-point (list (current-local-map))) - ;; (setq-local corfu-auto nil) Enable/disable auto completion - (corfu-mode 1))) - (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) -#+end_src - -You can also enable Corfu more generally for every minibuffer, as long as no -other completion UI is active. If you use Mct or Vertico as your main minibuffer -completion UI, the following snippet should yield the desired result. - -#+begin_src emacs-lisp - (defun corfu-enable-always-in-minibuffer () - "Enable Corfu in the minibuffer if Vertico/Mct are not active." - (unless (or (bound-and-true-p mct--active) - (bound-and-true-p vertico--input)) - ;; (setq-local corfu-auto nil) Enable/disable auto completion - (corfu-mode 1))) - (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1) -#+end_src - -** Completing with Corfu in the Eshell or Shell - -When completing in the Eshell I recommend conservative local settings without -auto completion, such that the completion behavior is similar to widely used -shells like Bash, Zsh or Fish. - -#+begin_src emacs-lisp - (add-hook 'eshell-mode-hook - (lambda () - (setq-local corfu-auto nil) - (corfu-mode))) -#+end_src - -When pressing =RET= while the Corfu popup is visible, the ~corfu-insert~ command -will be invoked. This command does inserts the currently selected candidate, but -it does not send the prompt input to Eshell or the comint process. Therefore you -often have to press =RET= twice which feels like an unnecessary double -confirmation. Fortunately it is easy to improve this! In my configuration I -define the command ~corfu-insert-and-send~ which performs the two steps at once. - -#+begin_src emacs-lisp - (defun corfu-insert-and-send () - (interactive) - ;; 1. First insert the completed candidate - (corfu-insert) - ;; 2. Send the entire prompt input to the shell - (cond - ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input)) - (eshell-send-input)) - ((derived-mode-p 'comint-mode) - (comint-send-input)))) - - (define-key corfu-map "\r" #'+corfu-insert-and-send) -#+end_src - -Shell completion uses the flexible ~pcomplete~ mechanism internally, which allows -you to program the completions per shell command. If you want to know more, look -into this [[https://www.masteringemacs.org/article/pcomplete-context-sensitive-completion-emacs][blog post]], which shows how to configure pcomplete for git commands. I -recommend the [[https://github.com/JonWaltman/pcmpl-args.el][pcmpl-args]] package which extends Pcomplete with completion support -and helpful annotation support for more commands. Similar to the Fish shell, -pcmpl-args uses man page parsing and --help output parsing to dynamically -generate completions. This package brings Eshell completion to another level! - -Unfortunately Pcomplete has a few technical issues, which we can work around -with the [[https://github.com/minad/cape][Cape]] library (Completion at point extensions). Cape provides wrappers, -which sanitize the pcomplete function. Ideally the bugs in pcomplete should be -fixed upstream. *For now these two advices are strongly recommended to achieve a -sane Eshell experience.* - -#+begin_src emacs-lisp - ;; Silence the pcomplete capf, no errors or messages! - (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) - - ;; Ensure that pcomplete does not write to the buffer - ;; and behaves as a pure `completion-at-point-function'. - (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify) -#+end_src - -** Orderless completion - -[[https://github.com/oantolin/orderless][Orderless]] is an advanced completion style that supports multi-component search -filters separated by a configurable character (space, by default). Normally, -entering characters like space which lie outside the completion region -boundaries (words, typically) causes Corfu to quit. This behavior is helpful -with auto-completion, which may pop-up when not desired, e.g. on entering a new -variable name. Just keep typing and Corfu will get out of the way. - -But orderless search terms can contain arbitrary characters; they are also -interpreted as regular expressions. To use orderless, set ~corfu-separator~ (a -space, by default) to the primary character of your orderless component -separator. - -Then, when a new orderless component is desired, use =M-SPC= -(~corfu-insert-separator~) to enter the /first/ component separator in the input, -and arbitrary orderless search terms and new separators can be entered -thereafter. - -To treat the entire input as Orderless input, you can set the customization -option ~corfu-quit-at-boundary=t~. This disables the predicate which checks if the -current completion boundary has been left. In contrast, if you /always/ want to -quit at the boundary, simply set ~corfu-quit-at-boundary=nil~. By default -~corfu-quit-at-boundary~ is set to ~separator~ which quits at completion boundaries -as long as no separator has been inserted with ~corfu-insert-separator~. - -Finally, there exists the user option ~corfu-quit-no-match~ which is set to -=separator= by default. With this setting Corfu stays alive as soon as you start -advanced filtering with a ~corfu-separator~ even if there are no matches, for -example due to a typo. As long as no separator character has been inserted with -~corfu-insert-separator~, Corfu will still quit if there are no matches. This -ensures that the Corfu popup goes away quickly if completion is not possible. - -In the following we show two configurations, one which works best with auto -completion and one which may work better with manual completion if you prefer to -always use =SPC= to separate the Orderless components. - - #+begin_src emacs-lisp - ;; Auto completion example - (use-package corfu - :custom - (corfu-auto t) ;; Enable auto completion - ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space - :bind - ;; Another key binding can be used, such as S-SPC. - ;; (:map corfu-map ("M-SPC" . corfu-insert-separator)) - :init - (corfu-global-mode)) - - ;; Manual completion example - (use-package corfu - :custom - ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space - :bind - ;; Configure SPC for separator insertion - (:map corfu-map ("SPC" . corfu-insert-separator)) - :init - (corfu-global-mode)) -#+end_src - -** 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 - -** Transfer completion to the minibuffer - -Sometimes it is useful to transfer the Corfu completion session to the -minibuffer, since the minibuffer offers richer interaction features. In -particular, [[https://github.com/oantolin/embark][Embark]] is available in the minibuffer, such that you can act on the -candidates or export/collect the candidates to a separate buffer. Hopefully we -can also add Corfu-support to Embark in the future, such that at least -export/collect is possible directly from Corfu. But in my opinion having the -ability to transfer the Corfu completion to the minibuffer is an even better -feature, since further completion can be performed there. - -The command ~corfu-move-to-minibuffer~ is defined here in terms of -~consult-completion-in-region~, which uses the minibuffer completion UI via -~completing-read~. - -#+begin_src emacs-lisp - (defun corfu-move-to-minibuffer () - (interactive) - (let ((completion-extra-properties corfu--extra) - completion-cycle-threshold completion-cycling) - (apply #'consult-completion-in-region completion-in-region--data))) - (define-key corfu-map "\M-m" #'corfu-move-to-minibuffer) -#+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~ - - =M-SPC= -> ~corfu-insert-separator~ - - =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]]: Corfu supports completion styles, including the advanced - [[https://github.com/oantolin/orderless][Orderless]] completion style, where the filtering expressions are separated by - spaces or another character (see ~corfu-separator~). - - - [[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 displays the candidate documentation in a - popup next to the Corfu popup, similar to =company-quickhelp=. - - - [[https://github.com/JonWaltman/pcmpl-args.el][pcmpl-args]]: Extend the Eshell/Shell Pcomplete mechanism with support for many - more commands. Similar to the Fish shell, Pcomplete uses man page parsing to - dynamically retrieve the completions and helpful annotations. This package - brings Eshell completions to another level! - - - [[https://github.com/minad/tempel][Tempel]]: Tiny template/snippet package with templates in Lisp syntax, which - can be used in conjunction with Corfu. - - - [[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. - -* Alternatives - - - [[https://github.com/company-mode/company-mode][Company]]: Company is a widely used and mature completion package, which - implements a similar interaction model and popup UI as Corfu. While Corfu - relies exclusively on the standard Emacs completion API (Capfs), Company - defines its own API for the backends. Furthermore Company includes its - completion backends, which are incompatible with the Emacs completion - infrastructure. As a result of this design, Company is a more complex - package than Corfu. Company by default uses overlays to display the popup in - contrast to the child frames used by Corfu. Overall both packages work well. - Company is more mature but the integration into Emacs is a bit less tight, - since for example the ~completion-at-point~ command (or the - ~completion-in-region~ function) does not invoke Company. - - - [[https://gitlab.com/protesilaos/mct][Mct]]: Protesilaos' Minibuffer Confines Transcended package supports both - minibuffer completion and completion in region. It reuses the default - completion UI for this purpose and installs a timer which live updates the - completion buffer. The main advantage of Mct is that you work with a regular - Emacs buffer instead of with a popup. You can take advantage of the usual - Emacs commands to navigate in the completions buffer. On top, Mct enhances - the movement such that you can quickly switch between the completions buffer - and the minibuffer or the region which is being completed. Mct does not - support timer-based auto completion, but the integration into Emacs is - naturally tight. - - - [[https://github.com/minad/consult][consult-completion-in-region]]: The Consult package provides the function - ~consult-completion-in-region~ which can be set as - ~completion-in-region-function~ such that it handles ~completion-at-point~. The - function works by transferring the in-buffer completion to the minibuffer. - In the minibuffer, the minibuffer completion UI, for example [[https://github.com/minad/vertico][Vertico]] takes - over. If you prefer to perform all your completions in the minibuffer - ~consult-completion-in-region~ is your best option. - -* 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 can use one of the alternatives in terminals. - - - 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.20/corfu-autoloads.el b/elpa/corfu-0.20/corfu-autoloads.el @@ -1,60 +0,0 @@ -;;; 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.20/corfu-pkg.el b/elpa/corfu-0.20/corfu-pkg.el @@ -1,2 +0,0 @@ -;; Generated package description from corfu.el -*- no-byte-compile: t -*- -(define-package "corfu" "0.20" "Completion Overlay Region FUnction" '((emacs "27.1")) :commit "e2cc92b029bd9334f88d382def7066c35c31b3a9" :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.20/corfu.el b/elpa/corfu-0.20/corfu.el @@ -1,1278 +0,0 @@ -;;; corfu.el --- Completion Overlay Region FUnction -*- lexical-binding: t -*- - -;; Copyright (C) 2021, 2022 Free Software Foundation, Inc. - -;; Author: Daniel Mendler <mail@daniel-mendler.de> -;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> -;; Created: 2021 -;; Version: 0.20 -;; 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-on-exact-match 'insert - "Configure how a single exact match should be handled." - :type '(choice (const insert) (const quit) (const nil))) - -(defcustom corfu-continue-commands - ;; nil is undefined command - '(nil ignore 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-preview-current 'insert - "Preview currently selected candidate. -If the variable has the value `insert', the candidate is automatically -inserted on further input." - :type '(choice boolean (const insert))) - -(defcustom corfu-preselect-first t - "Preselect first candidate." - :type 'boolean) - -(defvar corfu-commit-predicate nil) -(make-obsolete-variable - 'corfu-commit-predicate - "Set `corfu-preview-current' to the value `insert'." - "0.19") - -(defcustom corfu-separator ?\s - "Component separator character. -The character used for separating components in the input. The presence -of this separator character will inhibit quitting at completion -boundaries, so that any further characters can be entered. To enter the -first separator character, call `corfu-insert-separator' (bound to M-SPC -by default). Useful for multi-component completion styles such as -Orderless." - :type 'character) - -(defcustom corfu-quit-at-boundary 'separator - "Automatically quit at completion boundary. -nil: Never quit at completion boundary. -t: Always quit at completion boundary. -separator: Quit at boundary if no `corfu-separator' has been inserted." - :type '(choice boolean (const separator))) - -(defcustom corfu-quit-no-match 'separator - "Automatically quit if no matching candidate is found. -nil: Stay alive even if there is no match. -t: Quit if there is no match. -separator: Only stay alive if there is no match and -`corfu-separator' has been inserted." - :type '(choice boolean (const separator))) - -(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 '(1.0 . 0.2) - "Show documentation string in the echo area after that number of seconds. -Set to nil to disable the echo message or to t for an instant message. -The value can be a pair of two floats to specify initial and subsequent -delay." - :type '(choice (const :tag "Never" nil) - (const :tag "Instant" t) - (number :tag "Delay in seconds") - (cons :tag "Two Delays" - (choice :tag "Initial " number)) - (choice :tag "Subsequent" number))) - -(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) - (define-key map (concat "\e" " ") #'corfu-insert-separator) ;; Avoid ugly warning - 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.") - -(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--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--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 -(defvar x-gtk-resize-child-frames) ;; Not present on non-gtk builds -(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)) - (ch (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 ch)) - (y (if (> (+ yb (* corfu-count ch) ch ch) (frame-pixel-height)) - (- yb height ch 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)) - (set-frame-size corfu--frame width height t) - (if (frame-visible-p corfu--frame) - ;; XXX HACK Avoid flicker when frame is already visible. - ;; Redisplay, wait for resize and then move the frame. - (unless (equal (frame-position corfu--frame) (cons x y)) - (redisplay 'force) - (sleep-for 0.01) - (set-frame-position corfu--frame x y)) - ;; XXX HACK: Force redisplay, otherwise the popup sometimes does not display content. - (set-frame-position corfu--frame x y) - (redisplay 'force) - (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)) - (ml (ceiling (* cw corfu-left-margin-width))) - (mr (ceiling (* cw corfu-right-margin-width))) - (bw (ceiling (min mr (* cw corfu-bar-width)))) - (marginl (and (> ml 0) (propertize " " 'display `(space :width (,ml))))) - (marginr (and (> mr 0) (propertize " " 'display `(space :align-to right)))) - (sbar (when (> bw 0) - (concat (propertize " " 'display `(space :align-to (- right (,mr)))) - (propertize " " 'display `(space :width (,(- mr 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 ml (* cw off)) y - (+ (* width cw) ml mr) (* (length lines) ch) - (mapconcat (lambda (line) - (let ((str (concat marginl line - (if (and lo (<= lo row (+ lo bar))) sbar marginr)))) - (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 (substring field 0 - (seq-position field corfu-separator))) - (len (length word))) - (corfu--partition! - candidates - (and (>= (length it) len) - (eq t (compare-strings word 0 len it 0 len - completion-ignore-case)))))) - -(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) ""))) - ;; 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. - (unless (text-property-not-all 0 (length suffix) 'face nil suffix) - (setq suffix (propertize suffix 'face 'corfu-annotations))) - (list cand "" suffix))) - (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)) - ;; -4 because of margins and some additional safety - (max-width (min corfu-max-width (- (frame-width) 4)))) - (when (> width max-width) - (setq sw (max 0 (- max-width pw cw)) - width (+ pw cw sw))) - (when (< width corfu-min-width) - (setq cw (+ cw (- corfu-min-width width)) - width corfu-min-width)) - (setq width (min width max-width)) - (list pw width - (cl-loop for (cand prefix suffix) in cands collect - (truncate-string-to-width - (concat prefix - (make-string (max 0 (- pw (string-width prefix))) ?\s) - cand - (when (/= sw 0) - (make-string - (+ (max 0 (- cw (string-width cand))) - (max 0 (- 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)) - (corfu--echo-show corfu--echo-message)) - -(defun corfu--echo-show (&optional msg) - "Show MSG in echo area." - (when (or msg corfu--echo-message) - (setq msg (or msg "") - corfu--echo-message msg) - (corfu--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." - (if-let* ((delay (if (consp corfu-echo-documentation) - (funcall (if corfu--echo-message #'cdr #'car) - corfu-echo-documentation) - corfu-echo-documentation)) - (fun (plist-get corfu--extra :company-docsig)) - (cand (and (>= corfu--index 0) - (nth corfu--index corfu--candidates)))) - (if (or (eq delay t) (<= delay 0)) - (corfu--echo-show (funcall fun cand)) - (when corfu--echo-timer (cancel-timer corfu--echo-timer)) - (setq corfu--echo-timer - (run-at-time delay nil - (lambda () - (corfu--echo-show (funcall fun cand))))) - (corfu--echo-show)) - (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))) - (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 - (unless (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. Happens during auto completion. - ((and initializing (not corfu--candidates)) - (corfu-quit)) - ;; 2) Single exactly matching candidate and no further completion is possible. - ((and (not (equal str "")) - (equal (car corfu--candidates) str) (not (cdr corfu--candidates)) - (not (consp (completion-try-completion str table pred pt corfu--metadata))) - (or initializing corfu-on-exact-match)) - ;; Quit directly when initializing. This happens during auto completion. - (if (or initializing (eq corfu-on-exact-match 'quit)) - (corfu-quit) - (corfu--done str 'finished))) - ;; 3) There exist candidates => Show candidates popup. - (corfu--candidates - (corfu--candidates-popup beg) - (corfu--preview-current beg end str) - (corfu--echo-documentation) - (redisplay 'force)) ;; XXX HACK Ensure that popup is redisplayed - ;; 4) There are no candidates & corfu-quit-no-match => Confirmation popup. - ((and (not corfu--candidates) - (pcase-exhaustive corfu-quit-no-match - ('t nil) - ('nil t) - ('separator (seq-contains-p (car corfu--input) corfu-separator)))) - (corfu--popup-show beg 0 8 '(#("No match" 0 8 (face italic)))) - (redisplay 'force)) ;; XXX HACK Ensure that popup is redisplayed - (t (corfu-quit))))) - -(defun corfu--pre-command () - "Insert selected candidate unless command is marked to continue completion." - (when corfu--preview-ov - (delete-overlay corfu--preview-ov) - (setq corfu--preview-ov nil)) - (when (and (eq corfu-preview-current 'insert) - (/= corfu--index corfu--preselect) - (not (corfu--match-symbol-p corfu-continue-commands this-command))) - (corfu--insert 'exact))) - -(defun corfu-insert-separator () - "Insert a separator character, inhibiting quit on completion boundary." - (interactive) - (insert corfu-separator)) - -(defun corfu--post-command () - "Refresh Corfu after last command." - (or (pcase completion-in-region--data - (`(,beg ,end . ,_) - (when (let ((pt (point))) - (and (eq (marker-buffer beg) (current-buffer)) - ;; Check ranges - (<= beg pt end) - (save-excursion - (goto-char beg) - (<= (line-beginning-position) pt (line-end-position))) - (or - ;; Check if it is an explicitly listed continue command - (corfu--match-symbol-p corfu-continue-commands this-command) - (and - ;; Check for empty input - (or (not corfu--input) (< beg end)) - ;; Check separator or predicate - (or (not corfu-quit-at-boundary) - (and (eq corfu-quit-at-boundary 'separator) - (or (eq this-command #'corfu-insert-separator) - ;; with separator, any further chars allowed - (seq-contains-p (car corfu--input) corfu-separator))) - (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))))) - -(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 (>= 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) - (unless (equal str newstr) - (completion--replace beg end (concat 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) - (completion-in-region-mode 1) - (undo-boundary) ;; Necessary to support `corfu-reset' - (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) - ;; 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 'pre-command-hook #'corfu--pre-command 'local) - (remove-hook 'post-command-hook #'corfu--post-command) - (when corfu--preview-ov (delete-overlay corfu--preview-ov)) - (when corfu--echo-timer (cancel-timer corfu--echo-timer)) - (corfu--echo-show) - (accept-change-group corfu--change-group) - (mapc #'kill-local-variable corfu--state-vars)) - -(defun corfu--in-region (beg end table &optional pred) - "Corfu completion in region function. -See `completion-in-region' for the arguments BEG, END, TABLE, PRED." - (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--in-region'. This should never happen. - (funcall (default-value 'completion-in-region-function) beg end table pred) - ;; Restart the completion. This can happen for example if C-M-/ - ;; (`dabbrev-completion') is pressed while the Corfu popup is already open. - (when completion-in-region-mode (corfu-quit)) - (let* ((pt (max 0 (- (point) beg))) - (str (buffer-substring-no-properties beg end)) - (before (substring str 0 pt)) - (metadata (completion-metadata before table pred)) - (exit (plist-get completion-extra-properties :exit-function)) - (threshold (completion--cycle-threshold metadata)) - (completion-in-region-mode-predicate - (or completion-in-region-mode-predicate (lambda () t)))) - (pcase (completion-try-completion str table pred pt metadata) - ('nil (corfu--message "No match") nil) - ('t - (goto-char end) - (corfu--message "Sole match") - (when exit (funcall exit str 'finished)) - t) - (`(,newstr . ,newpt) - (pcase-let ((`(,base ,candidates ,total . ,_) - (corfu--recompute-candidates str pt table pred))) - (setq beg (copy-marker beg) - end (copy-marker end t) - completion-in-region--data (list beg end table pred)) - (unless (equal str newstr) - (completion--replace beg end (concat newstr))) - (goto-char (+ beg newpt)) - (if (= total 1) - (when exit - (funcall exit newstr - ;; If completion is finished and cannot be further completed, - ; return 'finished. Otherwise return 'exact. - (if (eq (try-completion (car candidates) table pred) t) - 'finished 'exact))) - (if (not (and threshold (or (eq threshold t) (>= threshold total)))) - (corfu--setup) - (corfu--cycle-candidates total candidates (+ base beg) end) - ;; Do not show Corfu when "trivially" cycling, i.e., - ;; when the completion is finished after the candidate. - (unless (equal (completion-boundaries - (buffer-substring-no-properties beg end) - table pred "") '(0 . 0)) - (corfu--setup))))) - t))))) - -(defun corfu--message (&rest msg) - "Show completion MSG." - (let (message-log-max) (apply #'message msg))) - -(defun corfu--cycle-candidates (total cands beg end) - "Cycle between TOTAL number of CANDS. -See `completion-in-region' for the arguments BEG, END, TABLE, PRED." - (let* ((idx 0) - (map (make-sparse-keymap)) - (replace (lambda () - (interactive) - (completion--replace beg end (concat (nth idx cands))) - (corfu--message "Cycling %d/%d..." (1+ idx) total) - (setq idx (mod (1+ idx) total)) - (set-transient-map map)))) - (define-key map [remap completion-at-point] replace) - (define-key map [remap corfu-complete] replace) - (define-key map (vector last-command-event) replace) - (funcall replace))) - -(defun corfu--auto-complete (tick) - "Initiate auto completion if TICK did not change." - (setq corfu--auto-timer nil) - (when (and (not completion-in-region-mode) (equal tick (corfu--auto-tick))) - (pcase (while-no-input ;; Interruptible capf query - (run-hook-wrapped 'completion-at-point-functions #'corfu--capf-wrapper)) - (`(,fun ,beg ,end ,table . ,plist) - (let ((completion-in-region-mode-predicate - (lambda () (eq beg (car-safe (funcall fun))))) - (completion-extra-properties plist)) - (setq completion-in-region--data - (list (copy-marker beg) (copy-marker end t) table - (plist-get plist :predicate))) - (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) - (not defining-kbd-macro) - (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 (corfu--auto-tick))))) - -(defun corfu--auto-tick () - "Return the current tick/status of the buffer. -Auto completion is only performed if the tick did not change." - (list (current-buffer) (buffer-chars-modified-tick) (point))) - -;;;###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--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 &optional prefix) - "Wrapper for `completion-at-point' FUN. -The wrapper determines if the capf is applicable at the current position -and performs sanity checking on the returned result. PREFIX is a prefix -length override, set to t for manual completion." - (pcase (funcall fun) - ((and res `(,beg ,end ,table . ,plist)) - (and (integer-or-marker-p beg) ;; Valid capf result - (<= beg (point) end) ;; Sanity checking - ;; When auto completing, check the prefix length! - (let ((len (or prefix - (plist-get plist :company-prefix-length) - (- (point) beg)))) - (or (eq len t) (>= len corfu-auto-prefix))) - ;; 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 t) (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 corfu-insert-separator)) - (put sym 'completion-predicate #'ignore)) - -(provide 'corfu) -;;; corfu.el ends here diff --git a/elpa/corfu-0.20/corfu.info b/elpa/corfu-0.20/corfu.info @@ -1,611 +0,0 @@ -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:: -* Alternatives:: -* Caveats:: -* Contributions:: - -— The Detailed Node Listing — - -Installation and Configuration - -* Auto completion:: -* Completing with Corfu in the minibuffer:: -* Completing with Corfu in the Eshell or Shell:: -* Orderless completion:: -* TAB-and-Go completion:: -* Transfer completion to the minibuffer:: - - - -File: corfu.info, Node: Introduction, Next: Features, Prev: Top, Up: Top - -1 Introduction -************** - -Corfu enhances completion at point with a small completion popup. 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 small 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), use Capfs which -talk to the LSP server to retrieve the completions. Corfu does not -include its own completion backends. The Emacs built-in Capfs and the -Capfs provided by other programming language packages are usually -sufficient. A few additional Capfs and completion utilities 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. - - <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 (configurable via - ‘corfu-preview-current’). - • The selected candidate automatically committed on further input by - default. (configurable via ‘corfu-preview-current’). - • The Orderless (https://github.com/oantolin/orderless) completion - style is supported. The filter string can contain arbitrary - characters, after inserting a space via ‘M-SPC’ (configurable via - ‘corfu-quit-at-boundary’ and ‘corfu-separator’). - • Deferred completion style highlighting for performance. - • Jumping to location/documentation of current candidate. - • Support for candidate annotations and documentation in the echo - area. - • Deprecated candidates are crossed out in the display. - • 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, such that you can adapt it precisely to your requirements. -However in order to quickly try out the Corfu completion package, it -should be sufficient to activate ‘corfu-global-mode’. Then you -experiment with manual completion for example in an Elisp buffer or in -an Eshell or Shell buffer. For auto completion, set ‘corfu-auto=t’ -before turning on ‘corfu-global-mode’. - - If you start to configure the package more deeply, I recommend to -give the Orderless completion style a try for filtering. Orderless -completion 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-separator ?\s) ;; Orderless field separator - ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary - ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match - ;; (corfu-preview-current nil) ;; Disable current candidate preview - ;; (corfu-preselect-first nil) ;; Disable candidate preselection - ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches - ;; (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: - -* Auto completion:: -* Completing with Corfu in the minibuffer:: -* Completing with Corfu in the Eshell or Shell:: -* Orderless completion:: -* TAB-and-Go completion:: -* Transfer completion to the minibuffer:: - - -File: corfu.info, Node: Auto completion, Next: Completing with Corfu in the minibuffer, Up: Installation and Configuration - -3.1 Auto completion -=================== - -Auto completion is disabled by default, but can be enabled by setting -‘corfu-auto=t’. Furthermore you may want to configure Corfu to quit -completion eagerly, such that the completion popup stays out of your way -when it appeared unexpectedly. - - ;; Enable auto completion and configure quitting - (setq corfu-auto t - corfu-quit-no-match 'separator) ;; or t - - In general, I recommend to experiment a bit with the various settings -and key bindings to find a configuration which works for you. There is -no one size fits all solution. Some people like auto completion, some -like manual completion, some want to cycle with TAB and some with the -arrow keys... - - -File: corfu.info, Node: Completing with Corfu in the minibuffer, Next: Completing with Corfu in the Eshell or Shell, Prev: Auto completion, Up: Installation and Configuration - -3.2 Completing with Corfu in the minibuffer -=========================================== - -Corfu can be used for completion in the minibuffer, since it relies on -child frames to display the candidates. By default, ‘corfu-global-mode’ -does not activate ‘corfu-mode’ in the minibuffer, to avoid interference -with specialised minibuffer completion UIs like Vertico or Mct. However -you may still want to enable Corfu completion for commands like ‘M-:’ -(‘eval-expression’) or ‘M-!’ (‘shell-command’), which read from the -minibuffer. Activate ‘corfu-mode’ only if ‘completion-at-point’ is -bound in the minibuffer-local keymap to achieve this effect. - - (defun corfu-enable-in-minibuffer () - "Enable Corfu in the minibuffer if `completion-at-point' is bound." - (when (where-is-internal #'completion-at-point (list (current-local-map))) - ;; (setq-local corfu-auto nil) Enable/disable auto completion - (corfu-mode 1))) - (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) - - You can also enable Corfu more generally for every minibuffer, as -long as no other completion UI is active. If you use Mct or Vertico as -your main minibuffer completion UI, the following snippet should yield -the desired result. - - (defun corfu-enable-always-in-minibuffer () - "Enable Corfu in the minibuffer if Vertico/Mct are not active." - (unless (or (bound-and-true-p mct--active) - (bound-and-true-p vertico--input)) - ;; (setq-local corfu-auto nil) Enable/disable auto completion - (corfu-mode 1))) - (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1) - - -File: corfu.info, Node: Completing with Corfu in the Eshell or Shell, Next: Orderless completion, Prev: Completing with Corfu in the minibuffer, Up: Installation and Configuration - -3.3 Completing with Corfu in the Eshell or Shell -================================================ - -When completing in the Eshell I recommend conservative local settings -without auto completion, such that the completion behavior is similar to -widely used shells like Bash, Zsh or Fish. - - (add-hook 'eshell-mode-hook - (lambda () - (setq-local corfu-auto nil) - (corfu-mode))) - - When pressing ‘RET’ while the Corfu popup is visible, the -‘corfu-insert’ command will be invoked. This command does inserts the -currently selected candidate, but it does not send the prompt input to -Eshell or the comint process. Therefore you often have to press ‘RET’ -twice which feels like an unnecessary double confirmation. Fortunately -it is easy to improve this! In my configuration I define the command -‘corfu-insert-and-send’ which performs the two steps at once. - - (defun corfu-insert-and-send () - (interactive) - ;; 1. First insert the completed candidate - (corfu-insert) - ;; 2. Send the entire prompt input to the shell - (cond - ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input)) - (eshell-send-input)) - ((derived-mode-p 'comint-mode) - (comint-send-input)))) - - (define-key corfu-map "\r" #'+corfu-insert-and-send) - - Shell completion uses the flexible ‘pcomplete’ mechanism internally, -which allows you to program the completions per shell command. If you -want to know more, look into this blog post -(https://www.masteringemacs.org/article/pcomplete-context-sensitive-completion-emacs), -which shows how to configure pcomplete for git commands. I recommend -the pcmpl-args (https://github.com/JonWaltman/pcmpl-args.el) package -which extends Pcomplete with completion support and helpful annotation -support for more commands. Similar to the Fish shell, pcmpl-args uses -man page parsing and –help output parsing to dynamically generate -completions. This package brings Eshell completion to another level! - - Unfortunately Pcomplete has a few technical issues, which we can work -around with the Cape (https://github.com/minad/cape) library (Completion -at point extensions). Cape provides wrappers, which sanitize the -pcomplete function. Ideally the bugs in pcomplete should be fixed -upstream. *For now these two advices are strongly recommended to -achieve a sane Eshell experience.* - - ;; Silence the pcomplete capf, no errors or messages! - (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) - - ;; Ensure that pcomplete does not write to the buffer - ;; and behaves as a pure `completion-at-point-function'. - (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify) - - -File: corfu.info, Node: Orderless completion, Next: TAB-and-Go completion, Prev: Completing with Corfu in the Eshell or Shell, Up: Installation and Configuration - -3.4 Orderless completion -======================== - -Orderless (https://github.com/oantolin/orderless) is an advanced -completion style that supports multi-component search filters separated -by a configurable character (space, by default). Normally, entering -characters like space which lie outside the completion region boundaries -(words, typically) causes Corfu to quit. This behavior is helpful with -auto-completion, which may pop-up when not desired, e.g. on entering a -new variable name. Just keep typing and Corfu will get out of the way. - - But orderless search terms can contain arbitrary characters; they are -also interpreted as regular expressions. To use orderless, set -‘corfu-separator’ (a space, by default) to the primary character of your -orderless component separator. - - Then, when a new orderless component is desired, use ‘M-SPC’ -(‘corfu-insert-separator’) to enter the _first_ component separator in -the input, and arbitrary orderless search terms and new separators can -be entered thereafter. - - To treat the entire input as Orderless input, you can set the -customization option ‘corfu-quit-at-boundary=t’. This disables the -predicate which checks if the current completion boundary has been left. -In contrast, if you _always_ want to quit at the boundary, simply set -‘corfu-quit-at-boundary=nil’. By default ‘corfu-quit-at-boundary’ is -set to ‘separator’ which quits at completion boundaries as long as no -separator has been inserted with ‘corfu-insert-separator’. - - Finally, there exists the user option ‘corfu-quit-no-match’ which is -set to ‘separator’ by default. With this setting Corfu stays alive as -soon as you start advanced filtering with a ‘corfu-separator’ even if -there are no matches, for example due to a typo. As long as no -separator character has been inserted with ‘corfu-insert-separator’, -Corfu will still quit if there are no matches. This ensures that the -Corfu popup goes away quickly if completion is not possible. - - In the following we show two configurations, one which works best -with auto completion and one which may work better with manual -completion if you prefer to always use ‘SPC’ to separate the Orderless -components. - - ;; Auto completion example - (use-package corfu - :custom - (corfu-auto t) ;; Enable auto completion - ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space - :bind - ;; Another key binding can be used, such as S-SPC. - ;; (:map corfu-map ("M-SPC" . corfu-insert-separator)) - :init - (corfu-global-mode)) - - ;; Manual completion example - (use-package corfu - :custom - ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space - :bind - ;; Configure SPC for separator insertion - (:map corfu-map ("SPC" . corfu-insert-separator)) - :init - (corfu-global-mode)) - - -File: corfu.info, Node: TAB-and-Go completion, Next: Transfer completion to the minibuffer, Prev: Orderless completion, Up: Installation and Configuration - -3.5 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: Transfer completion to the minibuffer, Prev: TAB-and-Go completion, Up: Installation and Configuration - -3.6 Transfer completion to the minibuffer -========================================= - -Sometimes it is useful to transfer the Corfu completion session to the -minibuffer, since the minibuffer offers richer interaction features. In -particular, Embark (https://github.com/oantolin/embark) is available in -the minibuffer, such that you can act on the candidates or -export/collect the candidates to a separate buffer. Hopefully we can -also add Corfu-support to Embark in the future, such that at least -export/collect is possible directly from Corfu. But in my opinion -having the ability to transfer the Corfu completion to the minibuffer is -an even better feature, since further completion can be performed there. - - The command ‘corfu-move-to-minibuffer’ is defined here in terms of -‘consult-completion-in-region’, which uses the minibuffer completion UI -via ‘completing-read’. - - (defun corfu-move-to-minibuffer () - (interactive) - (let ((completion-extra-properties corfu--extra) - completion-cycle-threshold completion-cycling) - (apply #'consult-completion-in-region completion-in-region--data))) - (define-key corfu-map "\M-m" #'corfu-move-to-minibuffer) - - -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’ - • ‘M-SPC’ -> ‘corfu-insert-separator’ - • ‘C-g’ -> ‘corfu-quit’ - • ‘keyboard-escape-quit’ -> ‘corfu-reset’ - - -File: corfu.info, Node: Complementary packages, Next: Alternatives, 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): Corfu supports - completion styles, including the advanced Orderless - (https://github.com/oantolin/orderless) completion style, where the - filtering expressions are separated by spaces or another character - (see ‘corfu-separator’). - - • 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 displays the candidate documentation in a popup next to the - Corfu popup, similar to ‘company-quickhelp’. - - • pcmpl-args (https://github.com/JonWaltman/pcmpl-args.el): Extend - the Eshell/Shell Pcomplete mechanism with support for many more - commands. Similar to the Fish shell, Pcomplete uses man page - parsing to dynamically retrieve the completions and helpful - annotations. This package brings Eshell completions to another - level! - - • Tempel (https://github.com/minad/tempel): Tiny template/snippet - package with templates in Lisp syntax, which can be used in - conjunction with Corfu. - - • 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: Alternatives, Next: Caveats, Prev: Complementary packages, Up: Top - -6 Alternatives -************** - - • Company (https://github.com/company-mode/company-mode): Company is - a widely used and mature completion package, which implements a - similar interaction model and popup UI as Corfu. While Corfu - relies exclusively on the standard Emacs completion API (Capfs), - Company defines its own API for the backends. Furthermore Company - includes its completion backends, which are incompatible with the - Emacs completion infrastructure. As a result of this design, - Company is a more complex package than Corfu. Company by default - uses overlays to display the popup in contrast to the child frames - used by Corfu. Overall both packages work well. Company is more - mature but the integration into Emacs is a bit less tight, since - for example the ‘completion-at-point’ command (or the - ‘completion-in-region’ function) does not invoke Company. - - • Mct (https://gitlab.com/protesilaos/mct): Protesilaos’ Minibuffer - Confines Transcended package supports both minibuffer completion - and completion in region. It reuses the default completion UI for - this purpose and installs a timer which live updates the completion - buffer. The main advantage of Mct is that you work with a regular - Emacs buffer instead of with a popup. You can take advantage of - the usual Emacs commands to navigate in the completions buffer. On - top, Mct enhances the movement such that you can quickly switch - between the completions buffer and the minibuffer or the region - which is being completed. Mct does not support timer-based auto - completion, but the integration into Emacs is naturally tight. - - • consult-completion-in-region (https://github.com/minad/consult): - The Consult package provides the function - ‘consult-completion-in-region’ which can be set as - ‘completion-in-region-function’ such that it handles - ‘completion-at-point’. The function works by transferring the - in-buffer completion to the minibuffer. In the minibuffer, the - minibuffer completion UI, for example Vertico - (https://github.com/minad/vertico) takes over. If you prefer to - perform all your completions in the minibuffer - ‘consult-completion-in-region’ is your best option. - - -File: corfu.info, Node: Caveats, Next: Contributions, Prev: Alternatives, Up: Top - -7 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 can use one of the alternatives in - terminals. - - • 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 - -8 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: Introduction794 -Node: Features2318 -Node: Installation and Configuration3705 -Node: Auto completion8565 -Node: Completing with Corfu in the minibuffer9414 -Node: Completing with Corfu in the Eshell or Shell11271 -Node: Orderless completion14224 -Node: TAB-and-Go completion17332 -Node: Transfer completion to the minibuffer18217 -Node: Key bindings19556 -Node: Complementary packages20559 -Node: Alternatives23106 -Node: Caveats25539 -Node: Contributions26125 - -End Tag Table - - -Local Variables: -coding: utf-8 -End: diff --git a/elpa/corfu-0.21.signed b/elpa/corfu-0.21.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2022-04-09T11:05:01+0200 using RSA +\ No newline at end of file diff --git a/elpa/corfu-0.20/LICENSE b/elpa/corfu-0.21/LICENSE diff --git a/elpa/corfu-0.21/README.org b/elpa/corfu-0.21/README.org @@ -0,0 +1,476 @@ +#+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 completion at point with a small completion popup. 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 small 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]], use Capfs which talk to the LSP server to retrieve the completions. + Corfu does not include its own completion backends. The Emacs built-in Capfs + and the Capfs provided by other programming language packages are usually + sufficient. A few additional Capfs and completion utilities 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. + + [[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 (configurable via ~corfu-preview-current~). + - The selected candidate automatically committed on further input by default. + (configurable via ~corfu-preview-current~). + - The [[https://github.com/oantolin/orderless][Orderless]] completion style is supported. The filter string can contain + arbitrary characters, after inserting a space via =M-SPC= (configurable via + ~corfu-quit-at-boundary~ and ~corfu-separator~). + - Deferred completion style highlighting for performance. + - Jumping to location/documentation of current candidate. + - Support for candidate annotations and documentation in the echo area. + - Deprecated candidates are crossed out in the display. + - 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, + such that you can adapt it precisely to your requirements. However in order to + quickly try out the Corfu completion package, it should be sufficient to + activate ~corfu-global-mode~. Then you experiment with manual completion for + example in an Elisp buffer or in an Eshell or Shell buffer. For auto + completion, set ~corfu-auto=t~ before turning on ~corfu-global-mode~. + + 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-separator ?\s) ;; Orderless field separator + ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary + ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match + ;; (corfu-preview-current nil) ;; Disable current candidate preview + ;; (corfu-preselect-first nil) ;; Disable candidate preselection + ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches + ;; (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)) + + ;; 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 + + If you start to configure the package more deeply, I recommend to give the + Orderless completion style a try for filtering. Orderless completion 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. + +#+begin_src emacs-lisp + ;; Optionally use the `orderless' completion style. + (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 basic) + completion-category-defaults nil + completion-category-overrides '((file (styles . (partial-completion)))))) +#+end_src + + The =basic= completion style is specified as fallback in addition to =orderless= + in order to ensure that completion commands which rely on dynamic completion + tables, e.g., ~completion-table-dynamic~ or ~completion-table-in-turn~, work + correctly. See =+orderless-dispatch= in the [[https://github.com/minad/consult/wiki][Consult wiki]] for an advanced + Orderless style dispatcher. Additionally enable =partial-completion= for file + path expansion. =partial-completion= is important for file 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. + + 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. 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]]. + +** Auto completion + + Auto completion is disabled by default, but can be enabled by setting + ~corfu-auto=t~. Furthermore you may want to configure Corfu to quit completion + eagerly, such that the completion popup stays out of your way when it + appeared unexpectedly. + + #+begin_src emacs-lisp + ;; Enable auto completion and configure quitting + (setq corfu-auto t + corfu-quit-no-match 'separator) ;; or t + #+end_src + + In general, I recommend to experiment a bit with the various settings and key + bindings to find a configuration which works for you. There is no one size + fits all solution. Some people like auto completion, some like manual + completion, some want to cycle with TAB and some with the arrow keys... + +** Completing with Corfu in the minibuffer + +Corfu can be used for completion in the minibuffer, since it relies on child +frames to display the candidates. By default, ~corfu-global-mode~ does not +activate ~corfu-mode~ in the minibuffer, to avoid interference with specialised +minibuffer completion UIs like Vertico or Mct. However you may still want to +enable Corfu completion for commands like ~M-:~ (~eval-expression~) or ~M-!~ +(~shell-command~), which read from the minibuffer. Activate ~corfu-mode~ only if +~completion-at-point~ is bound in the minibuffer-local keymap to achieve this +effect. + +#+begin_src emacs-lisp + (defun corfu-enable-in-minibuffer () + "Enable Corfu in the minibuffer if `completion-at-point' is bound." + (when (where-is-internal #'completion-at-point (list (current-local-map))) + ;; (setq-local corfu-auto nil) Enable/disable auto completion + (corfu-mode 1))) + (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) +#+end_src + +You can also enable Corfu more generally for every minibuffer, as long as no +other completion UI is active. If you use Mct or Vertico as your main minibuffer +completion UI, the following snippet should yield the desired result. + +#+begin_src emacs-lisp + (defun corfu-enable-always-in-minibuffer () + "Enable Corfu in the minibuffer if Vertico/Mct are not active." + (unless (or (bound-and-true-p mct--active) + (bound-and-true-p vertico--input)) + ;; (setq-local corfu-auto nil) Enable/disable auto completion + (corfu-mode 1))) + (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1) +#+end_src + +** Completing with Corfu in the Eshell or Shell + +When completing in the Eshell I recommend conservative local settings without +auto completion, such that the completion behavior is similar to widely used +shells like Bash, Zsh or Fish. + +#+begin_src emacs-lisp + (add-hook 'eshell-mode-hook + (lambda () + (setq-local corfu-auto nil) + (corfu-mode))) +#+end_src + +When pressing =RET= while the Corfu popup is visible, the ~corfu-insert~ command +will be invoked. This command does inserts the currently selected candidate, but +it does not send the prompt input to Eshell or the comint process. Therefore you +often have to press =RET= twice which feels like an unnecessary double +confirmation. Fortunately it is easy to improve this! In my configuration I +define the command ~corfu-insert-and-send~ which performs the two steps at once. + +#+begin_src emacs-lisp + (defun corfu-insert-and-send () + (interactive) + ;; 1. First insert the completed candidate + (corfu-insert) + ;; 2. Send the entire prompt input to the shell + (cond + ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input)) + (eshell-send-input)) + ((and (derived-mode-p 'comint-mode) (fboundp 'comint-send-input)) + (comint-send-input)))) + + (define-key corfu-map "\r" #'+corfu-insert-and-send) +#+end_src + +Shell completion uses the flexible ~pcomplete~ mechanism internally, which allows +you to program the completions per shell command. If you want to know more, look +into this [[https://www.masteringemacs.org/article/pcomplete-context-sensitive-completion-emacs][blog post]], which shows how to configure pcomplete for git commands. I +recommend the [[https://github.com/JonWaltman/pcmpl-args.el][pcmpl-args]] package which extends Pcomplete with completion support +and helpful annotation support for more commands. Similar to the Fish shell, +pcmpl-args uses man page parsing and --help output parsing to dynamically +generate completions. This package brings Eshell completion to another level! + +Unfortunately Pcomplete has a few technical issues, which we can work around +with the [[https://github.com/minad/cape][Cape]] library (Completion at point extensions). Cape provides wrappers, +which sanitize the pcomplete function. Ideally the bugs in pcomplete should be +fixed upstream. *For now these two advices are strongly recommended to achieve a +sane Eshell experience.* + +#+begin_src emacs-lisp + ;; Silence the pcomplete capf, no errors or messages! + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) + + ;; Ensure that pcomplete does not write to the buffer + ;; and behaves as a pure `completion-at-point-function'. + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify) +#+end_src + +** Orderless completion + +[[https://github.com/oantolin/orderless][Orderless]] is an advanced completion style that supports multi-component search +filters separated by a configurable character (space, by default). Normally, +entering characters like space which lie outside the completion region +boundaries (words, typically) causes Corfu to quit. This behavior is helpful +with auto-completion, which may pop-up when not desired, e.g. on entering a new +variable name. Just keep typing and Corfu will get out of the way. + +But orderless search terms can contain arbitrary characters; they are also +interpreted as regular expressions. To use orderless, set ~corfu-separator~ (a +space, by default) to the primary character of your orderless component +separator. + +Then, when a new orderless component is desired, use =M-SPC= +(~corfu-insert-separator~) to enter the /first/ component separator in the input, +and arbitrary orderless search terms and new separators can be entered +thereafter. + +To treat the entire input as Orderless input, you can set the customization +option ~corfu-quit-at-boundary=t~. This disables the predicate which checks if the +current completion boundary has been left. In contrast, if you /always/ want to +quit at the boundary, simply set ~corfu-quit-at-boundary=nil~. By default +~corfu-quit-at-boundary~ is set to ~separator~ which quits at completion boundaries +as long as no separator has been inserted with ~corfu-insert-separator~. + +Finally, there exists the user option ~corfu-quit-no-match~ which is set to +=separator= by default. With this setting Corfu stays alive as soon as you start +advanced filtering with a ~corfu-separator~ even if there are no matches, for +example due to a typo. As long as no separator character has been inserted with +~corfu-insert-separator~, Corfu will still quit if there are no matches. This +ensures that the Corfu popup goes away quickly if completion is not possible. + +In the following we show two configurations, one which works best with auto +completion and one which may work better with manual completion if you prefer to +always use =SPC= to separate the Orderless components. + + #+begin_src emacs-lisp + ;; Auto completion example + (use-package corfu + :custom + (corfu-auto t) ;; Enable auto completion + ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space + :bind + ;; Another key binding can be used, such as S-SPC. + ;; (:map corfu-map ("M-SPC" . corfu-insert-separator)) + :init + (corfu-global-mode)) + + ;; Manual completion example + (use-package corfu + :custom + ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space + :bind + ;; Configure SPC for separator insertion + (:map corfu-map ("SPC" . corfu-insert-separator)) + :init + (corfu-global-mode)) +#+end_src + +** 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. +Note that further input will not expand snippets or templates, which may not be +desired but which leads overall to a more predictable behavior. In order to +force snippet expansion, confirm a candidate explicitly with ~RET~. + +#+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 + +** Transfer completion to the minibuffer + +Sometimes it is useful to transfer the Corfu completion session to the +minibuffer, since the minibuffer offers richer interaction features. In +particular, [[https://github.com/oantolin/embark][Embark]] is available in the minibuffer, such that you can act on the +candidates or export/collect the candidates to a separate buffer. Hopefully we +can also add Corfu-support to Embark in the future, such that at least +export/collect is possible directly from Corfu. But in my opinion having the +ability to transfer the Corfu completion to the minibuffer is an even better +feature, since further completion can be performed there. + +The command ~corfu-move-to-minibuffer~ is defined here in terms of +~consult-completion-in-region~, which uses the minibuffer completion UI via +~completing-read~. + +#+begin_src emacs-lisp + (defun corfu-move-to-minibuffer () + (interactive) + (let ((completion-extra-properties corfu--extra) + completion-cycle-threshold completion-cycling) + (apply #'consult-completion-in-region completion-in-region--data))) + (define-key corfu-map "\M-m" #'corfu-move-to-minibuffer) +#+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~ + - =M-SPC= -> ~corfu-insert-separator~ + - =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]]: Corfu supports completion styles, including the advanced + [[https://github.com/oantolin/orderless][Orderless]] completion style, where the filtering expressions are separated by + spaces or another character (see ~corfu-separator~). + + - [[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 displays the candidate documentation in a + popup next to the Corfu popup, similar to =company-quickhelp=. + + - [[https://github.com/JonWaltman/pcmpl-args.el][pcmpl-args]]: Extend the Eshell/Shell Pcomplete mechanism with support for many + more commands. Similar to the Fish shell, Pcomplete uses man page parsing to + dynamically retrieve the completions and helpful annotations. This package + brings Eshell completions to another level! + + - [[https://github.com/minad/tempel][Tempel]]: Tiny template/snippet package with templates in Lisp syntax, which + can be used in conjunction with Corfu. + + - [[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. + +* Alternatives + + - [[https://github.com/company-mode/company-mode][Company]]: Company is a widely used and mature completion package, which + implements a similar interaction model and popup UI as Corfu. While Corfu + relies exclusively on the standard Emacs completion API (Capfs), Company + defines its own API for the backends. Furthermore Company includes its + completion backends, which are incompatible with the Emacs completion + infrastructure. As a result of this design, Company is a more complex + package than Corfu. Company by default uses overlays to display the popup in + contrast to the child frames used by Corfu. Overall both packages work well. + Company is more mature but the integration into Emacs is a bit less tight, + since for example the ~completion-at-point~ command (or the + ~completion-in-region~ function) does not invoke Company. + + - [[https://gitlab.com/protesilaos/mct][Mct]]: Protesilaos' Minibuffer Confines Transcended package supports both + minibuffer completion and completion in region. It reuses the default + completion UI for this purpose and installs a timer which live updates the + completion buffer. The main advantage of Mct is that you work with a regular + Emacs buffer instead of with a popup. You can take advantage of the usual + Emacs commands to navigate in the completions buffer. On top, Mct enhances + the movement such that you can quickly switch between the completions buffer + and the minibuffer or the region which is being completed. Mct does not + support timer-based auto completion, but the integration into Emacs is + naturally tight. + + - [[https://github.com/minad/consult][consult-completion-in-region]]: The Consult package provides the function + ~consult-completion-in-region~ which can be set as + ~completion-in-region-function~ such that it handles ~completion-at-point~. The + function works by transferring the in-buffer completion to the minibuffer. + In the minibuffer, the minibuffer completion UI, for example [[https://github.com/minad/vertico][Vertico]] takes + over. If you prefer to perform all your completions in the minibuffer + ~consult-completion-in-region~ is your best option. + +* 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 can use one of the alternatives in terminals. + + - 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.21/corfu-autoloads.el b/elpa/corfu-0.21/corfu-autoloads.el @@ -0,0 +1,72 @@ +;;; corfu-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*- +;; +;;; 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. + +This is a minor mode. If called interactively, toggle the `Corfu +mode' mode. If the prefix argument is positive, enable the mode, +and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `corfu-mode'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. + +\(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, toggle the mode if ARG is `toggle'. +Enable the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +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) + +(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-emacs-unix +;; End: +;;; corfu-autoloads.el ends here diff --git a/elpa/corfu-0.21/corfu-pkg.el b/elpa/corfu-0.21/corfu-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from corfu.el -*- no-byte-compile: t -*- +(define-package "corfu" "0.21" "Completion Overlay Region FUnction" '((emacs "27.1")) :commit "ba099c770dd6d410553473604f184adf20d7b359" :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.21/corfu.el b/elpa/corfu-0.21/corfu.el @@ -0,0 +1,1272 @@ +;;; corfu.el --- Completion Overlay Region FUnction -*- lexical-binding: t -*- + +;; Copyright (C) 2021, 2022 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.21 +;; 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-on-exact-match 'insert + "Configure how a single exact match should be handled." + :type '(choice (const insert) (const quit) (const nil))) + +(defcustom corfu-continue-commands + ;; nil is undefined command + '(nil ignore 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-preview-current 'insert + "Preview currently selected candidate. +If the variable has the value `insert', the candidate is automatically +inserted on further input." + :type '(choice boolean (const insert))) + +(defcustom corfu-preselect-first t + "Preselect first candidate." + :type 'boolean) + +(defcustom corfu-separator ?\s + "Component separator character. +The character used for separating components in the input. The presence +of this separator character will inhibit quitting at completion +boundaries, so that any further characters can be entered. To enter the +first separator character, call `corfu-insert-separator' (bound to M-SPC +by default). Useful for multi-component completion styles such as +Orderless." + :type 'character) + +(defcustom corfu-quit-at-boundary 'separator + "Automatically quit at completion boundary. +nil: Never quit at completion boundary. +t: Always quit at completion boundary. +separator: Quit at boundary if no `corfu-separator' has been inserted." + :type '(choice boolean (const separator))) + +(defcustom corfu-quit-no-match 'separator + "Automatically quit if no matching candidate is found. +nil: Stay alive even if there is no match. +t: Quit if there is no match. +separator: Only stay alive if there is no match and +`corfu-separator' has been inserted." + :type '(choice boolean (const separator))) + +(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 '(1.0 . 0.2) + "Show documentation string in the echo area after that number of seconds. +Set to nil to disable the echo message or to t for an instant message. +The value can be a pair of two floats to specify initial and subsequent +delay." + :type '(choice (const :tag "Never" nil) + (const :tag "Instant" t) + (number :tag "Delay in seconds") + (cons :tag "Two Delays" + (choice :tag "Initial " number)) + (choice :tag "Subsequent" number))) + +(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) + (define-key map (concat "\e" " ") #'corfu-insert-separator) ;; Avoid ugly warning + 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.") + +(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--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--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 +(defvar x-gtk-resize-child-frames) ;; Not present on non-gtk builds +(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)) + (ch (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 ch)) + (y (if (> (+ yb (* corfu-count ch) ch ch) (frame-pixel-height)) + (- yb height ch 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)) + (set-frame-size corfu--frame width height t) + (if (frame-visible-p corfu--frame) + ;; XXX HACK Avoid flicker when frame is already visible. + ;; Redisplay, wait for resize and then move the frame. + (unless (equal (frame-position corfu--frame) (cons x y)) + (redisplay 'force) + (sleep-for 0.01) + (set-frame-position corfu--frame x y)) + ;; XXX HACK: Force redisplay, otherwise the popup sometimes does not display content. + (set-frame-position corfu--frame x y) + (redisplay 'force) + (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)) + (ml (ceiling (* cw corfu-left-margin-width))) + (mr (ceiling (* cw corfu-right-margin-width))) + (bw (ceiling (min mr (* cw corfu-bar-width)))) + (marginl (and (> ml 0) (propertize " " 'display `(space :width (,ml))))) + (marginr (and (> mr 0) (propertize " " 'display `(space :align-to right)))) + (sbar (when (> bw 0) + (concat (propertize " " 'display `(space :align-to (- right (,mr)))) + (propertize " " 'display `(space :width (,(- mr 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 ml (* cw off)) y + (+ (* width cw) ml mr) (* (length lines) ch) + (mapconcat (lambda (line) + (let ((str (concat marginl line + (if (and lo (<= lo row (+ lo bar))) sbar marginr)))) + (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 (substring field 0 + (seq-position field corfu-separator))) + (len (length word))) + (corfu--partition! + candidates + (and (>= (length it) len) + (eq t (compare-strings word 0 len it 0 len + completion-ignore-case)))))) + +(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) ""))) + ;; 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. + (unless (text-property-not-all 0 (length suffix) 'face nil suffix) + (setq suffix (propertize suffix 'face 'corfu-annotations))) + (list cand "" suffix))) + (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)) + ;; -4 because of margins and some additional safety + (max-width (min corfu-max-width (- (frame-width) 4)))) + (when (> width max-width) + (setq sw (max 0 (- max-width pw cw)) + width (+ pw cw sw))) + (when (< width corfu-min-width) + (setq cw (+ cw (- corfu-min-width width)) + width corfu-min-width)) + (setq width (min width max-width)) + (list pw width + (cl-loop for (cand prefix suffix) in cands collect + (truncate-string-to-width + (concat prefix + (make-string (max 0 (- pw (string-width prefix))) ?\s) + cand + (when (/= sw 0) + (make-string + (+ (max 0 (- cw (string-width cand))) + (max 0 (- 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)) + (corfu--echo-show corfu--echo-message)) + +(defun corfu--echo-show (&optional msg) + "Show MSG in echo area." + (when (or msg corfu--echo-message) + (setq msg (or msg "") + corfu--echo-message msg) + (corfu--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." + (if-let* ((delay (if (consp corfu-echo-documentation) + (funcall (if corfu--echo-message #'cdr #'car) + corfu-echo-documentation) + corfu-echo-documentation)) + (fun (plist-get corfu--extra :company-docsig)) + (cand (and (>= corfu--index 0) + (nth corfu--index corfu--candidates)))) + (if (or (eq delay t) (<= delay 0)) + (corfu--echo-show (funcall fun cand)) + (when corfu--echo-timer (cancel-timer corfu--echo-timer)) + (setq corfu--echo-timer + (run-at-time delay nil + (lambda () + (corfu--echo-show (funcall fun cand))))) + (corfu--echo-show)) + (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))) + (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 + (unless (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. Happens during auto completion. + ((and initializing (not corfu--candidates)) + (corfu-quit)) + ;; 2) Single exactly matching candidate and no further completion is possible. + ((and (not (equal str "")) + (equal (car corfu--candidates) str) (not (cdr corfu--candidates)) + (not (consp (completion-try-completion str table pred pt corfu--metadata))) + (or initializing corfu-on-exact-match)) + ;; Quit directly when initializing. This happens during auto completion. + (if (or initializing (eq corfu-on-exact-match 'quit)) + (corfu-quit) + (corfu--done str 'finished))) + ;; 3) There exist candidates => Show candidates popup. + (corfu--candidates + (corfu--candidates-popup beg) + (corfu--preview-current beg end str) + (corfu--echo-documentation) + (redisplay 'force)) ;; XXX HACK Ensure that popup is redisplayed + ;; 4) There are no candidates & corfu-quit-no-match => Confirmation popup. + ((and (not corfu--candidates) + (pcase-exhaustive corfu-quit-no-match + ('t nil) + ('nil t) + ('separator (seq-contains-p (car corfu--input) corfu-separator)))) + (corfu--popup-show beg 0 8 '(#("No match" 0 8 (face italic)))) + (redisplay 'force)) ;; XXX HACK Ensure that popup is redisplayed + (t (corfu-quit))))) + +(defun corfu--pre-command () + "Insert selected candidate unless command is marked to continue completion." + (when corfu--preview-ov + (delete-overlay corfu--preview-ov) + (setq corfu--preview-ov nil)) + (when (and (eq corfu-preview-current 'insert) + (/= corfu--index corfu--preselect) + (not (corfu--match-symbol-p corfu-continue-commands this-command))) + (corfu--insert 'exact))) + +(defun corfu-insert-separator () + "Insert a separator character, inhibiting quit on completion boundary. +See `corfu-separator' for more details." + (interactive) + (insert corfu-separator)) + +(defun corfu--post-command () + "Refresh Corfu after last command." + (or (pcase completion-in-region--data + (`(,beg ,end . ,_) + (when (let ((pt (point))) + (and (eq (marker-buffer beg) (current-buffer)) + ;; Check ranges + (<= beg pt end) + (save-excursion + (goto-char beg) + (<= (line-beginning-position) pt (line-end-position))) + (or + ;; Check if it is an explicitly listed continue command + (corfu--match-symbol-p corfu-continue-commands this-command) + (and + ;; Check for empty input + (or (not corfu--input) (< beg end)) + ;; Check separator or predicate + (or (not corfu-quit-at-boundary) + (and (eq corfu-quit-at-boundary 'separator) + (or (eq this-command #'corfu-insert-separator) + ;; with separator, any further chars allowed + (seq-contains-p (car corfu--input) corfu-separator))) + (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))))) + +(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. +If a candidate is selected, insert it." + (interactive) + (pcase-let ((`(,beg ,end ,table ,pred) completion-in-region--data)) + (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) + (unless (equal str newstr) + (completion--replace beg end (concat 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 . ,_) completion-in-region--data) + (str (buffer-substring-no-properties beg end))) + ;; 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 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. +Quit if no candidate is selected." + (interactive) + (if (>= corfu--index 0) + (corfu--insert 'finished) + (corfu-quit))) + +(defun corfu--setup () + "Setup Corfu completion state." + (setq corfu--extra completion-extra-properties) + (completion-in-region-mode 1) + (undo-boundary) ;; Necessary to support `corfu-reset' + (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) + ;; 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 'pre-command-hook #'corfu--pre-command 'local) + (remove-hook 'post-command-hook #'corfu--post-command) + (when corfu--preview-ov (delete-overlay corfu--preview-ov)) + (when corfu--echo-timer (cancel-timer corfu--echo-timer)) + (corfu--echo-show) + (accept-change-group corfu--change-group) + (mapc #'kill-local-variable corfu--state-vars)) + +(defun corfu--in-region (beg end table &optional pred) + "Corfu completion in region function. +See `completion-in-region' for the arguments BEG, END, TABLE, PRED." + (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--in-region'. This should never happen. + (funcall (default-value 'completion-in-region-function) beg end table pred) + ;; Restart the completion. This can happen for example if C-M-/ + ;; (`dabbrev-completion') is pressed while the Corfu popup is already open. + (when completion-in-region-mode (corfu-quit)) + (let* ((pt (max 0 (- (point) beg))) + (str (buffer-substring-no-properties beg end)) + (before (substring str 0 pt)) + (metadata (completion-metadata before table pred)) + (exit (plist-get completion-extra-properties :exit-function)) + (threshold (completion--cycle-threshold metadata)) + (completion-in-region-mode-predicate + (or completion-in-region-mode-predicate (lambda () t)))) + (pcase (completion-try-completion str table pred pt metadata) + ('nil (corfu--message "No match") nil) + ('t + (goto-char end) + (corfu--message "Sole match") + (when exit (funcall exit str 'finished)) + t) + (`(,newstr . ,newpt) + (pcase-let ((`(,base ,candidates ,total . ,_) + (corfu--recompute-candidates str pt table pred))) + (setq beg (copy-marker beg) + end (copy-marker end t) + completion-in-region--data (list beg end table pred)) + (unless (equal str newstr) + (completion--replace beg end (concat newstr))) + (goto-char (+ beg newpt)) + (if (= total 1) + (when exit + (funcall exit newstr + ;; If completion is finished and cannot be further completed, + ;; return 'finished. Otherwise return 'exact. + (if (eq (try-completion (car candidates) table pred) t) + 'finished 'exact))) + (if (or (= total 0) (not threshold) + (and (not (eq threshold t)) (< threshold total))) + (corfu--setup) + (corfu--cycle-candidates total candidates (+ base beg) end) + ;; Do not show Corfu when "trivially" cycling, i.e., + ;; when the completion is finished after the candidate. + (unless (equal (completion-boundaries + (buffer-substring-no-properties beg end) + table pred "") '(0 . 0)) + (corfu--setup))))) + t))))) + +(defun corfu--message (&rest msg) + "Show completion MSG." + (let (message-log-max) (apply #'message msg))) + +(defun corfu--cycle-candidates (total cands beg end) + "Cycle between TOTAL number of CANDS. +See `completion-in-region' for the arguments BEG, END, TABLE, PRED." + (let* ((idx 0) + (map (make-sparse-keymap)) + (replace (lambda () + (interactive) + (completion--replace beg end (concat (nth idx cands))) + (corfu--message "Cycling %d/%d..." (1+ idx) total) + (setq idx (mod (1+ idx) total)) + (set-transient-map map)))) + (define-key map [remap completion-at-point] replace) + (define-key map [remap corfu-complete] replace) + (define-key map (vector last-command-event) replace) + (funcall replace))) + +(defun corfu--auto-complete (tick) + "Initiate auto completion if TICK did not change." + (setq corfu--auto-timer nil) + (when (and (not completion-in-region-mode) (equal tick (corfu--auto-tick))) + (pcase (while-no-input ;; Interruptible capf query + (run-hook-wrapped 'completion-at-point-functions #'corfu--capf-wrapper)) + (`(,fun ,beg ,end ,table . ,plist) + (let ((completion-in-region-mode-predicate + (lambda () (eq beg (car-safe (funcall fun))))) + (completion-extra-properties plist)) + (setq completion-in-region--data + (list (copy-marker beg) (copy-marker end t) table + (plist-get plist :predicate))) + (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) + (not defining-kbd-macro) + (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 (corfu--auto-tick))))) + +(defun corfu--auto-tick () + "Return the current tick/status of the buffer. +Auto completion is only performed if the tick did not change." + (list (current-buffer) (buffer-chars-modified-tick) (point))) + +;;;###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--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 &optional prefix) + "Wrapper for `completion-at-point' FUN. +The wrapper determines if the capf is applicable at the current position +and performs sanity checking on the returned result. PREFIX is a prefix +length override, set to t for manual completion." + (pcase (funcall fun) + ((and res `(,beg ,end ,table . ,plist)) + (and (integer-or-marker-p beg) ;; Valid capf result + (<= beg (point) end) ;; Sanity checking + ;; When auto completing, check the prefix length! + (let ((len (or prefix + (plist-get plist :company-prefix-length) + (- (point) beg)))) + (or (eq len t) (>= len corfu-auto-prefix))) + ;; 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 t) (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 corfu-insert-separator)) + (put sym 'completion-predicate #'ignore)) + +(provide 'corfu) +;;; corfu.el ends here diff --git a/elpa/corfu-0.21/corfu.info b/elpa/corfu-0.21/corfu.info @@ -0,0 +1,621 @@ +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:: +* Alternatives:: +* Caveats:: +* Contributions:: + +— The Detailed Node Listing — + +Installation and Configuration + +* Auto completion:: +* Completing with Corfu in the minibuffer:: +* Completing with Corfu in the Eshell or Shell:: +* Orderless completion:: +* TAB-and-Go completion:: +* Transfer completion to the minibuffer:: + + + +File: corfu.info, Node: Introduction, Next: Features, Prev: Top, Up: Top + +1 Introduction +************** + +Corfu enhances completion at point with a small completion popup. 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 small 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), use Capfs which +talk to the LSP server to retrieve the completions. Corfu does not +include its own completion backends. The Emacs built-in Capfs and the +Capfs provided by other programming language packages are usually +sufficient. A few additional Capfs and completion utilities 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. + + <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 (configurable via + ‘corfu-preview-current’). + • The selected candidate automatically committed on further input by + default. (configurable via ‘corfu-preview-current’). + • The Orderless (https://github.com/oantolin/orderless) completion + style is supported. The filter string can contain arbitrary + characters, after inserting a space via ‘M-SPC’ (configurable via + ‘corfu-quit-at-boundary’ and ‘corfu-separator’). + • Deferred completion style highlighting for performance. + • Jumping to location/documentation of current candidate. + • Support for candidate annotations and documentation in the echo + area. + • Deprecated candidates are crossed out in the display. + • 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, such that you can adapt it precisely to your requirements. +However in order to quickly try out the Corfu completion package, it +should be sufficient to activate ‘corfu-global-mode’. Then you +experiment with manual completion for example in an Elisp buffer or in +an Eshell or Shell buffer. For auto completion, set ‘corfu-auto=t’ +before turning on ‘corfu-global-mode’. + + 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-separator ?\s) ;; Orderless field separator + ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary + ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match + ;; (corfu-preview-current nil) ;; Disable current candidate preview + ;; (corfu-preselect-first nil) ;; Disable candidate preselection + ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches + ;; (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)) + + ;; 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)) + + If you start to configure the package more deeply, I recommend to +give the Orderless completion style a try for filtering. Orderless +completion 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. + + ;; Optionally use the `orderless' completion style. + (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 basic) + completion-category-defaults nil + completion-category-overrides '((file (styles . (partial-completion)))))) + + The ‘basic’ completion style is specified as fallback in addition to +‘orderless’ in order to ensure that completion commands which rely on +dynamic completion tables, e.g., ‘completion-table-dynamic’ or +‘completion-table-in-turn’, work correctly. See ‘+orderless-dispatch’ +in the Consult wiki (https://github.com/minad/consult/wiki) for an +advanced Orderless style dispatcher. Additionally enable +‘partial-completion’ for file path expansion. ‘partial-completion’ is +important for file 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. + + 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. 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: + +* Auto completion:: +* Completing with Corfu in the minibuffer:: +* Completing with Corfu in the Eshell or Shell:: +* Orderless completion:: +* TAB-and-Go completion:: +* Transfer completion to the minibuffer:: + + +File: corfu.info, Node: Auto completion, Next: Completing with Corfu in the minibuffer, Up: Installation and Configuration + +3.1 Auto completion +=================== + +Auto completion is disabled by default, but can be enabled by setting +‘corfu-auto=t’. Furthermore you may want to configure Corfu to quit +completion eagerly, such that the completion popup stays out of your way +when it appeared unexpectedly. + + ;; Enable auto completion and configure quitting + (setq corfu-auto t + corfu-quit-no-match 'separator) ;; or t + + In general, I recommend to experiment a bit with the various settings +and key bindings to find a configuration which works for you. There is +no one size fits all solution. Some people like auto completion, some +like manual completion, some want to cycle with TAB and some with the +arrow keys... + + +File: corfu.info, Node: Completing with Corfu in the minibuffer, Next: Completing with Corfu in the Eshell or Shell, Prev: Auto completion, Up: Installation and Configuration + +3.2 Completing with Corfu in the minibuffer +=========================================== + +Corfu can be used for completion in the minibuffer, since it relies on +child frames to display the candidates. By default, ‘corfu-global-mode’ +does not activate ‘corfu-mode’ in the minibuffer, to avoid interference +with specialised minibuffer completion UIs like Vertico or Mct. However +you may still want to enable Corfu completion for commands like ‘M-:’ +(‘eval-expression’) or ‘M-!’ (‘shell-command’), which read from the +minibuffer. Activate ‘corfu-mode’ only if ‘completion-at-point’ is +bound in the minibuffer-local keymap to achieve this effect. + + (defun corfu-enable-in-minibuffer () + "Enable Corfu in the minibuffer if `completion-at-point' is bound." + (when (where-is-internal #'completion-at-point (list (current-local-map))) + ;; (setq-local corfu-auto nil) Enable/disable auto completion + (corfu-mode 1))) + (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) + + You can also enable Corfu more generally for every minibuffer, as +long as no other completion UI is active. If you use Mct or Vertico as +your main minibuffer completion UI, the following snippet should yield +the desired result. + + (defun corfu-enable-always-in-minibuffer () + "Enable Corfu in the minibuffer if Vertico/Mct are not active." + (unless (or (bound-and-true-p mct--active) + (bound-and-true-p vertico--input)) + ;; (setq-local corfu-auto nil) Enable/disable auto completion + (corfu-mode 1))) + (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1) + + +File: corfu.info, Node: Completing with Corfu in the Eshell or Shell, Next: Orderless completion, Prev: Completing with Corfu in the minibuffer, Up: Installation and Configuration + +3.3 Completing with Corfu in the Eshell or Shell +================================================ + +When completing in the Eshell I recommend conservative local settings +without auto completion, such that the completion behavior is similar to +widely used shells like Bash, Zsh or Fish. + + (add-hook 'eshell-mode-hook + (lambda () + (setq-local corfu-auto nil) + (corfu-mode))) + + When pressing ‘RET’ while the Corfu popup is visible, the +‘corfu-insert’ command will be invoked. This command does inserts the +currently selected candidate, but it does not send the prompt input to +Eshell or the comint process. Therefore you often have to press ‘RET’ +twice which feels like an unnecessary double confirmation. Fortunately +it is easy to improve this! In my configuration I define the command +‘corfu-insert-and-send’ which performs the two steps at once. + + (defun corfu-insert-and-send () + (interactive) + ;; 1. First insert the completed candidate + (corfu-insert) + ;; 2. Send the entire prompt input to the shell + (cond + ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input)) + (eshell-send-input)) + ((and (derived-mode-p 'comint-mode) (fboundp 'comint-send-input)) + (comint-send-input)))) + + (define-key corfu-map "\r" #'+corfu-insert-and-send) + + Shell completion uses the flexible ‘pcomplete’ mechanism internally, +which allows you to program the completions per shell command. If you +want to know more, look into this blog post +(https://www.masteringemacs.org/article/pcomplete-context-sensitive-completion-emacs), +which shows how to configure pcomplete for git commands. I recommend +the pcmpl-args (https://github.com/JonWaltman/pcmpl-args.el) package +which extends Pcomplete with completion support and helpful annotation +support for more commands. Similar to the Fish shell, pcmpl-args uses +man page parsing and –help output parsing to dynamically generate +completions. This package brings Eshell completion to another level! + + Unfortunately Pcomplete has a few technical issues, which we can work +around with the Cape (https://github.com/minad/cape) library (Completion +at point extensions). Cape provides wrappers, which sanitize the +pcomplete function. Ideally the bugs in pcomplete should be fixed +upstream. *For now these two advices are strongly recommended to +achieve a sane Eshell experience.* + + ;; Silence the pcomplete capf, no errors or messages! + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) + + ;; Ensure that pcomplete does not write to the buffer + ;; and behaves as a pure `completion-at-point-function'. + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify) + + +File: corfu.info, Node: Orderless completion, Next: TAB-and-Go completion, Prev: Completing with Corfu in the Eshell or Shell, Up: Installation and Configuration + +3.4 Orderless completion +======================== + +Orderless (https://github.com/oantolin/orderless) is an advanced +completion style that supports multi-component search filters separated +by a configurable character (space, by default). Normally, entering +characters like space which lie outside the completion region boundaries +(words, typically) causes Corfu to quit. This behavior is helpful with +auto-completion, which may pop-up when not desired, e.g. on entering a +new variable name. Just keep typing and Corfu will get out of the way. + + But orderless search terms can contain arbitrary characters; they are +also interpreted as regular expressions. To use orderless, set +‘corfu-separator’ (a space, by default) to the primary character of your +orderless component separator. + + Then, when a new orderless component is desired, use ‘M-SPC’ +(‘corfu-insert-separator’) to enter the _first_ component separator in +the input, and arbitrary orderless search terms and new separators can +be entered thereafter. + + To treat the entire input as Orderless input, you can set the +customization option ‘corfu-quit-at-boundary=t’. This disables the +predicate which checks if the current completion boundary has been left. +In contrast, if you _always_ want to quit at the boundary, simply set +‘corfu-quit-at-boundary=nil’. By default ‘corfu-quit-at-boundary’ is +set to ‘separator’ which quits at completion boundaries as long as no +separator has been inserted with ‘corfu-insert-separator’. + + Finally, there exists the user option ‘corfu-quit-no-match’ which is +set to ‘separator’ by default. With this setting Corfu stays alive as +soon as you start advanced filtering with a ‘corfu-separator’ even if +there are no matches, for example due to a typo. As long as no +separator character has been inserted with ‘corfu-insert-separator’, +Corfu will still quit if there are no matches. This ensures that the +Corfu popup goes away quickly if completion is not possible. + + In the following we show two configurations, one which works best +with auto completion and one which may work better with manual +completion if you prefer to always use ‘SPC’ to separate the Orderless +components. + + ;; Auto completion example + (use-package corfu + :custom + (corfu-auto t) ;; Enable auto completion + ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space + :bind + ;; Another key binding can be used, such as S-SPC. + ;; (:map corfu-map ("M-SPC" . corfu-insert-separator)) + :init + (corfu-global-mode)) + + ;; Manual completion example + (use-package corfu + :custom + ;; (corfu-separator ?_) ;; Set to orderless separator, if not using space + :bind + ;; Configure SPC for separator insertion + (:map corfu-map ("SPC" . corfu-insert-separator)) + :init + (corfu-global-mode)) + + +File: corfu.info, Node: TAB-and-Go completion, Next: Transfer completion to the minibuffer, Prev: Orderless completion, Up: Installation and Configuration + +3.5 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. Note that further input will not expand snippets +or templates, which may not be desired but which leads overall to a more +predictable behavior. In order to force snippet expansion, confirm a +candidate explicitly with ‘RET’. + + (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: Transfer completion to the minibuffer, Prev: TAB-and-Go completion, Up: Installation and Configuration + +3.6 Transfer completion to the minibuffer +========================================= + +Sometimes it is useful to transfer the Corfu completion session to the +minibuffer, since the minibuffer offers richer interaction features. In +particular, Embark (https://github.com/oantolin/embark) is available in +the minibuffer, such that you can act on the candidates or +export/collect the candidates to a separate buffer. Hopefully we can +also add Corfu-support to Embark in the future, such that at least +export/collect is possible directly from Corfu. But in my opinion +having the ability to transfer the Corfu completion to the minibuffer is +an even better feature, since further completion can be performed there. + + The command ‘corfu-move-to-minibuffer’ is defined here in terms of +‘consult-completion-in-region’, which uses the minibuffer completion UI +via ‘completing-read’. + + (defun corfu-move-to-minibuffer () + (interactive) + (let ((completion-extra-properties corfu--extra) + completion-cycle-threshold completion-cycling) + (apply #'consult-completion-in-region completion-in-region--data))) + (define-key corfu-map "\M-m" #'corfu-move-to-minibuffer) + + +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’ + • ‘M-SPC’ -> ‘corfu-insert-separator’ + • ‘C-g’ -> ‘corfu-quit’ + • ‘keyboard-escape-quit’ -> ‘corfu-reset’ + + +File: corfu.info, Node: Complementary packages, Next: Alternatives, 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): Corfu supports + completion styles, including the advanced Orderless + (https://github.com/oantolin/orderless) completion style, where the + filtering expressions are separated by spaces or another character + (see ‘corfu-separator’). + + • 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 displays the candidate documentation in a popup next to the + Corfu popup, similar to ‘company-quickhelp’. + + • pcmpl-args (https://github.com/JonWaltman/pcmpl-args.el): Extend + the Eshell/Shell Pcomplete mechanism with support for many more + commands. Similar to the Fish shell, Pcomplete uses man page + parsing to dynamically retrieve the completions and helpful + annotations. This package brings Eshell completions to another + level! + + • Tempel (https://github.com/minad/tempel): Tiny template/snippet + package with templates in Lisp syntax, which can be used in + conjunction with Corfu. + + • 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: Alternatives, Next: Caveats, Prev: Complementary packages, Up: Top + +6 Alternatives +************** + + • Company (https://github.com/company-mode/company-mode): Company is + a widely used and mature completion package, which implements a + similar interaction model and popup UI as Corfu. While Corfu + relies exclusively on the standard Emacs completion API (Capfs), + Company defines its own API for the backends. Furthermore Company + includes its completion backends, which are incompatible with the + Emacs completion infrastructure. As a result of this design, + Company is a more complex package than Corfu. Company by default + uses overlays to display the popup in contrast to the child frames + used by Corfu. Overall both packages work well. Company is more + mature but the integration into Emacs is a bit less tight, since + for example the ‘completion-at-point’ command (or the + ‘completion-in-region’ function) does not invoke Company. + + • Mct (https://gitlab.com/protesilaos/mct): Protesilaos’ Minibuffer + Confines Transcended package supports both minibuffer completion + and completion in region. It reuses the default completion UI for + this purpose and installs a timer which live updates the completion + buffer. The main advantage of Mct is that you work with a regular + Emacs buffer instead of with a popup. You can take advantage of + the usual Emacs commands to navigate in the completions buffer. On + top, Mct enhances the movement such that you can quickly switch + between the completions buffer and the minibuffer or the region + which is being completed. Mct does not support timer-based auto + completion, but the integration into Emacs is naturally tight. + + • consult-completion-in-region (https://github.com/minad/consult): + The Consult package provides the function + ‘consult-completion-in-region’ which can be set as + ‘completion-in-region-function’ such that it handles + ‘completion-at-point’. The function works by transferring the + in-buffer completion to the minibuffer. In the minibuffer, the + minibuffer completion UI, for example Vertico + (https://github.com/minad/vertico) takes over. If you prefer to + perform all your completions in the minibuffer + ‘consult-completion-in-region’ is your best option. + + +File: corfu.info, Node: Caveats, Next: Contributions, Prev: Alternatives, Up: Top + +7 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 can use one of the alternatives in + terminals. + + • 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 + +8 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: Introduction794 +Node: Features2318 +Node: Installation and Configuration3705 +Node: Auto completion8915 +Node: Completing with Corfu in the minibuffer9764 +Node: Completing with Corfu in the Eshell or Shell11621 +Node: Orderless completion14609 +Node: TAB-and-Go completion17717 +Node: Transfer completion to the minibuffer18832 +Node: Key bindings20171 +Node: Complementary packages21174 +Node: Alternatives23721 +Node: Caveats26154 +Node: Contributions26740 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/corfu-0.20/dir b/elpa/corfu-0.21/dir diff --git a/init.el b/init.el @@ -182,6 +182,7 @@ '(corfu-auto-delay 0.0) '(corfu-auto-prefix 1) '(corfu-global-mode t) + '(corfu-preselect-first nil) '(corfu-quit-at-boundary t) '(create-lockfiles nil) '(cursor-type 'bar)