dotemacs

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

commit 3e06b6d031733bcddaad5202239c0f43458d9e23
parent 952c767e64b60723ca97250ee2138ba1e8c971d3
Author: Lukas Henkel <lh@entf.net>
Date:   Mon, 13 Dec 2021 21:48:06 +0100

Replace selectrum with vertico

Diffstat:
Aelpa/posframe-20211126.944/posframe-autoloads.el | 271+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/posframe-20211126.944/posframe-benchmark.el | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/posframe-20211126.944/posframe-benchmark.elc | 0
Aelpa/posframe-20211126.944/posframe-pkg.el | 12++++++++++++
Aelpa/posframe-20211126.944/posframe.el | 1462+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/posframe-20211126.944/posframe.elc | 0
Delpa/selectrum-3.1/selectrum-autoloads.el | 159-------------------------------------------------------------------------------
Delpa/selectrum-3.1/selectrum-helm.el | 132-------------------------------------------------------------------------------
Delpa/selectrum-3.1/selectrum-helm.elc | 0
Delpa/selectrum-3.1/selectrum-pkg.el | 12------------
Delpa/selectrum-3.1/selectrum.el | 2893-------------------------------------------------------------------------------
Delpa/selectrum-3.1/selectrum.elc | 0
Delpa/selectrum-prescient-5.1/selectrum-prescient-autoloads.el | 43-------------------------------------------
Delpa/selectrum-prescient-5.1/selectrum-prescient-pkg.el | 2--
Delpa/selectrum-prescient-5.1/selectrum-prescient.el | 208-------------------------------------------------------------------------------
Delpa/selectrum-prescient-5.1/selectrum-prescient.elc | 0
Aelpa/vertico-0.17.signed | 2++
Aelpa/vertico-0.17/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/README.org | 445+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/dir | 18++++++++++++++++++
Aelpa/vertico-0.17/vertico-autoloads.el | 265+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-buffer.el | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-buffer.elc | 0
Aelpa/vertico-0.17/vertico-directory.el | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-directory.elc | 0
Aelpa/vertico-0.17/vertico-flat.el | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-flat.elc | 0
Aelpa/vertico-0.17/vertico-grid.el | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-grid.elc | 0
Aelpa/vertico-0.17/vertico-indexed.el | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-indexed.elc | 0
Aelpa/vertico-0.17/vertico-mouse.el | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-mouse.elc | 0
Aelpa/vertico-0.17/vertico-pkg.el | 2++
Aelpa/vertico-0.17/vertico-quick.el | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-quick.elc | 0
Aelpa/vertico-0.17/vertico-repeat.el | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-repeat.elc | 0
Aelpa/vertico-0.17/vertico-reverse.el | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico-reverse.elc | 0
Aelpa/vertico-0.17/vertico.el | 790+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-0.17/vertico.elc | 0
Aelpa/vertico-0.17/vertico.info | 612+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.4.2.signed | 2++
Aelpa/vertico-posframe-0.4.2/LICENSE | 674+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.4.2/README.org | 26++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.4.2/vertico-posframe-autoloads.el | 47+++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.4.2/vertico-posframe-pkg.el | 2++
Aelpa/vertico-posframe-0.4.2/vertico-posframe.el | 328+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aelpa/vertico-posframe-0.4.2/vertico-posframe.elc | 0
Minit.el | 12++++++++----
51 files changed, 6752 insertions(+), 3453 deletions(-)

diff --git a/elpa/posframe-20211126.944/posframe-autoloads.el b/elpa/posframe-20211126.944/posframe-autoloads.el @@ -0,0 +1,271 @@ +;;; posframe-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "posframe" "posframe.el" (0 0 0 0)) +;;; Generated autoloads from posframe.el + +(autoload 'posframe-workable-p "posframe" "\ +Test posframe workable status." nil nil) + +(autoload 'posframe-show "posframe" "\ +Pop up a posframe to show STRING at POSITION. + + (1) POSITION + +POSITION can be: +1. An integer, meaning point position. +2. A cons of two integers, meaning absolute X and Y coordinates. +3. Other type, in which case the corresponding POSHANDLER should be + provided. + + (2) POSHANDLER + +POSHANDLER is a function of one argument returning an actual +position. Its argument is a plist of the following form: + + (:position xxx + :poshandler xxx + :font-height xxx + :font-width xxx + :posframe xxx + :posframe-width xxx + :posframe-height xxx + :posframe-buffer xxx + :parent-frame xxx + :parent-window-left xxx + :parent-window-top xxx + :parent-frame-width xxx + :parent-frame-height xxx + :parent-window xxx + :parent-window-width xxx + :parent-window-height xxx + :mouse-x xxx + ;mouse-y xxx + :minibuffer-height xxx + :mode-line-height xxx + :header-line-height xxx + :tab-line-height xxx + :x-pixel-offset xxx + :y-pixel-offset xxx) + +By default, poshandler is auto-selected based on the type of POSITION, +but the selection can be overridden using the POSHANDLER argument. + +The names of poshandler functions are like: + + `posframe-poshandler-p0.5p0-to-w0.5p1' + +which mean align posframe(0.5, 0) to a position(a, b) + +1. a = x of window(0.5, 0) +2. b = y of point(1, 1) + + posframe(p), frame(f), window(w), point(p), mouse(m) + + (0,0) (0.5,0) (1,0) + +------------+-----------+ + | | + | | + | | + (0, 0.5) + + (1, 0.5) + | | + | | + | | + +------------+-----------+ + (0,1) (0.5,1) (1,1) + +The alias of builtin poshandler functions are listed below: + +1. `posframe-poshandler-frame-center' +2. `posframe-poshandler-frame-top-center' +3. `posframe-poshandler-frame-top-left-corner' +4. `posframe-poshandler-frame-top-right-corner' +5. `posframe-poshandler-frame-bottom-center' +6. `posframe-poshandler-frame-bottom-left-corner' +7. `posframe-poshandler-frame-bottom-right-corner' +8. `posframe-poshandler-window-center' +9. `posframe-poshandler-window-top-center' +10. `posframe-poshandler-window-top-left-corner' +11. `posframe-poshandler-window-top-right-corner' +12. `posframe-poshandler-window-bottom-center' +13. `posframe-poshandler-window-bottom-left-corner' +14. `posframe-poshandler-window-bottom-right-corner' +15. `posframe-poshandler-point-top-left-corner' +16. `posframe-poshandler-point-bottom-left-corner' +17. `posframe-poshandler-point-bottom-left-corner-upward' +18. `posframe-poshandler-point-window-center' + +by the way, poshandler can be used by other packages easily with +the help of function `posframe-poshandler-argbuilder'. like: + + (let* ((info (posframe-poshandler-argbuilder *MY-CHILD-FRAME*)) + (posn (posframe-poshandler-window-center + `(:posframe-width 800 :posframe-height 400 ,@info)))) + `((left . ,(car posn)) + (top . ,(cdr posn)))) + + (3) POSHANDLER-EXTRA-INFO + +POSHANDLER-EXTRA-INFO is a plist, which will prepend to the +argument of poshandler function: 'info', it will *OVERRIDE* the +exist key in 'info'. + + (4) BUFFER-OR-NAME + +This posframe's buffer is BUFFER-OR-NAME, which can be a buffer +or a name of a (possibly nonexistent) buffer. + +buffer name can prefix with space, for example ' *mybuffer*', so +the buffer name will hide for ibuffer and `list-buffers'. + + (5) NO-PROPERTIES + +If NO-PROPERTIES is non-nil, The STRING's properties will +be removed before being shown in posframe. + + (6) HEIGHT, MAX-HEIGHT, MIN-HEIGHT, WIDTH, MAX-WIDTH and MIN-WIDTH + +These arguments are specified in the canonical character width +and height of posframe, more details can be found in docstring of +function `fit-frame-to-buffer', + + (7) LEFT-FRINGE and RIGHT-FRINGE + +If LEFT-FRINGE or RIGHT-FRINGE is a number, left fringe or +right fringe with be shown with the specified width. + + (8) BORDER-WIDTH, BORDER-COLOR, INTERNAL-BORDER-WIDTH and INTERNAL-BORDER-COLOR + +By default, posframe shows no borders, but users can specify +borders by setting BORDER-WIDTH to a positive number. Border +color can be specified by BORDER-COLOR. + +INTERNAL-BORDER-WIDTH and INTERNAL-BORDER-COLOR are same as +BORDER-WIDTH and BORDER-COLOR, but do not suggest to use for the +reason: + + Add distinct controls for child frames' borders (Bug#45620) + http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ff7b1a133bfa7f2614650f8551824ffaef13fadc + + (9) FONT, FOREGROUND-COLOR and BACKGROUND-COLOR + +Posframe's font as well as foreground and background colors are +derived from the current frame by default, but can be overridden +using the FONT, FOREGROUND-COLOR and BACKGROUND-COLOR arguments, +respectively. + + (10) RESPECT-HEADER-LINE and RESPECT-MODE-LINE + +By default, posframe will display no header-line, mode-line and +tab-line. In case a header-line, mode-line or tab-line is +desired, users can set RESPECT-HEADER-LINE and RESPECT-MODE-LINE +to t. + + (11) INITIALIZE + +INITIALIZE is a function with no argument. It will run when +posframe buffer is first selected with `with-current-buffer' +in `posframe-show', and only run once (for performance reasons). + + (12) LINES-TRUNCATE + +If LINES-TRUNCATE is non-nil, then lines will truncate in the +posframe instead of wrap. + + (13) OVERRIDE-PARAMETERS + +OVERRIDE-PARAMETERS is very powful, *all* the valid frame parameters +used by posframe's frame can be overridden by it. + +NOTE: some `posframe-show' arguments are not frame parameters, so they +can not be overrided by this argument. + + (14) TIMEOUT + +TIMEOUT can specify the number of seconds after which the posframe +will auto-hide. + + (15) REFRESH + +If REFRESH is a number, posframe's frame-size will be re-adjusted +every REFRESH seconds. + + (16) ACCEPT-FOCUS + +When ACCEPT-FOCUS is non-nil, posframe will accept focus. +be careful, you may face some bugs when set it to non-nil. + + (17) HIDEHANDLER + +HIDEHANDLER is a function, when it return t, posframe will be +hide, this function has a plist argument: + + (:posframe-buffer xxx + :posframe-parent-buffer xxx) + +The builtin hidehandler functions are listed below: + +1. `posframe-hidehandler-when-buffer-switch' + + (18) REFPOSHANDLER + +REFPOSHANDLER is a function, a reference position (most is +top-left of current frame) will be returned when call this +function. + +when it is nil or it return nil, child-frame feature will be used +and reference position will be deal with in Emacs. + +The user case I know at the moment is let ivy-posframe work well +in EXWM environment (let posframe show on the other appliction +window). + + DO NOT USE UNLESS NECESSARY!!! + +An example parent frame poshandler function is: + +1. `posframe-refposhandler-xwininfo' + + (19) Others + +You can use `posframe-delete-all' to delete all posframes. + +\(fn BUFFER-OR-NAME &key STRING POSITION POSHANDLER POSHANDLER-EXTRA-INFO WIDTH HEIGHT MAX-WIDTH MAX-HEIGHT MIN-WIDTH MIN-HEIGHT X-PIXEL-OFFSET Y-PIXEL-OFFSET LEFT-FRINGE RIGHT-FRINGE BORDER-WIDTH BORDER-COLOR INTERNAL-BORDER-WIDTH INTERNAL-BORDER-COLOR FONT FOREGROUND-COLOR BACKGROUND-COLOR RESPECT-HEADER-LINE RESPECT-MODE-LINE INITIALIZE NO-PROPERTIES KEEP-RATIO LINES-TRUNCATE OVERRIDE-PARAMETERS TIMEOUT REFRESH ACCEPT-FOCUS HIDEHANDLER REFPOSHANDLER &allow-other-keys)" nil nil) + +(autoload 'posframe-hide-all "posframe" "\ +Hide all posframe frames." t nil) + +(autoload 'posframe-delete-all "posframe" "\ +Delete all posframe frames and buffers." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "posframe" '("posframe-"))) + +;;;*** + +;;;### (autoloads nil "posframe-benchmark" "posframe-benchmark.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from posframe-benchmark.el + +(autoload 'posframe-benchmark "posframe-benchmark" "\ +Benchmark tool for posframe." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "posframe-benchmark" '("posframe-benchmark-alist"))) + +;;;*** + +;;;### (autoloads nil nil ("posframe-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; posframe-autoloads.el ends here diff --git a/elpa/posframe-20211126.944/posframe-benchmark.el b/elpa/posframe-20211126.944/posframe-benchmark.el @@ -0,0 +1,85 @@ +;;; posframe-benchmark.el --- Benchmark tool for posframe -*- lexical-binding:t -*- + +;; Copyright (C) 2018-2020 Free Software Foundation, Inc. + +;; Author: Feng Shu <tumashu@163.com> +;; Maintainer: Feng Shu <tumashu@163.com> +;; URL: https://github.com/tumashu/posframe +;; Version: 1.0.3 +;; Keywords: convenience, tooltip +;; Package-Requires: ((emacs "26")) + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: +(require 'cl-lib) +(require 'posframe) + +(defvar posframe-benchmark-alist + (let ((str (with-temp-buffer + (insert-file-contents (locate-library "posframe.el")) + (buffer-string)))) + `((font-at + (font-at (point-min))) + (redraw-display + (redraw-display)) + (redraw-frame + (redraw-frame (window-frame))) + (remove-text-properties + (let ((string ,str)) + (remove-text-properties + 0 (length string) '(read-only t) + string))) + (mouse-position + (mouse-position)) + (default-font-width + (default-font-width)) + (posframe--get-font-height + (posframe--get-font-height (point-min))) + (posframe--mouse-banish + (posframe--mouse-banish (window-frame))) + (frame-parameter + (frame-parameter (window-frame) 'no-accept-focus)) + (set-mouse-position + (set-mouse-position (window-frame) 0 0)) + (posn-at-point + (posn-at-point)) + (posn-x-y + (posn-x-y (posn-at-point))) + (posn-object-x-y + (posn-object-x-y (posn-at-point))) + (set-frame-parameter + (set-frame-parameter (window-frame) 'test 1)) + (raise-frame + (raise-frame (window-frame)))))) + +;;;###autoload +(defun posframe-benchmark () + "Benchmark tool for posframe." + (interactive) + (let ((n 1000)) + (message "\n* Posframe Benchmark") + (dolist (x posframe-benchmark-alist) + (message "\n** Benchmark `%S' %s times ..." (car x) n) + (benchmark n (car (cdr x)))) + (message "\n* Finished."))) + + +(provide 'posframe-benchmark) + +;;; posframe.el ends here diff --git a/elpa/posframe-20211126.944/posframe-benchmark.elc b/elpa/posframe-20211126.944/posframe-benchmark.elc Binary files differ. diff --git a/elpa/posframe-20211126.944/posframe-pkg.el b/elpa/posframe-20211126.944/posframe-pkg.el @@ -0,0 +1,12 @@ +(define-package "posframe" "20211126.944" "Pop a posframe (just a frame) at point" + '((emacs "26.1")) + :commit "3b1dc400d286b0a4bd42e518bf3e7eedb49fd1e6" :authors + '(("Feng Shu" . "tumashu@163.com")) + :maintainer + '("Feng Shu" . "tumashu@163.com") + :keywords + '("convenience" "tooltip") + :url "https://github.com/tumashu/posframe") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/posframe-20211126.944/posframe.el b/elpa/posframe-20211126.944/posframe.el @@ -0,0 +1,1462 @@ +;;; posframe.el --- Pop a posframe (just a frame) at point -*- lexical-binding:t -*- + +;; Copyright (C) 2018-2020 Free Software Foundation, Inc. + +;; Author: Feng Shu <tumashu@163.com> +;; Maintainer: Feng Shu <tumashu@163.com> +;; URL: https://github.com/tumashu/posframe +;; Version: 1.1.2 +;; Keywords: convenience, tooltip +;; Package-Requires: ((emacs "26.1")) + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; * Posframe README :README: + +;; Posframe can pop up a frame at point, this *posframe* is a +;; child-frame connected to its root window's buffer. + +;; The main advantages are: +;; 1. It is fast enough for daily usage :-) +;; 2. It works well with CJK languages. + +;; More info please see: README.org + +;;; Code: +;; * posframe's code :CODE: +(require 'cl-lib) + +(defgroup posframe nil + "Pop a posframe (just a frame) at point." + :group 'lisp + :prefix "posframe-") + +(defcustom posframe-inhibit-double-buffering nil + "Set the posframe's frame-parameter: inhibit-double-buffering." + :group 'posframe + :type 'boolean) + +(defcustom posframe-mouse-banish-function #'posframe-mouse-banish-default + "The function used to banish mouse. + +Function `posframe-mouse-banish-default' will work well in most +case, but suggest use function `posframe-mouse-banish-simple' or +custom function for EXWM users." + :type 'function) + +(defvar-local posframe--frame nil + "Record posframe's frame.") + +(defvar-local posframe--last-posframe-pixel-position nil + "Record the last pixel position of posframe's frame.") + +(defvar-local posframe--last-posframe-size nil + "Record the last size of posframe's frame.") + +(defvar-local posframe--last-posframe-displayed-size nil + "Record the last displayed size of posframe's frame.") + +(defvar-local posframe--last-parent-frame-size nil + "Record the last size of posframe's parent-frame.") + +(defvar-local posframe--last-poshandler-info nil + "Record the last poshandler info.") + +(defvar-local posframe--last-font-height-info nil + "Record the last font height info.") + +(defvar-local posframe--last-args nil + "Record the last arguments of `posframe--create-posframe'. + +If these args have changed, posframe will recreate its +frame.") + +(defvar-local posframe--timeout-timer nil + "Record the timer to deal with timeout argument of `posframe-show'.") + +(defvar-local posframe--refresh-timer nil + "Record the timer to deal with refresh argument of `posframe-show'.") + +(defvar-local posframe--initialized-p nil + "Record initialize status of `posframe-show'.") + +(defvar-local posframe--accept-focus nil + "Record accept focus status of `posframe-show'.") + +(defvar posframe-hidehandler-timer nil + "Timer used by hidehandler function.") + +;; Avoid compilation warnings on Emacs < 27. +(defvar x-gtk-resize-child-frames) + +(defvar posframe-gtk-resize-child-frames + (when (and + (> emacs-major-version 26) + (string-match-p "GTK3" system-configuration-features) + (let ((value (or (getenv "XDG_CURRENT_DESKTOP") (getenv "DESKTOP_SESSION")))) + (and (stringp value) + ;; It can be "ubuntu:GNOME". + (string-match-p "GNOME" value)))) + ;; Not future-proof, but we can use it now. + 'resize-mode) + "Value to bind `x-gtk-resize-child-frames' to. + +The value `resize-mode' only has effect on new child frames, so +if you change it, call `posframe-delete-all' for it to take +effect.") + +;;;###autoload +(defun posframe-workable-p () + "Test posframe workable status." + (and (>= emacs-major-version 26) + (not (or noninteractive + emacs-basic-display + (not (display-graphic-p)))))) + +(cl-defun posframe--create-posframe (buffer-or-name + &key + parent-frame + foreground-color + background-color + left-fringe + right-fringe + border-width + border-color + internal-border-width + internal-border-color + font + keep-ratio + lines-truncate + override-parameters + respect-header-line + respect-mode-line + accept-focus) + "Create and return a posframe child frame. +This posframe's buffer is BUFFER-OR-NAME. + +The below optional arguments are similar to `posframe-show''s: +PARENT-FRAME, FOREGROUND-COLOR, BACKGROUND-COLOR, LEFT-FRINGE, +RIGHT-FRINGE, BORDER-WIDTH, BORDER-COLOR, INTERNAL-BORDER-WIDTH, +INTERNAL-BORDER-COLOR, FONT, KEEP-RATIO, LINES-TRUNCATE, +OVERRIDE-PARAMETERS, RESPECT-HEADER-LINE, RESPECT-MODE-LINE, +ACCEPT-FOCUS." + (let ((left-fringe (or left-fringe 0)) + (right-fringe (or right-fringe 0)) + ;; See emacs.git: Add distinct controls for child frames' borders (Bug#45620) + ;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ff7b1a133bfa7f2614650f8551824ffaef13fadc + (border-width (or border-width internal-border-width 0)) + (border-color (or border-color internal-border-color)) + (buffer (get-buffer-create buffer-or-name)) + (after-make-frame-functions nil) + (x-gtk-resize-child-frames posframe-gtk-resize-child-frames) + (args (list foreground-color + background-color + right-fringe + left-fringe + border-width + border-color + internal-border-width + internal-border-color + font + keep-ratio + override-parameters + respect-header-line + respect-mode-line + accept-focus))) + (with-current-buffer buffer + ;; Many variables take effect after call `set-window-buffer' + (setq-local display-line-numbers nil) + (setq-local frame-title-format "") + (setq-local left-margin-width nil) + (setq-local right-margin-width nil) + (setq-local left-fringe-width nil) + (setq-local right-fringe-width nil) + (setq-local fringes-outside-margins 0) + (setq-local fringe-indicator-alist nil) + ;; Need to use `lines-truncate' as our keyword variable instead of + ;; `truncate-lines' so we don't shadow the variable that we are trying to + ;; set. + (setq-local truncate-lines lines-truncate) + (setq-local cursor-type nil) + (setq-local cursor-in-non-selected-windows nil) + (setq-local show-trailing-whitespace nil) + (setq-local posframe--accept-focus accept-focus) + (unless respect-mode-line + (setq-local mode-line-format nil)) + (unless respect-header-line + (setq-local header-line-format nil)) + + (add-hook 'kill-buffer-hook #'posframe-auto-delete nil t) + + ;; Create child-frame + (unless (and (frame-live-p posframe--frame) + ;; For speed reason, posframe will reuse + ;; existing frame at possible, but when + ;; user change args, recreating frame + ;; is needed. + (equal posframe--last-args args)) + (posframe-delete-frame buffer) + (setq-local posframe--last-args args) + (setq-local posframe--last-posframe-pixel-position nil) + (setq-local posframe--last-posframe-size nil) + (setq-local posframe--frame + (make-frame + `(,@override-parameters + ,(when foreground-color + (cons 'foreground-color foreground-color)) + ,(when background-color + (cons 'background-color background-color)) + ,(when font + (cons 'font font)) + (title . "posframe") + (parent-frame . ,parent-frame) + (keep-ratio ,keep-ratio) + (posframe-buffer . ,(cons (buffer-name buffer) + buffer)) + (fullscreen . nil) + (no-accept-focus . ,(not accept-focus)) + (min-width . 0) + (min-height . 0) + (border-width . 0) + (internal-border-width . ,border-width) + (child-frame-border-width . ,border-width) + (vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil) + (left-fringe . ,left-fringe) + (right-fringe . ,right-fringe) + (menu-bar-lines . 0) + (tool-bar-lines . 0) + (tab-bar-lines . 0) + (line-spacing . 0) + (unsplittable . t) + (no-other-frame . t) + (undecorated . t) + (visibility . nil) + (cursor-type . nil) + (minibuffer . nil) + (width . 1) + (height . 1) + (no-special-glyphs . t) + (skip-taskbar . t) + (inhibit-double-buffering . ,posframe-inhibit-double-buffering) + ;; Do not save child-frame when use desktop.el + (desktop-dont-save . t)))) + (when border-color + (set-face-background + (if (facep 'child-frame-border) + 'child-frame-border + 'internal-border) + border-color posframe--frame) + ;; HACK: Set face background after border color, otherwise the + ;; border is not updated (BUG!). + (when (version< emacs-version "28.0") + (set-frame-parameter + posframe--frame 'background-color + (or background-color (face-attribute 'default :background))))) + (let ((posframe-window (frame-root-window posframe--frame))) + ;; This method is more stable than 'setq mode/header-line-format nil' + (unless respect-mode-line + (set-window-parameter posframe-window 'mode-line-format 'none)) + (unless respect-header-line + (set-window-parameter posframe-window 'header-line-format 'none)) + (set-window-buffer posframe-window buffer) + (set-window-dedicated-p posframe-window t))) + + ;; Remove tab-bar always. + (set-frame-parameter posframe--frame 'tab-bar-lines 0) + (when (version< "27.0" emacs-version) + (setq-local tab-line-format nil)) + + ;; If user set 'parent-frame to nil after run posframe-show. + ;; for cache reason, next call to posframe-show will be affected. + ;; so we should force set parent-frame again in this place. + (set-frame-parameter posframe--frame 'parent-frame parent-frame) + + posframe--frame))) + +;;;###autoload +(cl-defun posframe-show (buffer-or-name + &key + string + position + poshandler + poshandler-extra-info + width + height + max-width + max-height + min-width + min-height + x-pixel-offset + y-pixel-offset + left-fringe + right-fringe + border-width + border-color + internal-border-width + internal-border-color + font + foreground-color + background-color + respect-header-line + respect-mode-line + initialize + no-properties + keep-ratio + lines-truncate + override-parameters + timeout + refresh + accept-focus + hidehandler + refposhandler + &allow-other-keys) + "Pop up a posframe to show STRING at POSITION. + + (1) POSITION + +POSITION can be: +1. An integer, meaning point position. +2. A cons of two integers, meaning absolute X and Y coordinates. +3. Other type, in which case the corresponding POSHANDLER should be + provided. + + (2) POSHANDLER + +POSHANDLER is a function of one argument returning an actual +position. Its argument is a plist of the following form: + + (:position xxx + :poshandler xxx + :font-height xxx + :font-width xxx + :posframe xxx + :posframe-width xxx + :posframe-height xxx + :posframe-buffer xxx + :parent-frame xxx + :parent-window-left xxx + :parent-window-top xxx + :parent-frame-width xxx + :parent-frame-height xxx + :parent-window xxx + :parent-window-width xxx + :parent-window-height xxx + :mouse-x xxx + ;mouse-y xxx + :minibuffer-height xxx + :mode-line-height xxx + :header-line-height xxx + :tab-line-height xxx + :x-pixel-offset xxx + :y-pixel-offset xxx) + +By default, poshandler is auto-selected based on the type of POSITION, +but the selection can be overridden using the POSHANDLER argument. + +The names of poshandler functions are like: + + `posframe-poshandler-p0.5p0-to-w0.5p1' + +which mean align posframe(0.5, 0) to a position(a, b) + +1. a = x of window(0.5, 0) +2. b = y of point(1, 1) + + posframe(p), frame(f), window(w), point(p), mouse(m) + + (0,0) (0.5,0) (1,0) + +------------+-----------+ + | | + | | + | | + (0, 0.5) + + (1, 0.5) + | | + | | + | | + +------------+-----------+ + (0,1) (0.5,1) (1,1) + +The alias of builtin poshandler functions are listed below: + +1. `posframe-poshandler-frame-center' +2. `posframe-poshandler-frame-top-center' +3. `posframe-poshandler-frame-top-left-corner' +4. `posframe-poshandler-frame-top-right-corner' +5. `posframe-poshandler-frame-bottom-center' +6. `posframe-poshandler-frame-bottom-left-corner' +7. `posframe-poshandler-frame-bottom-right-corner' +8. `posframe-poshandler-window-center' +9. `posframe-poshandler-window-top-center' +10. `posframe-poshandler-window-top-left-corner' +11. `posframe-poshandler-window-top-right-corner' +12. `posframe-poshandler-window-bottom-center' +13. `posframe-poshandler-window-bottom-left-corner' +14. `posframe-poshandler-window-bottom-right-corner' +15. `posframe-poshandler-point-top-left-corner' +16. `posframe-poshandler-point-bottom-left-corner' +17. `posframe-poshandler-point-bottom-left-corner-upward' +18. `posframe-poshandler-point-window-center' + +by the way, poshandler can be used by other packages easily with +the help of function `posframe-poshandler-argbuilder'. like: + + (let* ((info (posframe-poshandler-argbuilder *MY-CHILD-FRAME*)) + (posn (posframe-poshandler-window-center + `(:posframe-width 800 :posframe-height 400 ,@info)))) + `((left . ,(car posn)) + (top . ,(cdr posn)))) + + (3) POSHANDLER-EXTRA-INFO + +POSHANDLER-EXTRA-INFO is a plist, which will prepend to the +argument of poshandler function: 'info', it will *OVERRIDE* the +exist key in 'info'. + + (4) BUFFER-OR-NAME + +This posframe's buffer is BUFFER-OR-NAME, which can be a buffer +or a name of a (possibly nonexistent) buffer. + +buffer name can prefix with space, for example ' *mybuffer*', so +the buffer name will hide for ibuffer and `list-buffers'. + + (5) NO-PROPERTIES + +If NO-PROPERTIES is non-nil, The STRING's properties will +be removed before being shown in posframe. + + (6) HEIGHT, MAX-HEIGHT, MIN-HEIGHT, WIDTH, MAX-WIDTH and MIN-WIDTH + +These arguments are specified in the canonical character width +and height of posframe, more details can be found in docstring of +function `fit-frame-to-buffer', + + (7) LEFT-FRINGE and RIGHT-FRINGE + +If LEFT-FRINGE or RIGHT-FRINGE is a number, left fringe or +right fringe with be shown with the specified width. + + (8) BORDER-WIDTH, BORDER-COLOR, INTERNAL-BORDER-WIDTH and INTERNAL-BORDER-COLOR + +By default, posframe shows no borders, but users can specify +borders by setting BORDER-WIDTH to a positive number. Border +color can be specified by BORDER-COLOR. + +INTERNAL-BORDER-WIDTH and INTERNAL-BORDER-COLOR are same as +BORDER-WIDTH and BORDER-COLOR, but do not suggest to use for the +reason: + + Add distinct controls for child frames' borders (Bug#45620) + http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ff7b1a133bfa7f2614650f8551824ffaef13fadc + + (9) FONT, FOREGROUND-COLOR and BACKGROUND-COLOR + +Posframe's font as well as foreground and background colors are +derived from the current frame by default, but can be overridden +using the FONT, FOREGROUND-COLOR and BACKGROUND-COLOR arguments, +respectively. + + (10) RESPECT-HEADER-LINE and RESPECT-MODE-LINE + +By default, posframe will display no header-line, mode-line and +tab-line. In case a header-line, mode-line or tab-line is +desired, users can set RESPECT-HEADER-LINE and RESPECT-MODE-LINE +to t. + + (11) INITIALIZE + +INITIALIZE is a function with no argument. It will run when +posframe buffer is first selected with `with-current-buffer' +in `posframe-show', and only run once (for performance reasons). + + (12) LINES-TRUNCATE + +If LINES-TRUNCATE is non-nil, then lines will truncate in the +posframe instead of wrap. + + (13) OVERRIDE-PARAMETERS + +OVERRIDE-PARAMETERS is very powful, *all* the valid frame parameters +used by posframe's frame can be overridden by it. + +NOTE: some `posframe-show' arguments are not frame parameters, so they +can not be overrided by this argument. + + (14) TIMEOUT + +TIMEOUT can specify the number of seconds after which the posframe +will auto-hide. + + (15) REFRESH + +If REFRESH is a number, posframe's frame-size will be re-adjusted +every REFRESH seconds. + + (16) ACCEPT-FOCUS + +When ACCEPT-FOCUS is non-nil, posframe will accept focus. +be careful, you may face some bugs when set it to non-nil. + + (17) HIDEHANDLER + +HIDEHANDLER is a function, when it return t, posframe will be +hide, this function has a plist argument: + + (:posframe-buffer xxx + :posframe-parent-buffer xxx) + +The builtin hidehandler functions are listed below: + +1. `posframe-hidehandler-when-buffer-switch' + + (18) REFPOSHANDLER + +REFPOSHANDLER is a function, a reference position (most is +top-left of current frame) will be returned when call this +function. + +when it is nil or it return nil, child-frame feature will be used +and reference position will be deal with in Emacs. + +The user case I know at the moment is let ivy-posframe work well +in EXWM environment (let posframe show on the other appliction +window). + + DO NOT USE UNLESS NECESSARY!!! + +An example parent frame poshandler function is: + +1. `posframe-refposhandler-xwininfo' + + (19) Others + +You can use `posframe-delete-all' to delete all posframes." + (let* ((position (or position (point))) + (max-width (if (numberp max-width) + (min max-width (frame-width)) + (frame-width))) + (max-height (if (numberp max-height) + (min max-height (frame-height)) + (frame-height))) + (min-width (min (or min-width 1) max-width)) + (min-height (min (or min-height 1) max-height)) + (width (when width + (min (max width min-width) max-width))) + (height (when height + (min (max height min-height) max-height))) + (x-pixel-offset (or x-pixel-offset 0)) + (y-pixel-offset (or y-pixel-offset 0)) + ;;----------------------------------------------------- + (buffer (get-buffer-create buffer-or-name)) + (parent-window (selected-window)) + (parent-window-top (window-pixel-top parent-window)) + (parent-window-left (window-pixel-left parent-window)) + (parent-window-width (window-pixel-width parent-window)) + (parent-window-height (window-pixel-height parent-window)) + (parent-frame (window-frame parent-window)) + (parent-frame-width (frame-pixel-width parent-frame)) + (parent-frame-height (frame-pixel-height parent-frame)) + (ref-position + (when (functionp refposhandler) + (ignore-errors + (funcall refposhandler parent-frame)))) + (font-width (default-font-width)) + (font-height (with-current-buffer (window-buffer parent-window) + (posframe--get-font-height position))) + (mode-line-height (window-mode-line-height)) + (minibuffer-height (window-pixel-height (minibuffer-window))) + (header-line-height (window-header-line-height parent-window)) + (tab-line-height (if (functionp 'window-tab-line-height) + (window-tab-line-height) + 0)) + (mouse-position (cdr (mouse-pixel-position))) + (frame-resize-pixelwise t) + posframe) + + (with-current-buffer buffer + + ;; Initialize + (unless posframe--initialized-p + (let ((func initialize)) + (when (functionp func) + (funcall func) + (setq posframe--initialized-p t)))) + + ;; Create posframe + (setq posframe + (posframe--create-posframe + buffer + :font font + :parent-frame + (unless ref-position + parent-frame) + :left-fringe left-fringe + :right-fringe right-fringe + :border-width border-width + :border-color border-color + :internal-border-width internal-border-width + :internal-border-color internal-border-color + :foreground-color foreground-color + :background-color background-color + :keep-ratio keep-ratio + :lines-truncate lines-truncate + :respect-header-line respect-header-line + :respect-mode-line respect-mode-line + :override-parameters override-parameters + :accept-focus accept-focus)) + + ;; Insert string into the posframe buffer + (posframe--insert-string string no-properties) + + (let ((size-info + (list :posframe posframe + :width width + :height height + :max-width max-width + :max-height max-height + :min-width min-width + :min-height min-height))) + ;; Set posframe's size + (posframe--set-frame-size size-info) + ;; Re-adjust posframe's size when buffer's content has changed. + (posframe--run-refresh-timer refresh size-info)) + + ;; Get new position of posframe. + (setq position + (posframe-run-poshandler + ;; All poshandlers will get info from this plist. + `(,@poshandler-extra-info + ,@(list :position position + :poshandler poshandler + :font-height font-height + :font-width font-width + :posframe posframe + :posframe-width (frame-pixel-width posframe) + :posframe-height (frame-pixel-height posframe) + :posframe-buffer buffer + :parent-frame parent-frame + :parent-frame-width parent-frame-width + :parent-frame-height parent-frame-height + :ref-position ref-position + :parent-window parent-window + :parent-window-top parent-window-top + :parent-window-left parent-window-left + :parent-window-width parent-window-width + :parent-window-height parent-window-height + :mouse-x (car mouse-position) + :mouse-y (cdr mouse-position) + :mode-line-height mode-line-height + :minibuffer-height minibuffer-height + :header-line-height header-line-height + :tab-line-height tab-line-height + :x-pixel-offset x-pixel-offset + :y-pixel-offset y-pixel-offset)))) + + ;; Move posframe + (posframe--set-frame-position + posframe position parent-frame-width parent-frame-height) + + ;; Delay hide posframe when timeout is a number. + (posframe--run-timeout-timer posframe timeout) + + ;; Make sure not hide buffer's content for scroll down. + (let ((window (frame-root-window posframe--frame))) + (when (window-live-p window) + (set-window-point window 0))) + + ;; Hide posframe when switch buffer + (let* ((parent-buffer (window-buffer parent-window)) + (parent-buffer-name (buffer-name parent-buffer))) + (set-frame-parameter posframe--frame 'posframe-hidehandler hidehandler) + (set-frame-parameter posframe--frame 'posframe-parent-buffer + (cons parent-buffer-name parent-buffer))) + + ;; Mouse banish + (funcall + posframe-mouse-banish-function + (list :parent-frame parent-frame + :mouse-x (when (car mouse-position) + (+ (or (car ref-position) 0) + (car mouse-position))) + :mouse-y (when (cdr mouse-position) + (+ (or (cdr ref-position) 0) + (cdr mouse-position))) + :posframe-x + (if (>= (car position) 0) + (car position) + (- (frame-pixel-width parent-frame) + (frame-pixel-width posframe))) + :posframe-y + (if (>= (cdr position) 0) + (cdr position) + (- (frame-pixel-height parent-frame) + (frame-pixel-height posframe))) + :posframe-width (frame-pixel-width posframe) + :posframe-height (frame-pixel-height posframe) + :parent-frame-width parent-frame-width + :parent-frame-height parent-frame-height)) + + ;; Return posframe + posframe))) + +(defun posframe--get-font-height (position) + "Get the font's height at POSITION." + (if (eq position (car posframe--last-font-height-info)) + (cdr posframe--last-font-height-info) + (let* ((font (when (and (integerp position) + (not (= position 1))) + (font-at (if (>= position (point-max)) + (- (point-max) 1) + position)))) + (height (when (integerp position) + (if (or (= position 1) (not (fontp font))) + (default-line-height) + (aref (font-info font) 3))))) + (setq posframe--last-font-height-info + (cons position height)) + height))) + +(defun posframe-mouse-banish-simple (info) + "Banish mouse to (0, 0) of posframe base on INFO." + (let ((parent-frame (plist-get info :parent-frame)) + (x (plist-get info :posframe-x)) + (y (plist-get info :posframe-y)) + (w (plist-get info :posframe-width)) + (h (plist-get info :posframe-height)) + (p-w (plist-get info :parent-frame-width)) + (p-h (plist-get info :parent-frame-height))) + (set-mouse-pixel-position + parent-frame + (if (= x 0) + (min p-w (+ w 5)) + (max 0 (- x 5))) + (if (= y 0) + (min p-h (+ h 10)) + (max 0 (- y 10)))))) + +(defun posframe-mouse-banish-default (info) + "Banish mouse base on INFO. + +FIXME: This is a hacky fix for the mouse focus problem, which like: +https://github.com/tumashu/posframe/issues/4#issuecomment-357514918" + (let* ((parent-frame (plist-get info :parent-frame)) + (m-x (plist-get info :mouse-x)) + (m-y (plist-get info :mouse-y)) + (x (plist-get info :posframe-x)) + (y (plist-get info :posframe-y)) + (w (plist-get info :posframe-width)) + (h (plist-get info :posframe-height)) + (p-w (plist-get info :parent-frame-width)) + (p-h (plist-get info :parent-frame-height))) + (when (and m-x m-y + (>= m-x x) + (<= m-x (+ x w)) + (>= m-y y) + (<= m-y (+ y h))) + (set-mouse-pixel-position + parent-frame + (if (= x 0) + (min p-w (+ w 5)) + (max 0 (- x 5))) + (if (= y 0) + (min p-h (+ h 10)) + (max 0 (- y 10))))))) + +(defun posframe--redirect-posframe-focus () + "Redirect focus from the posframe to the parent frame. +This prevents the posframe from catching keyboard input if the +window manager selects it." + (when (and (eq (selected-frame) posframe--frame) + ;; Do not redirect focus when posframe can accept focus. + ;; See posframe-show's accept-focus argument. + (not posframe--accept-focus)) + (redirect-frame-focus posframe--frame (frame-parent)))) + +(if (version< emacs-version "27.1") + (with-no-warnings + (add-hook 'focus-in-hook #'posframe--redirect-posframe-focus)) + (add-function :after after-focus-change-function #'posframe--redirect-posframe-focus)) + +(defun posframe--insert-string (string no-properties) + "Insert STRING to current buffer. +If NO-PROPERTIES is non-nil, all properties of STRING +will be removed." + (when (and string (stringp string)) + (remove-text-properties + 0 (length string) '(read-only t) string) + (let ((str (if no-properties + (substring-no-properties string) + string))) + (erase-buffer) + (insert str)))) + +(defun posframe--fit-frame-to-buffer (posframe max-height min-height max-width min-width only) + "POSFRAME version of function `fit-frame-to-buffer'. +Arguments HEIGHT, MAX-HEIGHT, MIN-HEIGHT, WIDTH, MAX-WIDTH, +MIN-WIDTH and ONLY are similar function `fit-frame-to-buffer''s." + ;; This only has effect if the user set the latter var to `hide'. + (let ((x-gtk-resize-child-frames posframe-gtk-resize-child-frames)) + ;; More info: Don't skip empty lines when fitting mini frame to buffer (Bug#44080) + ;; http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=e0de9f3295b4c46cb7198ec0b9634809d7b7a36d + (if (functionp 'fit-frame-to-buffer-1) + (fit-frame-to-buffer-1 + posframe max-height min-height max-width min-width only nil nil) + (fit-frame-to-buffer + posframe max-height min-height max-width min-width only)))) + +(defun posframe--set-frame-size (size-info) + "Set POSFRAME's size based on SIZE-INFO." + (let ((posframe (plist-get size-info :posframe)) + (width (plist-get size-info :width)) + (height (plist-get size-info :height)) + (max-width (plist-get size-info :max-width)) + (max-height (plist-get size-info :max-height)) + (min-width (plist-get size-info :min-width)) + (min-height (plist-get size-info :min-height))) + (when height (set-frame-height posframe height)) + (when width (set-frame-width posframe width)) + (unless (and height width) + (posframe--fit-frame-to-buffer + posframe max-height min-height max-width min-width + (cond (width 'vertically) + (height 'horizontally)))) + (setq-local posframe--last-posframe-size size-info))) + +(defun posframe--set-frame-position (posframe position + parent-frame-width + parent-frame-height) + "Move POSFRAME to POSITION. +This need PARENT-FRAME-WIDTH and PARENT-FRAME-HEIGHT" + (unless (and (equal position posframe--last-posframe-pixel-position) + ;; When working frame's size change, re-posit + ;; the posframe. + (equal posframe--last-parent-frame-size + (cons parent-frame-width parent-frame-height)) + (equal posframe--last-posframe-displayed-size + (cons (frame-pixel-width posframe) + (frame-pixel-height posframe)))) + (set-frame-position posframe (car position) (cdr position)) + (setq-local posframe--last-posframe-pixel-position position) + (setq-local posframe--last-parent-frame-size + (cons parent-frame-width parent-frame-height)) + (setq-local posframe--last-posframe-displayed-size + (cons (frame-pixel-width posframe) + (frame-pixel-height posframe)))) + ;; Make posframe's posframe--frame visible + (unless (frame-visible-p posframe) + (make-frame-visible posframe) + ;; Fix issue: https://github.com/tumashu/ivy-posframe/pull/30 + (redraw-frame posframe))) + +(defun posframe--run-timeout-timer (posframe secs) + "Hide POSFRAME after a delay of SECS seconds." + (when (and (numberp secs) (> secs 0)) + (when (timerp posframe--timeout-timer) + (cancel-timer posframe--timeout-timer)) + (setq-local posframe--timeout-timer + (run-with-timer + secs nil #'posframe--make-frame-invisible posframe)))) + +(defun posframe--make-frame-invisible (frame) + "`make-frame-invisible' replacement to hide FRAME safely." + (when (frame-live-p frame) + (make-frame-invisible frame))) + +(defun posframe--run-refresh-timer (repeat size-info) + "Refresh POSFRAME every REPEAT seconds. + +It will set POSFRAME's size by SIZE-INFO." + (let ((posframe (plist-get size-info :posframe)) + (width (plist-get size-info :width)) + (height (plist-get size-info :height))) + (when (and (numberp repeat) (> repeat 0)) + (unless (and width height) + (when (timerp posframe--refresh-timer) + (cancel-timer posframe--refresh-timer)) + (setq-local posframe--refresh-timer + (run-with-timer + nil repeat + (lambda (size-info) + (let ((frame-resize-pixelwise t)) + (when (and posframe (frame-live-p posframe)) + (posframe--set-frame-size size-info)))) + size-info)))))) + +(defun posframe-refresh (buffer-or-name) + "Refresh posframe pertaining to BUFFER-OR-NAME. + +For example: + + (defvar buf \" *test*\") + (posframe-show buf) + + (with-current-buffer buf + (erase-buffer) + (insert \"ffffffffffffff\") + (posframe-refresh buf)) + +User can use posframe-show's :refresh argument, +to do similar job: + + (defvar buf \" *test*\") + (posframe-show buf :refresh 0.25) + + (with-current-buffer buf + (erase-buffer) + (insert \"ffffffffffffff\"))" + (dolist (frame (frame-list)) + (let ((buffer-info (frame-parameter frame 'posframe-buffer)) + (frame-resize-pixelwise t)) + (when (or (equal buffer-or-name (car buffer-info)) + (equal buffer-or-name (cdr buffer-info))) + (with-current-buffer buffer-or-name + (posframe--set-frame-size posframe--last-posframe-size)))))) + +(defun posframe-hide (buffer-or-name) + "Hide posframe pertaining to BUFFER-OR-NAME. +BUFFER-OR-NAME can be a buffer or a buffer name." + ;; Make sure buffer-list-update-hook is nil when posframe-hide is + ;; called, otherwise: + ;; (add-hook 'buffer-list-update-hook #'posframe-hide) + ;; will lead to infinite recursion. + (let ((buffer-list-update-hook nil)) + (dolist (frame (frame-list)) + (let ((buffer-info (frame-parameter frame 'posframe-buffer))) + (when (or (equal buffer-or-name (car buffer-info)) + (equal buffer-or-name (cdr buffer-info))) + (posframe--make-frame-invisible frame)))))) + +(defun posframe-hidehandler-daemon () + "Run posframe hidehandler daemon." + (when (timerp posframe-hidehandler-timer) + (cancel-timer posframe-hidehandler-timer)) + (setq posframe-hidehandler-timer + (run-with-idle-timer 0.5 t #'posframe-hidehandler-daemon-function))) + +(defun posframe-hidehandler-daemon-function () + "Posframe hidehandler daemon function." + (ignore-errors + (dolist (frame (frame-list)) + (let ((hidehandler (frame-parameter frame 'posframe-hidehandler)) + (buffer (frame-parameter frame 'posframe-buffer)) + (parent-buffer (frame-parameter frame 'posframe-parent-buffer))) + (when (and hidehandler + (funcall hidehandler + (list + :posframe-buffer buffer + :posframe-parent-buffer parent-buffer))) + (posframe--make-frame-invisible frame)))))) + +(posframe-hidehandler-daemon) +;; For compatibility, remove In the future. +(remove-hook 'post-command-hook 'posframe-run-hidehandler) + +(defun posframe-hidehandler-when-buffer-switch (info) + "Posframe hidehandler function. + +This function let posframe hide when user switch buffer. +Note: This function is called in `post-command-hook'. +Argument INFO ." + (let ((parent-buffer (cdr (plist-get info :posframe-parent-buffer)))) + (and (buffer-live-p parent-buffer) + (not (equal parent-buffer (current-buffer)))))) + +(defun posframe-delete (buffer-or-name) + "Delete posframe pertaining to BUFFER-OR-NAME and kill the buffer. +BUFFER-OR-NAME can be a buffer or a buffer name. + +This function is not commonly used, for delete and recreate +posframe is very very slowly, `posframe-hide' is more useful." + (posframe-delete-frame buffer-or-name) + (posframe--kill-buffer buffer-or-name)) + +(defun posframe-delete-frame (buffer-or-name) + "Delete posframe pertaining to BUFFER-OR-NAME. +BUFFER-OR-NAME can be a buffer or a buffer name." + (dolist (frame (frame-list)) + (let ((buffer-info (frame-parameter frame 'posframe-buffer)) + (buffer (get-buffer buffer-or-name))) + (when (or (equal buffer-or-name (car buffer-info)) + (equal buffer-or-name (cdr buffer-info))) + (when buffer + (with-current-buffer buffer + (dolist (timer '(posframe--refresh-timer + posframe--timeout-timer)) + (when (timerp timer) + (cancel-timer timer))))) + (delete-frame frame))))) + +(defun posframe--kill-buffer (buffer-or-name) + "Kill posframe's buffer: BUFFER-OR-NAME. +BUFFER-OR-NAME can be a buffer or a buffer name." + (when (buffer-live-p (get-buffer buffer-or-name)) + (kill-buffer buffer-or-name))) + +(defun posframe-funcall (buffer-or-name function &rest arguments) + "Select posframe of BUFFER-OR-NAME and call FUNCTION with ARGUMENTS. +BUFFER-OR-NAME can be a buffer or a buffer name." + (when (functionp function) + (when (get-buffer buffer-or-name) + (with-current-buffer buffer-or-name + (when (framep posframe--frame) + (with-selected-frame posframe--frame + (apply function arguments))))))) + +;;;###autoload +(defun posframe-hide-all () + "Hide all posframe frames." + (interactive) + (dolist (frame (frame-list)) + (when (frame-parameter frame 'posframe-buffer) + (posframe--make-frame-invisible frame)))) + +;;;###autoload +(defun posframe-delete-all () + "Delete all posframe frames and buffers." + (interactive) + (dolist (frame (frame-list)) + (when (frame-parameter frame 'posframe-buffer) + (delete-frame frame))) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when posframe--frame + (posframe--kill-buffer buffer))))) + +(defun posframe-auto-delete () + "Auto delete posframe when its buffer is killed. + +This function is used by `kill-buffer-hook'." + (posframe-delete-frame (current-buffer))) + +;; Posframe's position handler +(defun posframe-run-poshandler (info) + "Run posframe's position handler. + +the structure of INFO can be found in docstring +of `posframe-show'." + (if (equal info posframe--last-poshandler-info) + posframe--last-posframe-pixel-position + (setq posframe--last-poshandler-info info) + (let* ((ref-position (plist-get info :ref-position)) + (position (funcall + (or (plist-get info :poshandler) + (let ((position (plist-get info :position))) + (cond ((integerp position) + #'posframe-poshandler-point-bottom-left-corner) + ((and (consp position) + (integerp (car position)) + (integerp (cdr position))) + #'posframe-poshandler-absolute-x-y) + (t (error "Posframe: have no valid poshandler"))))) + info)) + (x (car position)) + (y (cdr position))) + (if (not ref-position) + position + (let* ((parent-frame-width (plist-get info :parent-frame-width)) + (parent-frame-height (plist-get info :parent-frame-height)) + (posframe-width (plist-get info :posframe-width)) + (posframe-height (plist-get info :posframe-height)) + (ref-x (or (car ref-position) 0)) + (ref-y (or (cdr ref-position) 0))) + (when (< x 0) + (setq x (- (+ x parent-frame-width) posframe-width))) + (when (< y 0) + (setq y (- (+ y parent-frame-height) posframe-height))) + (cons (+ ref-x x) + (+ ref-y y))))))) + +(cl-defun posframe-poshandler-argbuilder (&optional + child-frame + &key + position + poshandler + refposhandler + x-pixel-offset + y-pixel-offset) + "Return a info list of CHILD-FRAME, used as poshandler's info argument. + +if CHILD-FRAME is nil, parent frame will use selected frame. The +documents of POSITION, POSHANDLER, X-PIXEL-OFFSET and +Y-PIXEL-OFFSET can be found in dostring of `posframe-show'. + +NOTE: this function is not used by posframe itself, it just let +poshandler easily used for other purposes. + +WARN: In some situation, this function will return wrong info, +user should manual adjust returned info before use in poshandler +function. + +Optional argument: REFPOSHANDLER." + (let* ((position (or position (point))) + (frame-width (or (and child-frame (frame-pixel-width child-frame)) 0)) + (frame-height (or (and child-frame (frame-pixel-height child-frame)) 0)) + (frame-buffer (and child-frame (window-buffer (frame-root-window child-frame)))) + (parent-frame (selected-frame)) + (parent-frame-width (frame-pixel-width parent-frame)) + (parent-frame-height (frame-pixel-height parent-frame)) + (parent-window (selected-window)) + (parent-window-top (window-pixel-top parent-window)) + (parent-window-left (window-pixel-left parent-window)) + (parent-window-width (window-pixel-width parent-window)) + (parent-window-height (window-pixel-height parent-window)) + (font-width (default-font-width)) + (font-height (with-current-buffer (window-buffer parent-window) + (posframe--get-font-height position))) + (mode-line-height (window-mode-line-height parent-window)) + (minibuffer-height (window-pixel-height (minibuffer-window))) + (header-line-height (window-header-line-height parent-window)) + (tab-line-height (if (functionp 'window-tab-line-height) + (window-tab-line-height parent-window) + 0)) + (ref-position + (when (functionp refposhandler) + (ignore-errors + (funcall refposhandler parent-frame))))) + (list :position position + :poshandler poshandler + :font-height font-height + :font-width font-width + :posframe child-frame + :posframe-width frame-width + :posframe-height frame-height + :posframe-buffer frame-buffer + :parent-frame parent-frame + :parent-frame-width parent-frame-width + :parent-frame-height parent-frame-height + :ref-position ref-position + :parent-window parent-window + :parent-window-top parent-window-top + :parent-window-left parent-window-left + :parent-window-width parent-window-width + :parent-window-height parent-window-height + :mode-line-height mode-line-height + :minibuffer-height minibuffer-height + :header-line-height header-line-height + :tab-line-height tab-line-height + :x-pixel-offset (or x-pixel-offset 0) + :y-pixel-offset (or y-pixel-offset 0)))) + +(defun posframe-poshandler-absolute-x-y (info) + "Posframe's position handler. + +Deal with (integer . integer) style position, +the structure of INFO can be found in docstring +of `posframe-show'." + (let ((position (plist-get info :position)) + (x-pixel-offset (plist-get info :x-pixel-offset)) + (y-pixel-offset (plist-get info :y-pixel-offset))) + (cons (+ (car position) x-pixel-offset) + (+ (cdr position) y-pixel-offset)))) + +(defun posframe-poshandler-point-1 (info &optional font-height upward) + "The internal function used to deal with point-poshandler. +Argument INFO . + +Optional arguments: FONT-HEIGHT and UPWARD." + (let* ((x-pixel-offset (plist-get info :x-pixel-offset)) + (y-pixel-offset (plist-get info :y-pixel-offset)) + (posframe-width (plist-get info :posframe-width)) + (posframe-height (plist-get info :posframe-height)) + (window (plist-get info :parent-window)) + (xmax (plist-get info :parent-frame-width)) + (ymax (plist-get info :parent-frame-height)) + (position-info + (or + ;; :position-info has been removed, this line + ;; is used for compatible. + (plist-get info :position-info) + (plist-get info :position))) + (position-info + (if (integerp position-info) + (posn-at-point position-info window) + position-info)) + (header-line-height (plist-get info :header-line-height)) + (tab-line-height (plist-get info :tab-line-height)) + (x (+ (car (window-inside-pixel-edges window)) + (- (or (car (posn-x-y position-info)) 0) + (or (car (posn-object-x-y position-info)) 0)) + x-pixel-offset)) + (y-top (+ (cadr (window-pixel-edges window)) + tab-line-height + header-line-height + (- (or (cdr (posn-x-y position-info)) 0) + ;; Fix the conflict with flycheck + ;; http://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00537.html + (or (cdr (posn-object-x-y position-info)) 0)) + y-pixel-offset)) + (font-height (or font-height (plist-get info :font-height))) + (y-bottom (+ y-top font-height))) + (cons (max 0 (min x (- xmax (or posframe-width 0)))) + (max 0 (if (if upward + (> (- y-bottom (or posframe-height 0)) 0) + (> (+ y-bottom (or posframe-height 0)) ymax)) + (- y-top (or posframe-height 0)) + y-bottom))))) + +(defalias 'posframe-poshandler-point-bottom-left-corner #'posframe-poshandler-p0p0-to-p0p1) +(defun posframe-poshandler-p0p0-to-p0p1 (info) + "Posframe's position handler. + +Let posframe(0, 0) align to point(0, 1). The structure of INFO +can be found in docstring of `posframe-show'. + +Optional arguments: FONT-HEIGHT, UPWARD and CENTERING." + (posframe-poshandler-point-1 info)) + +(defalias 'posframe-poshandler-point-window-center #'posframe-poshandler-p0.5p0-to-w0.5p1) +(defun posframe-poshandler-p0.5p0-to-w0.5p1 (info) + "Posframe's position handler. + +Let posframe(0.5, 0) align to a position, which x = x of +window(0.5, 0) and y = y of point(0, 1). The structure of INFO +can be found in docstring of `posframe-show'." + (let ((x (car (posframe-poshandler-p0.5p0-to-w0.5w0 info))) + (y (cdr (posframe-poshandler-p0p0-to-p0p1 info)))) + (cons x y))) + +(defun posframe-poshandler-p0.5p0-to-f0.5p1 (info) + "Posframe's position handler. + +Let posframe(0.5, 0) align to a position, which x = x of +frame(0.5, 0) and y = y of point(0, 1). The structure of INFO can +be found in docstring of `posframe-show'." + (let ((x (car (posframe-poshandler-p0.5p0-to-f0.5f0 info))) + (y (cdr (posframe-poshandler-p0p0-to-p0p1 info)))) + (cons x y))) + +(defalias 'posframe-poshandler-point-bottom-left-corner-upward #'posframe-poshandler-p0p1-to-p0p1) +(defun posframe-poshandler-p0p1-to-p0p1 (info) + "Posframe's position handler. + +Let posframe(0, 1) align to point(0, 1). The structure of INFO +can be found in docstring of `posframe-show'." + (posframe-poshandler-point-1 info nil t)) + +(defalias 'posframe-poshandler-point-top-left-corner #'posframe-poshandler-p0p0-to-p0p0) +(defun posframe-poshandler-p0p0-to-p0p0 (info) + "Posframe's position handler. + +Let posframe(0, 0) align to point(0, 0). The structure of INFO +can be found in docstring of `posframe-show'." + (let ((font-height 0)) + (posframe-poshandler-point-1 info font-height))) + +(defalias 'posframe-poshandler-frame-center #'posframe-poshandler-p0.5p0.5-to-f0.5f0.5) +(defun posframe-poshandler-p0.5p0.5-to-f0.5f0.5 (info) + "Posframe's position handler. + +Let posframe(0.5, 0.5) align to frame(0.5, 0.5). The structure of +INFO can be found in docstring of `posframe-show'." + (cons (/ (- (plist-get info :parent-frame-width) + (plist-get info :posframe-width)) + 2) + (/ (- (plist-get info :parent-frame-height) + (plist-get info :posframe-height)) + 2))) + +(defalias 'posframe-poshandler-frame-top-center #'posframe-poshandler-p0.5p0-to-f0.5f0) +(defun posframe-poshandler-p0.5p0-to-f0.5f0 (info) + "Posframe's position handler. + +Let posframe(0.5, 0) align to frame(0.5, 0). The structure of +INFO can be found in docstring of `posframe-show'." + (cons (/ (- (plist-get info :parent-frame-width) + (plist-get info :posframe-width)) + 2) + 0)) + +(defalias 'posframe-poshandler-frame-top-left-corner #'posframe-poshandler-p0p0-to-f0f0) +(defun posframe-poshandler-p0p0-to-f0f0 (_info) + "Posframe's position handler. + +Let posframe(0, 0) align to frame(0, 0). The structure of INFO +can be found in docstring of `posframe-show'." + '(0 . 0)) + +(defalias 'posframe-poshandler-frame-top-right-corner #'posframe-poshandler-p1p0-to-f1f0) +(defun posframe-poshandler-p1p0-to-f1f0 (_info) + "Posframe's position handler. + +Let posframe(1, 0) align to frame(1, 0). The structure of INFO +can be found in docstring of `posframe-show'." + '(-1 . 0)) + +(defalias 'posframe-poshandler-frame-bottom-left-corner #'posframe-poshandler-p0p1-to-f0f1) +(defun posframe-poshandler-p0p1-to-f0f1 (info) + "Posframe's position handler. + +Let posframe(0, 1) align to frame(0, 1). The structure of INFO +can be found in docstring of `posframe-show'." + (cons 0 (- 0 + (plist-get info :mode-line-height) + (plist-get info :minibuffer-height)))) + +(defalias 'posframe-poshandler-frame-bottom-right-corner #'posframe-poshandler-p1p1-to-f1f1) +(defun posframe-poshandler-p1p1-to-f1f1 (info) + "Posframe's position handler. + +Let posframe(1, 1) align to frame(1, 1). The structure of INFO +can be found in docstring of `posframe-show'." + (cons -1 (- 0 + (plist-get info :mode-line-height) + (plist-get info :minibuffer-height)))) + +(defalias 'posframe-poshandler-frame-bottom-center #'posframe-poshandler-p0.5p1-to-f0.5f1) +(defun posframe-poshandler-p0.5p1-to-f0.5f1 (info) + "Posframe's position handler. + +Let posframe(0.5, 1) align to frame(0.5, 1). The structure of +INFO can be found in docstring of `posframe-show'." + (cons (/ (- (plist-get info :parent-frame-width) + (plist-get info :posframe-width)) + 2) + (- (plist-get info :parent-frame-height) + (plist-get info :posframe-height) + (plist-get info :mode-line-height) + (plist-get info :minibuffer-height)))) + +(defalias 'posframe-poshandler-window-center #'posframe-poshandler-p0.5p0.5-to-w0.5w0.5) +(defun posframe-poshandler-p0.5p0.5-to-w0.5w0.5 (info) + "Posframe's position handler. + +Let posframe(0.5, 0.5) align to window(0.5, 0.5). The structure +of INFO can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top)) + (window-width (plist-get info :parent-window-width)) + (window-height (plist-get info :parent-window-height)) + (posframe-width (plist-get info :posframe-width)) + (posframe-height (plist-get info :posframe-height))) + (cons (max 0 (+ window-left (/ (- window-width posframe-width) 2))) + (max 0 (+ window-top (/ (- window-height posframe-height) 2)))))) + +(defalias 'posframe-poshandler-window-top-left-corner #'posframe-poshandler-p0p0-to-w0w0) +(defun posframe-poshandler-p0p0-to-w0w0 (info) + "Posframe's position handler. + +Let posframe(0, 0) align to window(0, 0). The structure of INFO +can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top))) + (cons window-left + window-top))) + +(defalias 'posframe-poshandler-window-top-right-corner #'posframe-poshandler-p1p0-to-w1w0) +(defun posframe-poshandler-p1p0-to-w1w0 (info) + "Posframe's position handler. + +Let posframe(1, 0) align to window(1, 0). The structure of INFO +can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top)) + (window-width (plist-get info :parent-window-width)) + (posframe-width (plist-get info :posframe-width))) + (cons (+ window-left window-width + (- 0 posframe-width)) + window-top))) + +(defalias 'posframe-poshandler-window-top-center #'posframe-poshandler-p0.5p0-to-w0.5w0) +(defun posframe-poshandler-p0.5p0-to-w0.5w0 (info) + "Posframe's position handler. + +Let posframe(0.5, 0) align to window(0.5, 0). The structure of +INFO can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top)) + (window-width (plist-get info :parent-window-width)) + (posframe-width (plist-get info :posframe-width))) + (cons (max 0 (+ window-left (/ (- window-width posframe-width) 2))) + window-top))) + +(defalias 'posframe-poshandler-window-bottom-left-corner #'posframe-poshandler-p0p1-to-w0w1) +(defun posframe-poshandler-p0p1-to-w0w1 (info) + "Posframe's position handler. + +Let posframe(0, 1) align to window(0, 1). The structure of INFO +can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top)) + (window-height (plist-get info :parent-window-height)) + (posframe-height (plist-get info :posframe-height)) + (mode-line-height (plist-get info :mode-line-height))) + (cons window-left + (+ window-top window-height + (- 0 mode-line-height posframe-height))))) + +(defalias 'posframe-poshandler-window-bottom-right-corner #'posframe-poshandler-p1p1-to-w1w1) +(defun posframe-poshandler-p1p1-to-w1w1 (info) + "Posframe's position handler. + +Let posframe(1, 1) align to window(1, 1). The structure of INFO +can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top)) + (window-width (plist-get info :parent-window-width)) + (window-height (plist-get info :parent-window-height)) + (posframe-width (plist-get info :posframe-width)) + (posframe-height (plist-get info :posframe-height)) + (mode-line-height (plist-get info :mode-line-height))) + (cons (+ window-left window-width + (- 0 posframe-width)) + (+ window-top window-height + (- 0 mode-line-height posframe-height))))) + +(defalias 'posframe-poshandler-window-bottom-center #'posframe-poshandler-p0.5p1-to-w0.5w1) +(defun posframe-poshandler-p0.5p1-to-w0.5w1 (info) + "Posframe's position handler. + +Let posframe(0.5, 1) align to window(0.5, 1). The structure of +INFO can be found in docstring of `posframe-show'." + (let* ((window-left (plist-get info :parent-window-left)) + (window-top (plist-get info :parent-window-top)) + (window-width (plist-get info :parent-window-width)) + (window-height (plist-get info :parent-window-height)) + (posframe-width (plist-get info :posframe-width)) + (posframe-height (plist-get info :posframe-height)) + (mode-line-height (plist-get info :mode-line-height))) + (cons (max 0 (+ window-left (/ (- window-width posframe-width) 2))) + (+ window-top window-height + (- 0 mode-line-height posframe-height))))) + +(defun posframe-refposhandler-xwininfo (&optional frame) + "Parent FRAME poshander function. +Get the position of parent frame (current frame) with the help of +xwininfo." + (when (executable-find "xwininfo") + (with-temp-buffer + (let ((case-fold-search nil)) + (call-process "xwininfo" nil t nil + "-display" (frame-parameter frame 'display) + "-id" (frame-parameter frame 'window-id)) + (goto-char (point-min)) + (search-forward "Absolute upper-left") + (let ((x (string-to-number + (buffer-substring-no-properties + (search-forward "X: ") + (line-end-position)))) + (y (string-to-number + (buffer-substring-no-properties + (search-forward "Y: ") + (line-end-position))))) + (cons x y)))))) + + +(provide 'posframe) + +;;; posframe.el ends here diff --git a/elpa/posframe-20211126.944/posframe.elc b/elpa/posframe-20211126.944/posframe.elc Binary files differ. diff --git a/elpa/selectrum-3.1/selectrum-autoloads.el b/elpa/selectrum-3.1/selectrum-autoloads.el @@ -1,159 +0,0 @@ -;;; selectrum-autoloads.el --- automatically extracted autoloads -;; -;;; Code: - -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) - - -;;;### (autoloads nil "selectrum" "selectrum.el" (0 0 0 0)) -;;; Generated autoloads from selectrum.el - -(defvar selectrum-complete-in-buffer t "\ -If non-nil, use Selectrum for `completion-in-region'. -This option needs to be set before activating `selectrum-mode'.") - -(custom-autoload 'selectrum-complete-in-buffer "selectrum" t) - -(autoload 'selectrum-select-from-history "selectrum" "\ -Submit or insert candidate from minibuffer history. -To insert the history item into the previous session use the -binding for `selectrum-insert-current-candidate'. To submit the -history item and exit use `selectrum-select-current-candidate'." t nil) - -(autoload 'selectrum-completing-read "selectrum" "\ -Read choice using Selectrum. Can be used as `completing-read-function'. -For PROMPT, COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, -HIST, DEF, and INHERIT-INPUT-METHOD, see `completing-read'. - -\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)" nil nil) - -(autoload 'selectrum-completing-read-multiple "selectrum" "\ -Read one or more choices using Selectrum. -Replaces `completing-read-multiple'. For PROMPT, TABLE, -PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, DEF, and -INHERIT-INPUT-METHOD, see `completing-read-multiple'. - -The option `selectrum-completing-read-multiple-show-help' can be -used to control insertion of additional usage information into -the prompt. - -\(fn PROMPT TABLE &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)" nil nil) - -(autoload 'selectrum-completion-in-region "selectrum" "\ -Complete in-buffer text using a list of candidates. -Can be used as `completion-in-region-function'. For START, END, -COLLECTION, and PREDICATE, see `completion-in-region'. - -\(fn START END COLLECTION PREDICATE)" nil nil) - -(autoload 'selectrum-read-buffer "selectrum" "\ -Read buffer using Selectrum. Can be used as `read-buffer-function'. -Actually, as long as `selectrum-completing-read' is installed in -`completing-read-function', `read-buffer' already uses Selectrum. -Installing this function in `read-buffer-function' makes sure the -buffers are sorted in the default order (most to least recently -used) rather than in whatever order is defined by -`selectrum-preprocess-candidates-function', which is likely to be -less appropriate. It also allows you to view hidden buffers, -which is otherwise impossible due to tricky behavior of Emacs' -completion machinery. For PROMPT, DEF, REQUIRE-MATCH, and -PREDICATE, see `read-buffer'. - -\(fn PROMPT &optional DEF REQUIRE-MATCH PREDICATE)" nil nil) - -(autoload 'selectrum-read-file-name "selectrum" "\ -Read file name using Selectrum. Can be used as `read-file-name-function'. -For PROMPT, DIR, DEFAULT-FILENAME, MUSTMATCH, INITIAL, and -PREDICATE, see `read-file-name'. - -\(fn PROMPT &optional DIR DEFAULT-FILENAME MUSTMATCH INITIAL PREDICATE)" nil nil) - -(autoload 'selectrum--fix-dired-read-dir-and-switches "selectrum" "\ -Make \\[dired] do the \"right thing\" with its default candidate. -By default \\[dired] uses `read-file-name' internally, which -causes Selectrum to provide you with the first file inside the -working directory as the default candidate. However, it would -arguably be more semantically appropriate to use -`read-directory-name', and this is especially important for -Selectrum since this causes it to select the working directory -initially. - -To test that this advice is working correctly, type \\[dired] and -accept the default candidate. You should have opened the working -directory in Dired, and not a filtered listing for the current -file. - -This is an `:around' advice for `dired-read-dir-and-switches'. -FUNC and ARGS are standard as in any `:around' advice. - -\(fn FUNC &rest ARGS)" nil nil) - -(autoload 'selectrum-read-library-name "selectrum" "\ -Read and return a library name. -Similar to `read-library-name' except it handles `load-path' -shadows correctly." nil nil) - -(autoload 'selectrum--fix-minibuffer-message "selectrum" "\ -Ensure the cursor stays at the front of the minibuffer message. -This advice adjusts where the cursor gets placed for the overlay -of `minibuffer-message' and ensures the overlay gets displayed at -the right place without blocking the display of candidates. - -To test that this advice is working correctly, type \\[find-file] -twice in a row with `enable-recursive-minibuffers' set to nil. -The overlay indicating that recursive minibuffers are not allowed -should appear right after the user input area, not at the end of -the candidate list and the cursor should stay at the front. - -This is an `:around' advice for `minibuffer-message'. FUNC and -ARGS are standard as in all `:around' advice. - -\(fn FUNC &rest ARGS)" nil nil) - -(define-minor-mode selectrum-mode "\ -Minor mode to use Selectrum for `completing-read'." :global t (if selectrum-mode (progn (selectrum-mode -1) (setq selectrum-mode t) (setq selectrum--old-completing-read-function (default-value 'completing-read-function)) (setq-default completing-read-function #'selectrum-completing-read) (setq selectrum--old-read-buffer-function (default-value 'read-buffer-function)) (setq-default read-buffer-function #'selectrum-read-buffer) (setq selectrum--old-read-file-name-function (default-value 'read-file-name-function)) (setq-default read-file-name-function #'selectrum-read-file-name) (setq selectrum--old-completion-in-region-function (default-value 'completion-in-region-function)) (when selectrum-complete-in-buffer (setq-default completion-in-region-function #'selectrum-completion-in-region)) (advice-add #'completing-read-multiple :override #'selectrum-completing-read-multiple) (advice-add 'dired-read-dir-and-switches :around #'selectrum--fix-dired-read-dir-and-switches) (advice-add 'read-library-name :override #'selectrum-read-library-name) (advice-add #'minibuffer-message :around #'selectrum--fix-minibuffer-message) (define-key minibuffer-local-map [remap previous-matching-history-element] 'selectrum-select-from-history)) (when (equal (default-value 'completing-read-function) #'selectrum-completing-read) (setq-default completing-read-function selectrum--old-completing-read-function)) (when (equal (default-value 'read-buffer-function) #'selectrum-read-buffer) (setq-default read-buffer-function selectrum--old-read-buffer-function)) (when (equal (default-value 'read-file-name-function) #'selectrum-read-file-name) (setq-default read-file-name-function selectrum--old-read-file-name-function)) (when (equal (default-value 'completion-in-region-function) #'selectrum-completion-in-region) (setq-default completion-in-region-function selectrum--old-completion-in-region-function)) (advice-remove #'completing-read-multiple #'selectrum-completing-read-multiple) (advice-remove 'dired-read-dir-and-switches #'selectrum--fix-dired-read-dir-and-switches) (advice-remove 'read-library-name #'selectrum-read-library-name) (advice-remove #'minibuffer-message #'selectrum--fix-minibuffer-message) (when (eq (lookup-key minibuffer-local-map [remap previous-matching-history-element]) #'selectrum-select-from-history) (define-key minibuffer-local-map [remap previous-matching-history-element] nil)))) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "selectrum" '("selectrum-"))) - -;;;*** - -;;;### (autoloads nil "selectrum-helm" "selectrum-helm.el" (0 0 0 -;;;;;; 0)) -;;; Generated autoloads from selectrum-helm.el - -(defvar selectrum-helm-mode nil "\ -Non-nil if Selectrum-Helm mode is enabled. -See the `selectrum-helm-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 `selectrum-helm-mode'.") - -(custom-autoload 'selectrum-helm-mode "selectrum-helm" nil) - -(autoload 'selectrum-helm-mode "selectrum-helm" "\ -Minor mode to use Selectrum to implement Helm commands. - -If called interactively, enable Selectrum-Helm mode if ARG is -positive, and disable it if ARG is zero or negative. If called -from Lisp, also enable the mode if ARG is omitted or nil, and -toggle it if ARG is `toggle'; disable the mode otherwise. - -\(fn &optional ARG)" t nil) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "selectrum-helm" '("selectrum-helm--adapter"))) - -;;;*** - -;;;### (autoloads nil nil ("selectrum-pkg.el") (0 0 0 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; selectrum-autoloads.el ends here diff --git a/elpa/selectrum-3.1/selectrum-helm.el b/elpa/selectrum-3.1/selectrum-helm.el @@ -1,132 +0,0 @@ -;;; selectrum-helm.el --- Use Selectrum for Helm -*- lexical-binding: t -*- - -;; Copyright (C) 2020 Radon Rosborough - -;; Author: Radon Rosborough <radon.neon@gmail.com> -;; Created: 15 Apr 2020 -;; Homepage: https://github.com/raxod502/selectrum -;; Keywords: extensions -;; Package-Requires: ((emacs "25.1") (helm "3.6.1") (selectrum "3.1")) -;; SPDX-License-Identifier: MIT -;; Version: 3.1 - -;;; Commentary: - -;; This file provides a minor mode that causes all Helm commands to -;; redirect to use Selectrum instead, at some loss of functionality. - -;;; Code: - -;; To see the outline of this file, run M-x outline-minor-mode and -;; then press C-c @ C-t. To also show the top-level functions and -;; variable declarations in each section, run M-x occur with the -;; following query: ^;;;;* \|^( - -(require 'cl-lib) -(require 'let-alist) -(require 'map) -(require 'subr-x) - -(require 'selectrum) - -(declare-function helm "ext:helm") -(declare-function helm-get-current-source "ext:helm") - -(cl-defun selectrum-helm--normalize-source (source &optional only-one) - "Normalize single Helm SOURCE alist. -ONLY-ONE non-nil means don't add section headers." - (let-alist source - (when .init - (funcall .init)) - (let ((cands (cond - ((functionp .candidates) - (funcall .candidates)) - ((symbolp .candidates) - (symbol-value .candidates)) - (t - .candidates)))) - (dolist (func (if (functionp .candidate-transformer) - (list .candidate-transformer) - .candidate-transformer)) - (setq cands (funcall func cands))) - (setq cands (mapcar - (lambda (cand) - (when (consp cand) - (setq cand - (propertize - (car cand) - 'selectrum-helm-return - (cdr cand)))) - (setq cand - (propertize - cand - 'selectrum-helm-action - .action - 'selectrum-candidate-display-suffix - (unless only-one - (when-let ((name .name)) - (when (string-suffix-p ":" name) - (setq name - (substring name 0 (1- (length name))))) - (format " [%s]" name))) - 'selectrum-helm-source - .name)) - cand) - cands)) - cands))) - -(cl-defun selectrum-helm--normalize-sources (sources) - "Given SOURCES as passed to `helm', return flat list of candidate strings." - (cond - ((symbolp sources) - (setq sources (symbol-value sources))) - ((symbolp (car-safe (car-safe sources))) - (setq sources (list sources)))) - (apply #'append (mapcar (lambda (source) - (selectrum-helm--normalize-source - source (= 1 (length sources)))) - sources))) - -(defun selectrum-helm--adapter (&rest plist) - "Receive arguments to `helm' and invoke `selectrum--read' instead. -For PLIST, see `helm'. This is an `:override' advice for `helm'." - (let* ((result (selectrum--read - (or (plist-get plist :prompt) "pattern: ") - (selectrum-helm--normalize-sources - (plist-get plist :sources)) - :default-candidate (plist-get plist :preselect) - :initial-input (plist-get plist :input) - :history (plist-get plist :history))) - (cand (or (get-text-property 0 'selectrum-helm-return result) - result))) - (when-let ((action (get-text-property 0 'selectrum-helm-action result))) - (if (functionp action) - (funcall action cand) - (when (symbolp action) - (setq action (symbol-value action))) - (funcall (cdr (car action)) cand))))) - -;;;###autoload -(define-minor-mode selectrum-helm-mode - "Minor mode to use Selectrum to implement Helm commands." - :global t - :group 'selectrum - (if selectrum-helm-mode - (progn - (advice-add #'helm :override #'selectrum-helm--adapter) - (advice-add #'helm-get-current-source :override #'ignore)) - (advice-remove #'helm #'selectrum-helm--adapter) - (advice-remove #'helm-get-current-source #'ignore))) - -;;;; Closing remarks - -(provide 'selectrum-helm) - -;; Local Variables: -;; checkdoc-verb-check-experimental-flag: nil -;; indent-tabs-mode: nil -;; outline-regexp: ";;;;* " -;; sentence-end-double-space: nil -;; End: - -;;; selectrum-helm.el ends here diff --git a/elpa/selectrum-3.1/selectrum-helm.elc b/elpa/selectrum-3.1/selectrum-helm.elc Binary files differ. diff --git a/elpa/selectrum-3.1/selectrum-pkg.el b/elpa/selectrum-3.1/selectrum-pkg.el @@ -1,12 +0,0 @@ -(define-package "selectrum" "3.1" "Easily select item from list" - '((emacs "25.1")) - :commit "a9ecaa018f249c15fae8e1af5d4df337e846e92f" :authors - '(("Radon Rosborough" . "radon.neon@gmail.com")) - :maintainer - '("Radon Rosborough" . "radon.neon@gmail.com") - :keywords - '("extensions") - :url "https://github.com/raxod502/selectrum") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/selectrum-3.1/selectrum.el b/elpa/selectrum-3.1/selectrum.el @@ -1,2893 +0,0 @@ -;;; selectrum.el --- Easily select item from list -*- lexical-binding: t -*- - -;; Copyright (C) 2019 Radon Rosborough - -;; Author: Radon Rosborough <radon.neon@gmail.com> -;; Created: 8 Dec 2019 -;; Homepage: https://github.com/raxod502/selectrum -;; Keywords: extensions -;; Package-Requires: ((emacs "25.1")) -;; SPDX-License-Identifier: MIT -;; Version: 3.1 - -;;; Commentary: - -;; Selectrum is a better solution for incremental narrowing in Emacs, -;; replacing Helm, Ivy, and IDO. Its design philosophy is based on -;; choosing the right abstractions and prioritizing consistency and -;; predictability over special-cased improvements for particular -;; cases. As such, Selectrum follows existing Emacs conventions where -;; they exist and are reasonable, and it declines to implement -;; features which have marginal benefit compared to the additional -;; complexity of a new interface. - -;; Getting started: Selectrum provides a global minor mode, -;; `selectrum-mode', which enhances `completing-read' and all related -;; functions automatically without the need for further configuration. - -;; Please see https://github.com/raxod502/selectrum for more -;; information. - -;;; Code: - -(require 'cl-lib) -(require 'crm) -(require 'map) -(require 'minibuf-eldef) -(require 'regexp-opt) -(require 'seq) -(require 'subr-x) - -(define-obsolete-variable-alias - 'selectrum-active-p - 'selectrum-is-active - "3.1") - -(define-obsolete-variable-alias - 'selectrum-should-sort-p - 'selectrum-should-sort - "3.1") - -(define-obsolete-variable-alias - 'selectrum-fix-minibuffer-height - 'selectrum-fix-vertical-window-height - "3.1") - -(define-obsolete-function-alias - 'selectrum-read - 'selectrum--read - "3.1") - -(define-obsolete-function-alias - 'selectrum-default-candidate-refine-function - 'selectrum--default-candidate-refine-function - "3.1") - -(defun selectrum--default-candidate-refine-function (input candidates) - "Default value of `selectrum-refine-candidates-function'. -Return only candidates that contain the input as a substring. -INPUT is a string, CANDIDATES is a list of strings." - (let ((regexp (regexp-quote input))) - (cl-delete-if-not - (lambda (candidate) - (string-match-p regexp candidate)) - (copy-sequence candidates)))) - -(define-obsolete-function-alias - 'selectrum-default-candidate-highlight-function - 'selectrum--default-candidate-highlight-function - "3.1") - -(defun selectrum--default-candidate-highlight-function (input candidates) - "Default value of `selectrum-highlight-candidates-function'. -Highlight the substring match with -`selectrum-primary-highlight'. INPUT is a string, CANDIDATES is a -list of strings." - (let ((regexp (regexp-quote input))) - (save-match-data - (mapcar - (lambda (candidate) - (when (string-match regexp candidate) - (setq candidate (copy-sequence candidate)) - (put-text-property - (match-beginning 0) (match-end 0) - 'face 'selectrum-primary-highlight - candidate)) - candidate) - candidates)))) - -;;; Faces - -(defface selectrum-current-candidate - '((t :inherit highlight)) - "Face used to highlight the currently selected candidate." - :group 'selectrum-faces) - -(defface selectrum-primary-highlight - '((t :weight bold)) - "Face used to highlight the parts of candidates that match the input." - :group 'selectrum-faces) - -(defface selectrum-secondary-highlight - '((t :inherit selectrum-primary-highlight :underline t)) - "Additional face used to highlight parts of candidates. -May be used to highlight parts of candidates that match specific -parts of the input." - :group 'selectrum-faces) - -(defface selectrum-completion-annotation - '((t :inherit completions-annotations)) - "Face used to display annotations of completion tables." - :group 'selectrum-faces) - -(defface selectrum-completion-docsig - '((t :inherit selectrum-completion-annotation :slant italic)) - "Face used to display docsigs of completion tables." - :group 'selectrum-faces) - -;;; User options - -(defgroup selectrum nil - "Simple incremental narrowing framework with sane API." - :group 'convenience - :prefix "selectrum-" - :link '(url-link "https://github.com/raxod502/selectrum")) - -(defcustom selectrum-default-value-format " [default: %s]" - "Format string for the default value in the minibuffer." - :type '(choice (const nil) string)) - -(defcustom selectrum-should-sort t - "Non-nil if preprocessing function should sort. -This should be respected by user functions for optimal results." - :type 'boolean) - -(defcustom selectrum-max-window-height 10 - "Maximal window height to expand to. -The display window or minibuffer window will expand up to this -height when it is to small to show the candidates. If this option -is nil it defaults to `max-mini-window-height'. See its docstring -for further information of possible values." - :type 'number) - -(defcustom selectrum-num-candidates-displayed 'auto - "Configures how many candidates are displayed. -When `auto' the appropriate number will be determined -automatically according to the available space of the displaying -window and the height allowed by `selectrum-max-window-height'. -To configure a constant height for vertical display see -`selectrum-fix-vertical-window-height'." - :type '(choice (const :tag "Automatic" auto) integer)) - -(defcustom selectrum-fix-vertical-window-height nil - "Configure a fixed window height for vertical display. -If candidates are displayed vertically and this option is non-nil -the height will be determined by `selectrum-max-window-height'." - :type 'boolean) - -(defun selectrum-display-full-frame (buf _alist) - "Display BUF in full frame. -Can be used as `selectrum-display-action' to display candidates -in a single window spanning the current frame: - - (setq selectrum-display-action - \\='(selectrum-display-full-frame)." - (delete-other-windows) - (set-window-buffer (selected-window) buf) - (selected-window)) - -(defcustom selectrum-display-action nil - "Display action to show the candidates buffer. - -If this is nil the candidates are shown in the minibuffer. -Otherwise the candidates are shown in the window as determined -from the display action. Note that if you specify a window height -lower than `selectrum-max-window-height' the window will be -resized if needed to display that number of candidates. - -For the format see the ACTION argument of `display-buffer'. For -example to display candidates in some available window use: - - \\='(display-buffer-use-some-window) - -Or to display them in a bottom side window: - - \\='(display-buffer-in-side-window - (side . bottom) - (slot . -1)) - -Display buffer actions can also spawn a separate frame where -candidates can be displayed. To display candidates in the current -frame you can use the provided action function -`selectrum-display-full-frame'." - :type '(cons (choice function (repeat :tag "Functions" function)) - alist)) - -(defcustom selectrum-display-style - '(vertical) - "Current display style for candidates. -The car is a symbol of the current display style. Currently -available styles are `vertical' and `horizontal'. The cdr is a -plist of settings. Currently there are only settings for the -`horizontal' style: - -`:prompt-separator' for the string to display after the prompt if -the candidates are displayed in the minibuffer, -`:before-candidates' for the string to insert before the -candidate listing, `:candidates-separator' for the string to -insert between candidates, `:more-candidates' for the string to -indicate that more candidates are following after the currently -displayed ones and `:after-candidates' for a string to display -after the displayed candidates." - :type 'list) - -(defcustom selectrum-display-style-cycle-list - '((vertical) - (horizontal)) - "List of `selectrum-display-style' styles. -Use `selectrum-cycle-display-style' to cycle through these." - :type 'list) - -(defun selectrum-refine-candidates-using-completions-styles (input candidates) - "Use INPUT to filter and highlight CANDIDATES. -Uses `completion-styles'." - (nconc - (completion-all-completions - input candidates nil (length input) - (completion-metadata input - minibuffer-completion-table - minibuffer-completion-predicate)) - nil)) - -(defcustom selectrum-refine-candidates-function - #'selectrum-refine-candidates-using-completions-styles - "Function used to decide which candidates should be displayed. -The function receives two arguments, the user input (a string) -and the list of candidates (strings). Returns a new list of -candidates. Should not modify the input list. The returned list -may be modified by Selectrum, so a copy of the input should be -made. (Beware that `cl-remove-if' doesn't make a copy if there's -nothing to remove.)" - :type 'function) - -(defun selectrum-default-candidate-preprocess-function (candidates) - "Default value of `selectrum-preprocess-candidates-function'. -Sort first by length and then alphabetically. CANDIDATES is a -list of strings." - (if selectrum-should-sort - (sort candidates - (lambda (c1 c2) - (or (< (length c1) - (length c2)) - (and (= (length c1) - (length c2)) - (string-lessp c1 c2))))) - candidates)) - -(defcustom selectrum-completion-in-region-styles - '(basic partial-completion emacs22) - "The `completion-styles' used by `selectrum-completion-in-region'. -These are used for the initial filtering of candidates according -to the text around point. The initial filtering styles for -completion in region might generally differ from the styles you -want to use for usual completion. If this option is nil the -candidates will be filtered by `all-completions'." - :type completion--styles-type) - -(defcustom selectrum-preprocess-candidates-function - #'selectrum-default-candidate-preprocess-function - "Function used to preprocess the list of candidates. -Receive one argument, the list of candidates. Return a new list. -May modify the input list. The returned list may be modified by -Selectrum. Note that if you sort a list of candidates, you should -use a stable sort. That way, candidates which differ only in text -properties will retain their ordering, which may be significant -\(e.g. for `load-path' shadows in `read-library-name')." - :type 'function) - -(defun selectrum-candidates-identity (_input candidates) - "Return CANDIDATES unchanged." - candidates) - -(defcustom selectrum-highlight-candidates-function - #'selectrum-candidates-identity - "Function used to highlight matched candidates for display. -The function receives two arguments, the input string and the -list of candidates (strings) that are going to be displayed. -Return a list of propertized candidates. Do not modify the input -list or strings." - :type 'function) - -(defcustom selectrum-candidate-selected-hook nil - "Normal hook run when the user selects a candidate. -It gets the string the user selected as argument." - :type 'hook) - -(defcustom selectrum-candidate-inserted-hook nil - "Normal hook run when the user inserts a candidate. -\(This happens by typing \\[selectrum-insert-current-candidate].) -It gets the string the user inserted as argument." - :type 'hook) - -(defcustom selectrum-count-style 'matches - "The style to use for displaying count information before the prompt. - -Possible values are: - -- `matches': Show the total number of matches. -- `current/matches': Show the index of current match and the - total number of matches. -- nil: Show nothing." - :type '(choice - (const :tag "Disabled" nil) - (const :tag "Count matches" matches) - (const :tag "Count matches and show current match" - current/matches))) - -(defcustom selectrum-show-indices nil - "Non-nil means to add indices to the displayed candidates. -If this is a function, it should take in the row number of the -displayed candidate (starting from 1) as a parameter and it -should return the string to be displayed representing the index -of the candidate. If this is some other non-nil value, it is -treated as if it were (lambda (i) (format \"%2d \" i))." - :type '(choice function boolean)) - -(defcustom selectrum-completing-read-multiple-show-help t - "Non-nil means to show help for `selectrum-completing-read-multiple'. - -This options controls insertion of additional usage information -into the prompt when using commands which use -`completing-read-multiple'." - :type 'boolean) - -(defcustom selectrum-right-margin-padding 1 - "The number of spaces to add after right margin text. -This only takes effect when the -`selectrum-candidate-display-right-margin' property is presented -in candidates. - -This option is a workaround for 2 problems: - -- Some terminals will wrap the last character of a line when it - exactly fits. - -- Emacs doesn't provide a method to calculate the exact pixel - width of a unicode char, so a wide char can cause line - wrapping." - :type 'integer) - -(defcustom selectrum-multiline-display-settings - '((match ":" success) - (line-count "%d lines" success) - (newline "\\n" warning) - (truncation "..." shadow) - (whitespace " " shadow)) - "Settings used to configure the formatting of multi-line candidates. - -Currently, multi-line candidates are flattened, stripped of -repeated whitespace, and, if need be, truncated. The first line -is displayed truncated followed by a line count and trunctated -matches. This option configures how the formatting is done. - -When customizing this option, a setting for each transformation -\(defined below) must be present in the list. - -There are three values that make a setting: -1. A symbol from the following list: - - `newline' determines the string used to replace line breaks in the - candidate, which flattens the candidate into one line. - - `whitespace' determines the string used to replace repeated - whitespace, which shortens the candidate. - - `truncation' determines the string to append to a flattened and - truncated candidate. - - `match' determines the string to insert between the first - line and the matched lines. - - `line-count' determines the string for displaying the line count. -2. A string to indicate the display change. For `line-count' it should - be a format string for a decimal or the empty string for no display. -3. A face to assign to the indicator string. - -Therefore, a setting is represented as a list with three -elements: a symbol, a string, and a face, in that order. -This option is itself a list of 4 sub-lists, one for each -setting." - :type '(repeat (list :tag "Display settings" - (choice (const :tag "Matching line" - match) - (const :tag "Line truncation" - truncation) - (const :tag "New lines" - newline) - (const :tag "Repeated whitespace" - whitespace) - (const :tag "Line count" - line-count)) - (string :tag "Indicator string") - (face :tag "Indicator face")))) - -(defcustom selectrum-extend-current-candidate-highlight 'auto - "Whether to extend highlighting of the current candidate until the margin. - -When set to nil only highlight the displayed text. When set to -`auto' (the default) Selectrum will only highlight the displayed -text unless the session defines any annotations in which case the -highlighting is automatically extended. Any other non-nil value -means to always extend the highlighting." - :type '(choice (const :tag "Automatic" auto) boolean)) - -;;;###autoload -(defcustom selectrum-complete-in-buffer t - "If non-nil, use Selectrum for `completion-in-region'. -This option needs to be set before activating `selectrum-mode'." - :type 'boolean - :group 'selectrum) - -;;; Utility functions - -(defun selectrum--clamp (x lower upper) - "Constrain X to be between LOWER and UPPER inclusive. -If X < LOWER, return LOWER. If X > UPPER, return UPPER. Else -return X." - (min (max x lower) upper)) - -(defun selectrum--map-destructive (func lst) - "Apply FUNC to each element of LST, returning the new list. -Modify the original list destructively, instead of allocating a -new one." - (prog1 lst - (while lst - (setcar lst (funcall func (car lst))) - (setq lst (cdr lst))))) - -(defun selectrum--move-to-front-destructive (elt lst) - "Move all instances of ELT to front of LST, if present. -Make comparisons using `equal'. Modify the input list -destructively and return the modified list." - (let* ((elts nil) - ;; All problems in computer science are solved by an - ;; additional layer of indirection. - (lst (cons (make-symbol "dummy") lst)) - (link lst)) - (while (cdr link) - (if (equal elt (cadr link)) - (progn - (push (cadr link) elts) - (setcdr link (cddr link))) - (setq link (cdr link)))) - (nconc (nreverse elts) (cdr lst)))) - -(defmacro selectrum--minibuffer-with-setup-hook (fun &rest body) - "Variant of `minibuffer-with-setup-hook' using a symbol and `fset'. -This macro is only needed to prevent memory leaking issues with -the upstream `minibuffer-with-setup-hook' macro. FUN is the hook -function and BODY opens the minibuffer." - ;; Copied from https://github.com/minad/consult/commit/27e055e. - (declare (indent 1) (debug t)) - (let ((hook (make-symbol "hook")) - (append)) - (when (eq (car-safe fun) :append) - (setq append '(t) fun (cadr fun))) - `(let ((,hook (make-symbol "selectrum--minibuffer-setup"))) - (fset ,hook (lambda () - (remove-hook 'minibuffer-setup-hook ,hook) - (funcall ,fun))) - (unwind-protect - (progn - (add-hook 'minibuffer-setup-hook ,hook ,@append) - ,@body) - (remove-hook 'minibuffer-setup-hook ,hook))))) - -;;; Variables - -(defvar selectrum-minibuffer-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map minibuffer-local-map) - - (define-key map [remap keyboard-quit] #'abort-recursive-edit) - ;; This is bound in `minibuffer-local-map' by loading `delsel', so - ;; we have to account for it too. - (define-key map [remap minibuffer-keyboard-quit] - #'abort-recursive-edit) - ;; Override both the arrow keys and C-n/C-p. - (define-key map [remap previous-line] - #'selectrum-previous-candidate) - (define-key map [remap next-line] - #'selectrum-next-candidate) - (define-key map [remap previous-line-or-history-element] - #'selectrum-previous-candidate) - (define-key map [remap next-line-or-history-element] - #'selectrum-next-candidate) - (define-key map [remap exit-minibuffer] - #'selectrum-select-current-candidate) - (define-key map [remap scroll-down-command] - #'selectrum-previous-page) - (define-key map [remap scroll-up-command] - #'selectrum-next-page) - ;; Use `minibuffer-beginning-of-buffer' for Emacs >=27 and - ;; `beginning-of-buffer' for Emacs <=26. - (define-key map [remap minibuffer-beginning-of-buffer] - #'selectrum-goto-beginning) - (define-key map [remap beginning-of-buffer] - #'selectrum-goto-beginning) - (define-key map [remap end-of-buffer] - #'selectrum-goto-end) - (define-key map [remap kill-ring-save] - #'selectrum-kill-ring-save) - (define-key map [remap previous-matching-history-element] - #'selectrum-select-from-history) - (define-key map (kbd "C-M-DEL") #'backward-kill-sexp) - (define-key map (kbd "C-M-<backspace>") #'backward-kill-sexp) - (define-key map (kbd "C-j") #'selectrum-submit-exact-input) - (define-key map (kbd "TAB") #'selectrum-insert-current-candidate) - (define-key map (kbd "M-q") 'selectrum-cycle-display-style) - ;; Return the map. - map) - "Keymap used by Selectrum in the minibuffer.") - -(defvar-local selectrum-move-default-candidate t - "Non-nil means move default candidate to start of list. -Nil means select the default candidate initially even if it's not -at the start of the list.") - -(defvar selectrum--candidates-buffer " *selectrum*" - "Buffer to display candidates using `selectrum-display-action'.") - -(defvar selectrum--crm-separator-alist - '((":\\|,\\|\\s-" . ",") - ("[ \t]*:[ \t]*" . ":") - ("[ \t]*,[ \t]*" . ",") - (" " . " ")) - "Values of `crm-separator' mapped to separator strings. -If current `crm-separator' has a mapping the separator gets -inserted automatically when using -`selectrum-insert-current-candidate'.") - -(defvar selectrum--minibuffer-default-in-prompt-regexps - (let ((minibuffer-eldef-shorten-default nil)) - (minibuffer-default--in-prompt-regexps)) - "Regexps for determining if the prompt message includes the default value. -See `minibuffer-default-in-prompt-regexps', from which this is derived.") - -(defvar selectrum--minibuffer-local-filename-syntax - (let ((table (copy-syntax-table minibuffer-local-filename-syntax))) - (modify-syntax-entry ?\s "_" table) - table) - "Syntax table for reading file names. -Same as `minibuffer-local-filename-syntax' but considers spaces -as symbol constituents.") - -(defvar selectrum--old-completing-read-function nil - "Previous value of `completing-read-function'.") - -(defvar selectrum--old-completion-in-region-function nil - "Previous value of `completion-in-region-function'.") - -(defvar selectrum--old-read-buffer-function nil - "Previous value of `read-buffer-function'.") - -(defvar selectrum--old-read-file-name-function nil - "Previous value of `read-file-name-function'.") - -;;; Session state - -(defvar-local selectrum--last-buffer nil - "The buffer that was current before the active session") - -(defvar-local selectrum--candidates-overlay nil - "Overlay used to display current candidates.") - -(defvar-local selectrum--count-overlay nil - "Overlay used to display count information before prompt.") - -(defvar-local selectrum--dynamic-candidates nil - "The dynamic candidate function passed to `selectrum--read'. -When set the dynamic candidate function is called on each input -change. The results are subsequently preprocessed by -`selectrum-preprocess-candidates-function' and saved as -`selectrum--preprocessed-candidates'. See `selectrum--read' for -more details on function collections.") - -(defvar-local selectrum--preprocessed-candidates nil - "Preprocessed list of candidates. -This list contains the candidates of the current session after -preprocessing them with -`selectrum-preprocess-candidates-function'. The list is -subsequently passed to `selectrum-refine-candidates-function'. -For the refined candidates see `selectrum--refined-candidates'.") - -(defvar-local selectrum--refined-candidates nil - "Refined list of candidates to be displayed. -This is derived from `selectrum--preprocessed-candidates' by -`selectrum-refine-candidates-function' every time the user input -changes, and is subsequently passed to -`selectrum-highlight-candidates-function'.") - -(defvar-local selectrum--current-candidate-index nil - "Index of currently selected candidate, or nil if no candidates.") - -(defvar-local selectrum--first-index-displayed nil - "Index of the first displayed candidate.") - -(defvar-local selectrum--actual-num-candidates-displayed nil - "The actual number of candidates displayed.") - -(defvar-local selectrum--previous-input-string nil - "Previous user input string in the minibuffer. -Used to check if the user input has changed and candidates need -to be re-filtered.") - -(defvar-local selectrum--match-is-required nil - "Non-nil if the user must select one of the candidates. -Equivalently, nil if the user is allowed to submit their own -input that does not match any of the displayed candidates.") - -(defvar-local selectrum--is-crm-session nil - "Non-nil for `selectrum-completing-read-multiple' sessions.") - -(defvar-local selectrum--default-candidate nil - "Default candidate, or nil if none given.") - -;; The existence of this variable is a bit of a mess, but we'll run -;; with it for now. -(defvar-local selectrum--visual-input nil - "User input string as transformed by candidate refinement. -See `selectrum-refine-candidates-function'.") - -(defvar-local selectrum--last-command nil - "Name of last interactive command that invoked Selectrum.") - -(defvar-local selectrum--last-prefix-arg nil - "Prefix argument given to last interactive command that invoked Selectrum.") - -(defvar-local selectrum--last-input nil - "Input of last Selectrum session. This is different from -`selectrum--previous-input-string' which reflects the previous -input within a session.") - -(defvar-local selectrum--repeat nil - "Non-nil means try to restore the minibuffer state during setup. -This is used to implement `selectrum-repeat'.") - -(defvar-local selectrum-is-active nil - "Non-nil means Selectrum is currently active.") - -(defvar-local selectrum--should-skip-updates nil - "If selectrum should skip updates. - -In normal operation Selectrum checks for updating its UI after -each command. When this variable is non-nil the computation of -updates is skipped.") - -(defvar-local selectrum--is-initializing nil - "Non-nil means the current session is initializing. -This is non-nil during the first call of -`selectrum--minibuffer-post-command-hook'.") - -(defvar-local selectrum--total-num-candidates nil - "Saved number of candidates, used for `selectrum-show-indices'.") - -(defvar-local selectrum--virtual-default-file nil - "If set used as a virtual file to prompt with.") - -(defvar-local selectrum--line-height nil - "The `line-pixel-height' of current session.") - -(defvar-local selectrum--inserted-file-completion nil - "Non-nil when command should trigger refresh.") - -(defvar-local selectrum--read-args nil - "List of arguments passed to `selectrum--read'. -Passed to various hook functions, but the this usage of the hooks -has been deprecated.") - -;;;; Minibuffer state utility functions - -(defun selectrum--normalize-collection (collection &optional predicate) - "Normalize COLLECTION into a list of strings. -COLLECTION may be a list of strings or symbols or cons cells, an -obarray, a hash table, or a function, as per the docstring of -`all-completions'. The returned list may be mutated without -damaging the original COLLECTION. - -If PREDICATE is non-nil, then it filters the collection as in -`all-completions'." - ;; Making the last buffer current avoids the cost of potential - ;; buffer switching for each candidate within the predicate (see - ;; `describe-variable'). - (with-current-buffer (if (and (eq collection 'help--symbol-completion-table) - (buffer-live-p selectrum--last-buffer)) - selectrum--last-buffer - (current-buffer)) - (let ((completion-regexp-list nil)) - (all-completions "" collection predicate)))) - -(defun selectrum--remove-default-from-prompt (prompt) - "Remove the indication of the default value from PROMPT. -Selectrum has its own methods for indicating the default value, -making other methods redundant." - (save-match-data - (let ((regexps selectrum--minibuffer-default-in-prompt-regexps)) - (cl-dolist (matcher regexps prompt) - (let ((regex (if (stringp matcher) matcher (car matcher)))) - (when (string-match regex prompt) - (cl-return - (replace-match "" nil nil prompt - (if (consp matcher) - (cadr matcher) - 0))))))))) - -(defun selectrum-get-current-candidate (&optional notfull) - "Return currently selected Selectrum candidate if there is one. -If NOTFULL is non-nil don't use canonical representation of -candidate and return the candidate as displayed." - (when (and selectrum-is-active - selectrum--current-candidate-index - (or selectrum--refined-candidates - (< selectrum--current-candidate-index 0))) - (if notfull - (selectrum--get-candidate - selectrum--current-candidate-index) - (selectrum--get-full - (selectrum--get-candidate - selectrum--current-candidate-index))))) - -(defun selectrum-get-current-candidates (&optional notfull) - "Get list of current Selectrum candidates. -If NOTFULL is non-nil don't use canonical representation of -candidate and return the candidate as displayed." - (when (and selectrum-is-active - selectrum--refined-candidates) - (if notfull - selectrum--refined-candidates - (cl-loop for cand in selectrum--refined-candidates - collect (selectrum--get-full cand))))) - -(defun selectrum-get-current-input () - "Get current Selectrum user input." - (when selectrum-is-active - (with-selected-window (active-minibuffer-window) - (minibuffer-contents)))) - -(defun selectrum-set-selected-candidate (&optional string) - "Set currently selected candidate to STRING. -STRING defaults to `minibuffer-contents'. Computation of -candidates is skipped from there on. This is useful for injecting -a candidate in `minibuffer-setup-hook' and immediately exit with -it afterwards. With default completion there is no computation -triggered initially and this function can be used to mimic this -behavior." - (when selectrum-is-active - (with-selected-window (active-minibuffer-window) - (let ((string (or string (minibuffer-contents)))) - (setq-local selectrum--refined-candidates - (list string)) - (setq-local selectrum--current-candidate-index 0) - ;; Skip updates. - (setq-local selectrum--should-skip-updates t))))) - -(defun selectrum--get-full (candidate) - "Get full form of CANDIDATE." - (or (get-text-property 0 'selectrum--candidate-full candidate) - (get-text-property 0 'selectrum-candidate-full candidate) - (when minibuffer-completing-file-name - (if (and selectrum--current-candidate-index - (< selectrum--current-candidate-index 0)) - candidate - (let* ((input (minibuffer-contents)) - (path (substitute-in-file-name input)) - (dirlen (length (file-name-directory path))) - (prefixlen (car (completion--sifn-requote dirlen input))) - (prefix (substring input 0 prefixlen))) - (concat prefix candidate)))) - candidate)) - -(defun selectrum--get-candidate (index) - "Get candidate at given INDEX. Negative means get the current user input." - (if (and index (>= index 0)) - (nth index selectrum--refined-candidates) - (buffer-substring-no-properties - (minibuffer-prompt-end) - (point-max)))) - -(defun selectrum--get-meta (setting &optional table pred input) - "Get metadata SETTING from TABLE. -TABLE defaults to `minibuffer-completion-table'. -PRED defaults to `minibuffer-completion-predicate'. -INPUT defaults to current selectrum input string." - (let ((input (or input (minibuffer-contents))) - (pred (or pred minibuffer-completion-predicate)) - (table (or table minibuffer-completion-table))) - (when table - (completion-metadata-get - (completion-metadata input table pred) setting)))) - -(defun selectrum-exhibit (&optional keep-selection) - "Trigger an update of Selectrum's completion UI. -If KEEP-SELECTION is non-nil keep the current candidate selected -when possible (it is still a member of the candidate set)." - (when-let ((mini (active-minibuffer-window))) - (with-selected-window mini - (when (and minibuffer-completion-table - (not selectrum--dynamic-candidates)) - (setq-local selectrum--preprocessed-candidates nil)) - (setq-local selectrum--previous-input-string nil) - (selectrum--update - (and keep-selection - (selectrum-get-current-candidate)))))) - -;;; Hook functions - -(defun selectrum--count-info () - "Return a string of count information to be prepended to prompt." - (let ((total (length selectrum--refined-candidates)) - (current (1+ (or selectrum--current-candidate-index -1)))) - (pcase selectrum-count-style - ('matches (format "%-4d " total)) - ('current/matches (format "%-6s " (format "%d/%d" current total))) - (_ "")))) - -(defvar display-line-numbers) ; Undefined in Emacs 25. -(defun selectrum--get-display-window () - "Get candidate display window. - -Window will be created by `selectrum-display-action'." - (let ((buf (or (get-buffer selectrum--candidates-buffer) - (with-current-buffer - (get-buffer-create selectrum--candidates-buffer) - (setq cursor-type nil) - (setq-local cursor-in-non-selected-windows nil) - (setq display-line-numbers nil) - (setq buffer-undo-list t) - (setq buffer-read-only t) - (setq show-trailing-whitespace nil) - (goto-char (point-min)) - (current-buffer)))) - (action selectrum-display-action)) - (or (get-buffer-window buf 'visible) - (with-selected-window (minibuffer-selected-window) - (let* ((frame (selected-frame)) - (window (display-buffer buf action))) - (select-frame-set-input-focus frame) - window))))) - -(defun selectrum--expand-window-for-content-p (window) - "Return non-nil if WINDOW should be expanded. -This is the case when the height of WINDOW fits in the range as -determined by `selectrum--max-num-candidate-lines' and the -content height is greater than the window height." - (and (<= (window-body-height window) - (selectrum--max-num-candidate-lines window)) - (>= (cdr (window-text-pixel-size window)) - (window-body-height window 'pixelwise)))) - -(defun selectrum--vertical-display-style - (win cb nrows ncols - &optional index max-index first-index-displayed last-index-displayed - max-num - settings) - "Insert candidates vertically into current buffer. -Used as insertion function for `vertical' display style, see -`selectrum-display-style'. WIN is the window where buffer will -get displayed in. Callback CB returns the candidates to be -inserted. The callback has four arguments, the index position and -the number of candidates and optionally the third argument which -allows passing and annotation function. If given the function -receives three optional arguments: a prefix, suffix and a right -margin annotation of the currently selected candidate and should -take care of displaying them. The annotations display of others -candidates than the current is disabled in this case. The -optional forth argument of the callback should be non-nil if -candidates are supposed to be displayed horizontally. NROWS is -the number of lines available and NCOLS the number of available -columns. If there are candidates INDEX is the index of the -currently selected candidate and MAX-INDEX is the index of the -maximal index of the collection. When candidates are already -displayed FIRST-INDEX-DISPLAYED is the index of the candidate -that is displayed first and LAST-INDEX-DISPLAYED the index of the -last one and MAX-NUM if given specifies the maximal number of -candidates to be displayed, the callback won't return more -candidates than that anyway but the number can be useful if the -insertion function behaviour depends on the number of candidates -that get displayed. SETTINGS are a plist of additional settings -as specified in `selectrum-display-style', this function -currently doesn't have any." - (ignore ncols first-index-displayed last-index-displayed settings) - (let* ((rows (or max-num nrows)) - (first-index-displayed - (if (not index) - 0 - (selectrum--clamp - ;; Adding one here makes it look slightly better, as - ;; there are guaranteed to be more candidates shown - ;; below the selection than above. - (1+ (- index (max 1 (/ rows 2)))) - 0 - (max (- (1+ max-index) rows) - 0)))) - (displayed-candidates - (funcall cb first-index-displayed rows))) - (when (window-minibuffer-p win) - (insert "\n")) - (let ((n 0)) - (dolist (cand displayed-candidates) - (cl-incf n) - (insert cand "\n")) - n))) - -(defun selectrum--horizontal-display-style - (win cb nrows ncols - &optional index max-index first-index-displayed last-index-displayed - max-num - settings) - "Insert candidates horizontally into buffer BUF. -For BUF, WIN, CB, NROWS, NCOLS, INDEX, MAX-INDEX, -FIRST-INDEX-DISPLAYED, LAST-INDEX-DISPLAYED, MAX-NUM and SETTINGS -see `selectrum--vertical-display-style'. For known keys see -the `horizontal' description of `selectrum-display-style'." - (ignore nrows max-num) - (let* ((before-cands (or (plist-get settings :before-candidates) - "{")) - (prompt-sep (if (window-minibuffer-p win) - (or (plist-get settings :prompt-separator) - "") - "")) - (start (concat prompt-sep before-cands)) - (end (or (plist-get settings :after-candidates) - "}")) - (separator (or (plist-get settings :candidates-separator) - " | ")) - (more (or (plist-get settings :more-candidates) - (propertize "..." 'face 'shadow))) - (first-index-displayed - (cond ((or (not index) - (not first-index-displayed) - (not last-index-displayed)) - 0) - ((> index last-index-displayed) - (if (= index max-index) - max-index - (1+ last-index-displayed))) - ((< index first-index-displayed) - index) - (t - first-index-displayed))) - (cands - (funcall cb first-index-displayed - (floor ncols (1+ (length separator))) - #'ignore 'horizontal)) - (n 0) - (insert nil)) - (when cands - (let ((ncols ncols)) - (while (and cands (> ncols 0)) - (let ((cand (pop cands))) - (when (zerop n) - (setq ncols (- ncols (length start))) - (push start insert)) - (setq ncols (- ncols (length cand) (length separator))) - (when (or (zerop n) - (>= ncols 0)) - (put-text-property 0 (length cand) 'cand t cand) - (push cand insert) - (push separator insert) - (cl-incf n))))) - (if (= max-index (1- (+ first-index-displayed n))) - (progn - (pop insert) - (push end insert)) - (while (and insert - (not (= n 1)) - (or (not (equal (car insert) separator)) - (>= (+ (length (apply #'concat insert)) - (length more) - (length end)) - ncols))) - (when (get-text-property 0 'cand (car insert)) - (cl-decf n)) - (pop insert)) - (push more insert) - (push end insert)) - (setq insert (nreverse insert)) - (while insert - (insert (pop insert)))) - n)) - -(defun selectrum-cycle-display-style () - "Change current `selectrum-display-style'. -Cycles from current style through styles listed in -`selectrum-display-style-cycle-list'. With an active minibuffer -the display style is only changed for the current session. -Without that the global default value will be changed." - (interactive) - (let* ((miniw (active-minibuffer-window)) - (buf (if miniw - (window-buffer miniw) - (current-buffer)))) - (with-current-buffer buf - (when miniw - (make-local-variable 'selectrum-display-style-cycle-list) - (make-local-variable 'selectrum-display-style)) - (unless (eq last-command 'selectrum-cycle-display-style) - (setq selectrum-display-style-cycle-list - (cons selectrum-display-style - (delete selectrum-display-style - selectrum-display-style-cycle-list)))) - (setq selectrum-display-style-cycle-list - (append (cdr selectrum-display-style-cycle-list) - (list (car selectrum-display-style-cycle-list)))) - (setq selectrum-display-style - (car selectrum-display-style-cycle-list)) - (unless miniw - (message "Switched to %s" selectrum-display-style))))) - -(defun selectrum--insert-candidates - (insert-settings candidates buf win input plen - &optional index mindex findex num) - "Use INSERT-SETTINGS to insert CANDIDATES into BUF for display. -BUF is supposed to be displayed in window WIN. INPUT is the -current user input. PLEN is the prompt prefix length. INDEX -is the index of the currently selected candidate if any. MINDEX -is the maximum and FINDEX the first index. NUM is the number of -currently displayed candidates. Returns a cons: The car is -non-nil if candidates are supposed to be displayed horizontally -and the cdr is the number of candidates that were inserted." - (let* ((horizp nil) - (nlines (selectrum--max-num-candidate-lines win)) - (ncols (if (window-minibuffer-p win) - (- (window-body-width win) - (- (point-max) - (window-hscroll win)) - plen) - (window-body-width win))) - (ncands (when (numberp selectrum-num-candidates-displayed) - selectrum-num-candidates-displayed)) - (insert-variant (car insert-settings)) - (insert-fun (cond ((eq insert-variant 'horizontal) - #'selectrum--horizontal-display-style) - (t - #'selectrum--vertical-display-style))) - (settings - (cdr insert-settings)) - (cb (lambda (first-index-displayed - ncands &optional annot-fun horizontalp) - (with-current-buffer (window-buffer (active-minibuffer-window)) - (setq-local selectrum--first-index-displayed - first-index-displayed) - (setq horizp horizontalp) - (selectrum--candidates-display-strings - (funcall - selectrum-highlight-candidates-function - input - (seq-take - (nthcdr - first-index-displayed - candidates) - ;; Never allow more candidates than configured. - (if (numberp selectrum-num-candidates-displayed) - selectrum-num-candidates-displayed - ncands))) - (when (and first-index-displayed index) - (- index first-index-displayed)) - annot-fun horizontalp)))) - (lindex (when (and findex num) - (+ findex - (max 0 (1- num))))) - (n (with-current-buffer buf - (funcall insert-fun win cb - nlines ncols index mindex findex lindex - ncands settings)))) - (cons horizp - (if (or (not index) (not findex) - (>= (+ findex n) index)) - n - ;; When the insertion function was switched the current index - ;; might be out of sight in this case reinsert with the current - ;; index displayed as the first one. - (with-current-buffer buf - (erase-buffer) - (funcall insert-fun win cb - nlines ncols index mindex index lindex - ncands settings)))))) - -(defun selectrum--at-existing-prompt-path-p () - "Return non-nil when current file prompt exists." - (and minibuffer-completing-file-name - (file-exists-p - (substitute-in-file-name (minibuffer-contents))))) - -(defun selectrum--minibuffer-post-command-hook () - "Update minibuffer in response to user input." - (selectrum--update)) - -(defun selectrum--max-window-height (&optional frame max) - "Return maximal window height for frame. -The height is determined by the `frame-height' of FRAME which -defaults to the current one and MAX which defaults to -`selectrum-max-window-height' and falls back to -`max-mini-window-height' if the former is unset." - (let* ((max (or max - selectrum-max-window-height - max-mini-window-height - 0)) - (fh (frame-height - (or frame - (window-frame (minibuffer-selected-window)))))) - (if (floatp max) - (round (* fh max)) - max))) - -(defun selectrum--max-num-candidate-lines (window) - "Return maximum number of lines to use for display in WINDOW." - (let ((n (selectrum--max-window-height))) - (if selectrum-display-action - (max (window-body-height window) n) - n))) - -(defun selectrum--update (&optional keep-selected) - "Update state. -KEEP-SELECTED can be a candidate which should stay selected after -the update." - (unless selectrum--should-skip-updates - ;; Stay within input area. - (goto-char (max (point) (minibuffer-prompt-end))) - ;; Scroll the minibuffer when current prompt exceeds window width. - (let* ((width (window-width))) - (if (< (point) (- width (/ width 3))) - (set-window-hscroll nil 0) - (set-window-hscroll nil (- (point) (/ width 3))))) - ;; For some reason this resets and thus can't be set in setup hook. - (setq-local truncate-lines t) - (let ((inhibit-read-only t) - ;; Don't record undo information while messing with the - ;; minibuffer, as per - ;; <https://github.com/raxod502/selectrum/issues/31>. - (buffer-undo-list t) - (input (buffer-substring (minibuffer-prompt-end) - (point-max))) - (keep-mark-active (not deactivate-mark))) - (unless (equal input selectrum--previous-input-string) - ;; Track current input globally and in last buffer for - ;; selectrum-repeat. - (setq-default selectrum--last-input input) - (when (buffer-live-p selectrum--last-buffer) - (with-current-buffer selectrum--last-buffer - (setq-local selectrum--last-input input))) - (setq-local selectrum--previous-input-string input) - ;; Reset the persistent input, so that it will be nil if - ;; there's no special attention needed. - (setq-local selectrum--visual-input nil) - (let ((dynamic (functionp selectrum--dynamic-candidates)) - (init-table (and (not selectrum--preprocessed-candidates) - minibuffer-completion-table))) - ;; Compute `selectrum--preprocessed-candidates' if necessary. - (when (or dynamic init-table) - (setq-local - selectrum--preprocessed-candidates - (cond (dynamic - (let* ((result - ;; Ensure dynamic functions won't - ;; break in post command hook. - (condition-case-unless-debug err - (funcall - selectrum--dynamic-candidates - input) - (error (message (error-message-string err)) - nil))) - (cands - ;; Avoid modifying the returned - ;; candidates to let the function - ;; reuse them. - (copy-sequence - (if (stringp (car result)) - result - (setq input (or (alist-get 'input result) - input)) - (setq-local selectrum--visual-input input) - (alist-get 'candidates result))))) - (funcall selectrum-preprocess-candidates-function - cands))) - (init-table - ;; No candidates were passed, initialize them - ;; from `minibuffer-completion-table'. - (funcall selectrum-preprocess-candidates-function - (selectrum--normalize-collection - minibuffer-completion-table - minibuffer-completion-predicate))))) - (setq-local selectrum--total-num-candidates - (length selectrum--preprocessed-candidates)))) - ;; Do refinement. - (let* ((cands selectrum--preprocessed-candidates) - (completion-styles-alist - ;; Remap partial-style for file completions - ;; computed from partial input. - (if (and cands - (get-text-property - 0 'selectrum--partial (car cands))) - (cons '(partial-completion - ignore - selectrum--completion-pcm-all-completions "") - completion-styles-alist) - completion-styles-alist))) - (setq-local selectrum--refined-candidates - (funcall selectrum-refine-candidates-function - input cands))) - (when selectrum--virtual-default-file - (setq-local selectrum--refined-candidates - (cons (propertize - selectrum--virtual-default-file - 'face 'shadow) - selectrum--refined-candidates)) - (setq-local selectrum--virtual-default-file nil)) - (when (and selectrum-move-default-candidate - selectrum--default-candidate) - (setq-local selectrum--refined-candidates - (selectrum--move-to-front-destructive - selectrum--default-candidate - selectrum--refined-candidates))) - (setq-local selectrum--refined-candidates - (selectrum--move-to-front-destructive - ;; Make sure matching dirnames are sorted first. - (if (and minibuffer-completing-file-name - (member (file-name-as-directory input) - selectrum--refined-candidates)) - (file-name-as-directory input) - input) - selectrum--refined-candidates)) - (setq-local selectrum--refined-candidates - (delete "" selectrum--refined-candidates)) - (setq-local selectrum--first-index-displayed nil) - (setq-local selectrum--actual-num-candidates-displayed nil) - (if selectrum--repeat - (progn - (setq-local - selectrum--current-candidate-index - (and (> (length selectrum--refined-candidates) 0) - (min (or selectrum--current-candidate-index 0) - (1- (length selectrum--refined-candidates))))) - (setq-local selectrum--repeat nil)) - (setq-local selectrum--current-candidate-index - (cond - ;; Check for candidates needs to be first! - ((null selectrum--refined-candidates) - (when (or (not selectrum--match-is-required) - (selectrum--at-existing-prompt-path-p)) - -1)) - (keep-selected - (or (cl-position keep-selected - selectrum--refined-candidates - :key #'selectrum--get-full - :test #'equal) - 0)) - ((and selectrum--default-candidate - (string-empty-p (minibuffer-contents)) - (not (member selectrum--default-candidate - selectrum--refined-candidates))) - -1) - ((or (and selectrum--is-initializing - (equal selectrum--default-candidate - (minibuffer-contents))) - (and (not (= (minibuffer-prompt-end) (point-max))) - (or (and minibuffer-history-position - (not (zerop - minibuffer-history-position)) - isearch-mode) - (memq this-command - '(next-history-element - previous-history-element))) - (or (not selectrum--match-is-required) - (selectrum--at-existing-prompt-path-p)))) - -1) - (selectrum-move-default-candidate - 0) - (t - (or (cl-position selectrum--default-candidate - selectrum--refined-candidates - :key #'selectrum--get-full - :test #'equal) - 0)))))) - ;; Always keep the visual input if defined. - (setq input (or selectrum--visual-input input)) - ;; Handle prompt selection. - (if (and selectrum--current-candidate-index - (< selectrum--current-candidate-index 0)) - (add-text-properties - (minibuffer-prompt-end) (point-max) - '(face selectrum-current-candidate)) - (remove-text-properties - (minibuffer-prompt-end) (point-max) - '(face selectrum-current-candidate))) - (let* ((count-info (selectrum--count-info)) - (window (if selectrum-display-action - (and selectrum--refined-candidates - (selectrum--get-display-window)) - (active-minibuffer-window))) - (buffer (with-current-buffer - (get-buffer-create selectrum--candidates-buffer) - (erase-buffer) - (current-buffer))) - (default - (when (and selectrum-default-value-format - (= (minibuffer-prompt-end) (point-max)) - (or - (and selectrum--current-candidate-index - (< selectrum--current-candidate-index 0)) - (and (not selectrum--match-is-required) - (not selectrum--refined-candidates)) - (and selectrum--default-candidate - (not minibuffer-completing-file-name) - (not (member selectrum--default-candidate - selectrum--refined-candidates))))) - (format (propertize selectrum-default-value-format - 'face 'minibuffer-prompt) - (propertize - (or selectrum--default-candidate "\"\"") - 'face - (if (and selectrum--current-candidate-index - (< selectrum--current-candidate-index - 0)) - 'selectrum-current-candidate - 'minibuffer-prompt))))) - (minibuf-after-string (or default " ")) - (inserted-res - (selectrum--insert-candidates - selectrum-display-style - selectrum--refined-candidates - buffer - window - input - ;; FIXME: This only takes our count overlay into - ;; account there might be other overlays prefixing the - ;; prompt. - (length count-info) - ;; Exclude selected prompt. - (when (and selectrum--current-candidate-index - (not (< selectrum--current-candidate-index 0))) - selectrum--current-candidate-index) - (1- (length selectrum--refined-candidates)) - selectrum--first-index-displayed - selectrum--actual-num-candidates-displayed)) - (horizp (car inserted-res)) - (inserted-num (cdr inserted-res))) - (setq-local selectrum--actual-num-candidates-displayed inserted-num) - ;; Add padding for scrolled prompt. - (when (and (window-minibuffer-p window) - (not horizp) - (not (zerop (window-hscroll window)))) - (let ((padding (make-string (window-hscroll window) ?\s))) - (with-current-buffer buffer - (goto-char (point-min)) - (while (not (eobp)) - (insert padding) - (forward-line 1))))) - (unless (or selectrum-display-action - (zerop selectrum--actual-num-candidates-displayed) - (not selectrum--refined-candidates)) - (setq minibuf-after-string - (concat minibuf-after-string - (with-current-buffer buffer - (buffer-string))))) - (move-overlay selectrum--candidates-overlay - (point-max) (point-max)) - (put-text-property 0 1 'cursor t minibuf-after-string) - (overlay-put selectrum--candidates-overlay - 'after-string minibuf-after-string) - (overlay-put selectrum--count-overlay - 'before-string count-info) - (overlay-put selectrum--count-overlay - 'priority 1) - (when window - (selectrum--update-window-height - window (not horizp))) - (when keep-mark-active - (setq deactivate-mark nil)) - (setq-local selectrum--is-initializing nil))))) - -(defun selectrum--update-window-height (window vertical) - "Update window height of WINDOW. -WINDOW is the display window of current candidates and will be -updated to fit its content. If VERTICAL is non-nil the content of -window is supposed to be shown vertically." - (cond ((frame-root-window-p window)) - ((not vertical) - (when (or (window-minibuffer-p window) - (and (window-at-side-p window 'bottom) - (not (window-at-side-p window 'top)))) - (set-window-text-height window 1))) - ((and vertical selectrum-fix-vertical-window-height) - (let* ((max (selectrum--max-window-height)) - (lines (if selectrum-display-action - max - ;; Add one for prompt. - (1+ max))) - ;; Include possible line spacing. - (height (* lines selectrum--line-height))) - (selectrum--set-window-height window height))) - (t - (when-let ((expand (selectrum--expand-window-for-content-p window))) - (cond (selectrum-display-action - (selectrum--fit-window-to-buffer window)) - (t - (selectrum--set-window-height window))))))) - -(defun selectrum--fit-window-to-buffer (window) - "Fit window height to its buffer contents. -Also works for frames if WINDOW is the root window of its frame." - (let ((window-resize-pixelwise t) - (window-size-fixed nil) - (fit-frame-to-buffer 'vertically) - (fit-window-to-buffer-horizontally nil)) - (fit-window-to-buffer window nil 1))) - -(defun selectrum--set-window-height (window &optional height) - "Set window height of WINDOW to HEIGHT pixel. -If HEIGHT is not given WINDOW will be updated to fit its content -vertically." - (let ((dheight (or height (cdr (window-text-pixel-size window)))) - (wheight (window-pixel-height window)) - (window-resize-pixelwise t)) - (window-resize - window (- dheight wheight) nil nil 'pixelwise))) - -(defun selectrum--ensure-single-lines (candidates settings) - "Return list of single-line CANDIDATES. - -Multi-line candidates are merged into a single line. The -resulting single-line candidates are then shortened by replacing -repeated whitespace and maybe truncating the result. - -The specific details of the formatting are determined by -SETTINGS, see `selectrum-multiline-display-settings'." - (let* ((single/lines ()) - - ;; The formatting settings are the same for all multi-line - ;; candidates, and so only need to be gotten once from - ;; `settings'. - ;; - ;; - Matching lines - (match/transformation - (alist-get 'match settings)) - (match/display (car match/transformation)) - (match/face (cadr match/transformation)) - ;; - Truncated candidate - (truncation/transformation - (alist-get 'truncation settings)) - (truncation/display (car truncation/transformation)) - (truncation/face (cadr truncation/transformation)) - ;; - Newlines - (newline/transformation - (alist-get 'newline settings)) - (newline/display (car newline/transformation)) - (newline/face (cadr newline/transformation)) - ;; - Repeated whitespace - (whitespace/transformation - (alist-get 'whitespace settings)) - (whitespace/display (car whitespace/transformation)) - (whitespace/face (cadr whitespace/transformation)) - ;; - Line count - (nline/info - (alist-get 'line-count settings)) - (nlines/display (car nline/info)) - (nlines/face (cdr nline/info))) - - (dolist (cand candidates (nreverse single/lines)) - (let ((line - (if (not (string-match-p "\n" cand)) - cand - (let* ((lines (split-string cand "\n")) - (len (length lines)) - (input (minibuffer-contents)) - (first-line (with-temp-buffer - (insert cand) - (goto-char (point-min)) - (skip-chars-forward " \t\n") - (buffer-substring - (line-beginning-position) - (line-end-position)))) - (matches (delete - first-line - (if (string-empty-p input) - lines - (funcall - selectrum-highlight-candidates-function - input - (funcall - selectrum-refine-candidates-function - input - lines))))) - (nlines (unless (string-empty-p nlines/display) - (propertize (format nlines/display len) - 'face nlines/face))) - (truncated-first-line - (replace-regexp-in-string - "[ \t][ \t]+" - (propertize whitespace/display - 'face whitespace/face) - first-line 'fixed-case 'literal)) - (shortened-line - (if (< (length truncated-first-line) 78) - truncated-first-line - (substring truncated-first-line 0 78))) - (concated-matches - (mapconcat #'identity matches - (propertize newline/display - 'face newline/face))) - (truncated-matches - (replace-regexp-in-string - "[ \t][ \t]+" - (propertize whitespace/display - 'face whitespace/face) - concated-matches - 'fixed-case 'literal)) - (shortened-matches - (if (< (length truncated-matches) 1000) - truncated-matches - (concat - (substring truncated-matches 0 1000) - (propertize truncation/display - 'face truncation/face)))) - (line (concat shortened-line - (propertize truncation/display - 'face truncation/face) - nlines - (unless (string-empty-p shortened-matches) - (propertize match/display - 'face match/face)) - shortened-matches))) - line)))) - (push line single/lines))))) - -(defun selectrum--annotation (fun cand face) - "Return annotation for candidate. -Get annotation by calling FUN with CAND and apply FACE to it if -CAND does not have any face property defined." - (when-let ((str (funcall fun cand))) - (if (text-property-not-all 0 (length str) 'face nil str) - str - (propertize str 'face face)))) - -(cl-defun selectrum--annotate (cands &key annotf docsigf) - "Transform CANDS using ANNOTF and DOCSIGF. -ANNOTF results will annotate a candidate with a suffix using -`selectrum-candidate-display-suffix' and -`selectrum-completion-annotation' face unless the annotation -already has a face property. DOCSIGF results will annotate a -candidate with a margin annotation using -`selectrum-candidate-display-suffix' and -`selectrum-completion-docsig' face unless the annotation already -has a face property." - (let ((res ())) - (dolist (cand cands (nreverse res)) - (let* ((annot (when annotf - (selectrum--annotation - annotf - cand - 'selectrum-completion-annotation))) - (docsig (when docsigf - (selectrum--annotation - docsigf - cand - 'selectrum-completion-docsig))) - (new (if (or annot docsig) - (apply #'propertize - cand - `(,@(when annot - (list - 'selectrum-candidate-display-suffix - annot)) - ,@(when docsig - (list - 'selectrum-candidate-display-right-margin - docsig)))) - cand))) - (push new res))))) - -(defun selectrum--display-string (str) - "Return display string of STR. -Any string display specs in STR are replaced with the string they -will display as. This avoids prompt bleeding issues that occur -with display specs used within the after-string overlay." - (let ((len (length str)) - (pos 0) - (chunks ())) - (while (not (eq pos len)) - (let* ((end (next-single-property-change pos 'display str len)) - (display (get-text-property pos 'display str)) - (chunk (if (stringp display) - display - (substring str pos end)))) - (push chunk chunks) - (setq pos end))) - (apply #'concat (nreverse chunks)))) - -(defun selectrum--selection-highlight (str) - "Return copy of STR with selection highlight." - ;; Avoid trampling highlighting done by - ;; `selectrum-highlight-candidates-function'. In - ;; Emacs<27 `add-face-text-property' has a bug but - ;; in Emacs>=27 `font-lock-prepend-text-property' - ;; doesn't work. Even though these functions are - ;; both supposed to do the same thing. - ;; - ;; Anyway, no need to clean up the text properties - ;; afterwards, as an update will cause all these - ;; strings to be thrown away and re-generated from - ;; scratch. - ;; - ;; See: - ;; <https://github.com/raxod502/selectrum/issues/21> - ;; <https://github.com/raxod502/selectrum/issues/58> - ;; <https://github.com/raxod502/selectrum/pull/76> - (let ((str (copy-sequence str)) - (face 'selectrum-current-candidate)) - (if (version< emacs-version "27") - (font-lock-prepend-text-property - 0 (length str) - 'face face str) - (add-face-text-property - 0 (length str) - face - 'append str)) - str)) - -(defun selectrum--affixate (fun candidates) - "Use affixation FUN to transform CANDIDATES. -FUN takes CANDIDATES as argument and returns a list of strings or -a list of list items. In case of a string no annotations are -added and the string is the one to use for completion. In case of -a list the first item is the completion string. If the list has -two items the second one is used as a suffix and if there are -three items the second one is used as a prefix and the third as -suffix." - (let ((items (funcall fun candidates)) - (res ())) - (dolist (item items (nreverse res)) - (push (if (stringp item) - item - ;; See `completion--insert-strings'. - (let ((prefix (when (nth 2 item) (nth 1 item))) - (suffix (or (nth 2 item) (nth 1 item)))) - (apply #'propertize - (nth 0 item) - `(,@(when prefix - (list 'selectrum-candidate-display-prefix - prefix)) - ,@(when suffix - (list 'selectrum-candidate-display-suffix - suffix)))))) - res)))) - -(defun selectrum--candidates-display-strings (candidates - highlighted-index - annot-fun - horizontalp - &optional table pred props) - "Get display strings for CANDIDATES. -HIGHLIGHTED-INDEX is the currently selected index. If ANNOT-FUN -is non-nil don't add any annotations but call the function with -the annotations of the currently highlighted candidate. If -HORIZONTALP is non-nil candidates are supposed to be displayed -horizontally. TABLE defaults to `minibuffer-completion-table'. -PRED defaults to `minibuffer-completion-predicate'. PROPS -defaults to `completion-extra-properties'." - (let* ((index 0) - (props (or props completion-extra-properties)) - (annotf (or (selectrum--get-meta 'annotation-function table pred) - (plist-get props :annotation-function))) - (aff (or (selectrum--get-meta 'affixation-function table pred) - (plist-get props :affixation-function))) - (docsigf (plist-get props :company-docsig)) - (candidates (cond (aff - (selectrum--affixate aff candidates)) - ((or annotf docsigf) - (selectrum--annotate candidates - :annotf annotf - :docsigf docsigf)) - (t candidates))) - (extend (and (not horizontalp) - (if (eq selectrum-extend-current-candidate-highlight - 'auto) - (or aff annotf docsigf) - selectrum-extend-current-candidate-highlight))) - (show-indices selectrum-show-indices) - (margin-padding selectrum-right-margin-padding) - (lines (selectrum--ensure-single-lines - candidates - selectrum-multiline-display-settings))) - (with-temp-buffer - (dolist (candidate lines) - (let* ((prefix (get-text-property - 0 'selectrum-candidate-display-prefix - candidate)) - (suffix (get-text-property - 0 'selectrum-candidate-display-suffix - candidate)) - (right-margin (get-text-property - 0 'selectrum-candidate-display-right-margin - candidate)) - (displayed-candidate - (selectrum--display-string - (if annot-fun - candidate - (concat prefix candidate suffix)))) - (formatting-current-candidate - (equal index highlighted-index))) - ;; Add the ability to interact with candidates via the mouse. - (add-text-properties - 0 (length displayed-candidate) - (list - 'mouse-face 'highlight - ;; 'help-echo - ;; "mouse-1: select candidate\nmouse-3: insert candidate" - 'keymap - (let ((keymap (make-sparse-keymap))) - (define-key keymap [mouse-1] - `(lambda () - (interactive) - (selectrum-select-current-candidate ,(1+ index)))) - (define-key keymap [mouse-3] - `(lambda () - (interactive) - (selectrum-insert-current-candidate ,(1+ index)))) - keymap)) - displayed-candidate) - (when formatting-current-candidate - (setq displayed-candidate - (selectrum--selection-highlight displayed-candidate)) - (when annot-fun - (funcall annot-fun prefix suffix right-margin))) - (insert "\n") - (when show-indices - (let* ((display-fn (if (functionp show-indices) - show-indices - (lambda (i) (format "%2d " i)))) - (curr-index (substring-no-properties - (funcall display-fn (1+ index))))) - (insert - (propertize curr-index 'face 'minibuffer-prompt)))) - (insert displayed-candidate) - (cond - ((and right-margin (not annot-fun)) - (insert - (concat - (propertize - " " - 'face - (when formatting-current-candidate - 'selectrum-current-candidate) - 'display - `(space :align-to (- right-fringe - ,(string-width right-margin) - ,margin-padding))) - (if formatting-current-candidate - (selectrum--selection-highlight right-margin) - right-margin)))) - ((and extend - formatting-current-candidate) - (insert - (propertize - " " - 'face 'selectrum-current-candidate - 'display - `(space :align-to (- right-fringe - ,margin-padding))))))) - (cl-incf index)) - (split-string (buffer-string) "\n" t)))) - -(defun selectrum--minibuffer-setup-hook (candidates default buf) - "Set up minibuffer for interactive candidate selection. -CANDIDATES is the list of candidate strings. DEFAULT is the default -value which can be overridden and BUF the buffer the session was -started from." - (setq-local selectrum--last-buffer buf) - (cond (selectrum--repeat - (delete-minibuffer-contents) - (insert - (with-current-buffer - (or (and (buffer-live-p selectrum--last-buffer) - selectrum--last-buffer) - (current-buffer)) - (or selectrum--last-input "")))) - (t - ;; Track globally and in last buffer. - (setq-default selectrum--last-command this-command) - (setq-default selectrum--last-prefix-arg current-prefix-arg) - (when (buffer-live-p selectrum--last-buffer) - (with-current-buffer selectrum--last-buffer - (setq-local selectrum--last-command this-command) - (setq-local selectrum--last-prefix-arg current-prefix-arg))))) - (setq-local auto-hscroll-mode nil) - (setq-local selectrum--is-initializing t) - (setq-local selectrum--candidates-overlay - (make-overlay (point) (point) nil - 'front-advance 'rear-advance)) - (setq-local selectrum--count-overlay - (make-overlay (point-min) (point-min))) - ;; If metadata specifies a custom sort function use it as - ;; `selectrum-preprocess-candidates-function' for this session. - (when-let ((sortf (selectrum--get-meta 'display-sort-function))) - (setq-local selectrum-preprocess-candidates-function sortf)) - (cond ((functionp candidates) - (setq-local selectrum--preprocessed-candidates nil) - (setq-local selectrum--total-num-candidates 0) - (setq-local selectrum--dynamic-candidates candidates)) - (t - (setq-local selectrum--preprocessed-candidates - (funcall selectrum-preprocess-candidates-function - candidates)) - (setq-local selectrum--total-num-candidates (length candidates)))) - (setq-local selectrum--default-candidate - (if (and default (symbolp default)) - (symbol-name default) - default)) - (setq-default selectrum--default-candidate - selectrum--default-candidate) - ;; Make sure to trigger an "user input changed" event, so that - ;; candidate refinement happens in `post-command-hook' and an index - ;; is assigned. - (setq-local selectrum--previous-input-string nil) - (setq-local selectrum--line-height (line-pixel-height)) - (add-hook - 'post-command-hook - #'selectrum--minibuffer-post-command-hook - nil 'local)) - -;;; Minibuffer commands - -(defun selectrum-previous-candidate (&optional arg) - "Move selection ARG candidates up, stopping at the beginning." - (interactive "p") - (selectrum-next-candidate (- (or arg 1)))) - -(defun selectrum-next-candidate (&optional arg) - "Move selection ARG candidates down, stopping at the end." - (interactive "p") - (when selectrum--current-candidate-index - (setq selectrum--current-candidate-index - (selectrum--clamp - (+ selectrum--current-candidate-index (or arg 1)) - (if (and selectrum--match-is-required - (cond (minibuffer-completing-file-name - (not (selectrum--at-existing-prompt-path-p))) - (t - (not (string-empty-p - (minibuffer-contents)))))) - 0 - -1) - (1- (length selectrum--refined-candidates)))))) - -(defun selectrum-previous-page (&optional arg) - "Move selection upwards by ARG pages, stopping at the beginning." - (interactive "p") - (selectrum-next-page (- (or arg 1)))) - -(defun selectrum-next-page (&optional arg) - "Move selection downwards by ARG pages, stopping at the end." - (interactive "p") - (when selectrum--current-candidate-index - (setq-local selectrum--current-candidate-index - (selectrum--clamp - (+ selectrum--current-candidate-index - (* (or arg 1) selectrum--actual-num-candidates-displayed)) - 0 - (1- (length selectrum--refined-candidates)))))) - -(defun selectrum-goto-beginning () - "Move selection to first candidate." - (interactive) - (when selectrum--current-candidate-index - (setq-local selectrum--current-candidate-index 0))) - -(defun selectrum-goto-end () - "Move selection to last candidate." - (interactive) - (when selectrum--current-candidate-index - (setq-local selectrum--current-candidate-index - (1- (length selectrum--refined-candidates))))) - -(defun selectrum-kill-ring-save () - "Save current candidate to kill ring. -Or if there is an active region, save the region to kill ring." - (interactive) - (if (or (use-region-p) (not transient-mark-mode)) - (call-interactively #'kill-ring-save) - (when selectrum--current-candidate-index - (kill-new - (selectrum-get-current-candidate))))) - -(defun selectrum--exit-with (candidate) - "Exit minibuffer with given CANDIDATE. -If `selectrum--is-crm-session' is non-nil exit with the choosen candidates -plus CANDIDATE." - (let* ((result (cond ((and selectrum--is-crm-session - (string-match crm-separator - selectrum--previous-input-string)) - (let ((crm - (if (and selectrum--current-candidate-index - (< selectrum--current-candidate-index - 0)) - candidate - (with-temp-buffer - (insert selectrum--previous-input-string) - (goto-char (point-min)) - (while (re-search-forward - crm-separator nil t)) - (delete-region (point) (point-max)) - (insert (selectrum--get-full candidate)) - (buffer-string))))) - (dolist (cand (split-string crm crm-separator t)) - (apply #'run-hook-with-args - 'selectrum-candidate-selected-hook - (selectrum--get-full cand) - selectrum--read-args)) - crm)) - (t - (apply #'run-hook-with-args - 'selectrum-candidate-selected-hook - candidate - selectrum--read-args) - (selectrum--get-full candidate)))) - (inhibit-read-only t)) - (erase-buffer) - (insert (if (string-empty-p result) - (or selectrum--default-candidate result) - result)) - (exit-minibuffer))) - -(defun selectrum--index-for-arg (arg) - "Get candidate index for interactive argument ARG. -This is a helper function for commands which allow choosing a -candidate via prefix argument." - (if arg - (min - (+ (prefix-numeric-value arg) - (1- selectrum--first-index-displayed)) - (1- (length selectrum--refined-candidates))) - selectrum--current-candidate-index)) - -(defun selectrum-select-current-candidate (&optional arg) - "Exit minibuffer, picking the currently selected candidate. -If there are no candidates, return the current user input, unless -a match is required, in which case do nothing. - -Give a prefix argument ARG to select the nth displayed candidate. -Zero means to select the current user input. See -`selectrum-show-indices' which can be used to show candidate -indices." - (interactive "P") - (unless selectrum-is-active - (user-error "Cannot select a candidate when Selectrum is not active")) - (with-selected-window (active-minibuffer-window) - (let ((index (selectrum--index-for-arg arg))) - (if (or (not selectrum--match-is-required) - (string-empty-p - (minibuffer-contents)) - (and index (>= index 0)) - (if minibuffer-completing-file-name - (selectrum--at-existing-prompt-path-p) - (member (minibuffer-contents) - selectrum--refined-candidates))) - (selectrum--exit-with - (selectrum--get-candidate index)) - (minibuffer-message - (propertize "Match required" 'face 'minibuffer-prompt)))))) - -(defun selectrum-submit-exact-input () - "Exit minibuffer, using the current user input. -This differs from `selectrum-select-current-candidate' in that it -ignores the currently selected candidate, if one exists." - (interactive) - (let ((selectrum--current-candidate-index -1)) - (selectrum-select-current-candidate))) - -(defun selectrum--reset-minibuffer-history-state () - "Reset history for current prompt." - (setq-local minibuffer-history-position 0) - (setq-local minibuffer-text-before-history - (minibuffer-contents-no-properties))) - -(defun selectrum-insert-current-candidate (&optional arg) - "Insert current candidate into user input area. - -Give a prefix argument ARG to select the nth displayed candidate. -Zero means to select the current user input. See -`selectrum-show-indices' which can be used to show candidate -indices. When the prompt is selected this command triggers a -refresh." - (interactive "P") - (with-selected-window (active-minibuffer-window) - (if-let ((index (selectrum--index-for-arg arg)) - (candidate (selectrum--get-candidate index)) - (full (selectrum--get-full candidate))) - (progn - (if (and selectrum--current-candidate-index - (< selectrum--current-candidate-index 0)) - (if (and (= (minibuffer-prompt-end) (point-max)) - selectrum--default-candidate) - (insert selectrum--default-candidate) - (goto-char (point-max))) - (cond ((not selectrum--is-crm-session) - (delete-region (minibuffer-prompt-end) - (point-max)) - (insert full)) - (t - (goto-char - (if (re-search-backward crm-separator - (minibuffer-prompt-end) t) - (match-end 0) - (minibuffer-prompt-end))) - (delete-region (point) (point-max)) - (insert full) - (when-let ((match - (assoc crm-separator - selectrum--crm-separator-alist))) - (insert (cdr match))))) - (apply #'run-hook-with-args - 'selectrum-candidate-inserted-hook - candidate - selectrum--read-args)) - ;; Ensure refresh of UI. The input input string might be the - ;; same when the prompt was reinserted. When the prompt was - ;; selected this will switch selection to first candidate. - (setq-local selectrum--previous-input-string nil) - (when minibuffer-completing-file-name - ;; Possibly force a refresh for files. - (setq-local selectrum--inserted-file-completion t)) - (when minibuffer-history-position - (selectrum--reset-minibuffer-history-state))) - (unless completion-fail-discreetly - (ding) - (minibuffer-message "No match"))))) - -;;;###autoload -(defun selectrum-select-from-history () - "Submit or insert candidate from minibuffer history. -To insert the history item into the previous session use the -binding for `selectrum-insert-current-candidate'. To submit the -history item and exit use `selectrum-select-current-candidate'." - (interactive) - (unless (minibufferp) - (user-error "Command can only be used in minibuffer")) - (let ((history (symbol-value minibuffer-history-variable))) - (when (eq history t) - (user-error "No history is recorded for this command")) - (let* ((enable-recursive-minibuffers t) - (result - (selectrum--minibuffer-with-setup-hook - (lambda () - (setq-local selectrum-should-sort nil) - (setq-local selectrum-candidate-inserted-hook nil) - (setq-local selectrum-candidate-selected-hook nil) - (use-local-map - (make-composed-keymap nil (current-local-map))) - (define-key (current-local-map) - [remap selectrum-insert-current-candidate] - 'selectrum--insert-history) - (let ((inhibit-read-only t)) - (goto-char (or (search-backward ":" nil t) - (1- (minibuffer-prompt-end)))) - (insert - (apply - #'propertize - " [history]" - (text-properties-at (point)))))) - (catch 'selectrum-insert-action - (completing-read - (minibuffer-prompt) history nil t nil t))))) - (if (get-text-property 0 'selectum--insert result) - (progn - (delete-minibuffer-contents) - (insert result) - (selectrum--reset-minibuffer-history-state)) - (if (and selectrum--match-is-required - (not (member result selectrum--refined-candidates))) - (user-error "That history element is not one of the candidates") - (selectrum--exit-with result)))))) - -(defun selectrum--insert-history () - "Insert history item. -Only to be used from `selectrum-select-from-history'" - (interactive) - (throw 'selectrum-insert-action - (propertize (selectrum-get-current-candidate 'notfull) - 'selectum--insert t))) - -;;; Main entry points - -(cl-defun selectrum--read - (prompt candidates &rest args &key - default-candidate initial-input require-match - history no-move-default-candidate - may-modify-candidates - minibuffer-completion-table - minibuffer-completion-predicate) - "Prompt user with PROMPT to select one of CANDIDATES. -Return the selected string. - -CANDIDATES is a list of strings or a function to dynamically -generate them. If CANDIDATES is a function, then it receives one -argument, the current user input, and returns the list of -strings. If CANDIDATES are nil the candidates will be computed -from MINIBUFFER-COMPLETION-TABLE. - -Instead of a list of strings, the function may alternatively -return an alist with the following keys: -- `candidates': list of strings, as above. -- `input' (optional): transformed user input, used for - highlighting (see `selectrum-highlight-candidates-function'). - -PROMPT should generally end in a colon and space. Additional -keyword ARGS are accepted. - -DEFAULT-CANDIDATE, if provided, is sorted first in the list if -it's present. - -INITIAL-INPUT, if provided, is inserted into the user input area -initially (with point at the end). - -REQUIRE-MATCH, if non-nil, means the user must select one of the -listed candidates (so, for example, -\\[selectrum-submit-exact-input] has no effect). - -HISTORY is the `minibuffer-history-variable' to use (by default -`minibuffer-history'). - -NO-MOVE-DEFAULT-CANDIDATE, if non-nil, means that the default -candidate is not sorted first. Instead, it is left at its -original position in the candidate list. However, it is still -selected initially. This is handy for `switch-to-buffer' and -friends, for which getting the candidate list out of order at all -is very confusing. - -MAY-MODIFY-CANDIDATES, if non-nil, means that Selectrum is -allowed to modify the CANDIDATES list destructively. Otherwise a -copy is made. - -For MINIBUFFER-COMPLETION-TABLE and -MINIBUFFER-COMPLETION-PREDICATE see `minibuffer-completion-table' -and `minibuffer-completion-predicate'. They are used for internal -purposes and compatibility to Emacs completion API. By passing -these as keyword arguments they will be dynamically bound as per -semantics of `cl-defun'." - (unless (or may-modify-candidates - (functionp candidates)) - (setq candidates (copy-sequence candidates))) - (let* ((minibuffer-allow-text-properties t) - (resize-mini-windows 'grow-only) - (prompt (selectrum--remove-default-from-prompt prompt)) - ;; <https://github.com/raxod502/selectrum/issues/99> - (icomplete-mode nil) - (buf (current-buffer)) - (res - (selectrum--minibuffer-with-setup-hook - (lambda () - ;; Already set the active flag as early as possible - ;; so client setup hooks can use it to detect if - ;; they are running in a Selectrum session. - (setq-local selectrum-is-active t)) - (selectrum--minibuffer-with-setup-hook - (:append (lambda () - (setq-local selectrum--read-args - (cl-list* prompt candidates args)) - (setq-local selectrum--match-is-required - require-match) - ;; TODO the `:no-move-default-candidate' option of - ;; `selectrum--read' should be removed together with - ;; the obsolete `selectrum-read' alias. - (when no-move-default-candidate - (setq-local selectrum-move-default-candidate nil)) - (selectrum--minibuffer-setup-hook - candidates - (or (car-safe minibuffer-default) - minibuffer-default - default-candidate) - buf))) - (read-from-minibuffer - prompt initial-input selectrum-minibuffer-map nil - (or history 'minibuffer-history) default-candidate))))) - (cond (minibuffer-completion-table - ;; Behave like completing-read-default which strips the - ;; text properties but leaves the default unchanged - ;; when submitting the empty prompt to get it (see - ;; #180, #107). - (let ((exit-string (default-value 'selectrum--last-input)) - (default (default-value 'selectrum--default-candidate))) - (if (and exit-string - (string-empty-p exit-string) - (equal res default)) - default-candidate - (substring-no-properties res)))) - (t res)))) - -;;;###autoload -(defun selectrum-completing-read - (prompt collection &optional - predicate require-match initial-input - hist def inherit-input-method) - "Read choice using Selectrum. Can be used as `completing-read-function'. -For PROMPT, COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, -HIST, DEF, and INHERIT-INPUT-METHOD, see `completing-read'." - (ignore inherit-input-method) - (selectrum--read - prompt nil - :initial-input initial-input - :default-candidate (or (car-safe def) def) - :require-match (eq require-match t) - :history hist - :may-modify-candidates t - :minibuffer-completion-table collection - :minibuffer-completion-predicate predicate)) - -;;;###autoload -(defun selectrum-completing-read-multiple - (prompt table &optional predicate require-match initial-input - hist def _inherit-input-method) - "Read one or more choices using Selectrum. -Replaces `completing-read-multiple'. For PROMPT, TABLE, -PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, DEF, and -INHERIT-INPUT-METHOD, see `completing-read-multiple'. - -The option `selectrum-completing-read-multiple-show-help' can be -used to control insertion of additional usage information into -the prompt." - (let* ((crm-completion-table table) - (crm-separator crm-separator) - (coll (all-completions "" #'crm--collection-fn predicate)) - (candidates - (lambda (input) - (let ((beg 0) - (inputs ())) - (while (string-match crm-separator input beg) - (push (substring input beg (match-beginning 0)) - inputs) - (setq beg (match-end 0))) - (let ((coll (cl-delete-if - (lambda (i) - (member i inputs)) - (copy-sequence coll))) - (ninput (substring input beg))) - `((input . ,ninput) - (candidates . ,coll)))))) - (res nil)) - (setq - res - (selectrum--minibuffer-with-setup-hook - (lambda () - (setq-local selectrum--is-crm-session t) - (when selectrum-completing-read-multiple-show-help - (let ((inhibit-read-only t)) - (save-excursion - (goto-char (minibuffer-prompt-end)) - (when (search-backward ":" nil t) - (insert - (apply - #'propertize - (format " [add more using %s%s]" - (substitute-command-keys - "\\[selectrum-insert-current-candidate]") - (if (assoc crm-separator - selectrum--crm-separator-alist) - ;; Separator will be automatically - ;; inserted. - "" - "and crm-separator")) - (text-properties-at (point))))))))) - (selectrum--read - prompt - candidates - :require-match require-match - :initial-input initial-input - :history hist - :default-candidate def - :may-modify-candidates t - :minibuffer-completion-table table - :minibuffer-completion-predicate predicate))) - (split-string res crm-separator t))) - -;;;###autoload -(defun selectrum-completion-in-region - (start end collection predicate) - "Complete in-buffer text using a list of candidates. -Can be used as `completion-in-region-function'. For START, END, -COLLECTION, and PREDICATE, see `completion-in-region'." - (let* ((enable-recursive-minibuffers t) - (input (buffer-substring-no-properties start end)) - (meta (completion-metadata input collection predicate)) - (category (completion-metadata-get meta 'category)) - (bound (pcase category - ('file start) - (_ (+ start (car (completion-boundaries - input collection predicate "")))))) - (exit-func (plist-get completion-extra-properties - :exit-function)) - (cands (if (not selectrum-completion-in-region-styles) - (let ((completion-regexp-list nil)) - (all-completions input collection predicate)) - (nconc - (let ((completion-styles - selectrum-completion-in-region-styles)) - (completion-all-completions - input collection predicate - (- end start) meta)) - nil))) - ;; See doc of `completion-extra-properties'. - (exit-status nil) - (result nil)) - (if (null cands) - (prog1 nil - (unless completion-fail-discreetly (ding)) - (message "No match")) - (prog1 t - (pcase category - ('file - (let ((try nil)) - (setq result - (if (and (not (cdr cands)) - (stringp (setq try (try-completion - input collection predicate)))) - try - (selectrum--completing-read-file-name - "Completion: " collection predicate - nil input)) - exit-status 'sole))) - (_ - (setq result - (if (not (cdr cands)) - (car cands) - (selectrum--read - "Completion: " cands - :minibuffer-completion-table collection - :minibuffer-completion-predicate predicate)) - exit-status (cond ((not (member result cands)) 'sole) - (t 'finished))))) - (delete-region bound end) - (push-mark (point) 'no-message) - (insert (substring-no-properties result)) - (when exit-func - (funcall exit-func result exit-status)))))) - -;;;###autoload -(defun selectrum-read-buffer (prompt &optional def require-match predicate) - "Read buffer using Selectrum. Can be used as `read-buffer-function'. -Actually, as long as `selectrum-completing-read' is installed in -`completing-read-function', `read-buffer' already uses Selectrum. -Installing this function in `read-buffer-function' makes sure the -buffers are sorted in the default order (most to least recently -used) rather than in whatever order is defined by -`selectrum-preprocess-candidates-function', which is likely to be -less appropriate. It also allows you to view hidden buffers, -which is otherwise impossible due to tricky behavior of Emacs' -completion machinery. For PROMPT, DEF, REQUIRE-MATCH, and -PREDICATE, see `read-buffer'." - (let* ((buffalist (mapcar (lambda (buf) - (cons (buffer-name buf) buf)) - (buffer-list))) - (buffers (mapcar #'car (if predicate - (cl-delete-if-not predicate buffalist) - buffalist))) - (candidates - (lambda (input) - (let ((candidates (copy-sequence buffers))) - (if (string-prefix-p " " input) - (progn - (setq input (substring input 1)) - (setq candidates - (cl-delete-if-not - (lambda (name) - (string-prefix-p " " name)) - candidates))) - (setq candidates - (cl-delete-if - (lambda (name) - (string-prefix-p " " name)) - candidates))) - `((candidates . ,candidates) - (input . ,input)))))) - (selectrum--minibuffer-with-setup-hook - (lambda () - (setq-local selectrum-should-sort nil) - (setq-local selectrum-move-default-candidate nil)) - (selectrum--read - prompt candidates - :default-candidate def - :require-match (eq require-match t) - :history 'buffer-name-history - :may-modify-candidates t - :minibuffer-completion-table #'internal-complete-buffer - :minibuffer-completion-predicate predicate)))) - -(defun selectrum--partial-file-completions - (path collection predicate &optional raw) - "Get partial comps for PATH, file COLLECTION and PREDICATE. -Candidates are filtered for ./ and ../ and propertized for -Selectrum unless RAW is non-nil." - (pcase-let ((`(,pattern ,all ,prefix ,suffix) - (completion-pcm--find-all-completions - path collection predicate - (length path)))) - (when all - (let ((matches (completion-pcm--hilit-commonality - pattern all))) - (if raw - matches - (cl-loop for match in matches - unless (string-suffix-p "../" match) - collect - (let* ((path (string-remove-suffix - "./" match)) - (full (concat prefix path suffix))) - (propertize path - 'selectrum--candidate-full - full - 'selectrum--partial - prefix)))))))) - -(defun selectrum--completion-pcm-all-completions (_string cands pred _point) - "Used for partial-style file completions. -For STRING, CANDS, PRED and POINT see -`completion-pcm-all-completions'." - (when cands - (let* ((prefix (get-text-property 0 'selectrum--partial (car cands))) - (len (length prefix)) - (string (substitute-in-file-name (minibuffer-contents))) - (cands (cl-loop for cand in cands - collect - (propertize (concat prefix cand) - 'selectrum--candidate-full - (get-text-property - 0 'selectrum--candidate-full cand)))) - (res (selectrum--partial-file-completions string cands pred 'raw))) - (cl-loop for cand in res - collect (substring cand len))))) - -(defun selectrum--completing-read-file-name - (prompt collection &optional - predicate require-match initial-input - hist def _inherit-input-method) - "Selectrums completing read function for `read-file-name-default'. -For PROMPT, COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, - HIST, DEF, _INHERIT-INPUT-METHOD see `completing-read'." - (let* ((last-dir nil) - (msg "Press \\[selectrum-insert-current-candidate] to refresh") - (sortf nil) - (is-env-completion nil) - (coll - (lambda (input) - (let* (;; Path of input dir might include shadowed paths. - (path (substitute-in-file-name input)) - (is-remote-path - (file-remote-p path)) - (is-connected - (and is-remote-path - (file-remote-p path nil t))) - (dir (or (file-name-directory path) "")) - (maybe-tramp (equal dir "/")) - ;; The input used for matching current dir entries. - (matchstr (file-name-nondirectory path)) - (cands - (cond - ;; Guard against automatic tramp connections. - ((and (not selectrum--inserted-file-completion) - (not is-connected) - is-remote-path) - (prog1 nil - (minibuffer-message - (substitute-command-keys msg)))) - ;; Env var completion. - ((string-prefix-p "$" matchstr) - (setq is-env-completion t) - (setq matchstr (substring matchstr 1)) - (cl-loop for var in - (funcall - collection (concat dir "$") predicate t) - for val = (getenv var) - collect - (propertize - var - 'selectrum--candidate-full - (concat dir val) - 'selectrum-candidate-display-right-margin - val))) - ;; Use cache. - ((and (equal last-dir dir) - (not maybe-tramp) - (not is-env-completion) - (or (not selectrum--inserted-file-completion) - ;; Reuse cache if inserting file names - ;; in same dir. - (and (not (directory-name-p matchstr)) - (or (not is-remote-path) - is-connected) - (file-exists-p dir))) - (not (and minibuffer-history-position - (zerop minibuffer-history-position) - (memq this-command - '(previous-history-element - next-history-element))))) - (setq-local selectrum-preprocess-candidates-function - #'identity) - selectrum--preprocessed-candidates) - ;; Use partial completion. - ((and (not selectrum--inserted-file-completion) - (not (string-empty-p dir)) - (or (not is-remote-path) - is-connected) - (not (file-exists-p dir))) - (setq is-env-completion nil) - (setq-local selectrum-preprocess-candidates-function - sortf) - (setq-local selectrum--inserted-file-completion nil) - (selectrum--partial-file-completions - path collection predicate)) - ;; Compute from file table. - (t - (setq is-env-completion nil) - (setq-local selectrum-preprocess-candidates-function - sortf) - (setq-local selectrum--inserted-file-completion nil) - (let ((files - (condition-case _ - (delete - "./" - (delete - "../" - (funcall collection - (if maybe-tramp - path - dir) - predicate t))) - ;; May happen in case user quits out - ;; of a TRAMP prompt. - (quit 'quit)))) - (unless (eq files 'quit) - (if (and (not files) - is-remote-path - (not is-connected) - (not (file-exists-p dir))) - ;; On first connection when there aren't - ;; any results and dir doesn't exist try - ;; to get partial completions. - (selectrum--partial-file-completions - path collection predicate) - ;; Remove duplicate tramp entries. - (if maybe-tramp - (delete-dups files) - files)))))))) - (setq last-dir dir) - `((input . ,matchstr) - (candidates . ,cands)))))) - (selectrum--minibuffer-with-setup-hook - ;; The hook needs to run late as `read-file-name-default' sets - ;; its own syntax table in `minibuffer-with-setup-hook'. - (:append (lambda () - ;; Pickup the value as configured for current - ;; session. - (setq sortf selectrum-preprocess-candidates-function) - ;; Ensure the variable is also set when - ;; selectrum--completing-read-file-name is called - ;; directly. - (setq-local minibuffer-completing-file-name t) - (set-syntax-table - selectrum--minibuffer-local-filename-syntax))) - (selectrum--read - prompt coll - :default-candidate (or (car-safe def) def) - :initial-input (or (car-safe initial-input) initial-input) - :history hist - :require-match (eq require-match t) - :may-modify-candidates t - :minibuffer-completion-table collection - :minibuffer-completion-predicate predicate)))) - -;;;###autoload -(defun selectrum-read-file-name - (prompt &optional dir default-filename mustmatch initial predicate) - "Read file name using Selectrum. Can be used as `read-file-name-function'. -For PROMPT, DIR, DEFAULT-FILENAME, MUSTMATCH, INITIAL, and -PREDICATE, see `read-file-name'." - (let* ((crf completing-read-function) - ;; See <https://github.com/raxod502/selectrum/issues/61>. - ;; When you invoke another `completing-read' command - ;; recursively then it inherits the - ;; `completing-read-function' binding, and unless it's - ;; another file reading command using - ;; `selectrum--completing-read-file-name' this will cause - ;; an error. To circumvent this we use the function to - ;; reset the variable when called. - (completing-read-function - (lambda (&rest args) - (setq completing-read-function crf) - (if (not default-filename) - (apply #'selectrum--completing-read-file-name args) - (let* ((default (if (consp default-filename) - (car default-filename) - default-filename)) - (df (expand-file-name default)) - (dd (expand-file-name default-directory)) - (default-in-prompt-dir - (equal (file-name-directory - (directory-file-name df)) - (file-name-directory dd))) - (virtual (when (or (not default-in-prompt-dir) - (not (file-exists-p default))) - (propertize - (string-remove-prefix dd df) - 'selectrum--candidate-full - default)))) - ;; Ajudst default for internal handling as it wasn't - ;; passed to `read-file-name-default'. See comment at - ;; `read-file-name-default' call below. - (unless (equal df dd) ; Prompt selection. - ;; Make the default sorted first by its relative name - ;; when it is inside the prompting directory. - (when default-in-prompt-dir - (setq default - (file-relative-name default default-directory))) - (if (consp default-filename) - (setcar default-filename default) - (setq default-filename default)) - ;; Adjust the DEFAULT arg. - (setf (nth 6 args) default-filename)) - (selectrum--minibuffer-with-setup-hook - (lambda () - (when virtual - (setq-local selectrum--virtual-default-file virtual))) - (apply #'selectrum--completing-read-file-name args))))))) - (read-file-name-default - prompt dir - ;; We don't pass default-candidate here to avoid that - ;; submitting the selected prompt results in the default file - ;; name. This is the stock Emacs behavior where there is no - ;; concept of an active selection. Instead we pass the initial - ;; prompt as default so it gets returned when submitted. In - ;; addition to that we adjust the DEF argument passed to - ;; `selectrum--completing-read-file-name' above so the actual - ;; default gets sorted to the top. This should give the same - ;; convenience as in default completion (where you can press - ;; RET at the initial prompt to get the default). The downside - ;; is that this convenience is gone when sorting is disabled or - ;; the default-filename is outside the prompting directory but - ;; this should be rare case. - (concat - (expand-file-name - (or dir - default-directory)) - initial) - mustmatch initial predicate))) - -;;;###autoload -(defun selectrum--fix-dired-read-dir-and-switches (func &rest args) - "Make \\[dired] do the \"right thing\" with its default candidate. -By default \\[dired] uses `read-file-name' internally, which -causes Selectrum to provide you with the first file inside the -working directory as the default candidate. However, it would -arguably be more semantically appropriate to use -`read-directory-name', and this is especially important for -Selectrum since this causes it to select the working directory -initially. - -To test that this advice is working correctly, type \\[dired] and -accept the default candidate. You should have opened the working -directory in Dired, and not a filtered listing for the current -file. - -This is an `:around' advice for `dired-read-dir-and-switches'. -FUNC and ARGS are standard as in any `:around' advice." - (cl-letf* ((orig-read-file-name (symbol-function #'read-file-name)) - ((symbol-function #'read-file-name) - (lambda (prompt &optional - dir default-filename - mustmatch initial _predicate) - (cl-letf (((symbol-function #'read-file-name) - orig-read-file-name)) - (read-directory-name - prompt dir default-filename mustmatch initial))))) - (apply func args))) - -(defun selectrum--trailing-components (n path) - "Take at most N trailing components of PATH. -For large enough N, return PATH unchanged." - (let* ((n (min n (1+ (cl-count ?/ path)))) - (regexp (concat (string-join (make-list n "[^/]*") "/") "$"))) - (save-match-data - (string-match regexp path) - (match-string 0 path)))) - -;;;###autoload -(defun selectrum-read-library-name () - "Read and return a library name. -Similar to `read-library-name' except it handles `load-path' -shadows correctly." - (eval-and-compile - (require 'find-func)) - (let ((suffix-regexp (concat (regexp-opt (find-library-suffixes)) "\\'")) - (table (make-hash-table :test #'equal)) - (lst nil)) - (dolist (dir (or find-function-source-path load-path)) - (condition-case _ - (mapc - (lambda (entry) - (unless (string-match-p "^\\.\\.?$" entry) - (let ((base (file-name-base entry))) - (puthash base (cons entry (gethash base table)) table)))) - (directory-files dir 'full suffix-regexp 'nosort)) - (file-error))) - (maphash - (lambda (_ paths) - (setq paths (nreverse (seq-uniq paths))) - (cl-block nil - (let ((num-components 1) - (max-components (apply #'max (mapcar (lambda (path) - (1+ (cl-count ?/ path))) - paths)))) - (while t - (let ((abbrev-paths - (seq-uniq - (mapcar (lambda (path) - (file-name-sans-extension - (selectrum--trailing-components - num-components path))) - paths)))) - (when (or (= num-components max-components) - (= (length paths) (length abbrev-paths))) - (let ((candidate-paths - (mapcar (lambda (path) - (propertize - (file-name-base - (file-name-sans-extension path)) - 'selectrum-candidate-display-prefix - (file-name-directory - (file-name-sans-extension - (selectrum--trailing-components - num-components path))) - 'fixedcase 'literal - 'selectrum--lib-path path)) - paths))) - (setq lst (nconc candidate-paths lst))) - (cl-return))) - (cl-incf num-components))))) - table) - (get-text-property - 0 'selectrum--lib-path - (selectrum--read - "Library name: " lst :require-match t :may-modify-candidates t)))) - -(defun selectrum-repeat () - "Repeat the last command that used Selectrum, and try to restore state." - (interactive) - (unless selectrum--last-command - (user-error "No Selectrum command has been run yet")) - (setq current-prefix-arg selectrum--last-prefix-arg - this-command selectrum--last-command) - (selectrum--minibuffer-with-setup-hook - (lambda () - (setq-local selectrum--repeat t)) - (call-interactively selectrum--last-command))) - -;;;###autoload -(defun selectrum--fix-minibuffer-message (func &rest args) - "Ensure the cursor stays at the front of the minibuffer message. -This advice adjusts where the cursor gets placed for the overlay -of `minibuffer-message' and ensures the overlay gets displayed at -the right place without blocking the display of candidates. - -To test that this advice is working correctly, type \\[find-file] -twice in a row with `enable-recursive-minibuffers' set to nil. -The overlay indicating that recursive minibuffers are not allowed -should appear right after the user input area, not at the end of -the candidate list and the cursor should stay at the front. - -This is an `:around' advice for `minibuffer-message'. FUNC and -ARGS are standard as in all `:around' advice." - (if (bound-and-true-p selectrum-is-active) - (cl-letf* ((orig-put-text-property - (symbol-function #'put-text-property)) - ((symbol-function #'put-text-property) - (lambda (beg end key val &rest args) - ;; Set cursor property like - ;; `set-minibuffer-message' in Emacs 27. - (apply orig-put-text-property - beg end key (if (eq key 'cursor) 1 val) - args))) - (orig-make-overlay - (symbol-function #'make-overlay)) - ((symbol-function #'make-overlay) - (lambda (&rest args) - (let ((ov (apply orig-make-overlay args))) - ;; Set overlay priority like - ;; `set-minibuffer-message' in Emacs 27. - (overlay-put ov 'priority 1100) - ov)))) - (apply func args)) - (apply func args))) - -;; You may ask why we copy the entire minor-mode definition into the -;; autoloads file, and autoload several private functions as well. -;; This is because enabling `selectrum-mode' does not actually require -;; any of the code in Selectrum. So, to improve startup time, we avoid -;; loading Selectrum when enabling `selectrum-mode'. - -;;;###autoload -(progn - (define-minor-mode selectrum-mode - "Minor mode to use Selectrum for `completing-read'." - :global t - (if selectrum-mode - (progn - ;; Make sure not to blow away saved variable values if mode - ;; is enabled again when already on. - (selectrum-mode -1) - (setq selectrum-mode t) - (setq selectrum--old-completing-read-function - (default-value 'completing-read-function)) - (setq-default completing-read-function - #'selectrum-completing-read) - (setq selectrum--old-read-buffer-function - (default-value 'read-buffer-function)) - (setq-default read-buffer-function - #'selectrum-read-buffer) - (setq selectrum--old-read-file-name-function - (default-value 'read-file-name-function)) - (setq-default read-file-name-function - #'selectrum-read-file-name) - (setq selectrum--old-completion-in-region-function - (default-value 'completion-in-region-function)) - (when selectrum-complete-in-buffer - (setq-default completion-in-region-function - #'selectrum-completion-in-region)) - (advice-add #'completing-read-multiple :override - #'selectrum-completing-read-multiple) - ;; No sharp quote because Dired may not be loaded yet. - (advice-add 'dired-read-dir-and-switches :around - #'selectrum--fix-dired-read-dir-and-switches) - ;; No sharp quote because `read-library-name' is not defined - ;; in older Emacs versions. - (advice-add 'read-library-name :override - #'selectrum-read-library-name) - (advice-add #'minibuffer-message :around - #'selectrum--fix-minibuffer-message) - (define-key minibuffer-local-map - [remap previous-matching-history-element] - 'selectrum-select-from-history)) - (when (equal (default-value 'completing-read-function) - #'selectrum-completing-read) - (setq-default completing-read-function - selectrum--old-completing-read-function)) - (when (equal (default-value 'read-buffer-function) - #'selectrum-read-buffer) - (setq-default read-buffer-function - selectrum--old-read-buffer-function)) - (when (equal (default-value 'read-file-name-function) - #'selectrum-read-file-name) - (setq-default read-file-name-function - selectrum--old-read-file-name-function)) - (when (equal (default-value 'completion-in-region-function) - #'selectrum-completion-in-region) - (setq-default completion-in-region-function - selectrum--old-completion-in-region-function)) - (advice-remove #'completing-read-multiple - #'selectrum-completing-read-multiple) - ;; No sharp quote because Dired may not be loaded yet. - (advice-remove 'dired-read-dir-and-switches - #'selectrum--fix-dired-read-dir-and-switches) - ;; No sharp quote because `read-library-name' is not defined in - ;; older Emacs versions. - (advice-remove 'read-library-name #'selectrum-read-library-name) - (advice-remove #'minibuffer-message #'selectrum--fix-minibuffer-message) - (when (eq (lookup-key minibuffer-local-map - [remap previous-matching-history-element]) - #'selectrum-select-from-history) - (define-key minibuffer-local-map - [remap previous-matching-history-element] nil))))) - -;;; Closing remarks - -(provide 'selectrum) - -;; Local Variables: -;; checkdoc-verb-check-experimental-flag: nil -;; indent-tabs-mode: nil -;; sentence-end-double-space: nil -;; End: - -;;; selectrum.el ends here diff --git a/elpa/selectrum-3.1/selectrum.elc b/elpa/selectrum-3.1/selectrum.elc Binary files differ. diff --git a/elpa/selectrum-prescient-5.1/selectrum-prescient-autoloads.el b/elpa/selectrum-prescient-5.1/selectrum-prescient-autoloads.el @@ -1,43 +0,0 @@ -;;; selectrum-prescient-autoloads.el --- automatically extracted autoloads -;; -;;; Code: - -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) - - -;;;### (autoloads nil "selectrum-prescient" "selectrum-prescient.el" -;;;;;; (0 0 0 0)) -;;; Generated autoloads from selectrum-prescient.el - -(defvar selectrum-prescient-mode nil "\ -Non-nil if Selectrum-Prescient mode is enabled. -See the `selectrum-prescient-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 `selectrum-prescient-mode'.") - -(custom-autoload 'selectrum-prescient-mode "selectrum-prescient" nil) - -(autoload 'selectrum-prescient-mode "selectrum-prescient" "\ -Minor mode to use prescient.el in Selectrum menus. - -If called interactively, enable Selectrum-Prescient mode if ARG -is positive, and disable it if ARG is zero or negative. If -called from Lisp, also enable the mode if ARG is omitted or nil, -and toggle it if ARG is `toggle'; disable the mode otherwise. - -\(fn &optional ARG)" t nil) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "selectrum-prescient" '("selectrum-prescient-"))) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; selectrum-prescient-autoloads.el ends here diff --git a/elpa/selectrum-prescient-5.1/selectrum-prescient-pkg.el b/elpa/selectrum-prescient-5.1/selectrum-prescient-pkg.el @@ -1,2 +0,0 @@ -;;; Generated package description from selectrum-prescient.el -*- no-byte-compile: t -*- -(define-package "selectrum-prescient" "5.1" "Selectrum integration" '((emacs "25.1") (prescient "5.1") (selectrum "1.0")) :commit "2c0e9fc061ab723ec532428f312974ca7d8def12" :authors '(("Radon Rosborough" . "radon.neon@gmail.com")) :maintainer '("Radon Rosborough" . "radon.neon@gmail.com") :keywords '("extensions") :url "https://github.com/raxod502/prescient.el") diff --git a/elpa/selectrum-prescient-5.1/selectrum-prescient.el b/elpa/selectrum-prescient-5.1/selectrum-prescient.el @@ -1,208 +0,0 @@ -;;; selectrum-prescient.el --- Selectrum integration -*- lexical-binding: t -*- - -;; Copyright (C) 2019 Radon Rosborough - -;; Author: Radon Rosborough <radon.neon@gmail.com> -;; Homepage: https://github.com/raxod502/prescient.el -;; Keywords: extensions -;; Package-Version: 5.1 -;; Package-Commit: 2c0e9fc061ab723ec532428f312974ca7d8def12 -;; Created: 8 Dec 2019 -;; Package-Requires: ((emacs "25.1") (prescient "5.1") (selectrum "1.0")) -;; SPDX-License-Identifier: MIT -;; Version: 5.1 - -;;; Commentary: - -;; selectrum-prescient.el provides an interface for using prescient.el -;; to sort and filter candidates in Selectrum menus. To enable its -;; functionality, turn on `selectrum-prescient-mode' in your init-file -;; or interactively. - -;; For more information, see https://github.com/raxod502/prescient.el. - -;;; Code: - -;;;; Libraries - -(require 'prescient) -(require 'selectrum) - -(require 'subr-x) - -;;;; Minor mode - -(defun selectrum-prescient--preprocess (candidates) - "Sort CANDIDATES, unless `selectrum-should-sort-p' is nil." - (when selectrum-should-sort-p - (setq candidates (prescient-sort candidates))) - candidates) - -(defvar selectrum-prescient--old-preprocess-function nil - "Previous value of `selectrum-preprocess-candidates-function'.") - -(defvar selectrum-prescient--old-refine-function nil - "Previous value of `selectrum-refine-candidates-function'.") - -(defun selectrum-prescient--remember (candidate &rest _) - "Remember CANDIDATE in prescient.el. -For use on `selectrum-candidate-selected-hook'." - (prescient-remember candidate)) - -(defun selectrum-prescient--highlight (input candidates) - "According to INPUT, return list of propertized CANDIDATES." - (let ((regexps (prescient-filter-regexps input 'with-groups))) - (save-match-data - (mapcar - (lambda (candidate) - (setq candidate (copy-sequence candidate)) - (prog1 candidate - (dolist (regexp regexps) - (when (string-match regexp candidate) - (put-text-property - (match-beginning 0) (match-end 0) - 'face 'selectrum-primary-highlight candidate) - (cl-loop - for (start end) - on (cddr (match-data)) - by #'cddr - do (when (and start end) - (put-text-property - start end - 'face 'selectrum-secondary-highlight candidate))))))) - candidates)))) - -(defvar selectrum-prescient--old-highlight-function nil - "Previous value of `selectrum-highlight-candidates-function'.") - -;;;;; Toggling Commands -(defvar selectrum-prescient-toggle-map (make-sparse-keymap) - "A keymap of commands for toggling Prescient filters in Selectrum. -Such commands are created and automatically bound in this map by -`selectrum--prescient-create-and-bind-toggle-command'.") - -(defmacro selectrum-prescient-create-and-bind-toggle-command - (filter-type key-string) - "Create and bind a command to toggle the use of a filter method in Selectrum. - -The created command toggles the FILTER-TYPE algorithm on or off -buffer-locally, and doesn't affect the default -behavior (determined by `prescient-filter-method'). - -FILTER-TYPE is an unquoted symbol that can be used in -`prescient-filter-method'. KEY-STRING is a string that can be -passed to `kbd', whose output will be bound in -`selectrum-prescient-toggle-map' to the created command." - (let* ((filter-type-name (symbol-name filter-type))) - - `(define-key selectrum-prescient-toggle-map - (kbd ,key-string) - (defun ,(intern (concat "selectrum-prescient-toggle-" - filter-type-name)) - (arg) ; Arg list - ,(format - "Toggle the \"%s\" filter on or off. With ARG, use only this filter. -This toggling only affects filtering in the current Selectrum -buffer. It does not affect the default behavior (determined by -`prescient-filter-method')." filter-type-name) - (interactive "P") - - ;; Make `prescient-filter-method' buffer-local in the - ;; Selectrum buffer. We don't want to accidentally change the - ;; user's default behavior. - (make-local-variable 'prescient-filter-method) - - (if arg - ;; If user provides a prefix argument, set filtering to - ;; be a list of only one filter type. - (setq prescient-filter-method '(,filter-type)) - - ;; Otherwise, if we need to add or remove from the list, - ;; make sure it's actually a list and not just a symbol. - (when (symbolp prescient-filter-method) - (setq prescient-filter-method - (list prescient-filter-method))) - - (if (equal prescient-filter-method '(,filter-type)) - ;; Make sure the user doesn't accidentally disable all - ;; filtering. - (user-error - "Prescient.el: Can't toggle off only active filter method: %s" - ,filter-type-name) - - (setq prescient-filter-method - (if (memq ',filter-type prescient-filter-method) - (delq ',filter-type prescient-filter-method) - (cons ',filter-type prescient-filter-method))))) - - ;; After changing `prescient-filter-method', tell the user - ;; the new value and update Selectrum's display. - (message "Prescient.el filter is now %s" - prescient-filter-method) - (selectrum-exhibit))))) - -(selectrum-prescient-create-and-bind-toggle-command anchored "a") -(selectrum-prescient-create-and-bind-toggle-command fuzzy "f") -(selectrum-prescient-create-and-bind-toggle-command initialism "i") -(selectrum-prescient-create-and-bind-toggle-command literal "l") -(selectrum-prescient-create-and-bind-toggle-command prefix "p") -(selectrum-prescient-create-and-bind-toggle-command regexp "r") - -;;;###autoload -(define-minor-mode selectrum-prescient-mode - "Minor mode to use prescient.el in Selectrum menus." - :global t - :group 'prescient - (if selectrum-prescient-mode - (progn - ;; Prevent messing up variables if we explicitly enable the - ;; mode when it's already on. - (selectrum-prescient-mode -1) - (setq selectrum-prescient-mode t) - (setq selectrum-prescient--old-refine-function - selectrum-refine-candidates-function) - (setq selectrum-refine-candidates-function - #'prescient-filter) - (setq selectrum-prescient--old-preprocess-function - selectrum-preprocess-candidates-function) - (setq selectrum-preprocess-candidates-function - #'selectrum-prescient--preprocess) - (setq selectrum-prescient--old-highlight-function - selectrum-highlight-candidates-function) - (setq selectrum-highlight-candidates-function - #'selectrum-prescient--highlight) - (add-hook 'selectrum-candidate-selected-hook - #'selectrum-prescient--remember) - (add-hook 'selectrum-candidate-inserted-hook - #'selectrum-prescient--remember) - (define-key selectrum-minibuffer-map - (kbd "M-s") selectrum-prescient-toggle-map)) - (when (eq selectrum-refine-candidates-function - #'prescient-filter) - (setq selectrum-refine-candidates-function - selectrum-prescient--old-refine-function)) - (when (eq selectrum-preprocess-candidates-function - #'selectrum-prescient--preprocess) - (setq selectrum-preprocess-candidates-function - selectrum-prescient--old-preprocess-function)) - (when (eq selectrum-highlight-candidates-function - #'selectrum-prescient--highlight) - (setq selectrum-highlight-candidates-function - selectrum-prescient--old-highlight-function)) - (remove-hook 'selectrum-candidate-selected-hook - #'selectrum-prescient--remember) - (remove-hook 'selectrum-candidate-inserted-hook - #'selectrum-prescient--remember) - (when (equal (lookup-key selectrum-minibuffer-map (kbd "M-s")) - selectrum-prescient-toggle-map) - (define-key selectrum-minibuffer-map (kbd "M-s") nil)))) - -;;;; Closing remarks - -(provide 'selectrum-prescient) - -;;; selectrum-prescient.el ends here - -;; Local Variables: -;; outline-regexp: ";;;;* " -;; End: diff --git a/elpa/selectrum-prescient-5.1/selectrum-prescient.elc b/elpa/selectrum-prescient-5.1/selectrum-prescient.elc Binary files differ. diff --git a/elpa/vertico-0.17.signed b/elpa/vertico-0.17.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2021-12-01T23:15:02+0100 using RSA +\ No newline at end of file diff --git a/elpa/vertico-0.17/LICENSE b/elpa/vertico-0.17/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/elpa/vertico-0.17/README.org b/elpa/vertico-0.17/README.org @@ -0,0 +1,445 @@ +#+title: vertico.el - VERTical Interactive COmpletion +#+author: Daniel Mendler +#+language: en +#+export_file_name: vertico.texi +#+texinfo_dir_category: Emacs +#+texinfo_dir_title: Vertico: (vertico). +#+texinfo_dir_desc: VERTical Interactive COmpletion. + +#+html: <a href="https://www.gnu.org/software/emacs/"><img alt="GNU Emacs" src="https://github.com/minad/corfu/blob/screenshots/emacs.svg?raw=true"/></a> +#+html: <a href="http://elpa.gnu.org/packages/vertico.html"><img alt="GNU ELPA" src="https://elpa.gnu.org/packages/vertico.svg"/></a> +#+html: <a href="http://elpa.gnu.org/devel/vertico.html"><img alt="GNU-devel ELPA" src="https://elpa.gnu.org/devel/vertico.svg"/></a> +#+html: <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Vertigomovie_restoration.jpg/800px-Vertigomovie_restoration.jpg" align="right" width="30%"> + +* Introduction + + Vertico provides a performant and minimalistic vertical completion UI based on + the default completion system. The main focus of Vertico is to provide a UI + which behaves /correctly/ under all circumstances. By reusing the built-in + facilities system, Vertico achieves /full compatibility/ with built-in Emacs + completion commands and completion tables. Vertico only provides the + completion UI but aims to be flexible and extensible. Additional enhancements + are available as [[#extensions][extensions]] or [[#complementary-packages][complementary packages]]. The code base is small + and maintainable (~vertico.el~ is only about 600 lines of code without white + space and comments). + +* Features + + - Vertical display with arrow key navigation + - Prompt shows the current candidate index and the total number of candidates + - The current candidate is inserted with =TAB= and selected with =RET= + - Non-existing candidates can be entered by moving the point to the prompt line + - Configurable sorting by history position, length and alphabetically + - Long candidates with newlines are formatted to take up less space + - Deferred completion style highlighting for performance + - Support for annotations (~annotation-function~ and ~affixation-function~) + - Support for grouping and group cycling commands (~group-function~) + + [[https://github.com/minad/vertico/blob/main/screenshot.svg?raw=true]] + +* Key bindings + + Vertico defines its own local keymap in the minibuffer which is derived from + ~minibuffer-local-map~. The keymap keeps most of the ~fundamental-mode~ + keybindings intact and remaps and binds only a handful of commands. Note in + particular the binding of =TAB= to ~vertico-insert~ and the bindings of + ~vertico-exit/exit-input~. + + - ~beginning-of-buffer~, ~minibuffer-beginning-of-buffer~ -> ~vertico-first~ + - ~end-of-buffer~ -> ~vertico-last~ + - ~scroll-down-command~ -> ~vertico-scroll-down~ + - ~scroll-up-command~ -> ~vertico-scroll-up~ + - ~next-line~, ~next-line-or-history-element~ -> ~vertico-next~ + - ~previous-line~, ~previous-line-or-history-element~ -> ~vertico-previous~ + - ~forward-paragraph~ -> ~vertico-next-group~ + - ~backward-paragraph~ -> ~vertico-previous-group~ + - ~exit-minibuffer~ -> ~vertico-exit~ + - ~kill-ring-save~ -> ~vertico-save~ + - =C-<return>= -> ~vertico-exit-input~ + - =TAB= -> ~vertico-insert~ + +* Configuration + + Vertico is available from [[http://elpa.gnu.org/packages/vertico.html][GNU ELPA]]. You can install it directly via + ~package-install~. After installation, you can activate the global minor mode + with =M-x vertico-mode=. In order to configure Vertico and other packages in + your init.el, you may want to take advantage of ~use-package~. I recommend to + give Orderless completion a try, which is different from the prefix TAB + completion used by the basic default completion system or in shells. Here is + an example configuration: + + #+begin_src emacs-lisp + ;; Enable vertico + (use-package vertico + :init + (vertico-mode) + + ;; Different scroll margin + ;; (setq vertico-scroll-margin 0) + + ;; Show more candidates + ;; (setq vertico-count 20) + + ;; Grow and shrink the Vertico minibuffer + ;; (setq vertico-resize t) + + ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. + ;; (setq vertico-cycle t) + ) + + ;; Optionally use the `orderless' completion style. See + ;; `+orderless-dispatch' in the Consult wiki for an advanced Orderless style + ;; dispatcher. Additionally enable `partial-completion' for file path + ;; expansion. `partial-completion' is important for wildcard support. + ;; Multiple files can be opened at once with `find-file' if you enter a + ;; wildcard. You may also give the `initials' completion style a try. + (use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; A few more useful configurations... + (use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; Alternatively try `consult-completing-read-multiple'. + (defun crm-indicator (args) + (cons (concat "[CRM] " (car args)) (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + #+end_src + + See also the [[https://github.com/minad/vertico/wiki][Vertico Wiki]] for additional configuration tips. + +** Completion styles and TAB completion + + The bindings of the ~minibuffer-local-completion-map~ are not available in + Vertico by default. This means that TAB works differently from what you may + expect from the default Emacs completion system. + + If you prefer to have the default completion commands a key press away you can + add new bindings or even replace the Vertico bindings. Then the default + completion commands behave as usual. For example you can use =M-TAB= to cycle + between candidates if you have set ~completion-cycle-threshold~. + + #+begin_src emacs-lisp + (define-key vertico-map "?" #'minibuffer-completion-help) + (define-key vertico-map (kbd "M-RET") #'minibuffer-force-complete-and-exit) + (define-key vertico-map (kbd "M-TAB") #'minibuffer-complete) + #+end_src + + The ~orderless~ completion style does not support completion of a common prefix + substring, as you may be familiar with from shells or the basic default + completion system. The reason is that the Orderless input string is usually + not a prefix. In order to support completing prefixes you may want to combine + ~orderless~ with ~substring~ in your =completion-styles= configuration. + + #+begin_src emacs-lisp + (setq completion-styles '(substring orderless)) + #+end_src + + Alternatively you can experiment with the built-in completion-styles, e.g., + adding =partial-completion= or =flex=. The =partial-completion= style is important + to add if you want to open multiple files at once with ~find-file~ using + wildcards. In order to open multiple files at once, you have to move to the + prompt and then press =RET=. + + #+begin_src emacs-lisp + (setq completion-styles '(basic substring partial-completion flex)) + #+end_src + + Because Vertico is fully compatible with Emacs default completion + system, further customization of completion behavior can be achieved + by setting the designated Emacs variables. For example, one may wish + to disable case-sensitivity for file and buffer matching when built-in + completion styles are used instead of ~orderless~: + + #+begin_src emacs-lisp + (setq read-file-name-completion-ignore-case t + read-buffer-completion-ignore-case t + completion-ignore-case t) + #+end_src + +** Completion-at-point and completion-in-region + + The =completion-at-point= command is usually bound to =M-TAB= or =TAB=. In case you + want to use Vertico for completion-at-point/completion-in-region, you can use + the function ~consult-completion-in-region~ provided by the Consult package. + + #+begin_src emacs-lisp + ;; Use `consult-completion-in-region' if Vertico is enabled. + ;; Otherwise use the default `completion--in-region' function. + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + #+end_src + + The =completion-in-region-function= setting also affects TAB completion in the + minibuffer when =M-:= (~eval-expression~) is used. + + You may also want to look into my [[https://github.com/minad/corfu][Corfu]] package, which provides a minimal + completion system for =completion-in-region= in a child frame popup. Corfu is + also a narrowly focused package and developed in the same spirit as Vertico. + +** Completing-read-multiple (CRM) + + Consult offers an enhanced =completing-read-multiple= implementation which you + can use with Vertico. + + #+begin_src emacs-lisp + (advice-add #'completing-read-multiple + :override #'consult-completing-read-multiple) + #+end_src + +* Extensions + :properties: + :custom_id: extensions + :end: + + We maintain small extension packages to Vertico in this repository in the + subdirectory [[https://github.com/minad/vertico/tree/main/extensions][extensions/]]. The extensions are installed together with Vertico + if you pull the package from ELPA. The extensions are of course inactive by + default and can be enabled manually if desired. Furthermore it is possible to + install all of the files separately, both ~vertico.el~ and the ~vertico-*.el~ + extensions. Currently the following extensions come with the Vertico ELPA + package: + + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-buffer.el][vertico-buffer]]: =vertico-buffer-mode= to display Vertico in a separate buffer + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-directory.el][vertico-directory]]: Commands for Ido-like directory navigation + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-flat.el][vertico-flat]]: =vertico-flat-mode= to enable a flat, horizontal display + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-grid.el][vertico-grid]]: =vertico-grid-mode= to enable a grid display + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-indexed.el][vertico-indexed]]: =vertico-indexed-mode= to select indexed candidates with prefix arguments + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-mouse.el][vertico-mouse]]: =vertico-mouse-mode= to support for scrolling and candidate selection + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-quick.el][vertico-quick]]: Commands to select using Avy-style quick keys + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-repeat.el][vertico-repeat]]: The command =vertico-repeat= repeats the last completion session + - [[https://github.com/minad/vertico/blob/main/extensions/vertico-reverse.el][vertico-reverse]]: =vertico-reverse-mode= to reverse the display + + With these extensions it is possible to adapt Vertico such that it matches + your preference or behaves similar to other familiar UIs. For example, the + combination =vertico-flat= plus =vertico-directory= resembles Ido in look and + feel. For an interface similar to Helm, the extension =vertico-buffer= allows + you to configure more freely where the completion buffer opens, instead of + growing the minibuffer. + + Configuration example for =vertico-directory=: + + #+begin_src emacs-lisp + ;; Configure directory extension. + (use-package vertico-directory + :ensure nil + ;; More convenient directory navigation commands + :bind (:map vertico-map + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word)) + ;; Tidy shadowed file names + :hook (rfn-eshadow-update-overlay . vertico-directory-tidy)) + #+end_src + +* Complementary packages + :properties: + :custom_id: complementary-packages + :end: + + Vertico integrates well with complementary packages, which enrich the + completion UI. These packages are fully supported: + + - [[https://github.com/minad/marginalia][Marginalia]]: Rich annotations in the minibuffer + - [[https://github.com/minad/consult][Consult]]: Useful search and navigation commands + - [[https://github.com/oantolin/embark][Embark]]: Minibuffer actions and context menu + - [[https://github.com/oantolin/orderless][Orderless]]: Advanced completion style + + In order to get accustomed with the package ecosystem, I recommed the + following approach: + + 1. Start with plain Emacs. + 2. Install and enable Vertico to get incremental minibuffer completion. + 3. Install Orderless and/or configure the built-in completion styles + for more flexible minibuffer filtering. + 4. Install Marginalia if you like rich minibuffer annotations. + 5. Install Embark and add two keybindings for ~embark-dwim~ and ~embark-act~. + I am using =M-.= and =C-.=. These commands allow you to act on the object + at point or in the minibuffer. + 6. Install Consult if you want additional featureful completion commands, + e.g, the buffer switcher ~consult-buffer~ with preview or the line-based + search ~consult-line~. + 7. Install Embark-Consult and Wgrep for export from =consult-line= to =occur-mode= + buffers and from =consult-grep= to editable =grep-mode= buffers. + + You don't have to use all of these components. Use only the ones you like and + the ones which fit well into your setup. The steps 1. to 4. introduce no new + commands over plain Emacs. Step 5. introduces the new commands ~embark-act~ and + ~embark-dwim~. In step 6. you get the Consult commands, some offer new + functionality not present in Emacs already (e.g., ~consult-line~) and some are + substitutes (e.g., ~consult-buffer~ for ~switch-to-buffer~). + +* Child frames and Popups + +An often requested feature is the ability to display the completions in a child +frame popup. I do not recommend this, since from my experience it introduces +more problems than it solves. Child frames can feel slow and sometimes flicker. +On the other hand the completion display appears right in your focus at the +center of the screen, leading to a modern look and feel. Please give these +packages a try and judge for yourself. + +- [[https://github.com/muffinmad/emacs-mini-frame][mini-frame]]: Display the entire minibuffer in a child frame. +- [[https://github.com/minad/mini-popup][mini-popup]]: Slightly simpler alternative to mini-frame. +- [[https://github.com/tumashu/vertico-posframe][vertico-posframe]]: Display only the Vertico minibuffer in a child frame using + the posframe library. + +* Alternatives + + There are many alternative completion UIs, each UI with its own advantages and + disadvantages. + + Vertico aims to be 100% compliant with all Emacs commands and achieves that + with a minimal code base, relying purely on ~completing-read~ while avoiding to + invent its own APIs. Inventing a custom API as Helm or Ivy is explicitly + avoided in order to increase flexibility and package reuse. Due to its small + code base and reuse of the Emacs built-in facilities, bugs and compatibility + issues are less likely to occur in comparison to completion UIs or full + completion systems, which reimplement a lot of functionality. + + Since Vertico only provides the UI, you may want to combine it with some of + the complementary packages, to give a full-featured completion experience + similar to Helm or Ivy. Overall the packages in the spirit of Vertico have a + different style than Helm or Ivy. The idea is to have smaller independent + components, which one can add and understand step by step. Each component + focuses on its niche and tries to be as non-intrusive as possible. Vertico + targets users interested in crafting their Emacs precisely to their liking - + completion plays an integral part in how the users interacts with Emacs. + + There are other interactive completion UIs, which follow a similar philosophy: + + - [[https://github.com/raxod502/selectrum][Selectrum]]: Selectrum has a similar UI as Vertico, since it directly inspired + Vertico. The Selectrum code base is more complex. Unfortunately Selectrum is + not fully compatible with every Emacs completion command ([[https://github.com/raxod502/selectrum/issues/481][Issue #481]]), since + it uses its own filtering infrastructure, which deviates from the standard + Emacs completion facilities. Vertico additionally has the ability to cycle + over candidates, offers commands for grouping support and comes with a rich + set of [[#extensions][extensions]]. + - [[https://github.com/oantolin/icomplete-vertical][Icomplete-vertical]]: This package enhances the Emacs builtin Icomplete with a + vertical display. In contrast to Vertico, Icomplete rotates the candidates + such that the current candidate always appears at the top. From my + perspective, candidate rotation feels a bit less intuitive than the UI of + Vertico or Selectrum. Note that Emacs 28 offers a built-in + ~icomplete-vertical-mode~. + - [[https://gitlab.com/protesilaos/mct][Mct]]: Minibuffer and Completions in Tandem. Mct reuses the default ~*Completions*~ + buffer and enhances it with automatic updates and additional keybindings, to + select a candidate and move between minibuffer and completions buffer. Mct + is great if you prefer an unobtrusive UI since it can be configured to open + only when requested. Furthermore since Mct uses a fully functional buffer + you can reuse all your familar buffer commands inside the completions + buffer. The main distinction to an approach like Vertico's is that + ~*Completions*~ buffer displays all matching candidates. On the one hand this + is good since it allows you to interact with all the candidates and jump + around with Isearch or Avy. On the other hand it necessarily causes a small + slowdown in comparison to Vertico, which only displays a small subset of + candidates. + +* Problematic completion commands + + Vertico is robust in most scenarios. However some completion commands make + certain assumptions about the completion styles and the completion UI. Some of + these assumptions may not hold in Vertico or other UIs and require minor + workarounds. + +** ~org-refile~ + + ~org-refile~ uses ~org-olpath-completing-read~ to complete the outline path + in steps, when ~org-refile-use-outline-path~ is non-nil. + + Unfortunately the implementation of this Org completion table assumes that + the default completion UI is used. In order to fix the issue at the root, the + completion table should make use of completion boundaries similar to the + built-in file completion table. + + In order to workaround the issues with the current implementation I recommend + to disable the outline path completion in steps. The completion on the full + path is also faster since the input string matches directly against the full + path, which is particularily useful with Orderless. + + #+begin_src emacs-lisp + (setq org-refile-use-outline-path 'file + org-outline-path-complete-in-steps nil) + #+end_src + +** ~tmm-menubar~ + + The text menu bar works well with Vertico but always shows a =*Completions*= + buffer, which is unwanted if you use the Vertico UI. This completion buffer + can be disabled as follows. + + #+begin_src emacs-lisp + (advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions) + #+end_src + +** ~ffap-menu~ + + The command ~ffap-menu~ shows the ==*Completions*= buffer by default like + ~tmm-menubar~, which is unnecessary with Vertico. This completion buffer can be + disabled as follows. + + #+begin_src emacs-lisp + (advice-add #'ffap-menu-ask :around (lambda (&rest args) + (cl-letf (((symbol-function #'minibuffer-completion-help) + #'ignore)) + (apply args)))) + #+end_src + +** Tramp hostname completion + + In combination with Orderless, hostnames are not made available for + completion after entering =/ssh:=. In order to avoid this problem, the =basic= + completion style should be specified for the file completion category. + + #+begin_src emacs-lisp + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic partial-completion)))) + #+end_src + + For users who are familiar with the =completion-style= machinery: You may also + define a custom completion style which sets in only for remote files! + + #+begin_src emacs-lisp + (defun basic-remote-try-completion (string table pred point) + (and (vertico--remote-p string) + (completion-basic-try-completion string table pred point))) + (defun basic-remote-all-completions (string table pred point) + (and (vertico--remote-p string) + (completion-basic-all-completions string table pred point))) + (add-to-list + 'completion-styles-alist + '(basic-remote basic-remote-try-completion basic-remote-all-completions nil)) + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic-remote partial-completion)))) + #+end_src + +* Contributions + + Since this package is part of [[http://elpa.gnu.org/packages/vertico.html][GNU ELPA]] contributions require a copyright + assignment to the FSF. diff --git a/elpa/vertico-0.17/dir b/elpa/vertico-0.17/dir @@ -0,0 +1,18 @@ +This is the file .../info/dir, which contains the +topmost node of the Info hierarchy, called (dir)Top. +The first time you invoke Info you start off looking at this node. + +File: dir, Node: Top This is the top of the INFO tree + + This (the Directory node) gives a menu of major topics. + Typing "q" exits, "H" lists all Info commands, "d" returns here, + "h" gives a primer for first-timers, + "mEmacs<Return>" visits the Emacs manual, etc. + + In Emacs, you can click mouse button 2 on a menu item or cross reference + to select it. + +* Menu: + +Emacs +* Vertico: (vertico). VERTical Interactive COmpletion. diff --git a/elpa/vertico-0.17/vertico-autoloads.el b/elpa/vertico-0.17/vertico-autoloads.el @@ -0,0 +1,265 @@ +;;; vertico-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "vertico" "vertico.el" (0 0 0 0)) +;;; Generated autoloads from vertico.el + +(defvar vertico-mode nil "\ +Non-nil if Vertico mode is enabled. +See the `vertico-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-mode'.") + +(custom-autoload 'vertico-mode "vertico" nil) + +(autoload 'vertico-mode "vertico" "\ +VERTical Interactive COmpletion. + +If called interactively, enable Vertico mode if ARG is positive, +and disable it if ARG is zero or negative. If called from Lisp, +also enable the mode if ARG is omitted or nil, and toggle it if +ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico" '("vertico-"))) + +;;;*** + +;;;### (autoloads nil "vertico-buffer" "vertico-buffer.el" (0 0 0 +;;;;;; 0)) +;;; Generated autoloads from vertico-buffer.el + +(defvar vertico-buffer-mode nil "\ +Non-nil if Vertico-Buffer mode is enabled. +See the `vertico-buffer-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-buffer-mode'.") + +(custom-autoload 'vertico-buffer-mode "vertico-buffer" nil) + +(autoload 'vertico-buffer-mode "vertico-buffer" "\ +Display Vertico in a buffer instead of the minibuffer. + +If called interactively, enable Vertico-Buffer mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-buffer" '("vertico-buffer-"))) + +;;;*** + +;;;### (autoloads nil "vertico-directory" "vertico-directory.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from vertico-directory.el + +(autoload 'vertico-directory-enter "vertico-directory" "\ +Enter directory or exit completion with current candidate." t nil) + +(autoload 'vertico-directory-up "vertico-directory" "\ +Delete directory before point." t nil) + +(autoload 'vertico-directory-delete-char "vertico-directory" "\ +Delete directory or char before point." t nil) + +(autoload 'vertico-directory-delete-word "vertico-directory" "\ +Delete directory or word before point." t nil) + +(autoload 'vertico-directory-tidy "vertico-directory" "\ +Tidy shadowed file name, see `rfn-eshadow-overlay'." nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-directory" '("vertico-directory--completing-file-p"))) + +;;;*** + +;;;### (autoloads nil "vertico-flat" "vertico-flat.el" (0 0 0 0)) +;;; Generated autoloads from vertico-flat.el + +(defvar vertico-flat-mode nil "\ +Non-nil if Vertico-Flat mode is enabled. +See the `vertico-flat-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-flat-mode'.") + +(custom-autoload 'vertico-flat-mode "vertico-flat" nil) + +(autoload 'vertico-flat-mode "vertico-flat" "\ +Flat, horizontal display for Vertico. + +If called interactively, enable Vertico-Flat mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-flat" '("vertico-flat-"))) + +;;;*** + +;;;### (autoloads nil "vertico-grid" "vertico-grid.el" (0 0 0 0)) +;;; Generated autoloads from vertico-grid.el + +(defvar vertico-grid-mode nil "\ +Non-nil if Vertico-Grid mode is enabled. +See the `vertico-grid-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-grid-mode'.") + +(custom-autoload 'vertico-grid-mode "vertico-grid" nil) + +(autoload 'vertico-grid-mode "vertico-grid" "\ +Grid display for Vertico. + +If called interactively, enable Vertico-Grid mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-grid" '("vertico-grid-"))) + +;;;*** + +;;;### (autoloads nil "vertico-indexed" "vertico-indexed.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from vertico-indexed.el + +(defvar vertico-indexed-mode nil "\ +Non-nil if Vertico-Indexed mode is enabled. +See the `vertico-indexed-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-indexed-mode'.") + +(custom-autoload 'vertico-indexed-mode "vertico-indexed" nil) + +(autoload 'vertico-indexed-mode "vertico-indexed" "\ +Prefix candidates with indices. + +If called interactively, enable Vertico-Indexed mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-indexed" '("vertico-indexed--"))) + +;;;*** + +;;;### (autoloads nil "vertico-mouse" "vertico-mouse.el" (0 0 0 0)) +;;; Generated autoloads from vertico-mouse.el + +(defvar vertico-mouse-mode nil "\ +Non-nil if Vertico-Mouse mode is enabled. +See the `vertico-mouse-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-mouse-mode'.") + +(custom-autoload 'vertico-mouse-mode "vertico-mouse" nil) + +(autoload 'vertico-mouse-mode "vertico-mouse" "\ +Mouse support for Vertico. + +If called interactively, enable Vertico-Mouse mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-mouse" '("vertico-"))) + +;;;*** + +;;;### (autoloads nil "vertico-quick" "vertico-quick.el" (0 0 0 0)) +;;; Generated autoloads from vertico-quick.el + +(autoload 'vertico-quick-jump "vertico-quick" "\ +Jump to candidate using quick keys." t nil) + +(autoload 'vertico-quick-exit "vertico-quick" "\ +Exit with candidate using quick keys." t nil) + +(autoload 'vertico-quick-insert "vertico-quick" "\ +Insert candidate using quick keys." t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-quick" '("vertico-quick"))) + +;;;*** + +;;;### (autoloads nil "vertico-repeat" "vertico-repeat.el" (0 0 0 +;;;;;; 0)) +;;; Generated autoloads from vertico-repeat.el + +(autoload 'vertico-repeat "vertico-repeat" "\ +Repeat last Vertico completion session." t nil) + +(autoload 'vertico-repeat-save "vertico-repeat" "\ +Save Vertico status for `vertico-repeat'. +This function must be registered as `minibuffer-setup-hook'." nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-repeat" '("vertico-repeat--"))) + +;;;*** + +;;;### (autoloads nil "vertico-reverse" "vertico-reverse.el" (0 0 +;;;;;; 0 0)) +;;; Generated autoloads from vertico-reverse.el + +(defvar vertico-reverse-mode nil "\ +Non-nil if Vertico-Reverse mode is enabled. +See the `vertico-reverse-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-reverse-mode'.") + +(custom-autoload 'vertico-reverse-mode "vertico-reverse" nil) + +(autoload 'vertico-reverse-mode "vertico-reverse" "\ +Reverse the Vertico display. + +If called interactively, enable Vertico-Reverse mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-reverse" '("vertico-reverse-"))) + +;;;*** + +;;;### (autoloads nil nil ("vertico-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; vertico-autoloads.el ends here diff --git a/elpa/vertico-0.17/vertico-buffer.el b/elpa/vertico-0.17/vertico-buffer.el @@ -0,0 +1,141 @@ +;;; vertico-buffer.el --- Display Vertico in a buffer instead of the minibuffer -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which allows to display Vertico +;; in a buffer instead of the minibuffer. The buffer display can be enabled +;; by the `vertico-buffer-mode'. + +;;; Code: + +(require 'vertico) + +(defvar-local vertico-buffer--overlay nil) +(defvar-local vertico-buffer--buffer nil) + +(defcustom vertico-buffer-display-action + `(display-buffer-in-side-window + (window-height . ,(+ 3 vertico-count)) + (side . top)) + "Display action for the Vertico buffer." + :type `(choice + (const :tag "Reuse some window" + (display-buffer-reuse-window)) + (const :tag "Below target buffer" + (display-buffer-below-selected + (window-height . ,(+ 3 vertico-count)))) + (const :tag "Bottom of frame" + (display-buffer-at-bottom + (window-height . ,(+ 3 vertico-count)))) + (const :tag "Side window on the right" + (display-buffer-in-side-window + (side . right) + (window-width . 0.3))) + (const :tag "Side window on the left" + (display-buffer-in-side-window + (side . left) + (window-width . 0.3))) + (const :tag "Side window at the top" + (display-buffer-in-side-window + (window-height . ,(+ 3 vertico-count)) + (side . top))) + (const :tag "Side window at the bottom" + (display-buffer-in-side-window + (window-height . ,(+ 3 vertico-count)) + (side . bottom))) + (sexp :tag "Other"))) + +(defun vertico-buffer--display (lines) + "Display LINES in buffer." + (set-window-vscroll nil 100) + (let ((count (vertico--format-count)) + (prompt (minibuffer-prompt)) + (content (minibuffer-contents))) + (with-current-buffer vertico-buffer--buffer + (with-silent-modifications + (erase-buffer) + (insert (propertize (concat count prompt) 'face 'minibuffer-prompt) + content "\n" (string-join lines)))) + (let ((win (or (get-buffer-window vertico-buffer--buffer) + (display-buffer vertico-buffer--buffer vertico-buffer-display-action)))) + (overlay-put vertico--candidates-ov 'window win) + (when vertico--count-ov + (overlay-put vertico--count-ov 'window win)) + (set-window-point win (max (+ 1 (length prompt) (length count)) + (+ (point) (length count)))) + (with-current-buffer vertico-buffer--buffer + (setq-local truncate-lines (< (window-point win) (* 0.8 (window-width win)))))))) + +(defun vertico-buffer--select (_) + "Ensure that cursor is only shown if minibuffer is selected." + (with-current-buffer (buffer-local-value 'vertico-buffer--buffer + (window-buffer (active-minibuffer-window))) + (if (eq (selected-window) (active-minibuffer-window)) + (setq-local cursor-in-non-selected-windows 'box) + (setq-local cursor-in-non-selected-windows nil) + (goto-char (point-min))))) + +(defun vertico-buffer--destroy () + "Destroy Vertico buffer." + (set-window-vscroll nil 0) + (kill-buffer vertico-buffer--buffer)) + +(defun vertico-buffer--setup () + "Setup minibuffer overlay, which pushes the minibuffer content down." + (add-hook 'window-selection-change-functions 'vertico-buffer--select nil 'local) + (add-hook 'minibuffer-exit-hook 'vertico-buffer--destroy nil 'local) + (setq-local cursor-type '(bar . 0)) + (setq vertico-buffer--overlay (make-overlay (point-max) (point-max) nil t t)) + (overlay-put vertico-buffer--overlay 'window (selected-window)) + (overlay-put vertico-buffer--overlay 'priority 1000) + (overlay-put vertico-buffer--overlay 'before-string "\n\n") + (setq vertico-buffer--buffer (get-buffer-create + (if (= 1 (recursion-depth)) + " *Vertico*" + (format " *Vertico-%s*" (1- (recursion-depth)))))) + (with-current-buffer vertico-buffer--buffer + (add-hook 'window-selection-change-functions 'vertico-buffer--select nil 'local) + (setq-local display-line-numbers nil + truncate-lines t + show-trailing-whitespace nil + buffer-read-only t + cursor-in-non-selected-windows 'box))) + +;;;###autoload +(define-minor-mode vertico-buffer-mode + "Display Vertico in a buffer instead of the minibuffer." + :global t :group 'vertico + (cond + (vertico-buffer-mode + (advice-add #'vertico--display-candidates :override #'vertico-buffer--display) + (advice-add #'vertico--setup :after #'vertico-buffer--setup)) + (t + (advice-remove #'vertico--display-candidates #'vertico-buffer--display) + (advice-remove #'vertico--setup #'vertico-buffer--setup)))) + +(provide 'vertico-buffer) +;;; vertico-buffer.el ends here diff --git a/elpa/vertico-0.17/vertico-buffer.elc b/elpa/vertico-0.17/vertico-buffer.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-directory.el b/elpa/vertico-0.17/vertico-directory.el @@ -0,0 +1,113 @@ +;;; vertico-directory.el --- Ido-like direction navigation for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which provides Ido-like +;; directory navigation commands. The commands can be bound in the +;; `vertico-map'. Furthermore a cleanup function for shadowed file paths +;; is provided. +;; +;; (define-key vertico-map "\r" #'vertico-directory-enter) +;; (define-key vertico-map "\d" #'vertico-directory-delete-char) +;; (define-key vertico-map "\M-\d" #'vertico-directory-delete-word) +;; (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy) + +;;; Code: + +(require 'vertico) + +(defun vertico-directory--completing-file-p () + "Return non-nil when completing file names." + (eq 'file + (completion-metadata-get + (completion-metadata + (buffer-substring (minibuffer-prompt-end) + (max (minibuffer-prompt-end) (point))) + minibuffer-completion-table + minibuffer-completion-predicate) + 'category))) + +;;;###autoload +(defun vertico-directory-enter () + "Enter directory or exit completion with current candidate." + (interactive) + (if (and (>= vertico--index 0) + (let ((cand (vertico--candidate))) + (or (string-suffix-p "/" cand) + (and (vertico--remote-p cand) + (string-suffix-p ":" cand)))) + (vertico-directory--completing-file-p)) + (vertico-insert) + (vertico-exit))) + +;;;###autoload +(defun vertico-directory-up () + "Delete directory before point." + (interactive) + (when (and (> (point) (minibuffer-prompt-end)) + (eq (char-before) ?/) + (vertico-directory--completing-file-p)) + (save-excursion + (goto-char (1- (point))) + (when (search-backward "/" (minibuffer-prompt-end) t) + (delete-region (1+ (point)) (point-max)) + t)))) + +;;;###autoload +(defun vertico-directory-delete-char () + "Delete directory or char before point." + (interactive) + (unless (vertico-directory-up) + (call-interactively #'backward-delete-char))) + +;;;###autoload +(defun vertico-directory-delete-word () + "Delete directory or word before point." + (interactive) + (unless (vertico-directory-up) + (let ((pt (point))) + (forward-word -1) + (delete-region pt (point))))) + +;;;###autoload +(defun vertico-directory-tidy () + "Tidy shadowed file name, see `rfn-eshadow-overlay'." + (when (and (eq this-command #'self-insert-command) + (bound-and-true-p rfn-eshadow-overlay) + (overlay-buffer rfn-eshadow-overlay) + (= (point) (point-max)) + (or (>= (- (point) (overlay-end rfn-eshadow-overlay)) 2) + (eq ?/ (char-before (- (point) 2))))) + (delete-region (overlay-start rfn-eshadow-overlay) (overlay-end rfn-eshadow-overlay)))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-directory-up vertico-directory-enter + vertico-directory-delete-char vertico-directory-delete-word)) + (put sym 'completion-predicate #'vertico--command-p)) + +(provide 'vertico-directory) +;;; vertico-directory.el ends here diff --git a/elpa/vertico-0.17/vertico-directory.elc b/elpa/vertico-0.17/vertico-directory.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-flat.el b/elpa/vertico-0.17/vertico-flat.el @@ -0,0 +1,122 @@ +;;; vertico-flat.el --- Flat, horizontal display for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension providing a horizontal display. +;; +;; The mode can be bound to a key to toggle to the horizontal display. +;; (define-key vertico-map "\M-F" #'vertico-flat-mode) + +;;; Code: + +(require 'vertico) + +(defcustom vertico-flat-max-lines 1 + "Maximal number of lines to use." + :type 'integer + :group 'vertico) + +(defcustom vertico-flat-format + '(:left #("{" 0 1 (face minibuffer-prompt)) + :separator #(" | " 0 3 (face minibuffer-prompt)) + :right #("}" 0 1 (face minibuffer-prompt)) + :ellipsis #("…" 0 1 (face minibuffer-prompt)) + :no-match "[No match]") + "Formatting strings." + :type 'plist + :group 'vertico) + +(defun vertico-flat--display (candidates) + "Display CANDIDATES horizontally." + (setq-local truncate-lines nil) + (move-overlay vertico--candidates-ov (point-max) (point-max)) + (overlay-put + vertico--candidates-ov 'after-string + (concat #(" " 0 1 (cursor t)) + (if candidates + (concat (plist-get vertico-flat-format :left) + (string-join candidates (plist-get vertico-flat-format :separator)) + (plist-get vertico-flat-format :right)) + (plist-get vertico-flat-format :no-match))))) + +(defun vertico-flat--arrange-candidates () + "Arrange candidates." + (let* ((index (max 0 vertico--index)) (count vertico-count) + (candidates (nthcdr vertico--index vertico--candidates)) + (width (- (* vertico-flat-max-lines (- (window-width) 4)) + (length (plist-get vertico-flat-format :left)) + (length (plist-get vertico-flat-format :separator)) + (length (plist-get vertico-flat-format :right)) + (length (plist-get vertico-flat-format :ellipsis)) + (car (posn-col-row (posn-at-point (1- (point-max))))))) + (result) (wrapped)) + (while (and candidates (not (eq wrapped (car candidates))) + (> width 0) (> count 0)) + (let ((cand (car candidates))) + (setq cand (car (funcall vertico--highlight-function (list cand)))) + (when (string-match-p "\n" cand) + (setq cand (vertico--truncate-multiline cand width))) + (setq cand (string-trim + (replace-regexp-in-string + "[ \t]+" + (lambda (x) (apply #'propertize " " (text-properties-at 0 x))) + (vertico--format-candidate cand "" "" index vertico--index)))) + (setq index (1+ index) + count (1- count) + width (- width (string-width cand) (length (plist-get vertico-flat-format :separator)))) + (when (or (not result) (> width 0)) + (push cand result)) + (pop candidates) + (when (and vertico-cycle (not candidates)) + (setq candidates vertico--candidates index 0 + wrapped (nth vertico--index vertico--candidates))))) + (when (if wrapped + (> vertico--total (- vertico-count count)) + (and (/= vertico--total 0) (/= index vertico--total))) + (push (plist-get vertico-flat-format :ellipsis) result)) + (nreverse result))) + +;;;###autoload +(define-minor-mode vertico-flat-mode + "Flat, horizontal display for Vertico." + :global t :group 'vertico + (cond + (vertico-flat-mode + ;; Allow toggling between flat and grid modes + (when (and (bound-and-true-p vertico-grid-mode) (fboundp #'vertico-grid-mode)) + (vertico-grid-mode -1)) + ;; Shrink current minibuffer window + (when-let (win (active-minibuffer-window)) + (window-resize win (- (window-pixel-height)) nil nil 'pixelwise)) + (advice-add #'vertico--arrange-candidates :override #'vertico-flat--arrange-candidates) + (advice-add #'vertico--display-candidates :override #'vertico-flat--display)) + (t + (advice-remove #'vertico--arrange-candidates #'vertico-flat--arrange-candidates) + (advice-remove #'vertico--display-candidates #'vertico-flat--display)))) + +(provide 'vertico-flat) +;;; vertico-flat.el ends here diff --git a/elpa/vertico-0.17/vertico-flat.elc b/elpa/vertico-0.17/vertico-flat.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-grid.el b/elpa/vertico-0.17/vertico-grid.el @@ -0,0 +1,158 @@ +;;; vertico-grid.el --- Grid display for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension providing a grid display. +;; +;; The mode can be bound to a key to toggle to the grid display. +;; (define-key vertico-map "\M-G" #'vertico-grid-mode) + +;;; Code: + +(require 'vertico) +(eval-when-compile + (require 'cl-lib)) + +(defcustom vertico-grid-max-columns 8 + "Maximal number of grid columns." + :type 'integer + :group 'vertico) + +(defcustom vertico-grid-separator + #(" | " 2 3 (display (space :width (1)) face (:inverse-video t))) + "Separator between columns." + :type 'string + :group 'vertico) + +(defcustom vertico-grid-rows 6 + "Number of grid rows." + :type 'integer + :group 'vertico) + +(defcustom vertico-grid-lookahead 200 + "Number of candidates to lookahead for column number computation. +When scrolling beyond this limit, candidates may be truncated." + :type 'integer + :group 'vertico) + +(defvar-local vertico-grid--columns 1 + "Current number of grid columns.") + +(defun vertico-grid--arrange-candidates () + "Arrange candidates." + (when (<= vertico--index 0) + (let ((cand vertico--candidates) (w 1) (n 0)) + (while (and cand (< n vertico-grid-lookahead)) + (setq w (max w (length (car cand))) n (1+ n)) + (pop cand)) + (setq vertico-grid--columns + (max 1 (min vertico-grid-max-columns + (floor (window-width) (+ w (length vertico-grid-separator)))))))) + (let* ((sep (length vertico-grid-separator)) + (count (* vertico-grid-rows vertico-grid--columns)) + (start (* count (floor (max 0 vertico--index) count))) + (width (- (/ (window-width) vertico-grid--columns) sep)) + (cands + (seq-map-indexed (lambda (cand index) + (cl-incf index start) + (when (string-match-p "\n" cand) + (setq cand (vertico--truncate-multiline cand width))) + (truncate-string-to-width + (string-trim + (replace-regexp-in-string + "[ \t]+" + (lambda (x) (apply #'propertize " " (text-properties-at 0 x))) + (vertico--format-candidate cand "" "" index start))) + width)) + (funcall vertico--highlight-function + (seq-subseq vertico--candidates start + (min (+ start count) + vertico--total))))) + (width (make-vector vertico-grid--columns 0))) + (dotimes (col vertico-grid--columns) + (dotimes (row vertico-grid-rows) + (aset width col (max + (aref width col) + (string-width (or (nth (+ row (* col vertico-grid-rows)) cands) "")))))) + (dotimes (col (1- vertico-grid--columns)) + (cl-incf (aref width (1+ col)) (+ (aref width col) sep))) + (cl-loop for row from 0 to (1- vertico-grid-rows) collect + (let ((line (list "\n"))) + (cl-loop for col from (1- vertico-grid--columns) downto 0 do + (when-let (cand (nth (+ row (* col vertico-grid-rows)) cands)) + (push cand line) + (when (> col 0) + (push vertico-grid-separator line) + (push (propertize " " 'display + `(space :align-to (+ left ,(aref width (1- col))))) line)))) + (string-join line))))) + +(defun vertico-grid-left (&optional n) + "Move N columns to the left in the grid." + (interactive "p") + (vertico-grid-right (- (or n 1)))) + +(defun vertico-grid-right (&optional n) + "Move N columns to the right in the grid." + (interactive "p") + (let* ((page (* vertico-grid-rows vertico-grid--columns)) + (p (/ vertico--index page)) + (q (mod vertico--index page)) + (x (/ q vertico-grid-rows)) + (y (mod q vertico-grid-rows)) + (z (+ (* p page) (* vertico-grid--columns y) x (or n 1)))) + (setq x (mod z vertico-grid--columns) + y (/ z vertico-grid--columns)) + (vertico--goto (+ (* x vertico-grid-rows) (mod y vertico-grid-rows) + (* (/ y vertico-grid-rows) page))))) + +;;;###autoload +(define-minor-mode vertico-grid-mode + "Grid display for Vertico." + :global t :group 'vertico + (cond + (vertico-grid-mode + ;; Allow toggling between flat and grid modes + (when (and (bound-and-true-p vertico-flat-mode) (fboundp #'vertico-flat-mode)) + (vertico-flat-mode -1)) + ;; Shrink current minibuffer window + (when-let (win (active-minibuffer-window)) + (window-resize win (- (window-pixel-height)) nil nil 'pixelwise)) + (define-key vertico-map [remap left-char] #'vertico-grid-left) + (define-key vertico-map [remap right-char] #'vertico-grid-right) + (advice-add #'vertico--arrange-candidates :override #'vertico-grid--arrange-candidates)) + (t + (assq-delete-all 'left-char (assq 'remap vertico-map)) + (assq-delete-all 'right-char (assq 'remap vertico-map)) + (advice-remove #'vertico--arrange-candidates #'vertico-grid--arrange-candidates)))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-grid-left vertico-grid-right)) + (put sym 'completion-predicate #'vertico--command-p)) + +(provide 'vertico-grid) +;;; vertico-grid.el ends here diff --git a/elpa/vertico-0.17/vertico-grid.elc b/elpa/vertico-0.17/vertico-grid.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-indexed.el b/elpa/vertico-0.17/vertico-indexed.el @@ -0,0 +1,83 @@ +;;; vertico-indexed.el --- Select indexed candidates -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which prefixes candidates with +;; indices and allows selection using prefix arguments. + +;;; Code: + +(require 'vertico) + +(defface vertico-indexed + '((t :height 0.75 :inherit font-lock-comment-face)) + "Face used for the candidate index prefix." + :group 'vertico-faces) + +(defvar vertico-indexed--commands + '(vertico-insert vertico-exit vertico-directory-enter)) +(defvar-local vertico-indexed--min 0) +(defvar-local vertico-indexed--max 0) + +(defun vertico-indexed--format-candidate (orig cand prefix suffix index start) + "Format candidate, see `vertico--format-candidate' for arguments." + (setq vertico-indexed--min start vertico-indexed--max index) + (funcall orig cand + (concat (propertize (format + (format "%%%ds " (if (> vertico-count 10) 2 1)) + (- index start)) + 'face 'vertico-indexed) + prefix) + suffix index start)) + +(defun vertico-indexed--handle-prefix (orig &rest args) + "Handle prefix argument before calling ORIG function with ARGS." + (if (and current-prefix-arg (called-interactively-p t)) + (let ((vertico--index (+ vertico-indexed--min (prefix-numeric-value current-prefix-arg)))) + (if (or (< vertico--index vertico-indexed--min) + (> vertico--index vertico-indexed--max) + (= vertico--total 0)) + (minibuffer-message "Out of range") + (funcall orig))) + (apply orig args))) + +;;;###autoload +(define-minor-mode vertico-indexed-mode + "Prefix candidates with indices." + :global t :group 'vertico + (cond + (vertico-indexed-mode + (advice-add #'vertico--format-candidate :around #'vertico-indexed--format-candidate) + (dolist (cmd vertico-indexed--commands) + (advice-add cmd :around #'vertico-indexed--handle-prefix))) + (t + (advice-remove #'vertico--format-candidate #'vertico-indexed--format-candidate) + (dolist (cmd vertico-indexed--commands) + (advice-remove cmd #'vertico-indexed--handle-prefix))))) + +(provide 'vertico-indexed) +;;; vertico-indexed.el ends here diff --git a/elpa/vertico-0.17/vertico-indexed.elc b/elpa/vertico-0.17/vertico-indexed.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-mouse.el b/elpa/vertico-0.17/vertico-mouse.el @@ -0,0 +1,95 @@ +;;; vertico-mouse.el --- Mouse support for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which adds mouse support. + +;;; Code: + +(require 'vertico) + +(defface vertico-mouse + '((t :inherit highlight)) + "Face used for mouse highlighting." + :group 'vertico-faces) + +(defun vertico--mouse-candidate-map (index) + "Return keymap for candidate with INDEX." + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] (lambda () + (interactive) + (with-selected-window (active-minibuffer-window) + (let ((vertico--index index)) + (vertico-exit))))) + (define-key map [mouse-3] (lambda () + (interactive) + (with-selected-window (active-minibuffer-window) + (let ((vertico--index index)) + (vertico-insert))))) + map)) + +(defun vertico-mouse--format-candidate (orig cand prefix suffix index start) + "Format candidate, see `vertico--format-candidate' for arguments." + (setq cand (funcall orig cand prefix suffix index start)) + (when (equal suffix "") + (setq cand (concat (substring cand 0 -1) + (propertize " " 'display '(space :align-to right)) + "\n")) + (when (= index vertico--index) + (add-face-text-property 0 (length cand) 'vertico-current 'append cand))) + (add-text-properties 0 (1- (length cand)) + `(mouse-face vertico-mouse keymap ,(vertico--mouse-candidate-map index)) + cand) + cand) + +(defun vertico-mouse--scroll-up (n) + "Scroll up by N lines." + (vertico--goto (max 0 (+ vertico--index n)))) + +(defun vertico-mouse--scroll-down (n) + "Scroll down by N lines." + (vertico-mouse--scroll-up (- n))) + +(defun vertico-mouse--setup () + "Setup mouse scrolling." + (setq-local mwheel-scroll-up-function #'vertico-mouse--scroll-up + mwheel-scroll-down-function #'vertico-mouse--scroll-down)) + +;;;###autoload +(define-minor-mode vertico-mouse-mode + "Mouse support for Vertico." + :global t :group 'vertico + (cond + (vertico-mouse-mode + (advice-add #'vertico--format-candidate :around #'vertico-mouse--format-candidate) + (advice-add #'vertico--setup :after #'vertico-mouse--setup)) + (t + (advice-remove #'vertico--format-candidate #'vertico-mouse--format-candidate) + (advice-remove #'vertico--setup #'vertico-reverse--setup)))) + +(provide 'vertico-mouse) +;;; vertico-mouse.el ends here diff --git a/elpa/vertico-0.17/vertico-mouse.elc b/elpa/vertico-0.17/vertico-mouse.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-pkg.el b/elpa/vertico-0.17/vertico-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from vertico.el -*- no-byte-compile: t -*- +(define-package "vertico" "0.17" "VERTical Interactive COmpletion" '((emacs "27.1")) :authors '(("Daniel Mendler" . "mail@daniel-mendler.de")) :maintainer '("Daniel Mendler" . "mail@daniel-mendler.de") :url "https://github.com/minad/vertico") diff --git a/elpa/vertico-0.17/vertico-quick.el b/elpa/vertico-0.17/vertico-quick.el @@ -0,0 +1,140 @@ +;;; vertico-quick.el --- Quick keys for Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which provides quick keys. +;; (define-key vertico-map "\M-q" #'vertico-quick-insert) +;; (define-key vertico-map "\C-q" #'vertico-quick-exit) + +;;; Code: + +(require 'vertico) +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) + +(defface vertico-quick1 + '((((class color) (min-colors 88) (background dark)) + :background "#7042a2" :weight bold :foreground "white") + (((class color) (min-colors 88) (background light)) + :weight bold :background "#d5baff" :foreground "black") + (t :background "magenta" :foreground "white")) + "Face used for the first quick key." + :group 'vertico-faces) + +(defface vertico-quick2 + '((((class color) (min-colors 88) (background dark)) + :background "#004065" :weight bold :foreground "white") + (((class color) (min-colors 88) (background light)) + :weight bold :background "#8ae4f2" :foreground "black") + (t :background "blue" :foreground "white")) + "Face used for the second quick key." + :group 'vertico-faces) + +(defcustom vertico-quick1 "asdfgh" + "Single level quick keys." + :type 'string + :group 'vertico) + +(defcustom vertico-quick2 "jkl" + "Two level quick keys." + :type 'string + :group 'vertico) + +(defvar-local vertico-quick--list nil) +(defvar-local vertico-quick--first nil) + +(defun vertico-quick--format-candidate (orig cand prefix suffix index start) + "Format candidate, see `vertico--format-candidate' for arguments." + (let* ((fst (length vertico-quick1)) + (snd (length vertico-quick2)) + (len (+ fst snd)) + (idx (- index start)) + (keys (if (>= idx fst) + (let ((first (elt vertico-quick2 (mod (/ (- idx fst) len) snd))) + (second (elt (concat vertico-quick1 vertico-quick2) (mod (- idx fst) len)))) + (cond + ((eq first vertico-quick--first) + (push (cons second index) vertico-quick--list) + (concat " " (propertize (char-to-string second) 'face 'vertico-quick1))) + (vertico-quick--first " ") + (t + (push (cons first (list first)) vertico-quick--list) + (concat (propertize (char-to-string first) 'face 'vertico-quick1) + (propertize (char-to-string second) 'face 'vertico-quick2))))) + (let ((first (elt vertico-quick1 (mod idx fst)))) + (if vertico-quick--first + " " + (push (cons first index) vertico-quick--list) + (concat (propertize (char-to-string first) 'face 'vertico-quick1) " ")))))) + (if (bound-and-true-p vertico-flat-mode) + (setq keys (replace-regexp-in-string " " "" keys) + cand (string-trim cand) + cand (substring cand (min (length cand) (length keys)))) + (setq keys (concat keys (make-string (max 1 (- (length prefix) 2)) ?\s)))) + (funcall orig cand keys suffix index start))) + +(defun vertico-quick--read (&optional first) + "Read quick key given FIRST pressed key." + (cl-letf (((symbol-function #'vertico--format-candidate) + (apply-partially #'vertico-quick--format-candidate + (symbol-function #'vertico--format-candidate))) + (vertico-quick--first first) + (vertico-quick--list)) + (vertico--exhibit) + (alist-get (read-key) vertico-quick--list))) + +;;;###autoload +(defun vertico-quick-jump () + "Jump to candidate using quick keys." + (interactive) + (if (= vertico--total 0) + (and (minibuffer-message "No match") nil) + (let ((idx (vertico-quick--read))) + (when (consp idx) (setq idx (vertico-quick--read (car idx)))) + (when idx (setq vertico--index idx))))) + +;;;###autoload +(defun vertico-quick-exit () + "Exit with candidate using quick keys." + (interactive) + (when (vertico-quick-jump) + (vertico-exit))) + +;;;###autoload +(defun vertico-quick-insert () + "Insert candidate using quick keys." + (interactive) + (when (vertico-quick-jump) + (vertico-insert))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-quick-jump vertico-quick-exit vertico-quick-insert)) + (put sym 'completion-predicate #'vertico--command-p)) + +(provide 'vertico-quick) +;;; vertico-quick.el ends here diff --git a/elpa/vertico-0.17/vertico-quick.elc b/elpa/vertico-0.17/vertico-quick.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-repeat.el b/elpa/vertico-0.17/vertico-repeat.el @@ -0,0 +1,96 @@ +;;; vertico-repeat.el --- Repeat the last Vertico session -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which allows to repeat the last +;; Vertico session via the `vertico-repeat' command. +;; +;; (global-set-key "\M-r" #'vertico-repeat) +;; +;; It is necessary to register a minibuffer setup hook, which saves the +;; Vertico state for repetition. +;; +;; (add-hook 'minibuffer-setup-hook #'vertico-repeat-save) + +;;; Code: + +(require 'vertico) + +(defvar-local vertico-repeat--restore nil) +(defvar vertico-repeat--input nil) +(defvar vertico-repeat--command nil) +(defvar vertico-repeat--candidate nil) + +(defun vertico-repeat--save-input () + "Save current minibuffer content for `vertico-repeat'." + (setq vertico-repeat--input (minibuffer-contents))) + +(defun vertico-repeat--save-candidate () + "Save currently selected candidate for `vertico-repeat'." + (setq vertico-repeat--candidate + (and vertico--lock-candidate + (>= vertico--index 0) + (nth vertico--index vertico--candidates)))) + +(defun vertico-repeat--restore () + "Restore Vertico status for `vertico-repeat'." + (setq vertico-repeat--restore t) + (delete-minibuffer-contents) + (insert vertico-repeat--input) + (when vertico-repeat--candidate + (run-at-time 0 nil + (lambda () + (when-let (idx (seq-position vertico--candidates vertico-repeat--candidate)) + (setq vertico--index idx + vertico--lock-candidate t) + (vertico--exhibit)))))) + +;;;###autoload +(defun vertico-repeat () + "Repeat last Vertico completion session." + (interactive) + (unless vertico-repeat--command + (user-error "No repeatable Vertico session")) + (minibuffer-with-setup-hook + #'vertico-repeat--restore + (command-execute (setq this-command vertico-repeat--command)))) + +;;;###autoload +(defun vertico-repeat-save () + "Save Vertico status for `vertico-repeat'. +This function must be registered as `minibuffer-setup-hook'." + (when vertico--input + (unless vertico-repeat--restore + (setq vertico-repeat--command this-command + vertico-repeat--input "" + vertico-repeat--candidate nil + vertico-repeat--restore nil)) + (add-hook 'post-command-hook #'vertico-repeat--save-input nil 'local) + (add-hook 'minibuffer-exit-hook #'vertico-repeat--save-candidate nil 'local))) + +(provide 'vertico-repeat) +;;; vertico-repeat.el ends here diff --git a/elpa/vertico-0.17/vertico-repeat.elc b/elpa/vertico-0.17/vertico-repeat.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico-reverse.el b/elpa/vertico-0.17/vertico-reverse.el @@ -0,0 +1,79 @@ +;;; vertico-reverse.el --- Reverse the Vertico display -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.1 +;; Package-Requires: ((emacs "27.1") (vertico "0.17")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package is a Vertico extension, which reverses the list of candidates. + +;;; Code: + +(require 'vertico) + +(defvar vertico-reverse-map + (let ((map (make-composed-keymap nil vertico-map))) + (define-key map [remap beginning-of-buffer] #'vertico-last) + (define-key map [remap minibuffer-beginning-of-buffer] #'vertico-last) + (define-key map [remap end-of-buffer] #'vertico-first) + (define-key map [remap scroll-down-command] #'vertico-scroll-up) + (define-key map [remap scroll-up-command] #'vertico-scroll-down) + (define-key map [remap next-line] #'vertico-previous) + (define-key map [remap previous-line] #'vertico-next) + (define-key map [remap next-line-or-history-element] #'vertico-previous) + (define-key map [remap previous-line-or-history-element] #'vertico-next) + (define-key map [remap backward-paragraph] #'vertico-next-group) + (define-key map [remap forward-paragraph] #'vertico-previous-group) + map) + "Vertico keymap adapted to reversed candidate order.") + +(defun vertico-reverse--display (lines) + "Display LINES in reverse." + (move-overlay vertico--candidates-ov (point-min) (point-min)) + (setq lines (nreverse lines)) + (unless (eq vertico-resize t) + (setq lines (nconc (make-list (max 0 (- vertico-count (length lines))) "\n") lines))) + (let ((string (apply #'concat lines))) + (add-face-text-property 0 (length string) 'default 'append string) + (overlay-put vertico--candidates-ov 'before-string string)) + (vertico--resize-window (length lines))) + +(defun vertico-reverse--setup () + "Setup reverse keymap." + (use-local-map vertico-reverse-map)) + +;;;###autoload +(define-minor-mode vertico-reverse-mode + "Reverse the Vertico display." + :global t :group 'vertico + (cond + (vertico-reverse-mode + (advice-add #'vertico--display-candidates :override #'vertico-reverse--display) + (advice-add #'vertico--setup :after #'vertico-reverse--setup)) + (t + (advice-remove #'vertico--display-candidates #'vertico-reverse--display) + (advice-remove #'vertico--setup #'vertico-reverse--setup)))) + +(provide 'vertico-reverse) +;;; vertico-reverse.el ends here diff --git a/elpa/vertico-0.17/vertico-reverse.elc b/elpa/vertico-0.17/vertico-reverse.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico.el b/elpa/vertico-0.17/vertico.el @@ -0,0 +1,790 @@ +;;; vertico.el --- VERTical Interactive COmpletion -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Daniel Mendler <mail@daniel-mendler.de> +;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> +;; Created: 2021 +;; Version: 0.17 +;; Package-Requires: ((emacs "27.1")) +;; Homepage: https://github.com/minad/vertico + +;; This file is part of GNU Emacs. + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Vertico provides a performant and minimalistic vertical completion UI +;; based on the default completion system. By reusing the built-in +;; facilities, Vertico achieves full compatibility with built-in Emacs +;; completion commands and completion tables. + +;;; Code: + +(require 'seq) +(eval-when-compile + (require 'cl-lib) + (require 'subr-x)) + +(defgroup vertico nil + "VERTical Interactive COmpletion." + :group 'convenience + :group 'minibuffer + :prefix "vertico-") + +(defcustom vertico-count-format (cons "%-6s " "%s/%s") + "Format string used for the candidate count." + :type '(choice (const :tag "No candidate count" nil) (cons string string))) + +(defcustom vertico-group-format + (concat #(" " 0 4 (face vertico-group-separator)) + #(" %s " 0 4 (face vertico-group-title)) + #(" " 0 1 (face vertico-group-separator display (space :align-to right)))) + "Format string used for the group title." + :type '(choice (const :tag "No group titles" nil) string)) + +(defcustom vertico-count 10 + "Maximal number of candidates to show." + :type 'integer) + +(defcustom vertico-scroll-margin 2 + "Number of lines at the top and bottom when scrolling. +The value should lie between 0 and vertico-count/2." + :type 'integer) + +(defcustom vertico-resize resize-mini-windows + "How to resize the Vertico minibuffer window. +See `resize-mini-windows' for documentation." + :type '(choice (const :tag "Fixed" nil) + (const :tag "Shrink and grow" t) + (const :tag "Grow-only" grow-only))) + +(defcustom vertico-cycle nil + "Enable cycling for `vertico-next' and `vertico-previous'." + :type 'boolean) + +(defcustom vertico-multiline + (cons #("⤶" 0 1 (face vertico-multiline)) #("…" 0 1 (face vertico-multiline))) + "Replacements for multiline strings." + :type '(cons (string :tag "Newline") (string :tag "Truncation"))) + +(defcustom vertico-sort-function #'vertico-sort-history-length-alpha + "Default sorting function, used if no `display-sort-function' is specified." + :type `(choice + (const :tag "No sorting" nil) + (const :tag "By history, length and alpha" ,#'vertico-sort-history-length-alpha) + (const :tag "By history and alpha" ,#'vertico-sort-history-alpha) + (const :tag "By length and alpha" ,#'vertico-sort-length-alpha) + (const :tag "Alphabetically" ,#'vertico-sort-alpha) + (function :tag "Custom function"))) + +(defgroup vertico-faces nil + "Faces used by Vertico." + :group 'vertico + :group 'faces) + +(defface vertico-multiline '((t :inherit shadow)) + "Face used to highlight multiline replacement characters.") + +(defface vertico-group-title '((t :inherit shadow :slant italic)) + "Face used for the title text of the candidate group headlines.") + +(defface vertico-group-separator '((t :inherit shadow :strike-through t)) + "Face used for the separator lines of the candidate groups.") + +(defface vertico-current '((t :inherit highlight :extend t)) + "Face used to highlight the currently selected candidate.") + +(defvar vertico-map + (let ((map (make-composed-keymap nil minibuffer-local-map))) + (define-key map [remap beginning-of-buffer] #'vertico-first) + (define-key map [remap minibuffer-beginning-of-buffer] #'vertico-first) + (define-key map [remap end-of-buffer] #'vertico-last) + (define-key map [remap scroll-down-command] #'vertico-scroll-down) + (define-key map [remap scroll-up-command] #'vertico-scroll-up) + (define-key map [remap next-line] #'vertico-next) + (define-key map [remap previous-line] #'vertico-previous) + (define-key map [remap next-line-or-history-element] #'vertico-next) + (define-key map [remap previous-line-or-history-element] #'vertico-previous) + (define-key map [remap backward-paragraph] #'vertico-previous-group) + (define-key map [remap forward-paragraph] #'vertico-next-group) + (define-key map [remap exit-minibuffer] #'vertico-exit) + (define-key map [remap kill-ring-save] #'vertico-save) + (define-key map [C-return] #'vertico-exit-input) + (define-key map "\t" #'vertico-insert) + map) + "Vertico minibuffer keymap derived from `minibuffer-local-map'.") + +(defvar-local vertico--highlight-function #'identity + "Deferred candidate highlighting function.") + +(defvar-local vertico--history-hash nil + "History hash table.") + +(defvar-local vertico--history-base nil + "Base prefix of `vertico--history-hash'.") + +(defvar-local vertico--candidates-ov nil + "Overlay showing the candidates.") + +(defvar-local vertico--count-ov nil + "Overlay showing the number of candidates.") + +(defvar-local vertico--index -1 + "Index of current candidate or negative for prompt selection.") + +(defvar-local vertico--scroll 0 + "Scroll position.") + +(defvar-local vertico--input nil + "Cons of last minibuffer contents and point or t.") + +(defvar-local vertico--candidates nil + "List of candidates.") + +(defvar-local vertico--metadata nil + "Completion metadata.") + +(defvar-local vertico--base 0 + "Size of the base string, which is concatenated with the candidate.") + +(defvar-local vertico--total 0 + "Length of the candidate list `vertico--candidates'.") + +(defvar-local vertico--lock-candidate nil + "Lock-in current candidate.") + +(defvar-local vertico--lock-groups nil + "Lock-in current group order.") + +(defvar-local vertico--all-groups nil + "List of all group titles.") + +(defvar-local vertico--groups nil + "List of current group titles.") + +(defvar-local vertico--default-missing nil + "Default candidate is missing from candidates list.") + +(defun vertico--history-hash () + "Recompute history hash table and return it." + (or vertico--history-hash + (let* ((base vertico--history-base) + (base-size (length base)) + ;; History disabled if `minibuffer-history-variable' eq `t'. + (hist (and (not (eq minibuffer-history-variable t)) + (symbol-value minibuffer-history-variable))) + (hash (make-hash-table :test #'equal :size (length hist)))) + (if (= base-size 0) + ;; Put history elements into the hash + (cl-loop for elem in hist for index from 0 do + (unless (gethash elem hash) + (puthash elem index hash))) + ;; Drop base string from history elements, before putting them into the hash + (cl-loop for elem in hist for index from 0 do + (when (and (>= (length elem) base-size) + (eq t (compare-strings base 0 base-size elem 0 base-size))) + (setq elem (substring elem base-size)) + (unless (gethash elem hash) + (puthash elem index hash))))) + (setq vertico--history-hash hash)))) + +(defun vertico--length-string< (x y) + "Sorting predicate which compares X and Y first by length then by `string<'." + (or (< (length x) (length y)) (and (= (length x) (length y)) (string< x y)))) + +(defun vertico--sort-decorated (list) + "Sort decorated LIST and remove decorations." + (setq list (sort list #'car-less-than-car)) + (cl-loop for item on list do (setcar item (cdar item))) + list) + +(defmacro vertico--define-sort (by bsize bindex bpred pred) + "Generate optimized sorting function. +The function is configured by BY, BSIZE, BINDEX, BPRED and PRED." + `(defun ,(intern (mapconcat #'symbol-name `(vertico sort ,@by) "-")) (candidates) + ,(concat "Sort candidates by " (mapconcat #'symbol-name by ", ") ".") + (let* ((buckets (make-vector ,bsize nil)) + ,@(and (eq (car by) 'history) '((hhash (vertico--history-hash)) (hcands)))) + (dolist (% candidates) + ,(if (eq (car by) 'history) + ;; Find recent candidates or fill buckets + `(if-let (idx (gethash % hhash)) + (push (cons idx %) hcands) + (let ((idx (min ,(1- bsize) ,bindex))) + (aset buckets idx (cons % (aref buckets idx))))) + ;; Fill buckets + `(let ((idx (min ,(1- bsize) ,bindex))) + (aset buckets idx (cons % (aref buckets idx)))))) + (nconc ,@(and (eq (car by) 'history) '((vertico--sort-decorated hcands))) + (mapcan (lambda (bucket) (sort bucket #',bpred)) + (nbutlast (append buckets nil))) + ;; Last bucket needs special treatment + (sort (aref buckets ,(1- bsize)) #',pred))))) + +(vertico--define-sort (history length alpha) 32 (length %) string< vertico--length-string<) +(vertico--define-sort (history alpha) 32 (if (eq % "") 0 (/ (aref % 0) 4)) string< string<) +(vertico--define-sort (length alpha) 32 (length %) string< vertico--length-string<) +(vertico--define-sort (alpha) 32 (if (eq % "") 0 (/ (aref % 0) 4)) string< string<) + +(defun vertico--affixate (cands) + "Annotate CANDS with annotation function." + (if-let (aff (or (vertico--metadata-get 'affixation-function) + (plist-get completion-extra-properties :affixation-function))) + (funcall aff cands) + (if-let (ann (or (vertico--metadata-get 'annotation-function) + (plist-get completion-extra-properties :annotation-function))) + (cl-loop for cand in cands collect + (let ((suffix (or (funcall ann cand) ""))) + (list cand "" + ;; The default completion UI adds the `completions-annotations' face + ;; if no other faces are present. + (if (text-property-not-all 0 (length suffix) 'face nil suffix) + suffix + (propertize suffix 'face 'completions-annotations))))) + (cl-loop for cand in cands collect (list cand "" ""))))) + +(defun vertico--move-to-front (elem list) + "Move ELEM to front of LIST." + (if-let (found (member elem list)) + (let ((head (list (car found)))) + (nconc head (delq (setcar found nil) list))) + list)) + +;; bug#47711: Deferred highlighting for `completion-all-completions' +;; XXX There is one complication: `completion--twq-all' already adds `completions-common-part'. +;; See below `vertico--candidate'. +(defun vertico--all-completions (&rest args) + "Compute all completions for ARGS with deferred highlighting." + (cl-letf* ((orig-pcm (symbol-function #'completion-pcm--hilit-commonality)) + (orig-flex (symbol-function #'completion-flex-all-completions)) + ((symbol-function #'completion-flex-all-completions) + (lambda (&rest args) + ;; Unfortunately for flex we have to undo the deferred highlighting, since flex uses + ;; the completion-score for sorting, which is applied during highlighting. + (cl-letf (((symbol-function #'completion-pcm--hilit-commonality) orig-pcm)) + (apply orig-flex args)))) + ;; Defer the following highlighting functions + (hl #'identity) + ((symbol-function #'completion-hilit-commonality) + (lambda (cands prefix &optional base) + (setq hl (lambda (x) (nconc (completion-hilit-commonality x prefix base) nil))) + (and cands (nconc cands base)))) + ((symbol-function #'completion-pcm--hilit-commonality) + (lambda (pattern cands) + (setq hl (lambda (x) + ;; `completion-pcm--hilit-commonality' sometimes throws an internal error + ;; for example when entering "/sudo:://u". + (condition-case nil + (completion-pcm--hilit-commonality pattern x) + (t x)))) + cands))) + ;; Only advise orderless after it has been loaded to avoid load order issues + (if (and (fboundp 'orderless-highlight-matches) (fboundp 'orderless-pattern-compiler)) + (cl-letf (((symbol-function 'orderless-highlight-matches) + (lambda (pattern cands) + (let ((regexps (orderless-pattern-compiler pattern))) + (setq hl (lambda (x) (orderless-highlight-matches regexps x)))) + cands))) + (cons (apply #'completion-all-completions args) hl)) + (cons (apply #'completion-all-completions args) hl)))) + +(defun vertico--metadata-get (prop) + "Return PROP from completion metadata." + (completion-metadata-get vertico--metadata prop)) + +(defun vertico--sort-function () + "Return the sorting function." + (or (vertico--metadata-get 'display-sort-function) vertico-sort-function)) + +(defun vertico--filter-files (files) + "Filter FILES by `completion-ignored-extensions'." + (let ((re (concat "\\(?:\\(?:\\`\\|/\\)\\.\\.?/\\|" + (regexp-opt completion-ignored-extensions) + "\\)\\'"))) + (or (seq-remove (lambda (x) (string-match-p re x)) files) files))) + +(defun vertico--recompute-candidates (pt content) + "Recompute candidates given PT and CONTENT." + (pcase-let* ((before (substring content 0 pt)) + (after (substring content pt)) + ;; bug#47678: `completion-boundaries` fails for `partial-completion` + ;; if the cursor is moved between the slashes of "~//". + ;; See also marginalia.el which has the same issue. + (bounds (or (condition-case nil + (completion-boundaries before + minibuffer-completion-table + minibuffer-completion-predicate + after) + (t (cons 0 (length after)))))) + (field (substring content (car bounds) (+ pt (cdr bounds)))) + ;; `minibuffer-completing-file-name' has been obsoleted by the completion category + (completing-file (eq 'file (vertico--metadata-get 'category))) + (`(,all . ,hl) (vertico--all-completions content + minibuffer-completion-table + minibuffer-completion-predicate + pt vertico--metadata)) + (base (or (when-let (z (last all)) (prog1 (cdr z) (setcdr z nil))) 0)) + (base-str (substring content 0 base)) + (def (or (car-safe minibuffer-default) minibuffer-default)) + (groups)) + ;; Reset the history hash table + (unless (equal base-str vertico--history-base) + (setq vertico--history-base base-str vertico--history-hash nil)) + ;; Filter the ignored file extensions. We cannot use modified predicate for this filtering, + ;; since this breaks the special casing in the `completion-file-name-table' for `file-exists-p' + ;; and `file-directory-p'. + (when completing-file + (setq all (vertico--filter-files all))) + ;; Sort using the `display-sort-function' or the Vertico sort functions + (setq all (delete-consecutive-dups (funcall (or (vertico--sort-function) #'identity) all))) + ;; Move special candidates: "field" appears at the top, before "field/", before default value + (when (stringp def) + (setq all (vertico--move-to-front def all))) + (when (and completing-file (not (string-suffix-p "/" field))) + (setq all (vertico--move-to-front (concat field "/") all))) + (setq all (vertico--move-to-front field all)) + (when-let (group-fun (and all (vertico--metadata-get 'group-function))) + (setq groups (vertico--group-by group-fun all) all (car groups))) + (list base (length all) + ;; Default value is missing from collection + (and def (equal content "") (not (member def all))) + ;; Find position of old candidate in the new list. + (when vertico--lock-candidate + (if (< vertico--index 0) + vertico--index + (seq-position all (nth vertico--index vertico--candidates)))) + all (cadr groups) (or (caddr groups) vertico--all-groups) hl))) + +(defun vertico--cycle (list n) + "Rotate LIST to position N." + (nconc (copy-sequence (nthcdr n list)) (seq-take list n))) + +(defun vertico--group-by (fun elems) + "Group ELEMS by FUN." + (let ((ht (make-hash-table :test #'equal)) titles groups) + ;; Build hash table of groups + (while elems + (let* ((title (funcall fun (car elems) nil)) + (group (gethash title ht))) + (if group + (setcdr group (setcdr (cdr group) elems)) ;; Append to tail of group + (puthash title (cons elems elems) ht) ;; New group element (head . tail) + (push title titles)) + (pop elems))) + (setq titles (nreverse titles)) + ;; Cycle groups if `vertico--lock-groups' is set + (when-let (group (and vertico--lock-groups + (seq-find (lambda (group) (gethash group ht)) + vertico--all-groups))) + (setq titles (vertico--cycle titles (seq-position titles group)))) + ;; Build group list + (dolist (title titles) + (push (gethash title ht) groups)) + ;; Unlink last tail + (setcdr (cdar groups) nil) + (setq groups (nreverse groups)) + ;; Link groups + (let ((link groups)) + (while (cdr link) + (setcdr (cdar link) (caadr link)) + (pop link))) + ;; Check if new groups are found + (dolist (group vertico--all-groups) + (remhash group ht)) + (list (caar groups) titles + (if (hash-table-empty-p ht) vertico--all-groups titles)))) + +(defun vertico--remote-p (path) + "Return t if PATH is a remote path." + (string-match-p "\\`/[^/|:]+:" (substitute-in-file-name path))) + +(defun vertico--update-candidates (pt content) + "Preprocess candidates given PT and CONTENT." + ;; Redisplay the minibuffer such that the input becomes immediately + ;; visible before the expensive candidate recomputation is performed (Issue #89). + ;; Do not redisplay during initialization, since this leads to flicker. + (when (consp vertico--input) (redisplay)) + (let ((metadata (completion-metadata (substring content 0 pt) + minibuffer-completion-table + minibuffer-completion-predicate))) + (pcase + (let ((vertico--metadata metadata)) + ;; If Tramp is used, do not compute the candidates in an interruptible fashion, + ;; since this will break the Tramp password and user name prompts (See #23). + (if (and (eq 'file (vertico--metadata-get 'category)) + (or (vertico--remote-p content) (vertico--remote-p default-directory))) + (vertico--recompute-candidates pt content) + (let ((non-essential t)) + (while-no-input (vertico--recompute-candidates pt content))))) + ('nil (abort-recursive-edit)) + (`(,base ,total ,def-missing ,index ,candidates ,groups ,all-groups ,hl) + (setq vertico--input (cons content pt) + vertico--index index + vertico--base base + vertico--total total + vertico--highlight-function hl + vertico--groups groups + vertico--all-groups all-groups + vertico--candidates candidates + vertico--default-missing def-missing + vertico--metadata metadata) + ;; If the current index is nil, compute new index. Select the prompt: + ;; * If there are no candidates + ;; * If the default is missing from the candidate list. + ;; * For matching content, as long as the full content after the boundary is empty, + ;; including content after point. + (unless vertico--index + (setq vertico--lock-candidate nil + vertico--index + (if (or vertico--default-missing + (= 0 vertico--total) + (and (= base (length content)) + (test-completion content minibuffer-completion-table + minibuffer-completion-predicate))) + -1 0))))))) + +(defun vertico--flatten-string (prop str) + "Flatten STR with display or invisible PROP." + (let ((end (length str)) (pos 0) (chunks)) + (while (< pos end) + (let ((next (next-single-property-change pos prop str end)) + (val (get-text-property pos prop str))) + (cond + ((and val (eq prop 'display) (stringp val)) + (push val chunks)) + ((not (and val (eq prop 'invisible))) + (push (substring str pos next) chunks))) + (setq pos next))) + (apply #'concat (nreverse chunks)))) + +(defun vertico--truncate-multiline (cand max-width) + "Truncate multiline CAND to MAX-WIDTH." + (truncate-string-to-width + (thread-last cand + (replace-regexp-in-string "[\t ]+" " ") + (replace-regexp-in-string "[\t\n ]*\n[\t\n ]*" (car vertico-multiline)) + (replace-regexp-in-string "\\`[\t\n ]+\\|[\t\n ]+\\'" "")) + max-width 0 nil (cdr vertico-multiline))) + +(defun vertico--format-candidate (cand prefix suffix index _start) + "Format CAND given PREFIX, SUFFIX and INDEX." + (setq cand (concat prefix cand suffix "\n") + cand (vertico--flatten-string 'invisible (vertico--flatten-string 'display cand))) + (when (= index vertico--index) + (add-face-text-property 0 (length cand) 'vertico-current 'append cand)) + cand) + +(defun vertico--update-scroll () + "Update scroll position." + (let ((off (max (min vertico-scroll-margin (/ vertico-count 2)) 0)) + (corr (if (= vertico-scroll-margin (/ vertico-count 2)) (1- (mod vertico-count 2)) 0))) + (setq vertico--scroll (min (max 0 (- vertico--total vertico-count)) + (max 0 (+ vertico--index off 1 (- vertico-count)) + (min (- vertico--index off corr) vertico--scroll)))))) + +(defun vertico--arrange-candidates () + "Arrange candidates." + (vertico--update-scroll) + (let ((curr-line 0) (lines)) + ;; Compute group titles + (let* ((index vertico--scroll) + (title) + (group-fun (vertico--metadata-get 'group-function)) + (group-format (and group-fun vertico-group-format (concat vertico-group-format "\n"))) + (candidates + (thread-last (seq-subseq vertico--candidates index + (min (+ index vertico-count) vertico--total)) + (funcall vertico--highlight-function) + (vertico--affixate)))) + (dolist (cand candidates) + (let ((str (car cand))) + (when-let (new-title (and group-format (funcall group-fun str nil))) + (unless (equal title new-title) + (setq title new-title) + ;; Restore group title highlighting for prefix titles + (when (string-prefix-p title str) + (setq title (substring + (car (funcall + vertico--highlight-function + ;; Remove all properties from the title + (list (propertize str 'face 'vertico-group-title)))) + 0 (length title))) + (vertico--remove-face 0 (length title) 'completions-first-difference title)) + (push (format group-format title) lines)) + (setcar cand (funcall group-fun str 'transform)))) + (when (= index vertico--index) + (setq curr-line (length lines))) + (push (cons index cand) lines) + (setq index (1+ index)))) + ;; Drop excess lines + (setq lines (nreverse lines)) + (cl-loop for count from (length lines) above vertico-count do + (if (< curr-line (/ count 2)) + (nbutlast lines) + (setq curr-line (1- curr-line) lines (cdr lines)))) + ;; Format candidates + (let ((max-width (- (window-width) 4)) start) + (cl-loop for line on lines do + (pcase (car line) + (`(,index ,cand ,prefix ,suffix) + (setq start (or start index)) + (when (string-match-p "\n" cand) + (setq cand (vertico--truncate-multiline cand max-width))) + (setcar line (vertico--format-candidate cand prefix suffix index start)))))) + lines)) + +(defun vertico--display-candidates (lines) + "Update candidates overlay `vertico--candidates-ov' with LINES." + (move-overlay vertico--candidates-ov (point-max) (point-max)) + (overlay-put vertico--candidates-ov 'after-string + (apply #'concat #(" " 0 1 (cursor t)) (and lines "\n") lines)) + (vertico--resize-window (length lines))) + +(defun vertico--resize-window (height) + "Resize active minibuffer window to HEIGHT." + (setq-local truncate-lines (< (point) (* 0.8 (window-width)))) + (unless (frame-root-window-p (active-minibuffer-window)) + (unless vertico-resize + (setq height (max height vertico-count))) + (let* ((window-resize-pixelwise t) + (dp (- (max (cdr (window-text-pixel-size)) + (* (default-line-height) (1+ height))) + (window-pixel-height)))) + (when (or (and (> dp 0) (/= height 0)) + (and (< dp 0) (eq vertico-resize t))) + (window-resize nil dp nil nil 'pixelwise))))) + +(defun vertico--format-count () + "Format the count string." + (format (car vertico-count-format) + (format (cdr vertico-count-format) + (cond ((>= vertico--index 0) (1+ vertico--index)) + ((vertico--allow-prompt-selection-p) "*") + (t "!")) + vertico--total))) + +(defun vertico--display-count () + "Update count overlay `vertico--count-ov'." + (when vertico--count-ov + (move-overlay vertico--count-ov (point-min) (point-min)) + ;; Set priority for compatibility with `minibuffer-depth-indicate-mode' + (overlay-put vertico--count-ov 'priority 1) + (overlay-put vertico--count-ov 'before-string (vertico--format-count)))) + +(defun vertico--prompt-selection () + "Highlight the prompt if selected." + (let ((inhibit-modification-hooks t)) + (if (and (< vertico--index 0) (vertico--allow-prompt-selection-p)) + (add-face-text-property (minibuffer-prompt-end) (point-max) 'vertico-current 'append) + (vertico--remove-face (minibuffer-prompt-end) (point-max) 'vertico-current)))) + +(defun vertico--remove-face (beg end face &optional obj) + "Remove FACE between BEG and END from OBJ." + (while (< beg end) + (let ((next (next-single-property-change beg 'face obj end))) + (when-let (val (get-text-property beg 'face obj)) + (put-text-property beg next 'face (remq face (if (listp val) val (list val))) obj)) + (setq beg next)))) + +(defun vertico--exhibit () + "Exhibit completion UI." + (let* ((buffer-undo-list t) ;; Overlays affect point position and undo list! + (pt (max 0 (- (point) (minibuffer-prompt-end)))) + (content (minibuffer-contents))) + (unless (or (input-pending-p) (equal vertico--input (cons content pt))) + (vertico--update-candidates pt content)) + (vertico--prompt-selection) + (vertico--display-count) + (vertico--display-candidates (vertico--arrange-candidates)))) + +(defun vertico--allow-prompt-selection-p () + "Return t if prompt can be selected." + (or vertico--default-missing + (memq minibuffer--require-match '(nil confirm confirm-after-completion)))) + +(defun vertico--goto (index) + "Go to candidate with INDEX." + (let ((prompt (vertico--allow-prompt-selection-p))) + (setq vertico--index + (max (if (or prompt (= 0 vertico--total)) -1 0) + (min index (1- vertico--total))) + vertico--lock-candidate (or (>= vertico--index 0) prompt)))) + +(defun vertico-first () + "Go to first candidate, or to the prompt when the first candidate is selected." + (interactive) + (vertico--goto (if (> vertico--index 0) 0 -1))) + +(defun vertico-last () + "Go to last candidate." + (interactive) + (vertico--goto (1- vertico--total))) + +(defun vertico-scroll-down (&optional n) + "Go back by N pages." + (interactive "p") + (vertico--goto (max 0 (- vertico--index (* (or n 1) vertico-count))))) + +(defun vertico-scroll-up (&optional n) + "Go forward by N pages." + (interactive "p") + (vertico-scroll-down (- (or n 1)))) + +(defun vertico-next (&optional n) + "Go forward N candidates." + (interactive "p") + (let ((index (+ vertico--index (or n 1)))) + (vertico--goto + (cond + ((not vertico-cycle) index) + ((= vertico--total 0) -1) + ((vertico--allow-prompt-selection-p) (1- (mod (1+ index) (1+ vertico--total)))) + (t (mod index vertico--total)))))) + +(defun vertico-previous (&optional n) + "Go backward N candidates." + (interactive "p") + (vertico-next (- (or n 1)))) + +(defun vertico--match-p (input) + "Return t if INPUT is a valid match." + (or (memq minibuffer--require-match '(nil confirm-after-completion)) + (equal "" input) ;; The questionable null completion + (test-completion input + minibuffer-completion-table + minibuffer-completion-predicate) + (if (eq minibuffer--require-match 'confirm) + (eq (ignore-errors (read-char "Confirm")) 13) + (and (message "Match required") nil)))) + +(defun vertico-exit (&optional arg) + "Exit minibuffer with current candidate or input if prefix ARG is given." + (interactive "P") + (unless arg (vertico-insert)) + (when (vertico--match-p (minibuffer-contents-no-properties)) + (exit-minibuffer))) + +(defun vertico-next-group (&optional n) + "Cycle N groups forward. +When the prefix argument is 0, the group order is reset." + (interactive "p") + (when (cdr vertico--groups) + (if (eq n 0) + (setq vertico--groups nil + vertico--all-groups nil + vertico--lock-groups nil) + (setq vertico--groups + (vertico--cycle vertico--groups + (let ((len (length vertico--groups))) + (- len (mod (- (or n 1)) len)))) + vertico--all-groups + (vertico--cycle vertico--all-groups + (seq-position vertico--all-groups + (car vertico--groups))) + vertico--lock-groups t)) + (setq vertico--lock-candidate nil + vertico--input nil))) + +(defun vertico-previous-group (&optional n) + "Cycle N groups backward. +When the prefix argument is 0, the group order is reset." + (interactive "p") + (vertico-next-group (- (or n 1)))) + +(defun vertico-exit-input () + "Exit minibuffer with input." + (interactive) + (vertico-exit t)) + +(defun vertico-save () + "Save current candidate to kill ring." + (interactive) + (if (or (use-region-p) (not transient-mark-mode)) + (call-interactively #'kill-ring-save) + (kill-new (vertico--candidate)))) + +(defun vertico-insert () + "Insert current candidate in minibuffer." + (interactive) + ;; XXX There is a small bug here, depending on interpretation. When + ;; completing "~/emacs/master/li|/calc" where "|" is the cursor, + ;; then the returned candidate only includes the prefix + ;; "~/emacs/master/lisp/", but not the suffix "/calc". Default + ;; completion has the same problem when selecting in the + ;; *Completions* buffer. See bug#48356. + (when-let (cand (and (>= vertico--index 0) (vertico--candidate))) + (delete-minibuffer-contents) + (insert cand))) + +(defun vertico--candidate (&optional hl) + "Return current candidate string with optional highlighting if HL is non-nil." + (let ((content (substring (or (car-safe vertico--input) (minibuffer-contents))))) + (if (>= vertico--index 0) + (let ((cand (substring (nth vertico--index vertico--candidates)))) + ;;; XXX Drop the completions-common-part face which is added by `completion--twq-all'. + ;; This is a hack in Emacs and should better be fixed in Emacs itself, the corresponding + ;; code is already marked with a FIXME. Should this be reported as a bug? + (vertico--remove-face 0 (length cand) 'completions-common-part cand) + (concat (substring content 0 vertico--base) + (if hl (car (funcall vertico--highlight-function (list cand))) cand))) + ;; Remove prompt face + (vertico--remove-face 0 (length content) 'vertico-current content) + content))) + +(defun vertico--setup () + "Setup completion UI." + (setq vertico--input t + vertico--candidates-ov (make-overlay (point-max) (point-max) nil t t) + vertico--count-ov (and vertico-count-format + (make-overlay (point-min) (point-min) nil t t))) + (setq-local resize-mini-windows 'grow-only + max-mini-window-height 1.0 + truncate-lines t + completion-auto-help nil + completion-show-inline-help nil) + (use-local-map vertico-map) + ;; Use -90 to ensure that the exhibit hook runs early such that the + ;; candidates are available for Consult preview. It works, but besides + ;; that I'dont have a specific reason for this particular value. + (add-hook 'post-command-hook #'vertico--exhibit -90 'local)) + +(defun vertico--advice (&rest args) + "Advice for completion function, receiving ARGS." + (minibuffer-with-setup-hook #'vertico--setup (apply args))) + +;;;###autoload +(define-minor-mode vertico-mode + "VERTical Interactive COmpletion." + :global t :group 'vertico + (if vertico-mode + (progn + (advice-add #'completing-read-default :around #'vertico--advice) + (advice-add #'completing-read-multiple :around #'vertico--advice)) + (advice-remove #'completing-read-default #'vertico--advice) + (advice-remove #'completing-read-multiple #'vertico--advice))) + +;; Emacs 28: Do not show Vertico commands in M-X +(dolist (sym '(vertico-next vertico-next-group vertico-previous vertico-previous-group + vertico-scroll-down vertico-scroll-up vertico-exit vertico-insert + vertico-exit-input vertico-save vertico-first vertico-last)) + (put sym 'completion-predicate #'vertico--command-p)) + +(defun vertico--command-p (_sym buffer) + "Return non-nil if Vertico is active in BUFFER." + (buffer-local-value 'vertico--input buffer)) + +(provide 'vertico) +;;; vertico.el ends here diff --git a/elpa/vertico-0.17/vertico.elc b/elpa/vertico-0.17/vertico.elc Binary files differ. diff --git a/elpa/vertico-0.17/vertico.info b/elpa/vertico-0.17/vertico.info @@ -0,0 +1,612 @@ +This is vertico.info, produced by makeinfo version 6.7 from +vertico.texi. + +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* Vertico: (vertico). VERTical Interactive COmpletion. +END-INFO-DIR-ENTRY + + +File: vertico.info, Node: Top, Next: Introduction, Up: (dir) + +vertico.el - VERTical Interactive COmpletion +******************************************** + +* Menu: + +* Introduction:: +* Features:: +* Key bindings:: +* Configuration:: +* Extensions:: +* Complementary packages:: +* Child frames and Popups:: +* Alternatives:: +* Problematic completion commands:: +* Contributions:: + +— The Detailed Node Listing — + +Configuration + +* Completion styles and TAB completion:: +* Completion-at-point and completion-in-region:: +* Completing-read-multiple (CRM):: + +Problematic completion commands + +* org-refile:: +* tmm-menubar:: +* ffap-menu:: +* Tramp hostname completion:: + + + +File: vertico.info, Node: Introduction, Next: Features, Prev: Top, Up: Top + +1 Introduction +************** + +Vertico provides a performant and minimalistic vertical completion UI +based on the default completion system. The main focus of Vertico is to +provide a UI which behaves _correctly_ under all circumstances. By +reusing the built-in facilities system, Vertico achieves _full +compatibility_ with built-in Emacs completion commands and completion +tables. Vertico only provides the completion UI but aims to be flexible +and extensible. Additional enhancements are available as *note +extensions: Extensions. or *note complementary packages: Complementary +packages. The code base is small and maintainable (‘vertico.el’ is only +about 600 lines of code without white space and comments). + + +File: vertico.info, Node: Features, Next: Key bindings, Prev: Introduction, Up: Top + +2 Features +********** + + • Vertical display with arrow key navigation + • Prompt shows the current candidate index and the total number of + candidates + • The current candidate is inserted with ‘TAB’ and selected with + ‘RET’ + • Non-existing candidates can be entered by moving the point to the + prompt line + • Configurable sorting by history position, length and alphabetically + • Long candidates with newlines are formatted to take up less space + • Deferred completion style highlighting for performance + • Support for annotations (‘annotation-function’ and + ‘affixation-function’) + • Support for grouping and group cycling commands (‘group-function’) + + <https://github.com/minad/vertico/blob/main/screenshot.svg?raw=true> + + +File: vertico.info, Node: Key bindings, Next: Configuration, Prev: Features, Up: Top + +3 Key bindings +************** + +Vertico defines its own local keymap in the minibuffer which is derived +from ‘minibuffer-local-map’. The keymap keeps most of the +‘fundamental-mode’ keybindings intact and remaps and binds only a +handful of commands. Note in particular the binding of ‘TAB’ to +‘vertico-insert’ and the bindings of ‘vertico-exit/exit-input’. + + • ‘beginning-of-buffer’, ‘minibuffer-beginning-of-buffer’ -> + ‘vertico-first’ + • ‘end-of-buffer’ -> ‘vertico-last’ + • ‘scroll-down-command’ -> ‘vertico-scroll-down’ + • ‘scroll-up-command’ -> ‘vertico-scroll-up’ + • ‘next-line’, ‘next-line-or-history-element’ -> ‘vertico-next’ + • ‘previous-line’, ‘previous-line-or-history-element’ -> + ‘vertico-previous’ + • ‘forward-paragraph’ -> ‘vertico-next-group’ + • ‘backward-paragraph’ -> ‘vertico-previous-group’ + • ‘exit-minibuffer’ -> ‘vertico-exit’ + • ‘kill-ring-save’ -> ‘vertico-save’ + • ‘C-<return>’ -> ‘vertico-exit-input’ + • ‘TAB’ -> ‘vertico-insert’ + + +File: vertico.info, Node: Configuration, Next: Extensions, Prev: Key bindings, Up: Top + +4 Configuration +*************** + +Vertico is available from GNU ELPA +(http://elpa.gnu.org/packages/vertico.html). You can install it +directly via ‘package-install’. After installation, you can activate +the global minor mode with ‘M-x vertico-mode’. In order to configure +Vertico and other packages in your init.el, you may want to take +advantage of ‘use-package’. I recommend to give Orderless completion a +try, which is different from the prefix TAB completion used by the basic +default completion system or in shells. Here is an example +configuration: + + ;; Enable vertico + (use-package vertico + :init + (vertico-mode) + + ;; Different scroll margin + ;; (setq vertico-scroll-margin 0) + + ;; Show more candidates + ;; (setq vertico-count 20) + + ;; Grow and shrink the Vertico minibuffer + ;; (setq vertico-resize t) + + ;; Optionally enable cycling for `vertico-next' and `vertico-previous'. + ;; (setq vertico-cycle t) + ) + + ;; Optionally use the `orderless' completion style. See + ;; `+orderless-dispatch' in the Consult wiki for an advanced Orderless style + ;; dispatcher. Additionally enable `partial-completion' for file path + ;; expansion. `partial-completion' is important for wildcard support. + ;; Multiple files can be opened at once with `find-file' if you enter a + ;; wildcard. You may also give the `initials' completion style a try. + (use-package orderless + :init + ;; Configure a custom style dispatcher (see the Consult wiki) + ;; (setq orderless-style-dispatchers '(+orderless-dispatch) + ;; orderless-component-separator #'orderless-escapable-split-on-space) + (setq completion-styles '(orderless) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; A few more useful configurations... + (use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; Alternatively try `consult-completing-read-multiple'. + (defun crm-indicator (args) + (cons (concat "[CRM] " (car args)) (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + + See also the Vertico Wiki (https://github.com/minad/vertico/wiki) for +additional configuration tips. + +* Menu: + +* Completion styles and TAB completion:: +* Completion-at-point and completion-in-region:: +* Completing-read-multiple (CRM):: + + +File: vertico.info, Node: Completion styles and TAB completion, Next: Completion-at-point and completion-in-region, Up: Configuration + +4.1 Completion styles and TAB completion +======================================== + +The bindings of the ‘minibuffer-local-completion-map’ are not available +in Vertico by default. This means that TAB works differently from what +you may expect from the default Emacs completion system. + + If you prefer to have the default completion commands a key press +away you can add new bindings or even replace the Vertico bindings. +Then the default completion commands behave as usual. For example you +can use ‘M-TAB’ to cycle between candidates if you have set +‘completion-cycle-threshold’. + + (define-key vertico-map "?" #'minibuffer-completion-help) + (define-key vertico-map (kbd "M-RET") #'minibuffer-force-complete-and-exit) + (define-key vertico-map (kbd "M-TAB") #'minibuffer-complete) + + The ‘orderless’ completion style does not support completion of a +common prefix substring, as you may be familiar with from shells or the +basic default completion system. The reason is that the Orderless input +string is usually not a prefix. In order to support completing prefixes +you may want to combine ‘orderless’ with ‘substring’ in your +‘completion-styles’ configuration. + + (setq completion-styles '(substring orderless)) + + Alternatively you can experiment with the built-in completion-styles, +e.g., adding ‘partial-completion’ or ‘flex’. The ‘partial-completion’ +style is important to add if you want to open multiple files at once +with ‘find-file’ using wildcards. In order to open multiple files at +once, you have to move to the prompt and then press ‘RET’. + + (setq completion-styles '(basic substring partial-completion flex)) + + Because Vertico is fully compatible with Emacs default completion +system, further customization of completion behavior can be achieved by +setting the designated Emacs variables. For example, one may wish to +disable case-sensitivity for file and buffer matching when built-in +completion styles are used instead of ‘orderless’: + + (setq read-file-name-completion-ignore-case t + read-buffer-completion-ignore-case t + completion-ignore-case t) + + +File: vertico.info, Node: Completion-at-point and completion-in-region, Next: Completing-read-multiple (CRM), Prev: Completion styles and TAB completion, Up: Configuration + +4.2 Completion-at-point and completion-in-region +================================================ + +The ‘completion-at-point’ command is usually bound to ‘M-TAB’ or ‘TAB’. +In case you want to use Vertico for +completion-at-point/completion-in-region, you can use the function +‘consult-completion-in-region’ provided by the Consult package. + + ;; Use `consult-completion-in-region' if Vertico is enabled. + ;; Otherwise use the default `completion--in-region' function. + (setq completion-in-region-function + (lambda (&rest args) + (apply (if vertico-mode + #'consult-completion-in-region + #'completion--in-region) + args))) + + The ‘completion-in-region-function’ setting also affects TAB +completion in the minibuffer when ‘M-:’ (‘eval-expression’) is used. + + You may also want to look into my Corfu +(https://github.com/minad/corfu) package, which provides a minimal +completion system for ‘completion-in-region’ in a child frame popup. +Corfu is also a narrowly focused package and developed in the same +spirit as Vertico. + + +File: vertico.info, Node: Completing-read-multiple (CRM), Prev: Completion-at-point and completion-in-region, Up: Configuration + +4.3 Completing-read-multiple (CRM) +================================== + +Consult offers an enhanced ‘completing-read-multiple’ implementation +which you can use with Vertico. + + (advice-add #'completing-read-multiple + :override #'consult-completing-read-multiple) + + +File: vertico.info, Node: Extensions, Next: Complementary packages, Prev: Configuration, Up: Top + +5 Extensions +************ + +We maintain small extension packages to Vertico in this repository in +the subdirectory extensions/ +(https://github.com/minad/vertico/tree/main/extensions). The extensions +are installed together with Vertico if you pull the package from ELPA. +The extensions are of course inactive by default and can be enabled +manually if desired. Furthermore it is possible to install all of the +files separately, both ‘vertico.el’ and the ‘vertico-*.el’ extensions. +Currently the following extensions come with the Vertico ELPA package: + + • vertico-buffer + (https://github.com/minad/vertico/blob/main/extensions/vertico-buffer.el): + ‘vertico-buffer-mode’ to display Vertico in a separate buffer + • vertico-directory + (https://github.com/minad/vertico/blob/main/extensions/vertico-directory.el): + Commands for Ido-like directory navigation + • vertico-flat + (https://github.com/minad/vertico/blob/main/extensions/vertico-flat.el): + ‘vertico-flat-mode’ to enable a flat, horizontal display + • vertico-grid + (https://github.com/minad/vertico/blob/main/extensions/vertico-grid.el): + ‘vertico-grid-mode’ to enable a grid display + • vertico-indexed + (https://github.com/minad/vertico/blob/main/extensions/vertico-indexed.el): + ‘vertico-indexed-mode’ to select indexed candidates with prefix + arguments + • vertico-mouse + (https://github.com/minad/vertico/blob/main/extensions/vertico-mouse.el): + ‘vertico-mouse-mode’ to support for scrolling and candidate + selection + • vertico-quick + (https://github.com/minad/vertico/blob/main/extensions/vertico-quick.el): + Commands to select using Avy-style quick keys + • vertico-repeat + (https://github.com/minad/vertico/blob/main/extensions/vertico-repeat.el): + The command ‘vertico-repeat’ repeats the last completion session + • vertico-reverse + (https://github.com/minad/vertico/blob/main/extensions/vertico-reverse.el): + ‘vertico-reverse-mode’ to reverse the display + + With these extensions it is possible to adapt Vertico such that it +matches your preference or behaves similar to other familiar UIs. For +example, the combination ‘vertico-flat’ plus ‘vertico-directory’ +resembles Ido in look and feel. For an interface similar to Helm, the +extension ‘vertico-buffer’ allows you to configure more freely where the +completion buffer opens, instead of growing the minibuffer. + + Configuration example for ‘vertico-directory’: + + ;; Configure directory extension. + (use-package vertico-directory + :ensure nil + ;; More convenient directory navigation commands + :bind (:map vertico-map + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word)) + ;; Tidy shadowed file names + :hook (rfn-eshadow-update-overlay . vertico-directory-tidy)) + + +File: vertico.info, Node: Complementary packages, Next: Child frames and Popups, Prev: Extensions, Up: Top + +6 Complementary packages +************************ + +Vertico integrates well with complementary packages, which enrich the +completion UI. These packages are fully supported: + + • Marginalia (https://github.com/minad/marginalia): Rich annotations + in the minibuffer + • Consult (https://github.com/minad/consult): Useful search and + navigation commands + • Embark (https://github.com/oantolin/embark): Minibuffer actions and + context menu + • Orderless (https://github.com/oantolin/orderless): Advanced + completion style + + In order to get accustomed with the package ecosystem, I recommed the +following approach: + + 1. Start with plain Emacs. + 2. Install and enable Vertico to get incremental minibuffer + completion. + 3. Install Orderless and/or configure the built-in completion styles + for more flexible minibuffer filtering. + 4. Install Marginalia if you like rich minibuffer annotations. + 5. Install Embark and add two keybindings for ‘embark-dwim’ and + ‘embark-act’. I am using ‘M-.’ and ‘C-.’. These commands allow + you to act on the object at point or in the minibuffer. + 6. Install Consult if you want additional featureful completion + commands, e.g, the buffer switcher ‘consult-buffer’ with preview or + the line-based search ‘consult-line’. + 7. Install Embark-Consult and Wgrep for export from ‘consult-line’ to + ‘occur-mode’ buffers and from ‘consult-grep’ to editable + ‘grep-mode’ buffers. + + You don’t have to use all of these components. Use only the ones you +like and the ones which fit well into your setup. The steps 1. to 4. +introduce no new commands over plain Emacs. Step 5. introduces the new +commands ‘embark-act’ and ‘embark-dwim’. In step 6. you get the +Consult commands, some offer new functionality not present in Emacs +already (e.g., ‘consult-line’) and some are substitutes (e.g., +‘consult-buffer’ for ‘switch-to-buffer’). + + +File: vertico.info, Node: Child frames and Popups, Next: Alternatives, Prev: Complementary packages, Up: Top + +7 Child frames and Popups +************************* + +An often requested feature is the ability to display the completions in +a child frame popup. I do not recommend this, since from my experience +it introduces more problems than it solves. Child frames can feel slow +and sometimes flicker. On the other hand the completion display appears +right in your focus at the center of the screen, leading to a modern +look and feel. Please give these packages a try and judge for yourself. + + • mini-frame (https://github.com/muffinmad/emacs-mini-frame): Display + the entire minibuffer in a child frame. + • mini-popup (https://github.com/minad/mini-popup): Slightly simpler + alternative to mini-frame. + • vertico-posframe (https://github.com/tumashu/vertico-posframe): + Display only the Vertico minibuffer in a child frame using the + posframe library. + + +File: vertico.info, Node: Alternatives, Next: Problematic completion commands, Prev: Child frames and Popups, Up: Top + +8 Alternatives +************** + +There are many alternative completion UIs, each UI with its own +advantages and disadvantages. + + Vertico aims to be 100% compliant with all Emacs commands and +achieves that with a minimal code base, relying purely on +‘completing-read’ while avoiding to invent its own APIs. Inventing a +custom API as Helm or Ivy is explicitly avoided in order to increase +flexibility and package reuse. Due to its small code base and reuse of +the Emacs built-in facilities, bugs and compatibility issues are less +likely to occur in comparison to completion UIs or full completion +systems, which reimplement a lot of functionality. + + Since Vertico only provides the UI, you may want to combine it with +some of the complementary packages, to give a full-featured completion +experience similar to Helm or Ivy. Overall the packages in the spirit +of Vertico have a different style than Helm or Ivy. The idea is to have +smaller independent components, which one can add and understand step by +step. Each component focuses on its niche and tries to be as +non-intrusive as possible. Vertico targets users interested in crafting +their Emacs precisely to their liking - completion plays an integral +part in how the users interacts with Emacs. + + There are other interactive completion UIs, which follow a similar +philosophy: + + • Selectrum (https://github.com/raxod502/selectrum): Selectrum has a + similar UI as Vertico, since it directly inspired Vertico. The + Selectrum code base is more complex. Unfortunately Selectrum is + not fully compatible with every Emacs completion command (Issue + #481 (https://github.com/raxod502/selectrum/issues/481)), since it + uses its own filtering infrastructure, which deviates from the + standard Emacs completion facilities. Vertico additionally has the + ability to cycle over candidates, offers commands for grouping + support and comes with a rich set of *note extensions: Extensions. + • Icomplete-vertical + (https://github.com/oantolin/icomplete-vertical): This package + enhances the Emacs builtin Icomplete with a vertical display. In + contrast to Vertico, Icomplete rotates the candidates such that the + current candidate always appears at the top. From my perspective, + candidate rotation feels a bit less intuitive than the UI of + Vertico or Selectrum. Note that Emacs 28 offers a built-in + ‘icomplete-vertical-mode’. + • Mct (https://gitlab.com/protesilaos/mct): Minibuffer and + Completions in Tandem. Mct reuses the default ‘*Completions*’ + buffer and enhances it with automatic updates and additional + keybindings, to select a candidate and move between minibuffer and + completions buffer. Mct is great if you prefer an unobtrusive UI + since it can be configured to open only when requested. + Furthermore since Mct uses a fully functional buffer you can reuse + all your familar buffer commands inside the completions buffer. + The main distinction to an approach like Vertico’s is that + ‘*Completions*’ buffer displays all matching candidates. On the + one hand this is good since it allows you to interact with all the + candidates and jump around with Isearch or Avy. On the other hand + it necessarily causes a small slowdown in comparison to Vertico, + which only displays a small subset of candidates. + + +File: vertico.info, Node: Problematic completion commands, Next: Contributions, Prev: Alternatives, Up: Top + +9 Problematic completion commands +********************************* + +Vertico is robust in most scenarios. However some completion commands +make certain assumptions about the completion styles and the completion +UI. Some of these assumptions may not hold in Vertico or other UIs and +require minor workarounds. + +* Menu: + +* org-refile:: +* tmm-menubar:: +* ffap-menu:: +* Tramp hostname completion:: + + +File: vertico.info, Node: org-refile, Next: tmm-menubar, Up: Problematic completion commands + +9.1 ‘org-refile’ +================ + +‘org-refile’ uses ‘org-olpath-completing-read’ to complete the outline +path in steps, when ‘org-refile-use-outline-path’ is non-nil. + + Unfortunately the implementation of this Org completion table assumes +that the default completion UI is used. In order to fix the issue at +the root, the completion table should make use of completion boundaries +similar to the built-in file completion table. + + In order to workaround the issues with the current implementation I +recommend to disable the outline path completion in steps. The +completion on the full path is also faster since the input string +matches directly against the full path, which is particularily useful +with Orderless. + + (setq org-refile-use-outline-path 'file + org-outline-path-complete-in-steps nil) + + +File: vertico.info, Node: tmm-menubar, Next: ffap-menu, Prev: org-refile, Up: Problematic completion commands + +9.2 ‘tmm-menubar’ +================= + +The text menu bar works well with Vertico but always shows a +‘*Completions*’ buffer, which is unwanted if you use the Vertico UI. +This completion buffer can be disabled as follows. + + (advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions) + + +File: vertico.info, Node: ffap-menu, Next: Tramp hostname completion, Prev: tmm-menubar, Up: Problematic completion commands + +9.3 ‘ffap-menu’ +=============== + +The command ‘ffap-menu’ shows the ‘=*Completions*’ buffer by default +like ‘tmm-menubar’, which is unnecessary with Vertico. This completion +buffer can be disabled as follows. + + (advice-add #'ffap-menu-ask :around (lambda (&rest args) + (cl-letf (((symbol-function #'minibuffer-completion-help) + #'ignore)) + (apply args)))) + + +File: vertico.info, Node: Tramp hostname completion, Prev: ffap-menu, Up: Problematic completion commands + +9.4 Tramp hostname completion +============================= + +In combination with Orderless, hostnames are not made available for +completion after entering ‘/ssh:’. In order to avoid this problem, the +‘basic’ completion style should be specified for the file completion +category. + + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic partial-completion)))) + + For users who are familiar with the ‘completion-style’ machinery: You +may also define a custom completion style which sets in only for remote +files! + + (defun basic-remote-try-completion (string table pred point) + (and (vertico--remote-p string) + (completion-basic-try-completion string table pred point))) + (defun basic-remote-all-completions (string table pred point) + (and (vertico--remote-p string) + (completion-basic-all-completions string table pred point))) + (add-to-list + 'completion-styles-alist + '(basic-remote basic-remote-try-completion basic-remote-all-completions nil)) + (setq completion-styles '(orderless) + completion-category-overrides '((file (styles basic-remote partial-completion)))) + + +File: vertico.info, Node: Contributions, Prev: Problematic completion commands, Up: Top + +10 Contributions +**************** + +Since this package is part of GNU ELPA +(http://elpa.gnu.org/packages/vertico.html) contributions require a +copyright assignment to the FSF. + + + +Tag Table: +Node: Top196 +Node: Introduction856 +Node: Features1658 +Node: Key bindings2545 +Node: Configuration3780 +Node: Completion styles and TAB completion7087 +Node: Completion-at-point and completion-in-region9397 +Node: Completing-read-multiple (CRM)10722 +Node: Extensions11141 +Node: Complementary packages14250 +Node: Child frames and Popups16354 +Node: Alternatives17344 +Node: Problematic completion commands20882 +Node: org-refile21394 +Node: tmm-menubar22326 +Node: ffap-menu22743 +Node: Tramp hostname completion23376 +Node: Contributions24688 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: diff --git a/elpa/vertico-posframe-0.4.2.signed b/elpa/vertico-posframe-0.4.2.signed @@ -0,0 +1 @@ +Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <elpasign@elpa.gnu.org> (trust undefined) created at 2021-12-02T11:10:02+0100 using RSA +\ No newline at end of file diff --git a/elpa/vertico-posframe-0.4.2/LICENSE b/elpa/vertico-posframe-0.4.2/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff --git a/elpa/vertico-posframe-0.4.2/README.org b/elpa/vertico-posframe-0.4.2/README.org @@ -0,0 +1,26 @@ +#+TITLE: README of vertico-posframe + +** What is vertico-posframe + +vertico-posframe is an vertico extension, which lets vertico use +posframe to show its candidate menu. + +NOTE: vertico-posframe requires Emacs 26 and do not support mouse +click. + +** How to enable vertico-posframe +#+BEGIN_EXAMPLE +(require 'vertico-posframe) +(vertico-posframe-mode 1) +#+END_EXAMPLE + +** Tips +*** How to show fringe to vertico-posframe +#+BEGIN_EXAMPLE +(setq vertico-posframe-parameters + '((left-fringe . 8) + (right-fringe . 8))) +#+END_EXAMPLE + +By the way, User can set *any* parameters of vertico-posframe with +the help of `vertico-posframe-parameters'. diff --git a/elpa/vertico-posframe-0.4.2/vertico-posframe-autoloads.el b/elpa/vertico-posframe-0.4.2/vertico-posframe-autoloads.el @@ -0,0 +1,47 @@ +;;; vertico-posframe-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "vertico-posframe" "vertico-posframe.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from vertico-posframe.el + +(defvar vertico-posframe-mode nil "\ +Non-nil if Vertico-Posframe mode is enabled. +See the `vertico-posframe-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `vertico-posframe-mode'.") + +(custom-autoload 'vertico-posframe-mode "vertico-posframe" nil) + +(autoload 'vertico-posframe-mode "vertico-posframe" "\ +Display Vertico in posframe instead of the minibuffer. + +If called interactively, enable Vertico-Posframe mode if ARG is +positive, and disable it if ARG is zero or negative. If called +from Lisp, also enable the mode if ARG is omitted or nil, and +toggle it if ARG is `toggle'; disable the mode otherwise. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "vertico-posframe" '("vertico-posframe-"))) + +;;;*** + +;;;### (autoloads nil nil ("vertico-posframe-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; vertico-posframe-autoloads.el ends here diff --git a/elpa/vertico-posframe-0.4.2/vertico-posframe-pkg.el b/elpa/vertico-posframe-0.4.2/vertico-posframe-pkg.el @@ -0,0 +1,2 @@ +;; Generated package description from vertico-posframe.el -*- no-byte-compile: t -*- +(define-package "vertico-posframe" "0.4.2" "Using posframe to show Vertico" '((emacs "26.0") (posframe "1.0.0") (vertico "0.13.0")) :authors '(("Feng Shu" . "tumashu@163.com")) :maintainer '("Feng Shu" . "tumashu@163.com") :keywords '("abbrev" "convenience" "matching" "vertico") :url "https://github.com/tumashu/vertico-posframe") diff --git a/elpa/vertico-posframe-0.4.2/vertico-posframe.el b/elpa/vertico-posframe-0.4.2/vertico-posframe.el @@ -0,0 +1,328 @@ +;;; vertico-posframe.el --- Using posframe to show Vertico -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; Author: Feng Shu <tumashu@163.com> +;; Maintainer: Feng Shu <tumashu@163.com> +;; URL: https://github.com/tumashu/vertico-posframe +;; Version: 0.4.2 +;; Keywords: abbrev, convenience, matching, vertico +;; Package-Requires: ((emacs "26.0") (posframe "1.0.0") (vertico "0.13.0")) + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + + +;;; Commentary: +;; * vertico-posframe README :README: + +;; ** What is vertico-posframe + +;; vertico-posframe is an vertico extension, which lets vertico use posframe to show +;; its candidate menu. + +;; NOTE: vertico-posframe requires Emacs 26 and do not support mouse +;; click. + +;; ** How to enable vertico-posframe +;; #+BEGIN_EXAMPLE +;; (require 'vertico-posframe) +;; (vertico-posframe-mode 1) +;; #+END_EXAMPLE + +;; ** Tips + +;; *** How to show fringe to vertico-posframe +;; #+BEGIN_EXAMPLE +;; (setq vertico-posframe-parameters +;; '((left-fringe . 8) +;; (right-fringe . 8))) +;; #+END_EXAMPLE + +;; By the way, User can set *any* parameters of vertico-posframe with +;; the help of `vertico-posframe-parameters'. + +;;; Code: +;; * vertico-posframe's code +(require 'posframe) +(require 'vertico) + +(defgroup vertico-posframe nil + "Using posframe to show vertico." + :group 'vertico-posframe) + +(defcustom vertico-posframe-font nil + "The font used by vertico-posframe. +When nil, Using current frame's font as fallback." + :type 'string) + +(defcustom vertico-posframe-width nil + "The width of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-height nil + "The height of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-min-width nil + "The min width of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-min-height nil + "The min height of vertico-posframe." + :type 'number) + +(defcustom vertico-posframe-poshandler #'posframe-poshandler-frame-center + "The posframe poshandler used by vertico-posframe." + :type 'function) + +(defcustom vertico-posframe-refposhandler #'vertico-posframe-refposhandler-default + "The refposhandler used by vertico-posframe. + +NOTE: This variable is very useful to EXWM users." + :type 'function) + +(defcustom vertico-posframe-size-function #'vertico-posframe-get-size + "The function which is used to deal with posframe's size." + :type 'function) + +(defcustom vertico-posframe-border-width 2 + "The border width used by vertico-posframe. +When 0, no border is showed." + :type 'number) + +(defcustom vertico-posframe-parameters nil + "The frame parameters used by vertico-posframe." + :type 'string) + +(defcustom vertico-posframe-show-minibuffer-rules + (list "^eval-*") + "A list of rule showed minibuffer. + +a rule can be a regexp or a function. + +1. when rule is a regexp and it match `this-command'. +2. when rule is a function and it return t. +3. when rule is a symbol, its value is t. + +minibuffer will not be hided by minibuffer-cover." + :type '(repeat (choice string function))) + +(defface vertico-posframe + '((t (:inherit default))) + "Face used by the vertico-posframe." + :group 'vertico-posframe) + +(defface vertico-posframe-border + '((t (:inherit default :background "gray50"))) + "Face used by the vertico-posframe's border." + :group 'vertico-posframe) + +(defface vertico-posframe-cursor + '((t (:inherit cursor))) + "Face used by the vertico-posframe's fake cursor." + :group 'vertico-posframe) + +(defvar vertico-posframe--buffer " *vertico-posframe--buffer*") +(defvar vertico-posframe--minibuffer-cover " *vertico-posframe--minibuffer-cover*") + +;; Fix warn +(defvar exwm--connection) +(defvar exwm-workspace--workareas) +(defvar exwm-workspace-current-index) + +(defun vertico-posframe-refposhandler-default (&optional frame) + "The default posframe refposhandler used by vertico-posframe. +Optional argument FRAME ." + (cond + ;; EXWM environment + ((bound-and-true-p exwm--connection) + (or (ignore-errors + (let ((info (elt exwm-workspace--workareas + exwm-workspace-current-index))) + (cons (elt info 0) + (elt info 1)))) + ;; Need user install xwininfo. + (ignore-errors + (posframe-refposhandler-xwininfo frame)) + ;; Fallback, this value will incorrect sometime, for example: user + ;; have panel. + (cons 0 0))) + (t nil))) + +(defun vertico-posframe-hidehandler (_) + "Hidehandler used by vertico-posframe." + (not (minibufferp))) + +(defun vertico-posframe-get-size () + "The default functon used by `vertico-posframe-size-function'." + (list + :height vertico-posframe-height + :width vertico-posframe-width + :min-height (or vertico-posframe-min-height + (let ((height (+ vertico-count 1))) + (min height (or vertico-posframe-height height)))) + :min-width (or vertico-posframe-min-width + (let ((width (round (* (frame-width) 0.62)))) + (min width (or vertico-posframe-width width)))))) + +(defun vertico-posframe--display (lines) + "Display LINES in posframe." + (let* ((show-minibuffer-p (vertico-posframe--show-minibuffer-p)) + (count (vertico-posframe--format-count)) + (prompt (propertize (minibuffer-prompt) 'face 'minibuffer-prompt)) + ;; NOTE: Vertico count in minibuffer is before-string of an + ;; overlay, so minibuffer contents will not include it. + (contents (minibuffer-contents)) + (n (+ (length count) + (max (point) (+ (length prompt) 1)))) + ;; FIXME: make sure background and foreground do + ;; not have similar color. ivy-posframe have not + ;; this problem, I can not find the reason. + (cursor-face + (list :foreground (face-attribute 'default :background) + :inherit 'vertico-posframe-cursor))) + (with-current-buffer (get-buffer-create vertico-posframe--buffer) + (setq-local inhibit-read-only nil + inhibit-modification-hooks t + cursor-in-non-selected-windows 'box) + (erase-buffer) + (insert count prompt contents "\n" (string-join lines)) + (add-text-properties n (+ n 1) `(face ,cursor-face))) + (with-selected-window (vertico-posframe-last-window) + ;; Create a posframe to cover minibuffer. + (if show-minibuffer-p + (vertico-posframe--hide-minibuffer-cover) + (vertico-posframe--create-minibuffer-cover)) + (vertico-posframe--show)))) + +(defun vertico-posframe--format-count () + "Format vertico count." + (propertize (or (vertico--format-count) "") 'face 'minibuffer-prompt)) + +(defun vertico-posframe--show (&optional string) + "`posframe-show' of vertico-posframe. +Show STRING when it is a string." + (apply #'posframe-show + vertico-posframe--buffer + :string string + :font vertico-posframe-font + :poshandler vertico-posframe-poshandler + :background-color (face-attribute 'vertico-posframe :background nil t) + :foreground-color (face-attribute 'vertico-posframe :foreground nil t) + :border-width vertico-posframe-border-width + :border-color (face-attribute 'vertico-posframe-border :background nil t) + :override-parameters vertico-posframe-parameters + :refposhandler vertico-posframe-refposhandler + :hidehandler #'vertico-posframe-hidehandler + :lines-truncate t + (funcall vertico-posframe-size-function))) + +(defun vertico-posframe--show-init () + "Create posframe in advance to limit flicker for `vertico-posframe--show'." + (posframe-show vertico-posframe--buffer + :string "" + :font vertico-posframe-font + :position (cons 0 0) + :background-color (face-attribute 'vertico-posframe :background nil t) + :foreground-color (face-attribute 'vertico-posframe :foreground nil t) + :border-width vertico-posframe-border-width + :border-color (face-attribute 'vertico-posframe-border :background nil t) + :override-parameters vertico-posframe-parameters + :timeout 0.1)) + +(defun vertico-posframe--create-minibuffer-cover (&optional string) + "Create minibuffer cover." + (let ((color (face-background 'default nil)) + (win (active-minibuffer-window))) + (posframe-show vertico-posframe--minibuffer-cover + :string (or string (make-string (frame-width) ?\ )) + :position (cons 0 (- (frame-pixel-height) (window-pixel-height win))) + :height (+ (window-height win) 1) + :background-color color + :foreground-color color + :lines-truncate t + :timeout 3))) + +(defun vertico-posframe--hide-minibuffer-cover () + "Hide minibuffer cover." + ;; FIXME: delay 0.1 second to remove minibuffer cover, which can + ;; limit minibuffer flicker. + (run-with-timer + 0.1 nil + (lambda () + (posframe-hide vertico-posframe--minibuffer-cover)))) + +(defun vertico-posframe--show-minibuffer-p () + "Test show minibuffer or not." + (or current-input-method + (cl-some + (lambda (rule) + (cond ((functionp rule) + (funcall rule)) + ((and rule (stringp rule)) + (string-match-p rule (symbol-name this-command))) + ((symbolp rule) + (symbol-value rule)) + (t nil))) + vertico-posframe-show-minibuffer-rules))) + +(defun vertico-posframe-last-window () + "Get the last actived window before active minibuffer." + (let ((window (minibuffer-selected-window))) + (or (if (window-live-p window) + window + (next-window)) + (selected-window)))) + +(defun vertico-posframe--hide () + "Hide vertico buffer." + (when (posframe-workable-p) + (posframe-hide vertico-posframe--buffer) + (vertico-posframe--hide-minibuffer-cover))) + +(defun vertico-posframe--setup () + "Setup minibuffer overlay, which pushes the minibuffer content down." + (add-hook 'minibuffer-exit-hook 'vertico-posframe--hide nil 'local) + (setq-local cursor-type '(bar . 0))) + +(defun vertico-posframe--minibuffer-message (message &rest _args) + "Advice function of `minibuffer-message'. +Argument MESSAGE ." + (let* ((count (vertico-posframe--format-count)) + (contents (buffer-string))) + (vertico-posframe--show (concat count contents message)))) + +;;;###autoload +(define-minor-mode vertico-posframe-mode + "Display Vertico in posframe instead of the minibuffer." + :global t + (cond + (vertico-posframe-mode + (advice-add #'minibuffer-message :before #'vertico-posframe--minibuffer-message) + (advice-add #'vertico--display-candidates :override #'vertico-posframe--display) + (advice-add #'vertico--setup :after #'vertico-posframe--setup) + ;; Create posframe in advance to limit flicker. + (vertico-posframe--show-init) + (vertico-posframe--create-minibuffer-cover "")) + (t + (advice-remove #'minibuffer-message #'vertico-posframe--minibuffer-message) + (advice-remove #'vertico--display-candidates #'vertico-posframe--display) + (advice-remove #'vertico--setup #'vertico-posframe--setup) + (posframe-delete vertico-posframe--buffer) + (posframe-delete vertico-posframe--minibuffer-cover)))) + +(provide 'vertico-posframe) +;;; vertico-posframe.el ends here diff --git a/elpa/vertico-posframe-0.4.2/vertico-posframe.elc b/elpa/vertico-posframe-0.4.2/vertico-posframe.elc Binary files differ. diff --git a/init.el b/init.el @@ -40,9 +40,8 @@ (delete-selection-mode 1) (which-key-mode 1) -(selectrum-mode 1) -(selectrum-prescient-mode 1) -(prescient-persist-mode 1) +(vertico-mode 1) +(vertico-posframe-mode 1) (marginalia-mode 1) (corfu-global-mode 1) (global-aggressive-indent-mode 1) @@ -128,8 +127,10 @@ '(aw-keys '(97 115 100 102 103 104 106 107 108)) '(aw-scope 'frame) '(backup-by-copying t) + '(bookmark-completion-ignore-case nil) '(column-number-mode t) '(company-idle-delay 0) + '(completion-styles '(basic substring initials flex)) '(corfu-auto t) '(corfu-auto-delay 0.0) '(corfu-auto-prefix 1) @@ -152,7 +153,10 @@ ("melpa-stable" . "https://stable.melpa.org/packages/") ("melpa" . "https://melpa.org/packages/"))) '(package-selected-packages - '(corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-roam org-contrib org ace-window expand-region selectrum-prescient consult marginalia selectrum uuidgen request diminish which-key)) + '(vertico-posframe vertico corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-roam org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key)) + '(pcomplete-ignore-case t) + '(read-buffer-completion-ignore-case t) + '(read-file-name-completion-ignore-case t) '(reb-re-syntax 'string) '(ring-bell-function 'ignore) '(scroll-conservatively 100)