From a1ccd4d63281ae8d0426b6c2c6a053d0fe64bcc1 Mon Sep 17 00:00:00 2001 From: Raphael Roberts Date: Thu, 1 Apr 2021 19:40:44 -0500 Subject: [PATCH] Update packages --- elpa/counsel-0.13.0/counsel-pkg.el | 2 - .../counsel-autoloads.el | 68 +- elpa/counsel-0.13.4/counsel-pkg.el | 2 + .../counsel.el | 2016 ++++-- elpa/cython-mode-0.29.21/cython-mode-pkg.el | 2 - .../cython-mode-autoloads.el | 0 elpa/cython-mode-0.29.22/cython-mode-pkg.el | 2 + .../cython-mode.el | 4 +- .../dash-autoloads.el | 0 elpa/{dash-2.18.0 => dash-2.18.1}/dash-pkg.el | 4 +- elpa/{dash-2.18.0 => dash-2.18.1}/dash.el | 21 +- elpa/{dash-2.18.0 => dash-2.18.1}/dash.info | 6 +- elpa/{dash-2.18.0 => dash-2.18.1}/dir | 0 elpa/format-all-0.3.0/format-all-pkg.el | 2 - .../format-all-autoloads.el | 37 +- elpa/format-all-0.4.0/format-all-pkg.el | 2 + .../format-all.el | 663 +- elpa/inheritenv-0.1/inheritenv-autoloads.el | 47 + elpa/inheritenv-0.1/inheritenv-pkg.el | 2 + elpa/inheritenv-0.1/inheritenv.el | 86 + elpa/ivy-0.13.0/colir.el | 124 - elpa/ivy-0.13.0/ivy-autoloads.el | 161 - elpa/ivy-0.13.0/ivy-overlay.el | 154 - elpa/ivy-0.13.0/ivy-pkg.el | 12 - elpa/ivy-0.13.0/ivy.el | 5056 --------------- elpa/ivy-0.13.0/ivy.info | 1954 ------ elpa/ivy-0.13.1.signed | 1 - elpa/ivy-0.13.1/ChangeLog | 76 - elpa/ivy-0.13.1/colir.el | 124 - elpa/ivy-0.13.1/dir | 18 - elpa/ivy-0.13.1/ivy-autoloads.el | 168 - elpa/ivy-0.13.1/ivy-overlay.el | 154 - elpa/ivy-0.13.1/ivy-pkg.el | 2 - elpa/ivy-0.13.1/ivy.el | 5056 --------------- elpa/ivy-0.13.1/ivy.info | 1954 ------ elpa/ivy-20210216.1611/dir | 18 - elpa/ivy-20210216.1611/elpa.el | 6 - elpa/ivy-20210216.1611/ivy-help.org | 138 - .../colir.el | 2 +- elpa/{ivy-0.13.0 => ivy-20210311.1638}/dir | 0 .../{ivy-0.13.0 => ivy-20210311.1638}/elpa.el | 0 .../ivy-autoloads.el | 0 .../ivy-faces.el | 2 +- .../ivy-help.org | 0 .../ivy-overlay.el | 2 +- .../ivy-pkg.el | 4 +- .../ivy.el | 22 +- .../ivy.info | 111 +- elpa/ivy-hydra-0.13.0/ivy-hydra-pkg.el | 2 - elpa/ivy-hydra-0.13.0/ivy-hydra.el | 135 - .../ivy-hydra-autoloads.el | 0 elpa/ivy-hydra-0.13.4/ivy-hydra-pkg.el | 2 + .../ivy-hydra.el | 60 +- .../markdown-mode-pkg.el | 2 - .../markdown-mode-autoloads.el | 0 .../markdown-mode-pkg.el | 2 + .../markdown-mode.el | 6 +- elpa/php-mode-1.23.0/php-mode-pkg.el | 12 - elpa/php-mode-1.23.0/php-util-buffer.el | 135 - .../php-align.el | 3 +- .../php-face.el | 3 +- elpa/php-mode-1.24.0/php-local-manual.el | 39 + .../php-mode-autoloads.el | 16 +- .../php-mode-debug.el | 3 +- elpa/php-mode-1.24.0/php-mode-pkg.el | 12 + .../php-mode.el | 57 +- .../php-project.el | 3 +- .../php.el | 3 +- .../ssh-config-keywords.txt | 0 .../ssh-config-mode-autoloads.el | 0 .../ssh-config-mode-pkg.el | 2 +- .../ssh-config-mode.el | 25 +- elpa/swiper-0.13.1.signed | 1 - elpa/swiper-0.13.1/.dir-locals.el | 14 - elpa/swiper-0.13.1/ChangeLog | 5518 ----------------- elpa/swiper-0.13.1/swiper-pkg.el | 2 - .../swiper-autoloads.el | 4 - elpa/swiper-0.13.4/swiper-pkg.el | 2 + .../swiper.el | 430 +- elpa/transient-0.2.0/transient-autoloads.el | 26 - elpa/transient-0.2.0/transient-pkg.el | 12 - elpa/{transient-0.2.0 => transient-0.3.0}/dir | 0 elpa/transient-0.3.0/transient-autoloads.el | 80 + elpa/transient-0.3.0/transient-pkg.el | 12 + .../transient.el | 937 ++- .../transient.info | 406 +- 86 files changed, 3734 insertions(+), 22517 deletions(-) delete mode 100755 elpa/counsel-0.13.0/counsel-pkg.el rename elpa/{counsel-0.13.0 => counsel-0.13.4}/counsel-autoloads.el (90%) mode change 100755 => 100644 create mode 100644 elpa/counsel-0.13.4/counsel-pkg.el rename elpa/{counsel-0.13.0 => counsel-0.13.4}/counsel.el (77%) mode change 100755 => 100644 delete mode 100755 elpa/cython-mode-0.29.21/cython-mode-pkg.el rename elpa/{cython-mode-0.29.21 => cython-mode-0.29.22}/cython-mode-autoloads.el (100%) mode change 100755 => 100644 create mode 100644 elpa/cython-mode-0.29.22/cython-mode-pkg.el rename elpa/{cython-mode-0.29.21 => cython-mode-0.29.22}/cython-mode.el (99%) mode change 100755 => 100644 rename elpa/{dash-2.18.0 => dash-2.18.1}/dash-autoloads.el (100%) rename elpa/{dash-2.18.0 => dash-2.18.1}/dash-pkg.el (66%) rename elpa/{dash-2.18.0 => dash-2.18.1}/dash.el (99%) rename elpa/{dash-2.18.0 => dash-2.18.1}/dash.info (99%) rename elpa/{dash-2.18.0 => dash-2.18.1}/dir (100%) delete mode 100755 elpa/format-all-0.3.0/format-all-pkg.el rename elpa/{format-all-0.3.0 => format-all-0.4.0}/format-all-autoloads.el (57%) mode change 100755 => 100644 create mode 100644 elpa/format-all-0.4.0/format-all-pkg.el rename elpa/{format-all-0.3.0 => format-all-0.4.0}/format-all.el (56%) mode change 100755 => 100644 create mode 100644 elpa/inheritenv-0.1/inheritenv-autoloads.el create mode 100644 elpa/inheritenv-0.1/inheritenv-pkg.el create mode 100644 elpa/inheritenv-0.1/inheritenv.el delete mode 100755 elpa/ivy-0.13.0/colir.el delete mode 100755 elpa/ivy-0.13.0/ivy-autoloads.el delete mode 100755 elpa/ivy-0.13.0/ivy-overlay.el delete mode 100755 elpa/ivy-0.13.0/ivy-pkg.el delete mode 100755 elpa/ivy-0.13.0/ivy.el delete mode 100755 elpa/ivy-0.13.0/ivy.info delete mode 100644 elpa/ivy-0.13.1.signed delete mode 100644 elpa/ivy-0.13.1/ChangeLog delete mode 100644 elpa/ivy-0.13.1/colir.el delete mode 100644 elpa/ivy-0.13.1/dir delete mode 100644 elpa/ivy-0.13.1/ivy-autoloads.el delete mode 100644 elpa/ivy-0.13.1/ivy-overlay.el delete mode 100644 elpa/ivy-0.13.1/ivy-pkg.el delete mode 100644 elpa/ivy-0.13.1/ivy.el delete mode 100644 elpa/ivy-0.13.1/ivy.info delete mode 100644 elpa/ivy-20210216.1611/dir delete mode 100644 elpa/ivy-20210216.1611/elpa.el delete mode 100644 elpa/ivy-20210216.1611/ivy-help.org rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/colir.el (98%) rename elpa/{ivy-0.13.0 => ivy-20210311.1638}/dir (100%) mode change 100755 => 100644 rename elpa/{ivy-0.13.0 => ivy-20210311.1638}/elpa.el (100%) mode change 100755 => 100644 rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/ivy-autoloads.el (100%) rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/ivy-faces.el (98%) rename elpa/{ivy-0.13.0 => ivy-20210311.1638}/ivy-help.org (100%) mode change 100755 => 100644 rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/ivy-overlay.el (98%) rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/ivy-pkg.el (66%) rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/ivy.el (99%) rename elpa/{ivy-20210216.1611 => ivy-20210311.1638}/ivy.info (97%) delete mode 100755 elpa/ivy-hydra-0.13.0/ivy-hydra-pkg.el delete mode 100755 elpa/ivy-hydra-0.13.0/ivy-hydra.el rename elpa/{ivy-hydra-0.13.0 => ivy-hydra-0.13.4}/ivy-hydra-autoloads.el (100%) mode change 100755 => 100644 create mode 100644 elpa/ivy-hydra-0.13.4/ivy-hydra-pkg.el rename elpa/{ivy-0.13.1 => ivy-hydra-0.13.4}/ivy-hydra.el (68%) delete mode 100644 elpa/markdown-mode-20210216.852/markdown-mode-pkg.el rename elpa/{markdown-mode-20210216.852 => markdown-mode-20210220.1301}/markdown-mode-autoloads.el (100%) create mode 100644 elpa/markdown-mode-20210220.1301/markdown-mode-pkg.el rename elpa/{markdown-mode-20210216.852 => markdown-mode-20210220.1301}/markdown-mode.el (99%) delete mode 100755 elpa/php-mode-1.23.0/php-mode-pkg.el delete mode 100755 elpa/php-mode-1.23.0/php-util-buffer.el rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php-align.el (98%) mode change 100755 => 100644 rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php-face.el (99%) mode change 100755 => 100644 create mode 100644 elpa/php-mode-1.24.0/php-local-manual.el rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php-mode-autoloads.el (97%) mode change 100755 => 100644 rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php-mode-debug.el (98%) mode change 100755 => 100644 create mode 100644 elpa/php-mode-1.24.0/php-mode-pkg.el rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php-mode.el (97%) mode change 100755 => 100644 rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php-project.el (99%) mode change 100755 => 100644 rename elpa/{php-mode-1.23.0 => php-mode-1.24.0}/php.el (99%) mode change 100755 => 100644 rename elpa/{ssh-config-mode-20210217.1051 => ssh-config-mode-20210401.243}/ssh-config-keywords.txt (100%) rename elpa/{ssh-config-mode-20210217.1051 => ssh-config-mode-20210401.243}/ssh-config-mode-autoloads.el (100%) rename elpa/{ssh-config-mode-20210217.1051 => ssh-config-mode-20210401.243}/ssh-config-mode-pkg.el (61%) rename elpa/{ssh-config-mode-20210217.1051 => ssh-config-mode-20210401.243}/ssh-config-mode.el (93%) delete mode 100644 elpa/swiper-0.13.1.signed delete mode 100644 elpa/swiper-0.13.1/.dir-locals.el delete mode 100644 elpa/swiper-0.13.1/ChangeLog delete mode 100644 elpa/swiper-0.13.1/swiper-pkg.el rename elpa/{swiper-0.13.1 => swiper-0.13.4}/swiper-autoloads.el (95%) create mode 100644 elpa/swiper-0.13.4/swiper-pkg.el rename elpa/{swiper-0.13.1 => swiper-0.13.4}/swiper.el (85%) delete mode 100755 elpa/transient-0.2.0/transient-autoloads.el delete mode 100755 elpa/transient-0.2.0/transient-pkg.el rename elpa/{transient-0.2.0 => transient-0.3.0}/dir (100%) mode change 100755 => 100644 create mode 100644 elpa/transient-0.3.0/transient-autoloads.el create mode 100644 elpa/transient-0.3.0/transient-pkg.el rename elpa/{transient-0.2.0 => transient-0.3.0}/transient.el (80%) mode change 100755 => 100644 rename elpa/{transient-0.2.0 => transient-0.3.0}/transient.info (90%) mode change 100755 => 100644 diff --git a/elpa/counsel-0.13.0/counsel-pkg.el b/elpa/counsel-0.13.0/counsel-pkg.el deleted file mode 100755 index be9e8d7..0000000 --- a/elpa/counsel-0.13.0/counsel-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;;; Generated package description from /data/data/com.termux/files/home/.emacs.d/elpa/counsel-0.13.0/counsel.el -*- no-byte-compile: t -*- -(define-package "counsel" "0.13.0" "Various completion functions using Ivy" '((emacs "24.5") (swiper "0.13.0")) :commit "cd634c6f51458f81898ecf2821ac3169cb65a1eb" :keywords '("convenience" "matching" "tools") :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/counsel-0.13.0/counsel-autoloads.el b/elpa/counsel-0.13.4/counsel-autoloads.el old mode 100755 new mode 100644 similarity index 90% rename from elpa/counsel-0.13.0/counsel-autoloads.el rename to elpa/counsel-0.13.4/counsel-autoloads.el index 914235a..1b2b6a7 --- a/elpa/counsel-0.13.0/counsel-autoloads.el +++ b/elpa/counsel-0.13.4/counsel-autoloads.el @@ -9,18 +9,6 @@ ;;;### (autoloads nil "counsel" "counsel.el" (0 0 0 0)) ;;; Generated autoloads from counsel.el -(autoload 'counsel-el "counsel" "\ -Elisp completion at point." t nil) - -(autoload 'counsel-cl "counsel" "\ -Common Lisp completion at point." t nil) - -(autoload 'counsel-jedi "counsel" "\ -Python completion at point." t nil) - -(autoload 'counsel-clj "counsel" "\ -Clojure completion at point." t nil) - (autoload 'counsel-company "counsel" "\ Complete using `company-candidates'." t nil) @@ -39,6 +27,9 @@ Forward to `describe-function'. Interactive functions (i.e., commands) are highlighted according to `ivy-highlight-face'." t nil) +(autoload 'counsel-describe-symbol "counsel" "\ +Forward to `describe-symbol'." t nil) + (autoload 'counsel-set-variable "counsel" "\ Set a variable SYM, with completion. @@ -134,7 +125,7 @@ Call the \"git log --grep\" shell command." t nil) Forward to `find-file'. When INITIAL-INPUT is non-nil, use it in the minibuffer during completion. -\(fn &optional INITIAL-INPUT)" t nil) +\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY)" t nil) (autoload 'counsel-dired "counsel" "\ Forward to `dired'. @@ -171,11 +162,13 @@ Pass X to `xdg-open' or equivalent command via the shell. \(fn X)" t nil) (autoload 'counsel-locate "counsel" "\ -Call the \"locate\" shell command. +Call a \"locate\" style shell command. INITIAL-INPUT can be given as the initial minibuffer input. \(fn &optional INITIAL-INPUT)" t nil) +(autoload 'counsel-tracker "counsel" nil t nil) + (autoload 'counsel-fzf "counsel" "\ Open a file using the fzf shell command. INITIAL-INPUT can be given as the initial minibuffer input. @@ -207,13 +200,19 @@ INITIAL-DIRECTORY, if non-nil, is used as the root directory for search. \(fn &optional INITIAL-INPUT INITIAL-DIRECTORY)" t nil) (autoload 'counsel-ag "counsel" "\ -Grep for a string in the current directory using ag. +Grep for a string in a root directory using ag. + +By default, the root directory is the first directory containing a .git subdirectory. + INITIAL-INPUT can be given as the initial minibuffer input. INITIAL-DIRECTORY, if non-nil, is used as the root directory for search. -EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'. +EXTRA-AG-ARGS, if non-nil, is appended to `counsel-ag-base-command'. AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument. CALLER is passed to `ivy-read'. +With a `\\[universal-argument]' prefix argument, prompt for INITIAL-DIRECTORY. +With a `\\[universal-argument] \\[universal-argument]' prefix argument, prompt additionally for EXTRA-AG-ARGS. + \(fn &optional INITIAL-INPUT INITIAL-DIRECTORY EXTRA-AG-ARGS AG-PROMPT &key CALLER)" t nil) (autoload 'counsel-pt "counsel" "\ @@ -240,7 +239,7 @@ EXTRA-RG-ARGS string, if non-nil, is appended to `counsel-rg-base-command'. RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument. Example input with inclusion and exclusion file patterns: - -g*.py -g!*test* -- ... + require i -- -g*.el \(fn &optional INITIAL-INPUT INITIAL-DIRECTORY EXTRA-RG-ARGS RG-PROMPT)" t nil) @@ -302,10 +301,20 @@ Capture something." t nil) (autoload 'counsel-org-agenda-headlines "counsel" "\ Choose from headers of `org-mode' files in the agenda." t nil) +(autoload 'counsel-org-link "counsel" "\ +Insert a link to an headline with completion." t nil) + (autoload 'counsel-mark-ring "counsel" "\ Browse `mark-ring' interactively. Obeys `widen-automatically', which see." t nil) +(autoload 'counsel-evil-marks "counsel" "\ +Ivy replacement for `evil-show-marks'. +By default, this function respects `counsel-evil-marks-exclude-registers'. +When ARG is non-nil, display all active evil registers. + +\(fn &optional ARG)" t nil) + (autoload 'counsel-package "counsel" "\ Install or delete packages. @@ -403,6 +412,21 @@ Show a list of all supported font families for a particular frame. You can insert or kill the name of the selected font." t nil) +(autoload 'counsel-kmacro "counsel" "\ +Interactively choose and run a keyboard macro. + +With prefix argument, run macro that many times. + +Macros are run using the current value of `kmacro-counter-value' +and their respective counter format. Displayed next to each macro is +the counter's format and initial value. + +One can use actions to copy the counter format or initial counter +value of a macro, using them for a new macro." t nil) + +(autoload 'counsel-geiser-doc-look-up-manual "counsel" "\ +Search Scheme documentation." t nil) + (autoload 'counsel-rhythmbox "counsel" "\ Choose a song from the Rhythmbox library to play or enqueue. @@ -430,6 +454,10 @@ in the current window." t nil) (autoload 'counsel-compile "counsel" "\ Call `compile' completing with smart suggestions, optionally for DIR. +Additional actions: + +\\{counsel-compile-map} + \(fn &optional DIR)" t nil) (autoload 'counsel-compile-env "counsel" "\ @@ -450,6 +478,12 @@ Additional actions:\\ (autoload 'counsel-major "counsel" nil t nil) +(autoload 'counsel-compilation-errors "counsel" "\ +Compilation errors." t nil) + +(autoload 'counsel-flycheck "counsel" "\ +Flycheck errors." t nil) + (defvar counsel-mode nil "\ Non-nil if Counsel mode is enabled. See the `counsel-mode' command diff --git a/elpa/counsel-0.13.4/counsel-pkg.el b/elpa/counsel-0.13.4/counsel-pkg.el new file mode 100644 index 0000000..d98d4f8 --- /dev/null +++ b/elpa/counsel-0.13.4/counsel-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from counsel.el -*- no-byte-compile: t -*- +(define-package "counsel" "0.13.4" "Various completion functions using Ivy" '((emacs "24.5") (ivy "0.13.4") (swiper "0.13.4")) :commit "8cf3f1821cbd1c266296bbd5e59582ae6b8b90a6" :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :keywords '("convenience" "matching" "tools") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/counsel-0.13.0/counsel.el b/elpa/counsel-0.13.4/counsel.el old mode 100755 new mode 100644 similarity index 77% rename from elpa/counsel-0.13.0/counsel.el rename to elpa/counsel-0.13.4/counsel.el index 0d44b2d..6486ce1 --- a/elpa/counsel-0.13.0/counsel.el +++ b/elpa/counsel-0.13.4/counsel.el @@ -1,13 +1,13 @@ ;;; counsel.el --- Various completion functions using Ivy -*- lexical-binding: t -*- -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. +;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/swiper -;; Package-Version: 0.13.0 -;; Package-Commit: cd634c6f51458f81898ecf2821ac3169cb65a1eb -;; Version: 0.13.0 -;; Package-Requires: ((emacs "24.5") (swiper "0.13.0")) +;; Package-Version: 0.13.4 +;; Package-Commit: 8cf3f1821cbd1c266296bbd5e59582ae6b8b90a6 +;; Version: 0.13.4 +;; Package-Requires: ((emacs "24.5") (ivy "0.13.4") (swiper "0.13.4")) ;; Keywords: convenience, matching, tools ;; This file is part of GNU Emacs. @@ -42,10 +42,15 @@ ;;; Code: +(require 'ivy) (require 'swiper) + (require 'compile) (require 'dired) +(eval-when-compile + (require 'subr-x)) + (defgroup counsel nil "Completion functions using Ivy." :group 'matching @@ -112,17 +117,25 @@ complex regexes." str) str)) +(defalias 'counsel--executable-find + ;; Gained optional argument in 27.1. + (if (>= emacs-major-version 27) + #'executable-find + (lambda (command &optional _remote) + (executable-find command))) + "Compatibility shim for `executable-find'.") + (defun counsel-require-program (cmd) "Check system for program used in CMD, printing error if not found. CMD is either a string or a list of strings. To skip the `executable-find' check, start the string with a space." - (unless (and (stringp cmd) (string-match-p "^ " cmd)) + (unless (and (stringp cmd) (string-prefix-p " " cmd)) (let ((program (if (listp cmd) (car cmd) (car (split-string cmd))))) (or (and (stringp program) (not (string= program "")) - (executable-find program)) + (counsel--executable-find program t)) (user-error "Required program \"%s\" not found in your path" program))))) (declare-function eshell-split-path "esh-util") @@ -137,14 +150,44 @@ To skip the `executable-find' check, start the string with a space." (replace-regexp-in-string ; Insert dir before any trailing colon. "\\(?:: ?\\)?\\'" dir (ivy-state-prompt ivy-last) t t)))) +(defalias 'counsel--flatten + ;; Added in Emacs 27.1 + (if (fboundp 'flatten-tree) + #'flatten-tree + (lambda (tree) + (let (elems) + (while (consp tree) + (let ((elem (pop tree))) + (while (consp elem) + (push (cdr elem) tree) + (setq elem (car elem))) + (if elem (push elem elems)))) + (if tree (push tree elems)) + (nreverse elems)))) + "Compatibility shim for `flatten-tree'.") + +(defun counsel--format (formatter &rest args) + "Like `format' but FORMATTER can be a list. +When FORMATTER is a list, only `%s' is replaced with ARGS. + +Return a list or string depending on input." + (cond + ((listp formatter) + (counsel--flatten (mapcar + (lambda (it) (if (equal it "%s") (pop args) it)) + formatter))) + (t (apply #'format formatter args)))) + ;;* Async Utility (defvar counsel--async-time nil "Store the time when a new process was started. Or the time of the last minibuffer update.") (defvar counsel--async-start nil - "Store the time when a new process was started. -Or the time of the last minibuffer update.") + "Store the time when a new process was started.") + +(defvar counsel--async-timer nil + "Timer used to dispose `counsel--async-command.") (defvar counsel--async-duration nil "Store the time a process takes to gather all its candidates. @@ -166,16 +209,16 @@ descriptions.") cmd (plist-put plist number str))))) -(defvar counsel-async-split-string-re-alist '((t . "\n")) +(defvar counsel-async-split-string-re-alist '((t . "[\r\n]")) "Store the regexp for splitting shell command output.") (defvar counsel-async-ignore-re-alist nil "An alist of regexp matching candidates to ignore in `counsel--async-filter'.") (defvar counsel--async-last-command nil - "Store the last command ran by `counsel--async-command'.") + "Store the last command ran by `counsel--async-command-1'.") -(defun counsel--async-command (cmd &optional sentinel filter name) +(defun counsel--async-command-1 (cmd &optional sentinel filter name) "Start and return new counsel process by calling CMD. CMD can be either a shell command as a string, or a list of the program name to be called directly, followed by its arguments. @@ -199,48 +242,76 @@ respectively." (set-process-filter proc (or filter #'counsel--async-filter)) proc)) +(defcustom counsel-async-command-delay 0 + "Number of seconds to wait before spawning another async command." + :type 'number) + +(defun counsel--async-command (&rest args) + "Like `counsel--async-command-1', with same ARGS, but debounced. +Calls to `counsel--async-command-1' are separated by at least +`counsel-async-command-delay' seconds, so as to avoid issues +caused by spawning too many subprocesses too quickly." + (if (zerop counsel-async-command-delay) + (apply #'counsel--async-command-1 args) + (when counsel--async-timer + (cancel-timer counsel--async-timer)) + (setq counsel--async-timer + (apply #'run-with-timer + counsel-async-command-delay + nil + #'counsel--async-command-1 + args)))) + (defun counsel--split-string (&optional str) (split-string (or str (buffer-string)) (ivy-alist-setting counsel-async-split-string-re-alist) t)) +(defun counsel--sync-sentinel-on-exit (process) + (if (zerop (process-exit-status process)) + (let ((cur (ivy-state-current ivy-last))) + (ivy--set-candidates + (ivy--sort-maybe + (with-current-buffer (process-buffer process) + (counsel--split-string)))) + (when counsel--async-start + (setq counsel--async-duration + (time-to-seconds (time-since counsel--async-start)))) + (let ((re (ivy-re-to-str ivy-regex))) + (if ivy--old-cands + (if (eq (ivy-alist-setting ivy-index-functions-alist) 'ivy-recompute-index-zero) + (ivy-set-index 0) + (ivy--recompute-index re ivy--all-candidates)) + ;; index was changed before a long-running query exited + (unless (string= cur (nth ivy--index ivy--all-candidates)) + (let ((func (ivy-alist-setting ivy-index-functions-alist))) + (if func + (funcall func re ivy--all-candidates) + (ivy--preselect-index + (if (> (length re) 0) + cur + (ivy-state-preselect ivy-last)) + ivy--all-candidates)))))) + (setq ivy--old-cands ivy--all-candidates) + (if ivy--all-candidates + (ivy--exhibit) + (ivy--insert-minibuffer ""))) + (setq counsel--async-last-error-string + (with-current-buffer (process-buffer process) (buffer-string))) + (setq ivy--all-candidates + (let ((status (process-exit-status process)) + (plist (plist-get counsel--async-exit-code-plist + (ivy-state-caller ivy-last)))) + (list (or (plist-get plist status) + (format "error code %d" status))))) + (setq ivy--old-cands ivy--all-candidates) + (ivy--exhibit))) + (defun counsel--async-sentinel (process _msg) "Sentinel function for an asynchronous counsel PROCESS." (when (eq (process-status process) 'exit) - (if (zerop (process-exit-status process)) - (progn - (ivy--set-candidates - (ivy--sort-maybe - (with-current-buffer (process-buffer process) - (counsel--split-string)))) - (when counsel--async-start - (setq counsel--async-duration - (time-to-seconds (time-since counsel--async-start)))) - (let ((re (ivy-re-to-str (funcall ivy--regex-function ivy-text)))) - (if ivy--old-cands - (if (eq (ivy-alist-setting ivy-index-functions-alist) 'ivy-recompute-index-zero) - (ivy-set-index 0) - (ivy--recompute-index ivy-text re ivy--all-candidates)) - (unless (ivy-set-index - (ivy--preselect-index - (ivy-state-preselect ivy-last) - ivy--all-candidates)) - (ivy--recompute-index ivy-text re ivy--all-candidates)))) - (setq ivy--old-cands ivy--all-candidates) - (if ivy--all-candidates - (ivy--exhibit) - (ivy--insert-minibuffer ""))) - (setq counsel--async-last-error-string - (with-current-buffer (process-buffer process) (buffer-string))) - (setq ivy--all-candidates - (let ((status (process-exit-status process)) - (plist (plist-get counsel--async-exit-code-plist - (ivy-state-caller ivy-last)))) - (list (or (plist-get plist status) - (format "error code %d" status))))) - (setq ivy--old-cands ivy--all-candidates) - (ivy--exhibit)))) + (counsel--sync-sentinel-on-exit process))) (defcustom counsel-async-filter-update-time 500000 "The amount of microseconds to wait until updating `counsel--async-filter'." @@ -276,113 +347,10 @@ Update the minibuffer with the amount of lines collected every (delete-process process)))) ;;* Completion at point -;;** `counsel-el' -;;;###autoload -(defun counsel-el () - "Elisp completion at point." - (interactive) - (let* ((bnd (unless (and (looking-at ")") - (eq (char-before) ?\()) - (bounds-of-thing-at-point 'symbol))) - (str (if bnd - (buffer-substring-no-properties - (car bnd) - (cdr bnd)) - "")) - (pred (and (eq (char-before (car bnd)) ?\() - #'fboundp)) - symbol-names) - (setq ivy-completion-beg (car bnd)) - (setq ivy-completion-end (cdr bnd)) - (if (string= str "") - (mapatoms - (lambda (x) - (when (and (symbolp x) (funcall pred x)) - (push (symbol-name x) symbol-names)))) - (setq symbol-names (all-completions str obarray pred))) - (ivy-read "Symbol name: " symbol-names - :initial-input str - :action #'ivy-completion-in-region-action - :caller 'counsel-el))) - -(ivy-configure 'counsel-el - :height 7) - -;;** `counsel-cl' -(declare-function slime-symbol-start-pos "ext:slime") -(declare-function slime-symbol-end-pos "ext:slime") -(declare-function slime-contextual-completions "ext:slime-c-p-c") - -;;;###autoload -(defun counsel-cl () - "Common Lisp completion at point." - (interactive) - (setq ivy-completion-beg (slime-symbol-start-pos)) - (setq ivy-completion-end (slime-symbol-end-pos)) - (ivy-read "Symbol name: " - (car (slime-contextual-completions - ivy-completion-beg - ivy-completion-end)) - :action #'ivy-completion-in-region-action)) - -;;** `counsel-jedi' -(declare-function deferred:sync! "ext:deferred") -(declare-function jedi:complete-request "ext:jedi-core") -(declare-function jedi:ac-direct-matches "ext:jedi") - -;;;###autoload -(defun counsel-jedi () - "Python completion at point." - (interactive) - (let ((bnd (bounds-of-thing-at-point 'symbol))) - (setq ivy-completion-beg (car bnd)) - (setq ivy-completion-end (cdr bnd))) - (deferred:sync! - (jedi:complete-request)) - (ivy-read "Symbol name: " (jedi:ac-direct-matches) - :action #'counsel--py-action)) - -(defun counsel--py-action (symbol-name) - "Insert SYMBOL-NAME, erasing the previous one." - (when (stringp symbol-name) - (with-ivy-window - (when ivy-completion-beg - (delete-region - ivy-completion-beg - ivy-completion-end)) - (setq ivy-completion-beg (point)) - (insert symbol-name) - (setq ivy-completion-end (point))))) - -;;** `counsel-clj' -(declare-function cider-sync-request:complete "ext:cider-client") -(defun counsel--generic (completion-fn) - "Complete thing at point with COMPLETION-FN." - (let* ((bnd (or (bounds-of-thing-at-point 'symbol) - (cons (point) (point)))) - (str (buffer-substring-no-properties - (car bnd) (cdr bnd))) - (candidates (funcall completion-fn str)) - (res (ivy-read (format "pattern (%s): " str) - candidates - :caller 'counsel--generic))) - (when (stringp res) - (when bnd - (delete-region (car bnd) (cdr bnd))) - (insert res)))) - -(ivy-configure 'counsel--generic - :height 7) - -;;;###autoload -(defun counsel-clj () - "Clojure completion at point." - (interactive) - (counsel--generic - (lambda (str) - (mapcar - #'cl-caddr - (cider-sync-request:complete str ":same"))))) +(define-obsolete-function-alias 'counsel-el 'complete-symbol "<2020-05-20 Wed>") +(define-obsolete-function-alias 'counsel-cl 'complete-symbol "<2020-05-20 Wed>") +(define-obsolete-function-alias 'counsel-jedi 'complete-symbol "<2020-05-20 Wed>") +(define-obsolete-function-alias 'counsel-clj 'complete-symbol "<2020-05-20 Wed>") ;;** `counsel-company' (defvar company-candidates) @@ -391,6 +359,8 @@ Update the minibuffer with the amount of lines collected every (declare-function company-abort "ext:company") (declare-function company-complete "ext:company") (declare-function company-mode "ext:company") +(declare-function company-call-backend "ext:company") +(declare-function company--clean-string "ext:company") ;;;###autoload (defun counsel-company () @@ -399,8 +369,13 @@ Update the minibuffer with the amount of lines collected every (company-mode 1) (unless company-candidates (company-complete)) - (let ((len (cond (company-common - (length company-common)) + (let ((len (cond ((let (l) + (and company-common + (string= company-common + (buffer-substring + (- (point) (setq l (length company-common))) + (point))) + l))) (company-prefix (length company-prefix))))) (when len @@ -411,8 +386,14 @@ Update the minibuffer with the amount of lines collected every :caller 'counsel-company)))) (ivy-configure 'counsel-company + :display-transformer-fn #'counsel--company-display-transformer :unwind-fn #'company-abort) +(defun counsel--company-display-transformer (s) + (concat s (let ((annot (company-call-backend 'annotation s))) + (when annot + (company--clean-string annot))))) + ;;** `counsel-irony' (declare-function irony-completion-candidates-async "ext:irony-completion") (declare-function irony-completion-symbol-bounds "ext:irony-completion") @@ -444,7 +425,8 @@ Update the minibuffer with the amount of lines collected every (cons (concat (car x) (irony-completion-annotation x)) (car x))) -(add-to-list 'ivy-display-functions-alist '(counsel-irony . ivy-display-function-overlay)) +(ivy-configure #'counsel-irony + :display-fn #'ivy-display-function-overlay) ;;* Elisp symbols ;;** `counsel-describe-variable' @@ -461,8 +443,8 @@ Update the minibuffer with the amount of lines collected every (defvar counsel-describe-symbol-history () "History list for variable and function names. -Used by commands `counsel-describe-variable' and -`counsel-describe-function'.") +Used by commands `counsel-describe-symbol', +`counsel-describe-variable', and `counsel-describe-function'.") (defun counsel-find-symbol () "Jump to the definition of the current symbol." @@ -479,6 +461,7 @@ Used by commands `counsel-describe-variable' and (declare-function xref-push-marker-stack "xref") (defalias 'counsel--push-xref-marker + ;; Added in Emacs 25.1. (if (require 'xref nil t) #'xref-push-marker-stack (require 'etags) @@ -546,9 +529,8 @@ Variables declared using `defcustom' are highlighted according to :caller 'counsel-describe-variable))) (ivy-configure 'counsel-describe-variable - :initial-input "^" - :display-transformer-fn #'counsel-describe-variable-transformer - :sort-fn #'ivy-string<) + :parent 'counsel-describe-symbol + :display-transformer-fn #'counsel-describe-variable-transformer) ;;** `counsel-describe-function' (ivy-set-actions @@ -597,10 +579,44 @@ to `ivy-highlight-face'." :caller 'counsel-describe-function))) (ivy-configure 'counsel-describe-function + :parent 'counsel-describe-symbol + :display-transformer-fn #'counsel-describe-function-transformer) + +;;** `counsel-describe-symbol' +(defcustom counsel-describe-symbol-function #'describe-symbol + "Function to call to describe a symbol passed as parameter." + :type 'function) + +;;;###autoload +(defun counsel-describe-symbol () + "Forward to `describe-symbol'." + (interactive) + (unless (functionp 'describe-symbol) + (user-error "This command requires Emacs 25.1 or later")) + (require 'help-mode) + (let ((enable-recursive-minibuffers t)) + (ivy-read "Describe symbol: " obarray + :predicate (lambda (sym) + (cl-some (lambda (backend) + (funcall (cadr backend) sym)) + describe-symbol-backends)) + :require-match t + :history 'counsel-describe-symbol-history + :keymap counsel-describe-map + :preselect (ivy-thing-at-point) + :action (lambda (x) + (funcall counsel-describe-symbol-function (intern x))) + :caller 'counsel-describe-symbol))) + +(ivy-configure 'counsel-describe-symbol :initial-input "^" - :display-transformer-fn #'counsel-describe-function-transformer :sort-fn #'ivy-string<) +(ivy-set-actions + 'counsel-describe-symbol + `(("I" ,#'counsel-info-lookup-symbol "info") + ("d" ,#'counsel--find-symbol "definition"))) + ;;** `counsel-set-variable' (defvar counsel-set-variable-history nil "Store history for `counsel-set-variable'.") @@ -608,26 +624,35 @@ to `ivy-highlight-face'." (defun counsel-read-setq-expression (sym) "Read and eval a setq expression for SYM." (setq this-command 'eval-expression) - (let* ((minibuffer-completing-symbol t) - (sym-value (symbol-value sym)) - (expr (minibuffer-with-setup-hook - (lambda () - (add-function :before-until (local 'eldoc-documentation-function) - #'elisp-eldoc-documentation-function) - (add-hook 'completion-at-point-functions #'elisp-completion-at-point nil t) - (run-hooks 'eval-expression-minibuffer-setup-hook) - (goto-char (minibuffer-prompt-end)) - (forward-char 6) - (insert (format "%S " sym))) - (read-from-minibuffer "Eval: " - (format - (if (and sym-value (consp sym-value)) - "(setq '%S)" - "(setq %S)") - sym-value) - read-expression-map t - 'read-expression-history)))) - (eval-expression expr))) + (let* ((sym-value (symbol-value sym)) + (init (format "(setq %s%S)" + (if (or (consp sym-value) + (and sym-value (symbolp sym-value))) + "'" + "") + sym-value))) + ;; Most of this duplicates `read--expression'. + (minibuffer-with-setup-hook + (lambda () + (set-syntax-table emacs-lisp-mode-syntax-table) + ;; Added in Emacs 25.1. + (when (fboundp 'elisp-completion-at-point) + (add-hook 'completion-at-point-functions + #'elisp-completion-at-point nil t)) + ;; Emacs 27+ already sets up ElDoc in this hook. Emacs 25 added + ;; `elisp-eldoc-documentation-function' and Emacs 28 obsoletes it. + (when (< emacs-major-version 27) + (when (fboundp 'elisp-eldoc-documentation-function) + (add-function :before-until (local 'eldoc-documentation-function) + #'elisp-eldoc-documentation-function)) + (eldoc-mode)) + (run-hooks 'eval-expression-minibuffer-setup-hook) + ;; The following diverges from `read--expression'. + (goto-char (minibuffer-prompt-end)) + (forward-char 6) + (insert (format "%S " sym))) + (read-from-minibuffer "Eval: " init read-expression-map t + 'read-expression-history)))) (defun counsel--setq-doconst (x) "Return a cons of description and value for X. @@ -704,12 +729,15 @@ With a prefix arg, restrict list to variables defined using (if (assoc res cands) (cdr (assoc res cands)) (read res))) + (kill-new (format "(setq %S %S)" sym res)) (set sym (if (and (listp res) (eq (car res) 'quote)) (cadr res) res)))) (unless (boundp sym) (set sym nil)) - (counsel-read-setq-expression sym))) + (let ((expr (counsel-read-setq-expression sym))) + (kill-new (format "%S" expr)) + (eval-expression expr)))) (when doc (lv-delete-window))))) @@ -855,6 +883,23 @@ packages are, in order of precedence, `amx' and `smex'." (smex-update)) smex-ido-cache))) +(defun counsel--M-x-externs-predicate (cand) + "Return non-nil if `counsel-M-x' should complete CAND. +CAND is a string returned by `counsel--M-x-externs'." + (not (get (intern cand) 'no-counsel-M-x))) + +(defun counsel--M-x-make-predicate () + "Return a predicate for `counsel-M-x' in the current buffer." + (defvar read-extended-command-predicate) + (let ((buf (current-buffer))) + (lambda (sym) + (and (commandp sym) + (not (get sym 'byte-obsolete-info)) + (not (get sym 'no-counsel-M-x)) + (or (not (bound-and-true-p read-extended-command-predicate)) + (and (functionp read-extended-command-predicate) + (funcall read-extended-command-predicate sym buf))))))) + (defun counsel--M-x-prompt () "String for `M-x' plus the string representation of `current-prefix-arg'." (concat (cond ((null current-prefix-arg) @@ -874,7 +919,8 @@ packages are, in order of precedence, `amx' and `smex'." (defun counsel-M-x-action (cmd) "Execute CMD." - (setq cmd (intern cmd)) + (setq cmd (intern + (subst-char-in-string ?\s ?- (string-remove-prefix "^" cmd)))) (cond ((bound-and-true-p amx-initialized) (amx-rank cmd)) ((bound-and-true-p smex-initialized-p) @@ -899,12 +945,8 @@ when available, in that order of precedence." (let ((externs (counsel--M-x-externs))) (ivy-read (counsel--M-x-prompt) (or externs obarray) :predicate (if externs - (lambda (x) - (not (get (intern x) 'no-counsel-M-x))) - (lambda (sym) - (and (commandp sym) - (not (get sym 'byte-obsolete-info)) - (not (get sym 'no-counsel-M-x))))) + #'counsel--M-x-externs-predicate + (counsel--M-x-make-predicate)) :require-match t :history 'counsel-M-x-history :action #'counsel-M-x-action @@ -1081,17 +1123,17 @@ See `describe-buffer-bindings' for further information." (describe-buffer-bindings buffer prefix)) (goto-char (point-min)) ;; Skip the "Key translations" section - (re-search-forward " ") - (forward-char 1) + (skip-chars-forward "^\C-l") + (forward-char 2) (while (not (eobp)) (when (looking-at "^\\([^\t\n]+\\)[\t ]*\\(.*\\)$") (let ((key (match-string 1)) (fun (match-string 2)) cmd) (unless (or (member fun '("??" "self-insert-command")) - (string-match re-exclude key) + (string-match-p re-exclude key) (not (or (commandp (setq cmd (intern-soft fun))) - (member fun '("Prefix Command"))))) + (equal fun "Prefix Command")))) (push (cons (format "%-15s %s" @@ -1099,7 +1141,7 @@ See `describe-buffer-bindings' for further information." fun) (cons key cmd)) res)))) - (forward-line 1))) + (forward-line))) (nreverse res))) (defcustom counsel-descbinds-function #'describe-function @@ -1175,6 +1217,15 @@ back to the face of the character after point, and finally the "Customize face with NAME in another window." (customize-face-other-window (intern name))) +(declare-function hi-lock-set-pattern "hi-lock") +(defun counsel-highlight-with-face (face) + "Highlight thing-at-point with FACE." + (hi-lock-mode 1) + (let ((thing (ivy-thing-at-point))) + (when (use-region-p) + (deactivate-mark)) + (hi-lock-set-pattern (regexp-quote thing) (intern face)))) + (ivy-set-actions 'counsel-describe-face '(("c" counsel-customize-face "customize") @@ -1213,17 +1264,18 @@ selected face." :caller 'counsel-faces))) (ivy-configure 'counsel-faces - :sort-fn #'ivy-string< + :parent 'counsel-describe-face :format-fn #'counsel--faces-format-function) (ivy-set-actions 'counsel-faces '(("c" counsel-customize-face "customize") - ("C" counsel-customize-face-other-window "customize other window"))) + ("C" counsel-customize-face-other-window "customize other window") + ("h" counsel-highlight-with-face "highlight"))) ;;* Git ;;** `counsel-git' -(defvar counsel-git-cmd "git ls-files --full-name --" +(defvar counsel-git-cmd "git ls-files -z --full-name --" "Command for `counsel-git'.") (ivy-set-actions @@ -1243,11 +1295,11 @@ Like `locate-dominating-file', but DIR defaults to (or (counsel--git-root) (error "Not in a Git repository"))) -(defun counsel-git-cands () - (let ((default-directory (counsel-locate-git-root))) +(defun counsel-git-cands (dir) + (let ((default-directory dir)) (split-string (shell-command-to-string counsel-git-cmd) - "\n" + "\0" t))) ;;;###autoload @@ -1257,7 +1309,7 @@ INITIAL-INPUT can be given as the initial minibuffer input." (interactive) (counsel-require-program counsel-git-cmd) (let ((default-directory (counsel-locate-git-root))) - (ivy-read "Find file: " (counsel-git-cands) + (ivy-read "Find file: " (counsel-git-cands default-directory) :initial-input initial-input :action #'counsel-git-action :caller 'counsel-git))) @@ -1277,7 +1329,7 @@ INITIAL-INPUT can be given as the initial minibuffer input." (counsel-cmd-to-dired (counsel--expand-ls (format "%s | %s | xargs ls" - counsel-git-cmd + (replace-regexp-in-string "\\(-0\\)\\|\\(-z\\)" "" counsel-git-cmd) (counsel--file-name-filter))))) (defvar counsel-dired-listing-switches "-alh" @@ -1318,7 +1370,7 @@ INITIAL-INPUT can be given as the initial minibuffer input." (define-key map (kbd "C-x C-d") 'counsel-cd) map)) -(defvar counsel-git-grep-cmd-default "git --no-pager grep --full-name -n --no-color -i -I -e \"%s\"" +(defvar counsel-git-grep-cmd-default "git --no-pager grep -n --no-color -I -e \"%s\"" "Initial command for `counsel-git-grep'.") (defvar counsel-git-grep-cmd nil @@ -1337,7 +1389,8 @@ Typical value: '(recenter)." :type 'hook) (defcustom counsel-git-grep-cmd-function #'counsel-git-grep-cmd-function-default - "How a git-grep shell call is built from the input." + "How a git-grep shell call is built from the input. +This function should set `ivy--old-re'." :type '(radio (function-item counsel-git-grep-cmd-function-default) (function-item counsel-git-grep-cmd-function-ignore-order) @@ -1364,7 +1417,9 @@ Typical value: '(recenter)." (ivy-more-chars) (progn (counsel--async-command - (funcall counsel-git-grep-cmd-function string)) + (concat + (funcall counsel-git-grep-cmd-function string) + (if (ivy--case-fold-p string) " -i" ""))) nil))) (defun counsel-git-grep-action (x) @@ -1387,14 +1442,12 @@ Typical value: '(recenter)." (swiper--add-overlays (ivy--regex ivy-text)))))) (defun counsel-git-grep-transformer (str) - "Higlight file and line number in STR." + "Highlight file and line number in STR." (when (string-match "\\`\\([^:]+\\):\\([^:]+\\):" str) - (ivy-add-face-text-property (match-beginning 1) (match-end 1) - 'ivy-grep-info - str) - (ivy-add-face-text-property (match-beginning 2) (match-end 2) - 'ivy-grep-line-number - str)) + (add-face-text-property (match-beginning 1) (match-end 1) + 'ivy-grep-info nil str) + (add-face-text-property (match-beginning 2) (match-end 2) + 'ivy-grep-line-number nil str)) str) (defvar counsel-git-grep-projects-alist nil @@ -1497,12 +1550,36 @@ When CMD is non-nil, prompt for a specific \"git grep\" command." :keymap counsel-git-grep-map :action #'counsel-git-grep-action :history 'counsel-git-grep-history + :require-match t :caller 'counsel-git-grep)))) +(defun counsel--git-grep-index (_re-str cands) + (let (name ln) + (cond + (ivy--old-cands + (ivy-recompute-index-swiper-async nil cands)) + ((unless (with-ivy-window + (when buffer-file-name + (setq ln (line-number-at-pos)) + (setq name (file-name-nondirectory buffer-file-name)))) + 0)) + ;; Closest to current line going forwards. + ((let ((beg (1+ (length name)))) + (cl-position-if (lambda (x) + (and (string-prefix-p name x) + (>= (string-to-number (substring x beg)) ln))) + cands))) + ;; Closest to current line going backwards. + ((cl-position-if (lambda (x) + (string-prefix-p name x)) + cands + :from-end t)) + (t 0)))) + (ivy-configure 'counsel-git-grep :occur #'counsel-git-grep-occur :unwind-fn #'counsel--grep-unwind - :index-fn #'ivy-recompute-index-swiper-async + :index-fn #'counsel--git-grep-index :display-transformer-fn #'counsel-git-grep-transformer :grep-p t :exit-codes '(1 "No matches found")) @@ -1513,7 +1590,10 @@ When CMD is non-nil, prompt for a specific \"git grep\" command." (ivy-more-chars) (let ((regex (setq ivy--old-re (ivy--regex str t)))) - (counsel--async-command (format counsel-git-grep-cmd regex)) + (counsel--async-command + (concat + (format counsel-git-grep-cmd regex) + (if (ivy--case-fold-p str) " -i" ""))) nil))) (defun counsel-git-grep-switch-cmd () @@ -1541,10 +1621,7 @@ When CMD is non-nil, prompt for a specific \"git grep\" command." str) (defun counsel--git-grep-occur-cmd (input) - (let* ((regex (funcall ivy--regex-function input)) - (regex (if (eq ivy--regex-function #'ivy--regex-fuzzy) - (replace-regexp-in-string "\n" "" regex) - regex)) + (let* ((regex ivy--old-re) (positive-pattern (replace-regexp-in-string ;; git-grep can't handle .*? "\\.\\*\\?" ".*" @@ -1556,7 +1633,10 @@ When CMD is non-nil, prompt for a specific \"git grep\" command." (format "| grep -v %s" (car x)))) regex " ")))) - (concat (format counsel-git-grep-cmd positive-pattern) negative-patterns))) + (concat + (format counsel-git-grep-cmd positive-pattern) + negative-patterns + (if (ivy--case-fold-p input) " -i" "")))) (defun counsel-git-grep-occur (&optional _cands) "Generate a custom occur buffer for `counsel-git-grep'." @@ -1609,16 +1689,16 @@ done") "\n" t))) :caller 'counsel-git-stash))) ;;** `counsel-git-log' -(defvar counsel-git-log-cmd "GIT_PAGER=cat git log --grep '%s'" +(defvar counsel-git-log-cmd "GIT_PAGER=cat git log --no-color --grep '%s'" "Command used for \"git log\".") -(defun counsel-git-log-function (str) - "Search for STR in git log." +(defun counsel-git-log-function (_) + "Search for `ivy-regex' in git log." (or (ivy-more-chars) (progn ;; `counsel--yank-pop-format-function' uses this - (setq ivy--old-re (funcall ivy--regex-function str)) + (setq ivy--old-re ivy-regex) (counsel--async-command ;; "git log --grep" likes to have groups quoted e.g. \(foo\). ;; But it doesn't like the non-greedy ".*?". @@ -1684,7 +1764,7 @@ TREE is the selected candidate." (ivy-read "Select worktree: " (or (cl-delete default-directory (counsel-git-worktree-list) :key #'counsel-git-worktree-parse-root :test #'string=) - (error "No other worktrees!")) + (error "No other worktrees")) :action (lambda (tree) (counsel-git-change-worktree-action (ivy-state-directory ivy-last) tree)) @@ -1750,9 +1830,17 @@ currently checked out." (let ((map (make-sparse-keymap))) (define-key map (kbd "C-DEL") 'counsel-up-directory) (define-key map (kbd "C-") 'counsel-up-directory) - (define-key map (kbd "`") (ivy-make-magic-action 'counsel-find-file "b")) + (define-key map (kbd "`") #'counsel-file-jump-from-find) + (define-key map (kbd "C-`") (ivy-make-magic-action 'counsel-find-file "b")) + (define-key map [remap undo] 'counsel-find-file-undo) map)) +(defun counsel-file-jump-from-find () + "Switch to `counsel-file-jump' from `counsel-find-file'." + (interactive) + (ivy-quit-and-run + (counsel-file-jump ivy-text (ivy-state-directory ivy-last)))) + (when (executable-find "git") (add-to-list 'ivy-ffap-url-functions 'counsel-github-url-p) (add-to-list 'ivy-ffap-url-functions 'counsel-emacs-url-p)) @@ -1850,6 +1938,7 @@ choose between `yes-or-no-p' and `y-or-n-p'; otherwise default to ("x" counsel-find-file-extern "open externally") ("r" counsel-find-file-as-root "open as root") ("R" find-file-read-only "read only") + ("l" find-file-literally "open literally") ("k" counsel-find-file-delete "delete") ("c" counsel-find-file-copy "copy file") ("m" counsel-find-file-move "move or rename") @@ -1899,7 +1988,7 @@ Skip some dotfiles unless `ivy-text' requires them." (setq res (cl-remove-if-not counsel--find-file-predicate res)))) (if (or (null ivy-use-ignore) (null counsel-find-file-ignore-regexp) - (string-match-p "\\`\\." ivy-text)) + (string-match-p counsel-find-file-ignore-regexp ivy-text)) res (or (cl-remove-if (lambda (x) @@ -1920,15 +2009,14 @@ Skip some dotfiles unless `ivy-text' requires them." (defun counsel-find-file-action (x) "Find file X." - (with-ivy-window - (cond ((and counsel-find-file-speedup-remote - (file-remote-p ivy--directory)) - (let ((find-file-hook nil)) - (find-file (expand-file-name x ivy--directory)))) - ((member (file-name-extension x) counsel-find-file-extern-extensions) - (counsel-find-file-extern x)) - (t - (find-file (expand-file-name x ivy--directory)))))) + (cond ((and counsel-find-file-speedup-remote + (file-remote-p ivy--directory)) + (let ((find-file-hook nil)) + (find-file (expand-file-name x ivy--directory)))) + ((member (file-name-extension x) counsel-find-file-extern-extensions) + (counsel-find-file-extern x)) + (t + (find-file (expand-file-name x ivy--directory))))) (defun counsel--preselect-file () "Return candidate to preselect during filename completion. @@ -1939,7 +2027,8 @@ The preselect behavior can be customized via user options (when counsel-find-file-at-point (require 'ffap) (let ((f (ffap-guesser))) - (when f (expand-file-name f)))) + (when (and f (not (ivy-ffap-url-p f))) + (expand-file-name f)))) (and counsel-preselect-current-file buffer-file-name (file-name-nondirectory buffer-file-name)))) @@ -1960,18 +2049,18 @@ The preselect behavior can be customized via user options :caller caller))) ;;;###autoload -(defun counsel-find-file (&optional initial-input) +(defun counsel-find-file (&optional initial-input initial-directory) "Forward to `find-file'. When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." (interactive) - (counsel--find-file-1 - "Find file: " initial-input - #'counsel-find-file-action - 'counsel-find-file)) + (let ((default-directory (or initial-directory default-directory))) + (counsel--find-file-1 "Find file: " initial-input + #'counsel-find-file-action + 'counsel-find-file))) (ivy-configure 'counsel-find-file - :occur #'counsel-find-file-occur - :display-transformer-fn #'ivy-read-file-transformer) + :parent 'read-file-name-internal + :occur #'counsel-find-file-occur) (defvar counsel-find-file-occur-cmd "ls -a | %s | xargs -d '\\n' ls -d --group-directories-first" "Format string for `counsel-find-file-occur'.") @@ -1986,7 +2075,7 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." (defvar counsel-file-name-filter-alist '(("ag -i '%s'" . t) ("ack -i '%s'" . t) - ("perl -ne '/(%s.*)/i && print \"$1\\n\";'" . t) + ("perl -ne '/(.*%s.*)/i && print \"$1\\n\";'" . t) ("grep -i -E '%s'")) "Alist of file name filtering commands. The car is a shell command and the cdr is t when the shell @@ -2010,7 +2099,7 @@ If USE-IGNORE is non-nil, try to generate a command that respects (when (and use-ignore ivy-use-ignore counsel-find-file-ignore-regexp (cdr filter-cmd) - (not (string-match-p "\\`\\." ivy-text)) + (not (string-match-p counsel-find-file-ignore-regexp ivy-text)) (not (string-match-p counsel-find-file-ignore-regexp (or (car ivy--old-cands) "")))) (let ((ignore-re (list (counsel--elisp-to-pcre @@ -2086,7 +2175,7 @@ See variable `counsel-up-directory-level'." (ivy-set-index 0) (setq ivy--directory "") (setq ivy--all-candidates nil) - (setq ivy-text "") + (ivy-set-text "") (delete-minibuffer-contents) (insert up-dir)) (if (and counsel-up-directory-level (not (string= ivy-text ""))) @@ -2100,6 +2189,16 @@ See variable `counsel-up-directory-level'." (interactive) (ivy--directory-enter)) +(defun counsel-find-file-undo () + (interactive) + (if (string= ivy-text "") + (let ((dir (progn + (pop ivy--directory-hist) + (pop ivy--directory-hist)))) + (when dir + (ivy--cd dir))) + (undo))) + (defun counsel-at-git-issue-p () "When point is at an issue in a Git-versioned file, return the issue string." (and (looking-at "#[0-9]+") @@ -2198,29 +2297,111 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." 'counsel-dired))) (ivy-configure 'counsel-dired - :display-transformer-fn #'ivy-read-file-transformer) + :parent 'read-file-name-internal) ;;** `counsel-recentf' (defvar recentf-list) (declare-function recentf-mode "recentf") +(defcustom counsel-recentf-include-xdg-list nil + "Include recently used files listed by XDG-compliant environments. +Examples of such environments are GNOME and KDE. See the URL +`https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec'." + :type 'boolean + :link '(url-link "\ +https://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec")) + ;;;###autoload (defun counsel-recentf () "Find a file on `recentf-list'." (interactive) (require 'recentf) (recentf-mode) - (ivy-read "Recentf: " (mapcar #'substring-no-properties recentf-list) + (ivy-read "Recentf: " (counsel-recentf-candidates) :action (lambda (f) (with-ivy-window (find-file f))) :require-match t :caller 'counsel-recentf)) + (ivy-set-actions 'counsel-recentf - '(("j" find-file-other-window "other window") + `(("j" find-file-other-window "other window") ("f" find-file-other-frame "other frame") - ("x" counsel-find-file-extern "open externally"))) + ("x" counsel-find-file-extern "open externally") + ("d" ,(lambda (file) (setq recentf-list (delete file recentf-list))) + "delete from recentf"))) + +(defun counsel-recentf-candidates () + "Return candidates for `counsel-recentf'. + +When `counsel-recentf-include-xdg-list' is non-nil, also include +the files in said list, sorting the combined list by file access +time." + (if (and counsel-recentf-include-xdg-list + (>= emacs-major-version 26)) + (delete-dups + (sort (nconc (mapcar #'substring-no-properties recentf-list) + (counsel--recentf-get-xdg-recent-files)) + (lambda (file1 file2) + (cond ((file-remote-p file1) + nil) + ((file-remote-p file2)) + (t + ;; Added in Emacs 26.1. + (declare-function file-attribute-access-time "files" + (attributes)) + (time-less-p (file-attribute-access-time + (file-attributes file2)) + (file-attribute-access-time + (file-attributes file1)))))))) + (mapcar #'substring-no-properties recentf-list))) + +(defalias 'counsel--xml-parse-region + (if (cond ((fboundp 'libxml-available-p) + ;; Added in Emacs 27.1. + (libxml-available-p)) + ((fboundp 'libxml-parse-xml-region) + ;; Checking for `fboundp' is not enough on Windows, where it + ;; will return non-nil even if the library is not installed. + (with-temp-buffer + (insert "") + (libxml-parse-xml-region (point-min) (point-max))))) + (lambda (&optional beg end) + (libxml-parse-xml-region (or beg (point-min)) (or end (point-max)))) + #'xml-parse-region) + "Compatibility shim for `libxml-parse-xml-region'. +For convenience, BEG and END default to `point-min' and +`point-max', respectively. + +\(fn &optional BEG END)") + +(defun counsel--recentf-get-xdg-recent-files () + "Return list of XDG recent files. + +This information is parsed from the file \"recently-used.xbel\", +which lists both files and directories, under `xdg-data-home'. +This function uses the `dom' library from Emacs 25.1 or later." + (unless (require 'dom nil t) + (user-error "This function requires Emacs 25.1 or later")) + (declare-function dom-attr "dom" (node attr)) + (declare-function dom-by-tag "dom" (dom tag)) + (let ((file-of-recent-files + (expand-file-name "recently-used.xbel" (counsel--xdg-data-home)))) + (unless (file-readable-p file-of-recent-files) + (user-error "List of XDG recent files not found: %s" + file-of-recent-files)) + (cl-mapcan (lambda (bookmark-node) + (let* ((file (dom-attr bookmark-node 'href)) + (file (string-remove-prefix "file://" file)) + (file (url-unhex-string file t)) + (file (decode-coding-string file 'utf-8 t))) + (and (file-exists-p file) + (list file)))) + (let ((dom (with-temp-buffer + (insert-file-contents file-of-recent-files) + (counsel--xml-parse-region)))) + (nreverse (dom-by-tag dom 'bookmark)))))) (defun counsel-buffer-or-recentf-candidates () "Return candidates for `counsel-buffer-or-recentf'." @@ -2235,7 +2416,7 @@ When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." (append buffers (cl-remove-if (lambda (f) (member f buffers)) - (mapcar #'substring-no-properties recentf-list))))) + (counsel-recentf-candidates))))) ;;;###autoload (defun counsel-buffer-or-recentf () @@ -2308,6 +2489,7 @@ By default `counsel-bookmark' opens a dired buffer for directories." 'counsel-bookmark `(("d" bookmark-delete "delete") ("e" bookmark-rename "edit") + ("s" bookmark-set "overwrite") ("x" ,(counsel--apply-bookmark-fn #'counsel-find-file-extern) "open externally") ("r" ,(counsel--apply-bookmark-fn #'counsel-find-file-as-root) @@ -2336,12 +2518,12 @@ current value of `default-directory'." :action #'dired)) (ivy-set-actions 'counsel-bookmarked-directory - '(("j" dired-other-window "other window") + `(("j" dired-other-window "other window") ("x" counsel-find-file-extern "open externally") ("r" counsel-find-file-as-root "open as root") - ("f" (lambda (dir) - (let ((default-directory dir)) - (call-interactively #'find-file))) + ("f" ,(lambda (dir) + (let ((default-directory dir)) + (call-interactively #'find-file))) "find-file"))) ;;** `counsel-file-register' @@ -2383,13 +2565,13 @@ can use `C-x r j i' to open that file." ;;** `counsel-locate' (defcustom counsel-locate-cmd (cond ((memq system-type '(darwin berkeley-unix)) - 'counsel-locate-cmd-noregex) + #'counsel-locate-cmd-noregex) ((and (eq system-type 'windows-nt) (executable-find "es.exe")) - 'counsel-locate-cmd-es) + #'counsel-locate-cmd-es) (t - 'counsel-locate-cmd-default)) - "The function for producing a locate command string from the input. + #'counsel-locate-cmd-default)) + "The function for producing a `locate' command string from the input. The function takes a string - the current input, and returns a string - the full shell command to run." @@ -2397,7 +2579,8 @@ string - the full shell command to run." (const :tag "Default" counsel-locate-cmd-default) (const :tag "No regex" counsel-locate-cmd-noregex) (const :tag "mdfind" counsel-locate-cmd-mdfind) - (const :tag "everything" counsel-locate-cmd-es))) + (const :tag "everything" counsel-locate-cmd-es) + (function :tag "Custom"))) (ivy-set-actions 'counsel-locate @@ -2432,33 +2615,33 @@ string - the full shell command to run." (dired-jump nil x)) (defun counsel-locate-cmd-default (input) - "Return a shell command based on INPUT." + "Return a `locate' shell command based on regexp INPUT." (counsel-require-program "locate") - (format "locate -i --regex '%s'" - (counsel--elisp-to-pcre - (ivy--regex input)))) + (format "locate -i --regex %s" + (shell-quote-argument + (counsel--elisp-to-pcre + (ivy--regex input))))) (defun counsel-locate-cmd-noregex (input) - "Return a shell command based on INPUT." + "Return a `locate' shell command based on INPUT." (counsel-require-program "locate") - (format "locate -i '%s'" input)) + (format "locate -i %s" (shell-quote-argument input))) (defun counsel-locate-cmd-mdfind (input) - "Return a shell command based on INPUT." + "Return a `mdfind' shell command based on INPUT." (counsel-require-program "mdfind") - (format "mdfind -name '%s'" input)) - -(defvar w32-ansi-code-page) + (format "mdfind -name %s" (shell-quote-argument input))) (defun counsel-locate-cmd-es (input) - "Return a shell command based on INPUT." + "Return a `es' shell command based on INPUT." + (defvar w32-ansi-code-page) (counsel-require-program "es.exe") - (let ((raw-string (format "es.exe -i -r -p %s" + (let ((raw-string (format "es.exe -i -p -r %s" (counsel--elisp-to-pcre (ivy--regex input t))))) - ;; W32 don't use Unicode by default, so we encode search command - ;; to local codepage to support searching filename contains non-ASCII - ;; characters. + ;; W32 doesn't use Unicode by default, so we encode search command + ;; to local codepage to support searching file names containing + ;; non-ASCII characters. (if (and (eq system-type 'windows-nt) (boundp 'w32-ansi-code-page)) (encode-coding-string raw-string @@ -2466,7 +2649,7 @@ string - the full shell command to run." raw-string))) (defun counsel-locate-function (input) - "Call the \"locate\" shell command with INPUT." + "Call a \"locate\" style shell command with INPUT." (or (ivy-more-chars) (progn @@ -2480,10 +2663,7 @@ string - the full shell command to run." (defun counsel-file-stale-p (fname seconds) "Return non-nil if FNAME was modified more than SECONDS ago." - (> (time-to-seconds - (time-subtract - (current-time) - (nth 5 (file-attributes fname)))) + (> (float-time (time-subtract nil (nth 5 (file-attributes fname)))) seconds)) (defun counsel--locate-updatedb () @@ -2498,7 +2678,7 @@ string - the full shell command to run." ;;;###autoload (defun counsel-locate (&optional initial-input) - "Call the \"locate\" shell command. + "Call a \"locate\" style shell command. INITIAL-INPUT can be given as the initial minibuffer input." (interactive) (counsel--locate-updatedb) @@ -2517,6 +2697,35 @@ INITIAL-INPUT can be given as the initial minibuffer input." :unwind-fn #'counsel-delete-process :exit-codes '(1 "Nothing found")) +;;** `counsel-tracker' +(defun counsel-tracker-function (input) + "Call the \"tracker\" shell command with INPUT." + (or + (ivy-more-chars) + (progn + (counsel--async-command + (format + "tracker sparql -q \"SELECT ?url WHERE { ?s a nfo:FileDataObject ; nie:url ?url . FILTER (STRSTARTS (?url, 'file://$HOME/')) . FILTER regex(?url, '%s') }\" | tail -n +2 | head -n -1" + (counsel--elisp-to-pcre (funcall ivy--regex-function input)))) + '("" "working...")))) + +(defun counsel-tracker-transformer (str) + (if (string-match "file:///" str) + (decode-coding-string (url-unhex-string (substring str 9)) 'utf-8) + str)) + +;;;###autoload +(defun counsel-tracker () + (interactive) + (ivy-read "Tracker: " 'counsel-tracker-function + :dynamic-collection t + :action (lambda (s) (find-file (counsel-tracker-transformer s))) + :caller 'counsel-tracker)) + +(ivy-configure 'counsel-tracker + :display-transformer-fn #'counsel-tracker-transformer + :unwind-fn #'counsel-delete-process) + ;;** `counsel-fzf' (defvar counsel-fzf-cmd "fzf -f \"%s\"" "Command for `counsel-fzf'.") @@ -2636,7 +2845,8 @@ FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." (defun counsel--find-return-list (args) (unless (listp args) - (user-error "`counsel-file-jump-args' is a list now, please customize accordingly.")) + (user-error + "`counsel-file-jump-args' is a list now; please customize accordingly")) (counsel--call (cons find-program args) (lambda () @@ -2654,6 +2864,18 @@ FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt argument." :type '(repeat string)) ;;** `counsel-file-jump' +(defvar counsel-file-jump-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "`") #'counsel-find-file-from-jump) + map) + "Key bindings to be used when in a file-jump minibuffer.") + +(defun counsel-find-file-from-jump () + "Switch to `counsel-find-file' from `counsel-file-jump'." + (interactive) + (ivy-quit-and-run + (counsel-find-file ivy-text (ivy-state-directory ivy-last)))) + ;;;###autoload (defun counsel-file-jump (&optional initial-input initial-directory) "Jump to a file below the current directory. @@ -2674,7 +2896,7 @@ INITIAL-DIRECTORY, if non-nil, is used as the root directory for search." :preselect (counsel--preselect-file) :require-match 'confirm-after-completion :history 'file-name-history - :keymap counsel-find-file-map + :keymap counsel-file-jump-map :caller 'counsel-file-jump))) (ivy-set-actions @@ -2711,26 +2933,6 @@ INITIAL-DIRECTORY, if non-nil, is used as the root directory for search." :caller 'counsel-dired-jump))) ;;* Grep -(defun counsel--grep-mode-occur (git-grep-dir-is-file) - "Generate a custom occur buffer for grep like commands. -If GIT-GREP-DIR-IS-FILE is t, then `ivy-state-directory' is treated as a full -path to a file rather than a directory (e.g. for `counsel-grep-occur'). - -This function expects that the candidates have already been filtered. -It applies no filtering to ivy--all-candidates." - (unless (eq major-mode 'ivy-occur-grep-mode) - (ivy-occur-grep-mode)) - (let ((directory - (if git-grep-dir-is-file - (file-name-directory (ivy-state-directory ivy-last)) - (ivy-state-directory ivy-last)))) - (setq default-directory directory) - ;; Need precise number of header lines for `wgrep' to work. - (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n" default-directory)) - (insert (format "%d candidates:\n" (length ivy--all-candidates))) - (ivy--occur-insert-lines - (mapcar #'counsel--normalize-grep-match ivy--all-candidates)))) - ;;** `counsel-ag' (defvar counsel-ag-map (let ((map (make-sparse-keymap))) @@ -2740,14 +2942,14 @@ It applies no filtering to ivy--all-candidates." (define-key map (kbd "C-x C-d") 'counsel-cd) map)) -(defcustom counsel-ag-base-command - (if (memq system-type '(ms-dos windows-nt)) - "ag --vimgrep %s" - "ag --nocolor --nogroup %s") +(defcustom counsel-ag-base-command "ag --vimgrep %s" "Format string to use in `counsel-ag-function' to construct the command. The %s will be replaced by optional extra ag arguments followed by the regex string." - :type 'string) + :type '(radio + (const "ag --vimgrep %s") + (const "ag --nocolor --nogroup %s") + (string :tag "custom"))) (defvar counsel-ag-command nil) @@ -2755,34 +2957,38 @@ regex string." (defvar counsel--regex-look-around nil) -(defconst counsel--command-args-separator "-- ") +(defconst counsel--command-args-separator " -- ") (defun counsel--split-command-args (arguments) "Split ARGUMENTS into its switches and search-term parts. Return pair of corresponding strings (SWITCHES . SEARCH-TERM)." - (let ((switches "") - (search-term arguments)) - (when (string-prefix-p "-" arguments) - (let ((index (string-match counsel--command-args-separator arguments))) - (when index - (setq search-term - (substring arguments (+ (length counsel--command-args-separator) index))) - (setq switches (substring arguments 0 index))))) - (cons switches search-term))) + (if (string-match counsel--command-args-separator arguments) + (let ((args (substring arguments (match-end 0))) + (search-term (substring arguments 0 (match-beginning 0)))) + (if (string-prefix-p "-" arguments) + (cons search-term args) + (cons args search-term))) + (cons "" arguments))) (defun counsel--format-ag-command (extra-args needle) "Construct a complete `counsel-ag-command' as a string. EXTRA-ARGS is a string of the additional arguments. NEEDLE is the search string." - (format counsel-ag-command - (if (string-match " \\(--\\) " extra-args) - (replace-match needle t t extra-args 1) - (concat extra-args " " needle)))) + (counsel--format counsel-ag-command + (if (listp counsel-ag-command) + (if (string-match " \\(--\\) " extra-args) + (counsel--format + (split-string (replace-match "%s" t t extra-args 1)) + needle) + (nconc (split-string extra-args) needle)) + (if (string-match " \\(--\\) " extra-args) + (replace-match needle t t extra-args 1) + (concat extra-args " " needle))))) (defun counsel--grep-regex (str) (counsel--elisp-to-pcre (setq ivy--old-re - (funcall ivy--regex-function str)) + (funcall (ivy-state-re-builder ivy-last) str)) counsel--regex-look-around)) (defun counsel--ag-extra-switches (regex) @@ -2801,51 +3007,65 @@ NEEDLE is the search string." (ivy-more-chars)) (let* ((default-directory (ivy-state-directory ivy-last)) (regex (counsel--grep-regex search-term)) - (switches (concat (car command-args) + (switches (concat (if (ivy--case-fold-p string) + " -i " + " -s ") (counsel--ag-extra-switches regex) - (and (ivy--case-fold-p string) " -i ")))) + (car command-args)))) (counsel--async-command (counsel--format-ag-command switches - (shell-quote-argument regex))) + (funcall (if (listp counsel-ag-command) #'identity + #'shell-quote-argument) + regex))) nil)))) ;;;###autoload (cl-defun counsel-ag (&optional initial-input initial-directory extra-ag-args ag-prompt &key caller) - "Grep for a string in the current directory using ag. + "Grep for a string in a root directory using ag. + +By default, the root directory is the first directory containing a .git subdirectory. + INITIAL-INPUT can be given as the initial minibuffer input. INITIAL-DIRECTORY, if non-nil, is used as the root directory for search. -EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'. +EXTRA-AG-ARGS, if non-nil, is appended to `counsel-ag-base-command'. AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument. -CALLER is passed to `ivy-read'." +CALLER is passed to `ivy-read'. + +With a `\\[universal-argument]' prefix argument, prompt for INITIAL-DIRECTORY. +With a `\\[universal-argument] \\[universal-argument]' prefix argument, \ +prompt additionally for EXTRA-AG-ARGS." (interactive) (setq counsel-ag-command counsel-ag-base-command) (setq counsel--regex-look-around counsel--grep-tool-look-around) (counsel-require-program counsel-ag-command) - (when current-prefix-arg - (setq initial-directory - (or initial-directory - (counsel-read-directory-name (concat - (car (split-string counsel-ag-command)) - " in directory: ")))) - (setq extra-ag-args - (or extra-ag-args - (read-from-minibuffer (format - "%s args: " - (car (split-string counsel-ag-command))))))) - (setq counsel-ag-command (counsel--format-ag-command (or extra-ag-args "") "%s")) - (let ((default-directory (or initial-directory - (counsel--git-root) - default-directory))) - (ivy-read (or ag-prompt - (concat (car (split-string counsel-ag-command)) ": ")) - #'counsel-ag-function - :initial-input initial-input - :dynamic-collection t - :keymap counsel-ag-map - :history 'counsel-git-grep-history - :action #'counsel-git-grep-action - :caller (or caller 'counsel-ag)))) + (let ((prog-name (car (if (listp counsel-ag-command) counsel-ag-command + (split-string counsel-ag-command)))) + (arg (prefix-numeric-value current-prefix-arg))) + (when (>= arg 4) + (setq initial-directory + (or initial-directory + (counsel-read-directory-name (concat + prog-name + " in directory: "))))) + (when (>= arg 16) + (setq extra-ag-args + (or extra-ag-args + (read-from-minibuffer (format "%s args: " prog-name))))) + (setq counsel-ag-command (counsel--format-ag-command (or extra-ag-args "") "%s")) + (let ((default-directory (or initial-directory + (counsel--git-root) + default-directory))) + (ivy-read (or ag-prompt + (concat prog-name ": ")) + #'counsel-ag-function + :initial-input initial-input + :dynamic-collection t + :keymap counsel-ag-map + :history 'counsel-git-grep-history + :action #'counsel-git-grep-action + :require-match t + :caller (or caller 'counsel-ag))))) (ivy-configure 'counsel-ag :occur #'counsel-ag-occur @@ -2854,47 +3074,74 @@ CALLER is passed to `ivy-read'." :grep-p t :exit-codes '(1 "No matches found")) -(defun counsel-read-directory-name (prompt) +(defun counsel-read-directory-name (prompt &optional default) "Read a directory name from user, a (partial) replacement of `read-directory-name'." (let ((counsel--find-file-predicate #'file-directory-p)) (ivy-read prompt #'read-file-name-internal :matcher #'counsel--find-file-matcher + :def default :history 'file-name-history :keymap counsel-find-file-map :caller 'counsel-read-directory-name))) (ivy-configure 'counsel-read-directory-name - :display-transformer-fn #'ivy-read-file-transformer) + :parent 'read-file-name-internal) (defun counsel-cd () "Change the directory for the currently running Ivy grep-like command. Works for `counsel-git-grep', `counsel-ag', etc." (interactive) - (let ((input ivy-text) - (new-dir (counsel-read-directory-name "cd: "))) + (counsel-delete-process) + (let* ((input ivy-text) + (enable-recursive-minibuffers t) + (def-dir (buffer-file-name (ivy-state-buffer ivy-last))) + (def-dir (and def-dir (file-name-directory def-dir))) + (new-dir (counsel-read-directory-name "cd: " def-dir))) (ivy-quit-and-run (funcall (ivy-state-caller ivy-last) input new-dir)))) +(defun counsel--grep-smart-case-flag () + (if (ivy--case-fold-p ivy-text) + "-i" + (if (and (stringp counsel-ag-base-command) + (string-match-p "\\`pt" counsel-ag-base-command)) + "-S" + "-s"))) + (defun counsel-grep-like-occur (cmd-template) (unless (eq major-mode 'ivy-occur-grep-mode) (ivy-occur-grep-mode) (setq default-directory (ivy-state-directory ivy-last))) - (setq ivy-text - (and (string-match "\"\\(.*\\)\"" (buffer-name)) - (match-string 1 (buffer-name)))) + (ivy-set-text + (if (string-match "\"\\(.*\\)\"" (buffer-name)) + (match-string 1 (buffer-name)) + (ivy-state-text ivy-occur-last))) (let* ((cmd (if (functionp cmd-template) (funcall cmd-template ivy-text) (let* ((command-args (counsel--split-command-args ivy-text)) (regex (counsel--grep-regex (cdr command-args))) - (switches (concat (car command-args) - (counsel--ag-extra-switches regex)))) - (format cmd-template - (concat - switches - (shell-quote-argument regex)))))) - (cands (counsel--split-string (shell-command-to-string cmd)))) + (extra-switches (counsel--ag-extra-switches regex)) + (all-args (append + (when (car command-args) + (split-string (car command-args))) + (when extra-switches + (split-string extra-switches)) + (list + (counsel--grep-smart-case-flag) + regex)))) + (if (stringp cmd-template) + (counsel--format + cmd-template + (mapconcat #'shell-quote-argument all-args " ")) + (cl-mapcan + (lambda (x) (if (string= x "%s") (copy-sequence all-args) (list x))) + cmd-template))))) + (cands (counsel--split-string + (if (stringp cmd) + (shell-command-to-string cmd) + (counsel--call cmd))))) (swiper--occur-insert-lines (mapcar #'counsel--normalize-grep-match cands)))) (defun counsel-ag-occur (&optional _cands) @@ -2916,7 +3163,7 @@ This uses `counsel-ag' with `counsel-pt-base-command' instead of (interactive) (let ((counsel-ag-base-command counsel-pt-base-command) (counsel--grep-tool-look-around nil)) - (counsel-ag initial-input :caller 'counsel-pt))) + (counsel-ag initial-input nil nil nil :caller 'counsel-pt))) (ivy-configure 'counsel-pt :unwind-fn #'counsel--grep-unwind @@ -2941,35 +3188,36 @@ This uses `counsel-ag' with `counsel-ack-base-command' replacing (interactive) (let ((counsel-ag-base-command counsel-ack-base-command) (counsel--grep-tool-look-around t)) - (counsel-ag initial-input :caller 'counsel-ack))) + (counsel-ag + initial-input nil nil nil + :caller 'counsel-ack))) ;;** `counsel-rg' (defcustom counsel-rg-base-command - (if (memq system-type '(ms-dos windows-nt)) - "rg --with-filename --no-heading --line-number --path-separator / --color never %s ." - "rg --with-filename --no-heading --line-number --color never %s") + (split-string + (if (memq system-type '(ms-dos windows-nt)) + "rg -M 240 --with-filename --no-heading --line-number --color never %s --path-separator / ." + "rg -M 240 --with-filename --no-heading --line-number --color never %s")) "Alternative to `counsel-ag-base-command' using ripgrep. Note: don't use single quotes for the regex." - :type 'string) + :type '(choice + (repeat :tag "List to be used in `process-file'." string) + (string :tag "String to be used in `shell-command-to-string'."))) (defun counsel--rg-targets () "Return a list of files to operate on, based on `dired-mode' marks." - (if (eq major-mode 'dired-mode) - (let ((files - (dired-get-marked-files 'no-dir nil nil t))) - (if (and (null (cdr files)) - (not (when (string-match-p "\\*ivy-occur" (buffer-name)) - (dired-toggle-marks) - (setq files (dired-get-marked-files 'no-dir)) - (dired-toggle-marks) - t))) - "" - (concat - " " - (mapconcat #'shell-quote-argument (delq t files) " ")))) - "")) + (when (eq major-mode 'dired-mode) + (let ((files + (dired-get-marked-files 'no-dir nil nil t))) + (when (or (cdr files) + (when (string-match-p "\\*ivy-occur" (buffer-name)) + (dired-toggle-marks) + (setq files (dired-get-marked-files 'no-dir)) + (dired-toggle-marks) + t)) + (delq t files))))) ;;;###autoload (defun counsel-rg (&optional initial-input initial-directory extra-rg-args rg-prompt) @@ -2980,14 +3228,18 @@ EXTRA-RG-ARGS string, if non-nil, is appended to `counsel-rg-base-command'. RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument. Example input with inclusion and exclusion file patterns: - -g*.py -g!*test* -- ..." + require i -- -g*.el" (interactive) (let ((counsel-ag-base-command - (concat counsel-rg-base-command (counsel--rg-targets))) + (if (listp counsel-rg-base-command) + (append counsel-rg-base-command (counsel--rg-targets)) + (concat counsel-rg-base-command " " + (mapconcat #'shell-quote-argument (counsel--rg-targets) " ")))) (counsel--grep-tool-look-around - (let ((rg (car (split-string counsel-rg-base-command))) + (let ((rg (car (if (listp counsel-rg-base-command) counsel-rg-base-command + (split-string counsel-rg-base-command)))) (switch "--pcre2")) - (and (eq 0 (call-process rg nil nil nil switch "--version")) + (and (eq 0 (call-process rg nil nil nil switch "--pcre2-version")) switch)))) (counsel-ag initial-input initial-directory extra-rg-args rg-prompt :caller 'counsel-rg))) @@ -3020,11 +3272,18 @@ substituted by the search regexp and file, respectively. Neither "Grep in the current directory for STRING." (or (ivy-more-chars) - (let ((regex (counsel--elisp-to-pcre - (setq ivy--old-re - (ivy--regex string))))) + (let* ((regex (counsel--grep-regex string)) + (cmd (counsel--format + counsel-grep-command + (funcall (if (listp counsel-grep-command) #'identity + #'shell-quote-argument) + regex)))) (counsel--async-command - (format counsel-grep-command (shell-quote-argument regex))) + (if (ivy--case-fold-p regex) + (if (listp cmd) (nconc (list (car cmd) "-i") (cdr cmd)) + (string-match " " cmd) + (replace-match " -i " nil nil cmd)) + cmd)) nil))) (defvar counsel--grep-last-pos nil @@ -3090,10 +3349,11 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (user-error "Current buffer is not visiting a file")) (counsel-require-program counsel-grep-base-command) (setq counsel-grep-command - (format counsel-grep-base-command - "%s" (shell-quote-argument - (file-name-nondirectory - buffer-file-name)))) + (counsel--format counsel-grep-base-command "%s" + (funcall (if (listp counsel-grep-base-command) #'identity + #'shell-quote-argument) + (file-name-nondirectory + buffer-file-name)))) (let ((default-directory (file-name-directory buffer-file-name)) (init-point (point)) res) @@ -3329,7 +3589,9 @@ otherwise continue prompting for tags." (delete-dups (append (counsel--org-get-tags) add-tags))) (counsel-org--set-tags)))))) - (counsel-org--set-tags))) + (counsel-org--set-tags) + (unless (member x counsel-org-tags) + (message "Tag %S has been removed." x)))) ((eq this-command 'ivy-call) (with-selected-window (active-minibuffer-window) (delete-minibuffer-contents))))) @@ -3418,6 +3680,14 @@ otherwise continue prompting for tags." "If non-nil, display priorities in matched `org-mode' headlines." :type 'boolean) +(defcustom counsel-org-headline-display-comment nil + "If non-nil, display COMMENT string in matched `org-mode' headlines." + :type 'boolean) + +(defcustom counsel-org-headline-display-statistics nil + "If non-nil, display statistics cookie in matched `org-mode' headlines." + :type 'boolean) + (declare-function org-get-heading "org") (declare-function org-goto-marker-or-bmk "org") (declare-function outline-next-heading "outline") @@ -3537,11 +3807,13 @@ version. Argument values are based on the `counsel-org-headline-display-*' user options." (nbutlast (mapcar #'not (list counsel-org-headline-display-tags counsel-org-headline-display-todo - counsel-org-headline-display-priority)) + counsel-org-headline-display-priority + counsel-org-headline-display-comment)) + ;; Added in Emacs 26.1. (if (if (fboundp 'func-arity) (< (cdr (func-arity #'org-get-heading)) 3) (version< org-version "9.1.1")) - 1 0))) + 2 0))) ;;** `counsel-org-file' (declare-function org-attach-dir "org-attach") @@ -3558,7 +3830,7 @@ include attachments of other Org buffers." (let (dirs) (save-excursion (goto-char (point-min)) - (while (re-search-forward "^:\\(ATTACH_DIR\\|ID\\):[\t ]+\\(.*\\)$" nil t) + (while (re-search-forward ":\\(?:ATTACH_DIR\\|ID\\):[\t ]+.*$" nil t) (let ((dir (org-attach-dir))) (when dir (push dir dirs))))) @@ -3624,18 +3896,28 @@ include attachments of other Org buffers." (interactive) (require 'org-capture) (ivy-read "Capture template: " - (delq nil - (mapcar - (lambda (x) - (when (> (length x) 2) - (format "%-5s %s" (nth 0 x) (nth 1 x)))) - ;; We build the list of capture templates as in - ;; `org-capture-select-template': - (or (org-contextualize-keys - (org-capture-upgrade-templates org-capture-templates) - org-capture-templates-contexts) - '(("t" "Task" entry (file+headline "" "Tasks") - "* TODO %?\n %u\n %a"))))) + ;; We build the list of capture templates as in `org-capture-select-template': + (let (prefixes) + (cl-mapcan + (lambda (x) + (let ((x-keys (car x))) + ;; Remove prefixed keys until we get one that matches the current item. + (while (and prefixes + (let ((p1-keys (caar prefixes))) + (or + (<= (length x-keys) (length p1-keys)) + (not (string-prefix-p p1-keys x-keys))))) + (pop prefixes)) + (if (> (length x) 2) + (let ((desc (mapconcat #'cadr (reverse (cons x prefixes)) " | "))) + (list (format "%-5s %s" x-keys desc))) + (push x prefixes) + nil))) + (or (org-contextualize-keys + (org-capture-upgrade-templates org-capture-templates) + org-capture-templates-contexts) + '(("t" "Task" entry (file+headline "" "Tasks") + "* TODO %?\n %u\n %a"))))) :require-match t :action (lambda (x) (org-capture nil (car (split-string x)))) @@ -3759,10 +4041,31 @@ This variable has no effect unless :history 'counsel-org-agenda-headlines-history :caller 'counsel-org-agenda-headlines))) -;;* Misc. Emacs +;;** `counsel-org-link' +(declare-function org-insert-link "ol") +(declare-function org-id-get-create "org-id") + +(defun counsel-org-link-action (x) + "Insert a link to X." + (let ((id (save-excursion + (goto-char (cdr x)) + (org-id-get-create)))) + (org-insert-link nil (concat "id:" id) (car x)))) + +;;;###autoload +(defun counsel-org-link () + "Insert a link to an headline with completion." + (interactive) + (ivy-read "Link: " (counsel-outline-candidates + '(:outline-title counsel-outline-title-org )) + :action #'counsel-org-link-action + :history 'counsel-org-link-history + :caller 'counsel-org-link)) + +;; Misc. Emacs ;;** `counsel-mark-ring' (defface counsel--mark-ring-highlight - '((t (:inherit highlight))) + '((t :inherit highlight)) "Face for current `counsel-mark-ring' line." :group 'ivy-faces) @@ -3803,15 +4106,6 @@ This variable has no effect unless Obeys `widen-automatically', which see." (interactive) (let* ((counsel--mark-ring-calling-point (point)) - (width (length (number-to-string (line-number-at-pos (point-max))))) - (fmt (format "%%%dd %%s" width)) - (make-candidate - (lambda (mark) - (goto-char (marker-position mark)) - (let ((linum (line-number-at-pos)) - (line (buffer-substring - (line-beginning-position) (line-end-position)))) - (propertize (format fmt linum line) 'point (point))))) (marks (copy-sequence mark-ring)) (marks (delete-dups marks)) (marks @@ -3819,33 +4113,125 @@ Obeys `widen-automatically', which see." (if (equal (mark-marker) (make-marker)) marks (cons (copy-marker (mark-marker)) marks))) - (cands - ;; Widen, both to save `line-number-at-pos' the trouble - ;; and for `buffer-substring' to work. - (save-excursion - (save-restriction - (widen) - (mapcar make-candidate marks))))) - (if cands - (ivy-read "Mark: " cands - :require-match t - :action (lambda (cand) - (let ((pos (get-text-property 0 'point cand))) - (when pos - (unless (<= (point-min) pos (point-max)) - (if widen-automatically - (widen) - (error "\ -Position of selected mark outside accessible part of buffer"))) - (goto-char pos)))) - :caller 'counsel-mark-ring) + (candidates (counsel-mark--get-candidates marks))) + (if candidates + (counsel-mark--ivy-read "Mark: " candidates 'counsel-mark-ring) (message "Mark ring is empty")))) +(defun counsel-mark--get-candidates (marks) + "Convert a list of MARKS into mark candidates. +candidates are simply strings formatted to have the line number of the +associated mark prepended to them and having an extra text property of +point to indicarte where the candidate mark is." + (when marks + (save-excursion + (save-restriction + ;; Widen, both to save `line-number-at-pos' the trouble + ;; and for `buffer-substring' to work. + (widen) + (let* ((width (length (number-to-string (line-number-at-pos (point-max))))) + (fmt (format "%%%dd %%s" width))) + (mapcar (lambda (mark) + (goto-char (marker-position mark)) + (let ((linum (line-number-at-pos)) + (line (buffer-substring + (line-beginning-position) (line-end-position)))) + (propertize (format fmt linum line) 'point (point)))) + marks)))))) + +(defun counsel-mark--ivy-read (prompt candidates caller) + "call `ivy-read' with sane defaults for traversing marks. +CANDIDATES should be an alist with the `car' of the list being +the string displayed by ivy and the `cdr' being the point that +mark should take you to. + +NOTE This has been abstracted out into it's own method so it can +be used by both `counsel-mark-ring' and `counsel-evil-marks'" + (ivy-read prompt candidates + :require-match t + :update-fn #'counsel--mark-ring-update-fn + :action (lambda (cand) + (let ((pos (get-text-property 0 'point cand))) + (when pos + (unless (<= (point-min) pos (point-max)) + (if widen-automatically + (widen) + (error "\ +Position of selected mark outside accessible part of buffer"))) + (goto-char pos)))) + :unwind #'counsel--mark-ring-unwind + :caller caller)) + (ivy-configure 'counsel-mark-ring :update-fn #'counsel--mark-ring-update-fn :unwind-fn #'counsel--mark-ring-unwind :sort-fn #'ivy-string<) +;;** `counsel-evil-marks' +(defvar counsel-evil-marks-exclude-registers nil + "List of evil registers to not display in `counsel-evil-marks' by default. +Each member of the list should be a character (stored as an integer).") + +(defvar evil-markers-alist) +(declare-function evil-global-marker-p "ext:evil-common") + +(defun counsel-mark--get-evil-candidates (all-markers-p) + "Convert all evil MARKS in the current buffer to mark candidates. +Works like `counsel-mark--get-candidates' but also prepends the +register tied to a mark in the message string." + ;; evil doesn't provide a standalone method to access the list of + ;; marks in the current buffer, as it does with registers. + (let* ((all-markers + (append + (cl-remove-if (lambda (m) + (or (evil-global-marker-p (car m)) + (not (markerp (cdr m))))) + evil-markers-alist) + (cl-remove-if (lambda (m) + (or (not (evil-global-marker-p (car m))) + (not (markerp (cdr m))))) + (default-value 'evil-markers-alist)))) + + (all-markers + ;; with prefix, ignore register exclusion list. + (if all-markers-p + all-markers + (cl-remove-if-not + (lambda (x) (not (member (car x) counsel-evil-marks-exclude-registers))) + all-markers))) + ;; separate the markers from the evil registers + ;; for call to `counsel-mark--get-candidates' + (registers (mapcar #'car all-markers)) + (markers (mapcar #'cdr all-markers)) + (candidates (counsel-mark--get-candidates markers))) + (when candidates + (let (register candidate result) + (while (and (setq register (pop registers)) + (setq candidate (pop candidates))) + (let ((point (get-text-property 0 'point candidate)) + (evil-candidate + (format "[%s]: %s" + (propertize (char-to-string register) + 'face 'counsel-evil-register-face) + candidate))) + (push (propertize evil-candidate 'point point) result))) + result)))) + +;;;###autoload +(defun counsel-evil-marks (&optional arg) + "Ivy replacement for `evil-show-marks'. +By default, this function respects `counsel-evil-marks-exclude-registers'. +When ARG is non-nil, display all active evil registers." + (interactive "P") + (if (and (boundp 'evil-markers-alist) + (fboundp 'evil-global-marker-p)) + (let* ((counsel--mark-ring-calling-point (point)) + (candidates (counsel-mark--get-evil-candidates arg))) + (if candidates + (counsel-mark--ivy-read "Evil mark: " candidates 'counsel-evil-marks) + (message "No evil marks are active"))) + (user-error "Required feature `evil' not installed or loaded"))) + ;;** `counsel-package' (defvar package--initialized) (defvar package-alist) @@ -3903,7 +4289,8 @@ Additional actions:\\ :history 'counsel-package-history :caller 'counsel-package)) -(cl-pushnew '(counsel-package . "^+") ivy-initial-inputs-alist :key #'car) +(ivy-configure 'counsel-package + :initial-input "^+") (defun counsel-package-action (package) "Delete or install PACKAGE." @@ -4079,13 +4466,18 @@ Signal a `buffer-read-only' error if called from a read-only buffer position." (with-ivy-window (barf-if-buffer-read-only) - (setq last-command 'yank) (setq yank-window-start (window-start)) + (unless (eq last-command 'yank) + ;; Avoid unexpected deletions with `yank-handler' properties. + (setq yank-undo-function nil)) (condition-case nil - ;; Avoid unexpected additions to `kill-ring' - (let (interprogram-paste-function) + (let (;; Deceive `yank-pop'. + (last-command 'yank) + ;; Avoid unexpected additions to `kill-ring'. + interprogram-paste-function) (yank-pop (counsel--yank-pop-position s))) (error + ;; Support strings not present in the kill ring. (insert s))) (when (funcall (if counsel-yank-pop-after-point #'> #'<) (point) (mark t)) @@ -4132,6 +4524,7 @@ preselected. Otherwise, the prefix argument defaults to 0, which results in the most recent kill being preselected." :type 'boolean) +;; Moved to subr.el in Emacs 27.1. (autoload 'xor "array") ;;;###autoload @@ -4175,14 +4568,14 @@ Note: Duplicate elements of `kill-ring' are always deleted." ;;** `counsel-register' (defvar counsel-register-actions - '(("\\`buffer position" . jump-to-register) + '(("\\`buffer" . jump-to-register) ("\\`text" . insert-register) ("\\`rectangle" . insert-register) - ("\\`window configuration" . jump-to-register) - ("\\`frame configuration" . jump-to-register) + ("\\`window" . jump-to-register) + ("\\`frame" . jump-to-register) ("\\`[-+]?[0-9]+\\(?:\\.[0-9]\\)?\\'" . insert-register) - ("\\`the file" . jump-to-register) - ("\\`keyboard macro" . jump-to-register) + ("\\`\\(?:the \\)?file " . jump-to-register) + ("\\`keyboard" . jump-to-register) ("\\`file-query" . jump-to-register)) "Alist of (REGEXP . FUNCTION) pairs for `counsel-register'. Selecting a register whose description matches REGEXP specifies @@ -4228,6 +4621,11 @@ matching the register's value description against a regexp in :sort-fn #'ivy-string<) ;;** `counsel-evil-registers' +(defface counsel-evil-register-face + '((t :inherit counsel-outline-1)) + "Face for highlighting `evil' registers in ivy." + :group 'ivy-faces) + ;;;###autoload (defun counsel-evil-registers () "Ivy replacement for `evil-show-registers'." @@ -4235,11 +4633,15 @@ matching the register's value description against a regexp in (if (fboundp 'evil-register-list) (ivy-read "evil-registers: " (cl-loop for (key . val) in (evil-register-list) - collect (format "[%c]: %s" key (if (stringp val) val ""))) + collect (format "[%s]: %s" + (propertize (char-to-string key) + 'face 'counsel-evil-register-face) + (if (stringp val) val ""))) :require-match t :action #'counsel-evil-registers-action :caller 'counsel-evil-registers) - (user-error "Required feature `evil' not installed."))) + (user-error "Required feature `evil' not installed"))) + (ivy-configure 'counsel-evil-registers :height 5 :format-fn #'counsel--yank-pop-format-function) @@ -4259,15 +4661,16 @@ S will be of the form \"[register]: content\"." (declare-function imenu--make-index-alist "imenu") (defun counsel--imenu-candidates () - (unless (featurep 'imenu) - (require 'imenu nil t)) + (require 'imenu) (let* ((imenu-auto-rescan t) (imenu-auto-rescan-maxout (if current-prefix-arg (buffer-size) imenu-auto-rescan-maxout)) (items (imenu--make-index-alist t)) (items (delete (assoc "*Rescan*" items) items)) - (items (counsel-imenu-categorize-functions items))) + (items (if (eq major-mode 'emacs-lisp-mode) + (counsel-imenu-categorize-functions items) + items))) (counsel-imenu-get-candidates-from items))) (defun counsel-imenu-get-candidates-from (alist &optional prefix) @@ -4310,6 +4713,9 @@ PREFIX is used to create the key." (with-ivy-window (imenu (cdr x)))) +(defvar counsel-imenu-history nil + "History for `counsel-imenu'.") + ;;;###autoload (defun counsel-imenu () "Jump to a buffer position indexed by imenu." @@ -4319,6 +4725,7 @@ PREFIX is used to create the key." :require-match t :action #'counsel-imenu-action :keymap counsel-imenu-map + :history 'counsel-imenu-history :caller 'counsel-imenu)) ;;** `counsel-list-processes' @@ -4391,36 +4798,92 @@ An extra action allows to switch to the process buffer." (let ((enable-recursive-minibuffers t)) (ivy-read "History: " (ivy-history-contents minibuffer-history-variable) :keymap ivy-reverse-i-search-map - :action #'insert + :action (lambda (x) + (insert (substring-no-properties (car x)))) :caller 'counsel-minibuffer-history))) ;;** `counsel-esh-history' -(defun counsel--browse-history (ring) +(defvar comint-input-ring-index) +(defvar eshell-history-index) +(defvar slime-repl-input-history-position) + +(defvar counsel-esh--index-last nil + "Index corresponding to last selection with `counsel-esh-history'.") + +(defvar counsel-shell-history--index-last nil + "Index corresponding to last selection with `counsel-shell-history'.") + +(defun counsel--browse-history-action (pair) + (let ((snd (cdr pair))) + (cl-case (ivy-state-caller ivy-last) + (counsel-esh-history + (setq eshell-history-index snd + counsel-esh--index-last snd)) + (counsel-shell-history + (setq comint-input-ring-index snd + counsel-shell-history--index-last snd)) + ;; Leave this as a no-op. If someone decides to patch + ;; `slime-repl-previous-input' or one of its utility functions, + ;; or to add history-replay to Slime, then this section can be + ;; updated to add the relevant support for those commands. + (counsel-slime-repl-history + nil)) + (ivy-completion-in-region-action (car pair)))) + +(cl-defun counsel--browse-history (ring &key caller) "Use Ivy to navigate through RING." - (setq ivy-completion-beg (point)) - (setq ivy-completion-end (point)) - (ivy-read "History: " (ivy-history-contents ring) - :keymap ivy-reverse-i-search-map - :action #'ivy-completion-in-region-action - :caller 'counsel-shell-history)) + (let* ((proc (get-buffer-process (current-buffer))) + (end (point)) + (beg (if proc + (min (process-mark proc) end) + end)) + (input (when (< beg end) + (concat "^" (buffer-substring beg end))))) + (setq ivy-completion-beg beg) + (setq ivy-completion-end end) + (ivy-read "History: " (ivy-history-contents ring) + :keymap ivy-reverse-i-search-map + :initial-input input + :action #'counsel--browse-history-action + :caller caller))) (defvar eshell-history-ring) +(defvar eshell-matching-input-from-input-string) ;;;###autoload (defun counsel-esh-history () "Browse Eshell history." (interactive) (require 'em-hist) - (counsel--browse-history eshell-history-ring)) + (counsel--browse-history eshell-history-ring + :caller #'counsel-esh-history)) + +(defadvice eshell-previous-matching-input (before + counsel-set-eshell-history-index + activate) + "Reassign `eshell-history-index'." + (when (and (memq last-command '(ivy-alt-done ivy-done)) + (equal (ivy-state-caller ivy-last) 'counsel-esh-history)) + (setq eshell-history-index counsel-esh--index-last))) (defvar comint-input-ring) +(defvar comint-matching-input-from-input-string) ;;;###autoload (defun counsel-shell-history () "Browse shell history." (interactive) (require 'comint) - (counsel--browse-history comint-input-ring)) + (counsel--browse-history comint-input-ring + :caller #'counsel-shell-history)) + +(defadvice comint-previous-matching-input (before + counsel-set-comint-history-index + activate) + "Reassign `comint-input-ring-index'." + (when (and (memq last-command '(ivy-alt-done ivy-done)) + (equal (ivy-state-caller ivy-last) 'counsel-shell-history)) + (setq comint-input-ring-index counsel-shell-history--index-last))) (defvar slime-repl-input-history) @@ -4429,7 +4892,13 @@ An extra action allows to switch to the process buffer." "Browse Slime REPL history." (interactive) (require 'slime-repl) - (counsel--browse-history slime-repl-input-history)) + (counsel--browse-history slime-repl-input-history + :caller #'counsel-slime-repl-history)) + +;; TODO: add advice for slime-repl-input-previous/next to properly +;; reassign the ring index and match string. This requires a case for +;; `counsel-slime-repl-history' within +;; `counsel--browse-history-action'. ;;** `counsel-hydra-heads' (defvar hydra-curr-body-fn) @@ -4534,6 +5003,8 @@ TREEP is used to expand internal nodes." (counsel-imenu))) ;;** `counsel-outline' +(declare-function org-trim "org-macs") + (defcustom counsel-outline-face-style nil "Determines how to style outline headings during completion. @@ -4593,7 +5064,12 @@ Intended as a value for the `:outline-title' setting in "Return title of current outline heading. Like `counsel-outline-title' (which see), but for `org-mode' buffers." - (apply #'org-get-heading (counsel--org-get-heading-args))) + (let ((statistics-re "\\[[0-9]*\\(?:%\\|/[0-9]*\\)]") + (heading (apply #'org-get-heading (counsel--org-get-heading-args)))) + (cond (counsel-org-headline-display-statistics + heading) + (heading + (org-trim (replace-regexp-in-string statistics-re " " heading)))))) (defun counsel-outline-title-markdown () "Return title of current outline heading. @@ -5048,11 +5524,257 @@ selected color." You can insert or kill the name of the selected font." (interactive) - (ivy-read "Font: " (delete-dups (font-family-list)) + (let ((current-font + (symbol-name (font-get (face-attribute 'default :font) :family)))) + (ivy-read "Font: " (delete-dups (font-family-list)) + :preselect current-font + :require-match t + :history 'counsel-fonts-history + :action #'insert + :caller 'counsel-fonts))) + +(ivy-configure 'counsel-fonts + :display-transformer-fn #'counsel--font-with-sample) + +(defun counsel--font-with-sample (font-name) + "Format function for `counsel-fonts'." + (format "%-75s%s" font-name + (propertize "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + 'face (list :family font-name)))) + +;;** `counsel-kmacro' +(defvar counsel-kmacro-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-k") #'counsel-kmacro-kill) + map)) + +(defun counsel-kmacro-kill () + "Kill the line, or delete the keyboard macro." + (interactive) + (if (not (eolp)) + (ivy-kill-line) + (counsel-kmacro-action-delete-kmacro + (assoc + (ivy-state-current ivy-last) + (ivy-state-collection ivy-last))) + (ivy--kill-current-candidate))) + +;;;###autoload +(defun counsel-kmacro () + "Interactively choose and run a keyboard macro. + +With prefix argument, run macro that many times. + +Macros are run using the current value of `kmacro-counter-value' +and their respective counter format. Displayed next to each macro is +the counter's format and initial value. + +One can use actions to copy the counter format or initial counter +value of a macro, using them for a new macro." + (interactive) + (if (or last-kbd-macro kmacro-ring) + (ivy-read + (concat "Execute macro (counter at " + (number-to-string (or kmacro-initial-counter-value kmacro-counter)) + "): ") + (counsel--kmacro-candidates) + :keymap counsel-kmacro-map + :require-match t + :action #'counsel-kmacro-action-run + :caller 'counsel-kmacro) + (user-error "No keyboard macros defined"))) + +(ivy-configure 'counsel-kmacro + :format-fn #'counsel--kmacro-format-function) + +(defcustom counsel-kmacro-separator "\n------------------------\n" + "Separator displayed between keyboard macros in `counsel-kmacro'." + :type 'string) + +(defun counsel--kmacro-format-function (formatted-kmacro) + "Transform FORMATTED-KMACRO into a string for `counsel-kmacro'." + (ivy--format-function-generic + (lambda (str) (ivy--add-face str 'ivy-current-match)) + (lambda (str) str) + formatted-kmacro + (propertize counsel-kmacro-separator 'face 'ivy-separator))) + +(defun counsel--kmacro-candidates () + "Create the list of keyboard macros used by `counsel-kmacro'. +This is a combination of `kmacro-ring' and, together in a list, `last-kbd-macro', +`kmacro-counter-format-start', and `kmacro-counter-value-start'." + (mapcar + (lambda (kmacro) + (cons + (concat "(" (nth 2 kmacro) "," (number-to-string (nth 1 kmacro)) "): " + (condition-case nil + (format-kbd-macro (if (listp kmacro) (car kmacro) kmacro) 1) + ;; Recover from error from `edmacro-fix-menu-commands'. + (error "Warning: Cannot display macros containing mouse clicks"))) + kmacro)) + (cons + (if (listp last-kbd-macro) + last-kbd-macro + (list + last-kbd-macro + kmacro-counter-value-start + kmacro-counter-format-start)) + kmacro-ring))) + +(defun counsel-kmacro-action-run (x) + "Run keyboard macro." + (let* ((actual-kmacro (cdr x)) + (kmacro-keys (nth 0 actual-kmacro)) + (kmacro-counter-format-start (nth 2 actual-kmacro))) + ;; With prefix argument, call the macro that many times. + (kmacro-call-macro (or current-prefix-arg 1) t nil kmacro-keys))) + +(defun counsel-kmacro-action-delete-kmacro (x) + "Delete a keyboard macro from within `counsel-kmacro'. + +Either delete a macro from `kmacro-ring', or set `last-kbd-macro' +to the popped head of the ring." + (let ((actual-macro (cdr x))) + (if (eq (nth 0 actual-macro) last-kbd-macro) + (setq last-kbd-macro + (if (eq kmacro-ring nil) + nil + (let ((prev-macro (pop kmacro-ring))) + (if (listp prev-macro) + (nth 0 prev-macro) + prev-macro)))) + (setq kmacro-ring (delq actual-macro kmacro-ring))))) + +(defun counsel-kmacro-action-copy-initial-counter-value (x) + "Pass an existing keyboard macro's original value to `kmacro-set-counter'. +This value will be used by the next executed macro, or as an +initial value by the next macro defined. + +Note that calling an existing macro that itself uses a counter +effectively resets the initial counter value for the next defined macro +to 0." + ;; NOTE: + ;; Calling `kmacro-start-macro' without an argument sets `kmacro-counter' + ;; to 0 if `kmacro-initial-counter'is nil, and sets `kmacro-initial-counter' + ;; to nil regardless. + ;; Using `kmacro-insert-counter' sets `kmacro-initial-counter' to nil. + (let* ((actual-kmacro (cdr x)) + (number (nth 1 actual-kmacro))) + (kmacro-set-counter number))) + +(defun counsel-kmacro-action-copy-counter-format-for-new-macro (x) + "Set `kmacro-default-counter-format' to an existing keyboard macro's counter format. +This will apply to the next macro a user defines." + (let* ((actual-kmacro (cdr x)) + (format (nth 2 actual-kmacro))) + (kmacro-set-format format))) + +(defun counsel-kmacro-action-cycle-ring-to-macro (x) + "Cycle `kmacro-ring' until `last-kbd-macro' is the selected macro. +This is convenient when using \\[kmacro-end-or-call-macro] to call macros. +Note that cycling the ring changes the starting value of the current macro +to changes the current macro counter." + (let ((actual-kmacro (cdr x))) + (unless (equal last-kbd-macro + (if (listp last-kbd-macro) + last-kbd-macro + (car actual-kmacro))) + (while (not (equal actual-kmacro + (car kmacro-ring))) + (kmacro-cycle-ring-previous)) + ;; Once selected macro is at the head of the ring, + ;; cycle one last time. + (kmacro-cycle-ring-previous)))) + +(defun counsel-kmacro-action-set-saved-starting-counter (x) + "Set the starting counter value of the chosen macro. + +By default, sets to current value of the counter. It has no +effect when selecting the current macro. + +Normally, when cycling keyboard macro ring with \\[kmacro-cycle-ring-previous] +or \\[kmacro-cycle-ring-next], the current value of the macro counter is +included with the current macro definition. Then, when cycling +back, that counter value is restored. This function is meant to +achieve something similar when cycling macros in the context of +using `counsel-kmacro', which does not use different counter +values when running different macros." + (let ((actual-kmacro (cdr x)) + (default-kmacro-counter-string (number-to-string kmacro-counter))) + (setq kmacro-ring (mapcar (lambda (this-macro-in-ring) + (if (equal this-macro-in-ring actual-kmacro) + (list (car this-macro-in-ring) + (read-from-minibuffer (concat "Set initial counter for macro (default: " + default-kmacro-counter-string + "): ") + nil nil t nil + default-kmacro-counter-string) + (cl-caddr this-macro-in-ring)) + this-macro-in-ring)) + kmacro-ring)))) + +(defun counsel-kmacro-action-execute-after-prompt (x) + "Execute an existing keyboard macro, prompting for a starting counter value, a +counter format, and the number of times to execute the macro. + +If called with a prefix, will suggest that value for both the +counter value and iteration amount." + (let* ((default-string (if current-prefix-arg + (number-to-string current-prefix-arg) + nil)) + (actual-kmacro (cdr x)) + (kmacro-keys (nth 0 actual-kmacro)) + (kmacro-starting-counter (number-to-string (nth 1 actual-kmacro))) + (kmacro-starting-format (nth 2 actual-kmacro)) + (number-of-iterations + (read-from-minibuffer + (concat "Enter number of iterations for macro (default: " + (or default-string (number-to-string 2)) + "): ") + nil nil t nil + (or default-string (number-to-string 2)))) + (kmacro-initial-counter-value + (read-from-minibuffer + (concat "Enter a starting counter for macro (default: " + (or default-string kmacro-starting-counter) + "): ") + nil nil t nil + (or default-string kmacro-starting-counter))) + (kmacro-counter-format-start + (symbol-name (read-from-minibuffer + (concat "Enter format for macro counter (default: " + kmacro-starting-format + "): ") + nil nil t nil + kmacro-starting-format)))) + (kmacro-call-macro number-of-iterations t nil kmacro-keys))) + +(ivy-set-actions + 'counsel-kmacro + '(("c" counsel-kmacro-action-cycle-ring-to-macro "cycle to") + ("d" counsel-kmacro-action-delete-kmacro "delete") + ("e" counsel-kmacro-action-execute-after-prompt "execute after prompt") + ("f" counsel-kmacro-action-copy-counter-format-for-new-macro "copy counter format for new macro") + ("s" counsel-kmacro-action-set-saved-starting-counter "set this counter value") + ("v" counsel-kmacro-action-copy-initial-counter-value "copy initial counter value"))) + +;;** `counsel-geiser-doc-look-up-manual' +(declare-function geiser-doc-manual-for-symbol "ext:geiser-doc") +(defvar geiser-completion-symbol-list-func) + +(defvar counsel-geiser-doc-look-up-manual-history () + "History for `counsel-geiser-doc-look-up-manual'.") + +;;;###autoload +(defun counsel-geiser-doc-look-up-manual () + "Search Scheme documentation." + (interactive) + (ivy-read "Symbol: " geiser-completion-symbol-list-func :require-match t - :history 'counsel-fonts-history - :action #'insert - :caller 'counsel-fonts)) + :history 'counsel-geiser-doc-look-up-manual-history + :action (lambda (cand) + (geiser-doc-manual-for-symbol (intern cand))) + :caller 'counsel-geiser-doc-look-up-manual)) ;;* Misc. OS ;;** `counsel-rhythmbox' @@ -5095,6 +5817,15 @@ You can insert or kill the name of the selected font." (dbus-call-method :session service path interface "AddToQueue" (cdr song)))) +(defun counsel-rhythmbox-playpause-current-song () + "Play/pause the current song." + (interactive) + (let ((service "org.gnome.Rhythmbox3") + (path "/org/mpris/MediaPlayer2") + (interface "org.mpris.MediaPlayer2.Player")) + (dbus-call-method :session service path interface + "PlayPause"))) + (defun counsel-rhythmbox-toggle-shuffle (_song) "Toggle Rhythmbox shuffle setting." (let* ((old-order (counsel--command "dconf" "read" "/org/gnome/rhythmbox/player/play-order")) @@ -5166,6 +5897,8 @@ You can insert or kill the name of the selected font." :caller 'counsel-rhythmbox)) ;;** `counsel-linux-app' + +;; Added in Emacs 26.1. (require 'xdg nil t) (defalias 'counsel--xdg-data-home @@ -5203,6 +5936,7 @@ as arguments." (const :tag "Command : Name - Comment" counsel-linux-app-format-function-default) (const :tag "Name - Comment (Command)" counsel-linux-app-format-function-name-first) (const :tag "Name - Comment" counsel-linux-app-format-function-name-only) + (const :tag "Name - Comment (Pretty)" counsel-linux-app-format-function-name-pretty) (const :tag "Command" counsel-linux-app-format-function-command-only) (function :tag "Custom"))) @@ -5277,7 +6011,9 @@ NAME is the name of the application, COMMENT its comment and EXEC the command to launch it." (format "% -45s: %s%s" (propertize - (ivy--truncate-string exec 45) + (ivy--truncate-string + (replace-regexp-in-string "env +[^ ]+ +" "" exec) + 45) 'face 'counsel-application-name) name (if comment @@ -5306,6 +6042,16 @@ EXEC is the command to launch the application." "Display only the command EXEC when formatting Linux application names." exec) +(defun counsel-linux-app-format-function-name-pretty (name comment _exec) + "Format Linux application names with the NAME (and COMMENT) only, but pretty." + (format "% -45s%s" + (propertize + (ivy--truncate-string name 45) + 'face 'counsel-application-name) + (if comment + (concat ": " comment) + ""))) + (defun counsel-linux-apps-list-desktop-files () "Return an alist of all Linux applications. Each list entry is a pair of (desktop-name . desktop-file). @@ -5315,6 +6061,7 @@ This function always returns its elements in a stable order." (dolist (dir counsel-linux-apps-directories) (when (file-exists-p dir) (let ((dir (file-name-as-directory dir))) + ;; Function `directory-files-recursively' added in Emacs 25.1. (dolist (file (directory-files-recursively dir ".*\\.desktop$")) (let ((id (subst-char-in-string ?/ ?- (file-relative-name file dir)))) (when (and (not (gethash id hash)) (file-readable-p file)) @@ -5435,7 +6182,7 @@ Any desktop entries that fail to parse are recorded in "Launch a Linux desktop application, similar to Alt-. When ARG is non-nil, ignore NoDisplay property in *.desktop files." (interactive "P") - (ivy-read "Run a command: " (counsel-linux-apps-list) + (ivy-read "Run application: " (counsel-linux-apps-list) :predicate (unless arg (lambda (x) (get-text-property 0 'visible (car x)))) :action #'counsel-linux-app-action-default :caller 'counsel-linux-app)) @@ -5483,15 +6230,22 @@ The buffers are those opened during a session of `counsel-switch-buffer'." (setq counsel--switch-buffer-temporary-buffers nil counsel--switch-buffer-previous-buffers nil)) +(defcustom counsel-switch-buffer-preview-virtual-buffers t + "When non-nil, `counsel-switch-buffer' will preview virtual buffers." + :type 'boolean) + (defun counsel--switch-buffer-update-fn () (unless counsel--switch-buffer-previous-buffers (setq counsel--switch-buffer-previous-buffers (buffer-list))) - (let* ((current (ivy-state-current ivy-last)) - (virtual (assoc current ivy--virtual-buffers))) + (let* ((virtual (assoc (ivy-state-current ivy-last) ivy--virtual-buffers))) + (when (member (ivy-state-current ivy-last) ivy-marked-candidates) + (setf (ivy-state-current ivy-last) + (substring (ivy-state-current ivy-last) (length ivy-mark-prefix)))) (cond - ((get-buffer current) - (ivy-call)) - ((and virtual (file-exists-p (cdr virtual))) + ((get-buffer (ivy-state-current ivy-last)) + (let ((ivy-marked-candidates nil)) + (ivy-call))) + ((and counsel-switch-buffer-preview-virtual-buffers virtual (file-exists-p (cdr virtual))) (let ((buf (ignore-errors ;; may not open due to `large-file-warning-threshold' etc. (find-file-noselect (cdr virtual))))) @@ -5574,7 +6328,8 @@ This variable is suitable for addition to `savehist-additional-variables'.") (defvar counsel-compile-root-functions - '(counsel--project-current + '(counsel--projectile-root + counsel--project-current counsel--configure-root counsel--git-root counsel--dir-locals-root) @@ -5589,6 +6344,12 @@ The root is determined by `counsel-compile-root-functions'." (or (run-hook-with-args-until-success 'counsel-compile-root-functions) (error "Couldn't find project root"))) +(defun counsel--projectile-root () + "Return root of current projectile project or nil on failure. +Use `projectile-project-root' to determine the root." + (and (fboundp 'projectile-project-root) + (projectile-project-root))) + (defun counsel--project-current () "Return root of current project or nil on failure. Use `project-current' to determine the root." @@ -5613,7 +6374,8 @@ Use the presence of a `dir-locals-file' to determine the root." (defvar counsel-compile-local-builds '(counsel-compile-get-filtered-history counsel-compile-get-build-directories - counsel-compile-get-make-invocation) + counsel-compile-get-make-invocation + counsel-compile-get-make-help-invocations) "Additional compile invocations to feed into `counsel-compile'. This can either be a list of compile invocation strings or @@ -5653,26 +6415,30 @@ list is passed to `compilation-environment'." (defvar counsel-compile-phony-pattern "^\\.PHONY:[\t ]+\\(.+\\)$" "Regexp for extracting phony targets from Makefiles.") -;; This is loosely based on the Bash Make completion code +(defvar counsel-compile-help-pattern + "\\(?:^\\(\\*\\)?[[:space:]]+\\([^[:space:]]+\\)[[:space:]]+-\\)" + "Regexp for extracting help targets from a make help call.") + +;; This is loosely based on the Bash Make completion code which +;; relies on GNUMake having the following return codes: +;; 0 = no-rebuild, -q & 1 needs rebuild, 2 error (defun counsel-compile--probe-make-targets (dir) "Return a list of Make targets for DIR. -Return an empty list is Make exits with an error. This might -happen because some sort of configuration needs to be done first -or the source tree is pristine and being used for multiple build -trees." - (let ((default-directory dir) - (targets nil)) - (with-temp-buffer - ;; 0 = no-rebuild, -q & 1 needs rebuild, 2 error (for GNUMake at - ;; least) - (when (< (call-process "make" nil t nil "-nqp") 2) +Return a single blank target (so we invoke the default target) +if Make exits with an error. This might happen because some sort +of configuration needs to be done first or the source tree is +pristine and being used for multiple build trees." + (with-temp-buffer + (let* ((default-directory dir) + (res (call-process "make" nil t nil "-nqp")) + targets) + (if (or (not (numberp res)) (> res 1)) + (list "") (goto-char (point-min)) (while (re-search-forward counsel-compile-phony-pattern nil t) - (setq targets - (nconc targets (split-string - (match-string-no-properties 1))))))) - (sort targets #'string-lessp))) + (push (split-string (match-string-no-properties 1)) targets)) + (sort (apply #'nconc targets) #'string-lessp))))) (defun counsel-compile--pretty-propertize (leader text face) "Return a pretty string of the form \" LEADER TEXT\". @@ -5683,12 +6449,13 @@ text with FACE." 'font-lock-warning-face) (propertize text 'face face))) -(defun counsel--compile-get-make-targets (srcdir &optional blddir) - "Return a list of Make targets for a given SRCDIR/BLDDIR combination. +(defun counsel--compile-get-make-targets (probe-fn srcdir &optional blddir) + "Return propertized make targets returned by PROBE-FN in SRCDIR. -We search the Makefile for a list of phony targets which are -generally the top level targets a Make system provides. -The resulting strings are tagged with properties that +The optional BLDDIR allows for handling build directories. We +search the Makefile for a list of phony targets which are +generally the top level targets a Make system provides. The +resulting strings are tagged with properties that `counsel-compile-history' can use for filtering results." (let ((fmt (format (propertize "make %s %%s" 'cmd t) counsel-compile-make-args)) @@ -5705,7 +6472,7 @@ The resulting strings are tagged with properties that (setq target (concat (format fmt target) suffix build-env)) (add-text-properties 0 (length target) props target) target) - (counsel-compile--probe-make-targets (or blddir srcdir))))) + (funcall probe-fn (or blddir srcdir))))) (defun counsel-compile-get-make-invocation (&optional blddir) "Have a look in the root directory for any build control files. @@ -5715,7 +6482,41 @@ sub-directories that builds may be invoked in." (let ((srcdir (counsel--compile-root))) (when (directory-files (or blddir srcdir) nil counsel-compile-make-pattern t) - (counsel--compile-get-make-targets srcdir blddir)))) + (counsel--compile-get-make-targets + #'counsel-compile--probe-make-targets srcdir blddir)))) + +(defun counsel-compile--probe-make-help (dir) + "Return a list of Make targets based on help for DIR. + +It is quite common for a 'make help' invocation to return a human +readable list of targets. Often common targets are marked with a +leading asterisk. The exact search pattern is controlled by +`counsel-compile-help-pattern'." + (let ((default-directory dir) + primary-targets targets) + ;; Only proceed if the help target exists. + (when (eql 1 (apply #'call-process "make" nil nil nil "-q" "help" + counsel-compile-env)) + (with-temp-buffer + (when (eql 0 (apply #'call-process "make" nil t nil "help" + counsel-compile-env)) + (goto-char (point-min)) + (while (re-search-forward counsel-compile-help-pattern nil t) + (push (match-string 2) + (if (match-beginning 1) primary-targets targets))) + (nconc (sort primary-targets #'string-lessp) + (sort targets #'string-lessp))))))) + +(defun counsel-compile-get-make-help-invocations (&optional blddir) + "Query the root directory for makefiles with help output. + +The optional BLDDIR is useful for other helpers that have found +sub-directories that builds may be invoked in." + (let ((srcdir (counsel--compile-root))) + (when (directory-files (or blddir srcdir) nil + counsel-compile-make-pattern t) + (counsel--compile-get-make-targets + #'counsel-compile--probe-make-help srcdir blddir)))) (defun counsel--find-build-subdir (srcdir) "Return builds subdirectory of SRCDIR, if one exists." @@ -5829,9 +6630,36 @@ specified by the `blddir' property." (compile cmd) (remove-hook 'compilation-start-hook #'counsel-compile--update-history)))))) +(defun counsel-compile-edit-command () + "Insert current compile command into the minibuffer for editing. + +This mirrors the behavior of `ivy-insert-current' but with specific +handling for the `counsel-compile' metadata." + (interactive) + (delete-minibuffer-contents) + (let* ((cmd (ivy-state-current ivy-last)) + (blddir (get-text-property 0 'blddir cmd))) + (when blddir + (setq counsel-compile--current-build-dir blddir)) + (insert (substring-no-properties + cmd 0 (and (get-text-property 0 'cmd cmd) + (next-single-property-change 0 'cmd cmd)))))) + +;; Currently the only thing we do is override ivy's default insert +;; operation which doesn't include the metadata we want. +(defvar counsel-compile-map + (let ((map (make-sparse-keymap))) + (define-key map [remap ivy-insert-current] #'counsel-compile-edit-command) + map) + "Additional ivy keybindings during command selection.") + ;;;###autoload (defun counsel-compile (&optional dir) - "Call `compile' completing with smart suggestions, optionally for DIR." + "Call `compile' completing with smart suggestions, optionally for DIR. + +Additional actions: + +\\{counsel-compile-map}" (interactive) (setq counsel-compile--current-build-dir (or dir (counsel--compile-root) @@ -5839,8 +6667,17 @@ specified by the `blddir' property." (ivy-read "Compile command: " (delete-dups (counsel--get-compile-candidates dir)) :action #'counsel-compile--action + :keymap counsel-compile-map :caller 'counsel-compile)) +(ivy-add-actions + 'counsel-compile + '(("d" counsel-compile-forget-command "delete"))) + +(defun counsel-compile-forget-command (cmd) + "Delete CMD from `counsel-compile-history'." + (setq counsel-compile-history + (delete cmd counsel-compile-history))) (defun counsel-compile-env--format-hint (cands) "Return a formatter for compile-env CANDS." @@ -5895,7 +6732,7 @@ and minor mode symbol." (mapcar (lambda (mode) (when (and (boundp mode) (commandp mode)) - (let ((lighter (alist-get mode minor-mode-alist))) + (let ((lighter (cdr (assq mode minor-mode-alist)))) (cons (concat (if (symbol-value mode) "-" "+") (symbol-name mode) @@ -5953,19 +6790,42 @@ Additional actions:\\ :action #'counsel-M-x-action :caller 'counsel-major)) -;;* `counsel-google' +;;** `counsel-search' (declare-function request "ext:request") -(defun counsel-google-function (input) - "Create a request to Google with INPUT. + +(defcustom counsel-search-engine 'ddg + "The search engine choice in `counsel-search-engines-alist'." + :type '(choice + (const ddg) + (const google))) + +(defcustom counsel-search-engines-alist + '((google + "http://suggestqueries.google.com/complete/search" + "https://www.google.com/search?q=" + counsel--search-request-data-google) + (ddg + "https://duckduckgo.com/ac/" + "https://duckduckgo.com/html/?q=" + counsel--search-request-data-ddg)) + "Search engine parameters for `counsel-search'." + :type '(list)) + +(defun counsel--search-request-data-google (data) + (mapcar #'identity (aref data 1))) + +(defun counsel--search-request-data-ddg (data) + (mapcar #'cdar data)) + +(defun counsel-search-function (input) + "Create a request to a search engine with INPUT. Return 0 tells `ivy--exhibit' not to update the minibuffer. We update it in the callback with `ivy-update-candidates'." (or (ivy-more-chars) - (progn - (require 'request) - (require 'json) + (let ((engine (cdr (assoc counsel-search-engine counsel-search-engines-alist)))) (request - "http://suggestqueries.google.com/complete/search" + (nth 0 engine) :type "GET" :params (list (cons "client" "firefox") @@ -5974,17 +6834,119 @@ We update it in the callback with `ivy-update-candidates'." :success (cl-function (lambda (&key data &allow-other-keys) (ivy-update-candidates - (mapcar #'identity (aref data 1)))))) + (funcall (nth 2 engine) data))))) 0))) -(defun counsel-google () - "Ivy interface for Google." +(defun counsel-search-action (x) + "Search for X." + (browse-url + (concat + (nth 2 (assoc counsel-search-engine counsel-search-engines-alist)) + (url-hexify-string x)))) + +(defun counsel-search () + "Ivy interface for dynamically querying a search engine." (interactive) - (ivy-read "search: " #'counsel-google-function - :action (lambda (x) - (browse-url (concat "https://www.google.com/search?q=" x))) + (require 'request) + (require 'json) + (ivy-read "search: " #'counsel-search-function + :action #'counsel-search-action :dynamic-collection t - :caller 'counsel-google)) + :caller 'counsel-search)) + +(define-obsolete-function-alias 'counsel-google + 'counsel-search "<2019-10-17 Thu>") + +;;** `counsel-compilation-errors' +(defun counsel--compilation-errors-buffer (buf) + (with-current-buffer buf + (let ((res nil) + (pt (point-min))) + (save-excursion + (while (setq pt (compilation-next-single-property-change + pt 'compilation-message)) + (let ((loc (get-text-property pt 'compilation-message))) + (when (and loc (setq loc (compilation--message->loc loc))) + (goto-char pt) + (push + (propertize + (buffer-substring-no-properties pt (line-end-position)) + 'pt pt + 'buffer buf) + res))))) + (nreverse res)))) + +(defun counsel-compilation-errors-cands () + (cl-loop + for buf in (buffer-list) + when (compilation-buffer-p buf) + nconc (counsel--compilation-errors-buffer buf))) + +(defun counsel-compilation-errors-action (x) + (pop-to-buffer (get-text-property 0 'buffer x)) + (goto-char (get-text-property 0 'pt x)) + (compile-goto-error)) + +;;;###autoload +(defun counsel-compilation-errors () + "Compilation errors." + (interactive) + (ivy-read "compilation errors: " (counsel-compilation-errors-cands) + :require-match t + :action #'counsel-compilation-errors-action + :history 'counsel-compilation-errors-history)) + +;;** `counsel-flycheck' +(defvar flycheck-current-errors) +(declare-function flycheck-error-filename "ext:flycheck") +(declare-function flycheck-error-line "ext:flycheck") +(declare-function flycheck-error-message "ext:flycheck") +(declare-function flycheck-jump-to-error "ext:flycheck") + +(defun counsel-flycheck-errors-cands () + (mapcar + (lambda (err) + (propertize + (format "%s:%d:%s" + (file-name-base (flycheck-error-filename err)) + (flycheck-error-line err) + (flycheck-error-message err)) 'error err)) + flycheck-current-errors)) + +(defun counsel-flycheck-occur (cands) + "Generate a custom occur buffer for `counsel-flycheck'." + (unless (eq major-mode 'ivy-occur-grep-mode) + (ivy-occur-grep-mode) + (setq default-directory (ivy-state-directory ivy-last))) + (swiper--occur-insert-lines + (mapcar + (lambda (cand) + (let ((err (get-text-property 0 'error cand))) + (propertize + (format + "%s:%d:%s" + (flycheck-error-filename err) + (flycheck-error-line err) + cand) + 'error err))) + cands))) + +(defun counsel-flycheck-errors-action (err) + (flycheck-jump-to-error (get-text-property 0 'error err))) + +(ivy-configure 'counsel-flycheck + :occur #'counsel-flycheck-occur) + +;;;###autoload +(defun counsel-flycheck () + "Flycheck errors." + (interactive) + (require 'flycheck) + (ivy-read "flycheck errors: " (counsel-flycheck-errors-cands) + :require-match t + :action #'counsel-flycheck-errors-action + :history 'counsel-flycheck-errors-history)) + ;;* `counsel-mode' (defvar counsel-mode-map @@ -5994,6 +6956,7 @@ We update it in the callback with `ivy-update-candidates'." (describe-bindings . counsel-descbinds) (describe-function . counsel-describe-function) (describe-variable . counsel-describe-variable) + (describe-symbol . counsel-describe-symbol) (apropos-command . counsel-apropos) (describe-face . counsel-describe-face) (list-faces-display . counsel-faces) @@ -6005,6 +6968,7 @@ We update it in the callback with `ivy-update-candidates'." (yank-pop . counsel-yank-pop) (info-lookup-symbol . counsel-info-lookup-symbol) (pop-to-mark-command . counsel-mark-ring) + (geiser-doc-look-up-manual . counsel-geiser-doc-look-up-manual) (bookmark-jump . counsel-bookmark))) (define-key map (vector 'remap (car binding)) (cdr binding))) map) @@ -6029,13 +6993,11 @@ Local bindings (`counsel-mode-map'): :lighter " counsel" (if counsel-mode (progn - (when (and (fboundp 'advice-add) - counsel-mode-override-describe-bindings) + (when counsel-mode-override-describe-bindings (advice-add #'describe-bindings :override #'counsel-descbinds)) (define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history)) - (when (fboundp 'advice-remove) - (advice-remove #'describe-bindings #'counsel-descbinds)))) + (advice-remove #'describe-bindings #'counsel-descbinds))) (provide 'counsel) diff --git a/elpa/cython-mode-0.29.21/cython-mode-pkg.el b/elpa/cython-mode-0.29.21/cython-mode-pkg.el deleted file mode 100755 index 74d8118..0000000 --- a/elpa/cython-mode-0.29.21/cython-mode-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;;; Generated package description from /data/data/com.termux/files/home/.emacs.d/elpa/cython-mode-0.29.21/cython-mode.el -*- no-byte-compile: t -*- -(define-package "cython-mode" "0.29.21" "Major mode for editing Cython files" 'nil :commit "976f5483c6df8570f34076ef25af7e7512dd9347") diff --git a/elpa/cython-mode-0.29.21/cython-mode-autoloads.el b/elpa/cython-mode-0.29.22/cython-mode-autoloads.el old mode 100755 new mode 100644 similarity index 100% rename from elpa/cython-mode-0.29.21/cython-mode-autoloads.el rename to elpa/cython-mode-0.29.22/cython-mode-autoloads.el diff --git a/elpa/cython-mode-0.29.22/cython-mode-pkg.el b/elpa/cython-mode-0.29.22/cython-mode-pkg.el new file mode 100644 index 0000000..015f83b --- /dev/null +++ b/elpa/cython-mode-0.29.22/cython-mode-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from cython-mode.el -*- no-byte-compile: t -*- +(define-package "cython-mode" "0.29.22" "Major mode for editing Cython files" 'nil :commit "3e470fcc3a4e9a33b66d5db6ab761c773888a1ea") diff --git a/elpa/cython-mode-0.29.21/cython-mode.el b/elpa/cython-mode-0.29.22/cython-mode.el old mode 100755 new mode 100644 similarity index 99% rename from elpa/cython-mode-0.29.21/cython-mode.el rename to elpa/cython-mode-0.29.22/cython-mode.el index 8469922..b195c82 --- a/elpa/cython-mode-0.29.21/cython-mode.el +++ b/elpa/cython-mode-0.29.22/cython-mode.el @@ -1,6 +1,6 @@ ;;; cython-mode.el --- Major mode for editing Cython files -;; Package-Version: 0.29.21 -;; Package-Commit: 976f5483c6df8570f34076ef25af7e7512dd9347 +;; Package-Version: 0.29.22 +;; Package-Commit: 3e470fcc3a4e9a33b66d5db6ab761c773888a1ea ;; License: Apache-2.0 diff --git a/elpa/dash-2.18.0/dash-autoloads.el b/elpa/dash-2.18.1/dash-autoloads.el similarity index 100% rename from elpa/dash-2.18.0/dash-autoloads.el rename to elpa/dash-2.18.1/dash-autoloads.el diff --git a/elpa/dash-2.18.0/dash-pkg.el b/elpa/dash-2.18.1/dash-pkg.el similarity index 66% rename from elpa/dash-2.18.0/dash-pkg.el rename to elpa/dash-2.18.1/dash-pkg.el index b7be1dc..e2ac2b3 100644 --- a/elpa/dash-2.18.0/dash-pkg.el +++ b/elpa/dash-2.18.1/dash-pkg.el @@ -1,6 +1,6 @@ -(define-package "dash" "2.18.0" "A modern list library for Emacs" +(define-package "dash" "2.18.1" "A modern list library for Emacs" '((emacs "24")) - :commit "0e975782086020aa12863fdb658d6a3cc748a10c" :authors + :commit "1a53e13d7964c84cf756ead353eb6dc094b65fd5" :authors '(("Magnar Sveen" . "magnars@gmail.com")) :maintainer '("Magnar Sveen" . "magnars@gmail.com") diff --git a/elpa/dash-2.18.0/dash.el b/elpa/dash-2.18.1/dash.el similarity index 99% rename from elpa/dash-2.18.0/dash.el rename to elpa/dash-2.18.1/dash.el index 80d4ef9..3e55f9d 100644 --- a/elpa/dash-2.18.0/dash.el +++ b/elpa/dash-2.18.1/dash.el @@ -3,7 +3,7 @@ ;; Copyright (C) 2012-2021 Free Software Foundation, Inc. ;; Author: Magnar Sveen -;; Version: 2.18.0 +;; Version: 2.18.1 ;; Package-Requires: ((emacs "24")) ;; Keywords: extensions, lisp ;; Homepage: https://github.com/magnars/dash.el @@ -685,12 +685,15 @@ Thus function FN should return a list." (defmacro --iterate (form init n) "Anaphoric version of `-iterate'." (declare (debug (form form form))) - (let ((res (make-symbol "result"))) - `(let ((it ,init) ,res) - (dotimes (_ ,n) - (push it ,res) - (setq it ,form)) - (nreverse ,res)))) + (let ((res (make-symbol "result")) + (len (make-symbol "n"))) + `(let ((,len ,n)) + (when (> ,len 0) + (let* ((it ,init) + (,res (list it))) + (dotimes (_ (1- ,len)) + (push (setq it ,form) ,res)) + (nreverse ,res)))))) (defun -iterate (fun init n) "Return a list of iterated applications of FUN to INIT. @@ -724,7 +727,9 @@ See also: `-flatten-n'" See also: `-flatten'" (declare (pure t) (side-effect-free t)) - (-last-item (--iterate (--mapcat (-list it) it) list (1+ num)))) + (dotimes (_ num) + (setq list (apply #'append (mapcar #'-list list)))) + list) (defun -concat (&rest lists) "Return a new list with the concatenation of the elements in the supplied LISTS." diff --git a/elpa/dash-2.18.0/dash.info b/elpa/dash-2.18.1/dash.info similarity index 99% rename from elpa/dash-2.18.0/dash.info rename to elpa/dash-2.18.1/dash.info index d4550b0..25c56f7 100644 --- a/elpa/dash-2.18.0/dash.info +++ b/elpa/dash-2.18.1/dash.info @@ -1,6 +1,6 @@ This is dash.info, produced by makeinfo version 6.5 from dash.texi. -This manual is for Dash version 2.18.0. +This manual is for Dash version 2.18.1. Copyright © 2012–2021 Free Software Foundation, Inc. @@ -22,7 +22,7 @@ File: dash.info, Node: Top, Next: Installation, Up: (dir) Dash **** -This manual is for Dash version 2.18.0. +This manual is for Dash version 2.18.1. Copyright © 2012–2021 Free Software Foundation, Inc. @@ -109,7 +109,7 @@ File: dash.info, Node: Using in a package, Next: Fontification of special vari If you use Dash in your own package, be sure to list it as a dependency in the library’s headers as follows (*note (elisp)Library Headers::). - ;; Package-Requires: ((dash "2.18.0")) + ;; Package-Requires: ((dash "2.18.1"))  File: dash.info, Node: Fontification of special variables, Next: Info symbol lookup, Prev: Using in a package, Up: Installation diff --git a/elpa/dash-2.18.0/dir b/elpa/dash-2.18.1/dir similarity index 100% rename from elpa/dash-2.18.0/dir rename to elpa/dash-2.18.1/dir diff --git a/elpa/format-all-0.3.0/format-all-pkg.el b/elpa/format-all-0.3.0/format-all-pkg.el deleted file mode 100755 index 1d528fa..0000000 --- a/elpa/format-all-0.3.0/format-all-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;;; Generated package description from /data/data/com.termux/files/home/.emacs.d/elpa/format-all-0.3.0/format-all.el -*- no-byte-compile: t -*- -(define-package "format-all" "0.3.0" "Auto-format C, C++, JS, Python, Ruby and 40 other languages" '((emacs "24") (cl-lib "0.5") (language-id "0.4")) :commit "8c8c47a863a397d947999fff4358caf20bafca0a" :keywords '("languages" "util") :authors '(("Lassi Kortela" . "lassi@lassi.io")) :maintainer '("Lassi Kortela" . "lassi@lassi.io") :url "https://github.com/lassik/emacs-format-all-the-code") diff --git a/elpa/format-all-0.3.0/format-all-autoloads.el b/elpa/format-all-0.4.0/format-all-autoloads.el old mode 100755 new mode 100644 similarity index 57% rename from elpa/format-all-0.3.0/format-all-autoloads.el rename to elpa/format-all-0.4.0/format-all-autoloads.el index 56def0e..2e8aab4 --- a/elpa/format-all-0.3.0/format-all-autoloads.el +++ b/elpa/format-all-0.4.0/format-all-autoloads.el @@ -25,10 +25,18 @@ external program. A suitable formatter is selected according to the `major-mode' of the buffer. Many popular programming languages are supported. It is fairly easy to add new languages that have an external -formatter. +formatter. When called interactively or PROMPT-P is non-nil, a +missing formatter is prompted in the minibuffer. + +If PROMPT is non-nil (or the function is called as an interactive +command), a missing formatter is prompted in the minibuffer. If +PROMPT is the symbol `always' (or a prefix argument is given), +the formatter is prompted for even if one has already been set. If any errors or warnings were encountered during formatting, -they are shown in a buffer called *format-all-errors*." t nil) +they are shown in a buffer called *format-all-errors*. + +\(fn &optional PROMPT)" t nil) (autoload 'format-all-mode "format-all" "\ Toggle automatic source code formatting before save. @@ -38,26 +46,15 @@ automatically called to format your code each time before you save the buffer. The mode is buffer-local and needs to be enabled separately each -time a file is visited. You may want to use `add-hook' to add a -function to your personal `after-change-major-mode-hook' in your -`user-init-file' to enable the mode based on the buffer's -`major-mode' and some `buffer-file-name' patterns. For example: - - (defvar my-auto-format-modes '(js-mode python-mode)) - (defvar my-auto-format-dirs '(\"foo\" \"bar\")) +time a file is visited. You may want to use `add-hook' in your +`user-init-file' to enable the mode based on buffer modes. E.g.: - (defun my-auto-format-buffer-p () - (and (member major-mode my-auto-format-modes) - (buffer-file-name) - (save-match-data - (let ((dir (file-name-directory (buffer-file-name)))) - (cl-some (lambda (regexp) (string-match regexp dir)) - my-auto-format-dirs))))) + (add-hook 'prog-mode-hook 'format-all-mode) - (defun my-after-change-major-mode () - (format-all-mode (if (my-auto-format-buffer-p) 1 0))) +To use a default formatter for projects that don't have one, add +this too: - (add-hook 'after-change-major-mode-hook 'my-after-change-major-mode) + (add-hook 'prog-mode-hook 'format-all-ensure-formatter) When `format-all-mode' is called as a Lisp function, the mode is toggled if ARG is ‘toggle’, disabled if ARG is a negative integer @@ -65,7 +62,7 @@ or zero, and enabled otherwise. \(fn &optional ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "format-all" '("asmfmt" "bibtex-mode" "black" "brittany" "buildifier" "cmake-format" "crystal" "dartfmt" "define-format-all-formatter" "dfmt" "dhall" "dockfmt" "elm-format" "emacs-lisp" "fish-indent" "format-all-" "fprettify" "gofmt" "html-tidy" "istyle-verilog" "ktlint" "latexindent" "ledger-mode" "lua-fmt" "mix-format" "nixfmt" "ocp-indent" "perltidy" "prettier" "purty" "rufo" "rustfmt" "scalafmt" "shfmt" "sqlformat" "styler" "swiftformat" "terraform-fmt"))) +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "format-all" '("atsfmt" "beautysh" "bibtex-mode" "black" "brittany" "bsrefmt" "buildifier" "cabal-fmt" "cmake-format" "crystal" "dartfmt" "define-format-all-formatter" "dfmt" "dhall" "dockfmt" "elm-format" "emacs-lisp" "fish-indent" "format-all-" "fprettify" "gleam" "hindent" "html-tidy" "istyle-verilog" "jsonnetfmt" "ktlint" "latexindent" "ledger-mode" "lua-fmt" "mix-format" "nix" "ocp-indent" "ormolu" "perltidy" "pgformatter" "prettier" "purty" "resfmt" "scalafmt" "shfmt" "snakefmt" "sqlformat" "swiftformat" "terraform-fmt" "yapf"))) ;;;*** diff --git a/elpa/format-all-0.4.0/format-all-pkg.el b/elpa/format-all-0.4.0/format-all-pkg.el new file mode 100644 index 0000000..4693e46 --- /dev/null +++ b/elpa/format-all-0.4.0/format-all-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from format-all.el -*- no-byte-compile: t -*- +(define-package "format-all" "0.4.0" "Auto-format C, C++, JS, Python, Ruby and 50 other languages" '((emacs "24.3") (inheritenv "0.1") (language-id "0.12")) :commit "caa0269ce89789a702823041ca7b309ddaffb5ce" :authors '(("Lassi Kortela" . "lassi@lassi.io")) :maintainer '("Lassi Kortela" . "lassi@lassi.io") :keywords '("languages" "util") :url "https://github.com/lassik/emacs-format-all-the-code") diff --git a/elpa/format-all-0.3.0/format-all.el b/elpa/format-all-0.4.0/format-all.el old mode 100755 new mode 100644 similarity index 56% rename from elpa/format-all-0.3.0/format-all.el rename to elpa/format-all-0.4.0/format-all.el index e065a83..8d77dd1 --- a/elpa/format-all-0.3.0/format-all.el +++ b/elpa/format-all-0.4.0/format-all.el @@ -1,11 +1,11 @@ -;;; format-all.el --- Auto-format C, C++, JS, Python, Ruby and 40 other languages -*- lexical-binding: t -*- +;;; format-all.el --- Auto-format C, C++, JS, Python, Ruby and 50 other languages -*- lexical-binding: t -*- ;; ;; Author: Lassi Kortela ;; URL: https://github.com/lassik/emacs-format-all-the-code -;; Package-Version: 0.3.0 -;; Package-Commit: 8c8c47a863a397d947999fff4358caf20bafca0a -;; Version: 0.3.0 -;; Package-Requires: ((emacs "24") (cl-lib "0.5") (language-id "0.4")) +;; Package-Version: 0.4.0 +;; Package-Commit: caa0269ce89789a702823041ca7b309ddaffb5ce +;; Version: 0.4.0 +;; Package-Requires: ((emacs "24.3") (inheritenv "0.1") (language-id "0.12")) ;; Keywords: languages util ;; SPDX-License-Identifier: MIT ;; @@ -26,9 +26,12 @@ ;; ;; - Angular/Vue (prettier) ;; - Assembly (asmfmt) +;; - ATS (atsfmt) ;; - Bazel Starlark (buildifier) -;; - BibTeX (emacs) -;; - C/C++/Objective-C (clang-format) +;; - BibTeX (Emacs) +;; - C/C++/Objective-C (clang-format, astyle) +;; - C# (clang-format, astyle) +;; - Cabal (cabal-fmt) ;; - Clojure/ClojureScript (node-cljfmt) ;; - CMake (cmake-format) ;; - Crystal (crystal tool format) @@ -39,36 +42,43 @@ ;; - Dockerfile (dockfmt) ;; - Elixir (mix format) ;; - Elm (elm-format) -;; - Emacs Lisp (emacs) +;; - Emacs Lisp (Emacs) ;; - Fish Shell (fish_indent) ;; - Fortran 90 (fprettify) -;; - Go (gofmt) +;; - Gleam (gleam format) +;; - GLSL (clang-format) +;; - Go (gofmt, goimports) ;; - GraphQL (prettier) -;; - Haskell (brittany) +;; - Haskell (brittany, hindent, ormolu, stylish-haskell) ;; - HTML/XHTML/XML (tidy) -;; - Java (clang-format) -;; - JavaScript/JSON/JSX (prettier) +;; - Java (clang-format, astyle) +;; - JavaScript/JSON/JSX (prettier, standard) +;; - Jsonnet (jsonnetfmt) ;; - Kotlin (ktlint) ;; - LaTeX (latexindent) ;; - Ledger (ledger-mode) -;; - Lua (lua-fmt) +;; - Lua (lua-fmt, prettier plugin-lua) ;; - Markdown (prettier) -;; - Nix (nixfmt) +;; - Nix (nixpkgs-fmt, nixfmt) ;; - OCaml (ocp-indent) ;; - Perl (perltidy) ;; - PHP (prettier plugin-php) ;; - Protocol Buffers (clang-format) ;; - PureScript (purty) -;; - Python (black) +;; - Python (black, yapf) ;; - R (styler) +;; - Reason (bsrefmt) +;; - ReScript (resfmt) ;; - Ruby (rufo) ;; - Rust (rustfmt) ;; - Scala (scalafmt) -;; - Shell script (shfmt) +;; - Shell script (beautysh, shfmt) +;; - Snakemake (snakefmt) ;; - Solidity (prettier prettier-plugin-solidity) -;; - SQL (sqlformat) +;; - SQL (pgformatter, sqlformat) ;; - Swift (swiftformat) ;; - Terraform (terraform fmt) +;; - TOML (prettier prettier-plugin-toml) ;; - TypeScript/TSX (prettier) ;; - Verilog (iStyle) ;; - YAML (prettier) @@ -77,11 +87,6 @@ ;; If `format-all-buffer` can't find the right program, it will try to ;; tell you how to install it. ;; -;; There are currently no customize variables, since it's not clear -;; what approach should be taken. Please see -;; https://github.com/lassik/emacs-format-all-the-code/issues for -;; discussion. -;; ;; Many of the external formatters support configuration files in the ;; source code directory to control their formatting. Please see the ;; documentation for each formatter. @@ -92,10 +97,98 @@ ;; ;;; Code: +(require 'cl-lib) +(require 'inheritenv) (require 'language-id) -(defvar format-all-debug nil - "When non-nil, format-all writes debug info using `message'.") +(defgroup format-all nil + "Lets you auto-format source code." + :group 'format-all) + +(defcustom format-all-debug nil + "When non-nil, troubleshooting info is written into the *Messages* buffer." + :type 'boolean + :group 'format-all) + +(defcustom format-all-default-formatters + '(("Assembly" asmfmt) + ("ATS" atsfmt) + ("Bazel" buildifier) + ("BibTeX" bibtex-mode) + ("C" clang-format) + ("C#" clang-format) + ("C++" clang-format) + ("Cabal Config" cabal-fmt) + ("Clojure" cljfmt) + ("CMake" cmake-format) + ("Crystal" crystal) + ("CSS" prettier) + ("D" dfmt) + ("Dart" dartfmt) + ("Dhall" dhall) + ("Dockerfile" dockfmt) + ("Elixir" mix-format) + ("Elm" elm-format) + ("Emacs Lisp" emacs-lisp) + ("Fish" fish-indent) + ("GLSL" clang-format) + ("Go" gofmt) + ("GraphQL" prettier) + ("Haskell" brittany) + ("HTML" html-tidy) + ("Java" clang-format) + ("JavaScript" prettier) + ("JSON" prettier) + ("Jsonnet" jsonnetfmt) + ("JSX" prettier) + ("Kotlin" ktlint) + ("LaTeX" latexindent) + ("Less" prettier) + ("Literate Haskell" brittany) + ("Lua" lua-fmt) + ("Markdown" prettier) + ("Nix" nixpkgs-fmt) + ("Objective-C" clang-format) + ("OCaml" ocp-indent) + ("Perl" perltidy) + ("PHP" prettier) + ("Protocol Buffer" clang-format) + ("PureScript" purty) + ("Python" black) + ("R" styler) + ("Reason" bsrefmt) + ("ReScript" resfmt) + ("Ruby" rufo) + ("Rust" rustfmt) + ("Scala" scalafmt) + ("SCSS" prettier) + ("Shell" shfmt) + ("Solidity" prettier) + ("SQL" sqlformat) + ("Swift" swiftformat) + ("Terraform" terraform-fmt) + ("TOML" prettier) + ("TSX" prettier) + ("TypeScript" prettier) + ("Verilog" istyle-verilog) + ("Vue" prettier) + ("XML" html-tidy) + ("YAML" prettier) + + ("_Angular" prettier) + ("_Flow" prettier) + ("_Fortran 90" fprettify) + ("_Gleam" gleam) + ("_Ledger" ledger-mode) + ("_Snakemake" snakefmt)) + "Default formatter to use for each language." + :type '(repeat (list string symbol)) + :group 'format-all) + +(defcustom format-all-always-show-errors nil + "When non-nil, warnings are shown even when formatting is successful." + :type 'boolean + :group 'format-all) (defvar format-all-after-format-functions nil "Hook run after each time `format-all-buffer' has formatted a buffer. @@ -119,7 +212,85 @@ is not guaranteed to be in any particular place, so `goto-char' before editing the buffer. Narrowing may be in effect unless STATUS is :reformatted.") -(eval-when-compile +(defvar format-all--user-args nil + "Internal variable to temporarily store arguments for formatters.") + +(defvar-local format-all-formatters nil + "Rules to select which formatter format-all uses. + +The value is an association list. + +The first item of each association is the name of a programming +language. (GitHub Linguist names are used.) + +The remaining items are one or more formatters to use for that +language. Each formatter is either: + +* a symbol (e.g. black, clang-format, rufo) + +* a list whose first item is that symbol, and any remaining items + are extra command line arguments to pass to the formatter + +If more than one formatter is given for the same language, all of +them are run as a chain, with the code from each formatter passed +to the next. The final code is from the last formatter. In case +any formatter in the chain is missing or fails to format the +code, the entire chain fails and the old code before formatting +is preserved. + +You'll probably want to set this in a \".dir-locals.el\" file or +in a hook function. Any number of buffers can share the same +association list. Using \".dir-locals.el\" is convenient since +the rules for an entire source tree can be given in one file.") + +(defun format-all--proper-list-p (object) + "Return t if OBJECT is a proper list, nil otherwise." + ;; If we could depend on Emacs 27.1 this function would be built in. + (and (listp object) (not (null (cl-list-length object))))) + +(defun format-all--normalize-formatter (formatter) + "Internal function to convert FORMATTER spec into normal form." + (let ((formatter (if (listp formatter) formatter (list formatter)))) + (when (cdr (last formatter)) + (error "Formatter is not a proper list: %S" formatter)) + (when (null formatter) + (error "Formatter name missing")) + (unless (symbolp (car formatter)) + (error "Formatter name is not a symbol: %S" (car formatter))) + (unless (cl-every #'stringp (cdr formatter)) + (error "Formatter command line arguments are not all strings: %S" + formatter)) + formatter)) + +(defun format-all--normalize-chain (chain) + "Internal function to convert CHAIN spec into normal form." + (when (or (not (listp chain)) (cdr (last chain))) + (error "Formatter chain is not a proper list: %S" chain)) + (mapcar #'format-all--normalize-formatter chain)) + +(defun format-all-valid-formatters-p (formatters) + "Return t if FORMATTERS is a valid value for `format-all-formatters'." + (and (format-all--proper-list-p formatters) + (cl-every + (lambda (chain) + (and (not (null chain)) + (format-all--proper-list-p chain) + (stringp (car chain)) + (cl-every + (lambda (formatter) + (and (not (null formatter)) + (or (symbolp formatter) + (and (format-all--proper-list-p formatter) + (and (symbolp (car formatter)) + (not (null (car formatter)))) + (cl-every #'stringp (cdr formatter)))))) + (cdr chain)))) + formatters))) + +(put 'format-all-formatters 'safe-local-variable + 'format-all-valid-formatters-p) + +(eval-and-compile (defconst format-all--system-type (cl-case system-type (windows-nt 'windows) @@ -134,7 +305,7 @@ STATUS is :reformatted.") ((string-match "netbsd" system-configuration) 'netbsd)))))) "Current operating system according to the format-all package.")) -(eval-when-compile +(eval-and-compile (defun format-all--resolve-system (choices) "Get first choice matching `format-all--system-type' from CHOICES." (cl-dolist (choice choices) @@ -184,9 +355,9 @@ takes INPUT (the unformatted source code as a string). THUNK is invoked such that the current buffer is an empty temp buffer. It should call the formatter on INPUT and write the formatted source code output to the temp buffer. It should return (ERRORP -ERRPUT). ERRORP is a boolean indicating whether the formatter +ERROR-OUTPUT). ERRORP is a boolean indicating whether the formatter caused an error and hence the contents of the temp buffer should -be discarded. ERRPUT is a string containing all error/warning +be discarded. ERROR-OUTPUT is a string containing all error/warning output from the formatter. Note that in some cases we can use the output of the formatter @@ -196,16 +367,17 @@ even if it produced warnings. Not all warnings are errors." (widen) (let ((inbuf (current-buffer)) (input (buffer-string))) - (with-temp-buffer - (cl-destructuring-bind (errorp errput) (funcall thunk input) - (let* ((no-chg (or errorp - (= 0 (let ((case-fold-search nil)) - (compare-buffer-substrings - inbuf nil nil nil nil nil))))) - (output (cond (errorp nil) - (no-chg t) - (t (buffer-string))))) - (list output errput)))))))) + (inheritenv + (with-temp-buffer + (cl-destructuring-bind (errorp error-output) (funcall thunk input) + (let* ((no-chg (or errorp + (= 0 (let ((case-fold-search nil)) + (compare-buffer-substrings + inbuf nil nil nil nil nil))))) + (output (cond (errorp nil) + (no-chg t) + (t (buffer-string))))) + (list output error-output))))))))) (defun format-all--buffer-native (mode &rest funcs) "Internal helper function to implement formatters. @@ -221,6 +393,12 @@ functions to avoid warnings from the Emacs byte compiler." (format-all--fix-trailing-whitespace) (list nil "")))) +(defun format-all--locate-file (filename) + "Internal helper to locate dominating copy of FILENAME for current buffer." + (let* ((dir (and (buffer-file-name) + (locate-dominating-file (buffer-file-name) filename)))) + (when dir (expand-file-name (concat dir filename))))) + (defun format-all--locate-default-directory (root-files) "Internal helper function to find working directory for formatter. @@ -266,7 +444,7 @@ or none of ROOT-FILES are found in any parent directories, the working directory will be the one where the formatted file is. ROOT-FILES is ignored for buffers that are not visiting a file." (let ((ok-statuses (or ok-statuses '(0))) - (args (format-all--flatten-once args)) + (args (append format-all--user-args (format-all--flatten-once args))) (default-directory (format-all--locate-default-directory root-files))) (when format-all-debug (message "Format-All: Running: %s" @@ -278,15 +456,15 @@ ROOT-FILES is ignored for buffers that are not visiting a file." (status (apply #'call-process-region input nil executable nil (list t errfile) nil args)) - (errput (with-temp-buffer - (insert-file-contents errfile) - (delete-file errfile) - (buffer-string))) + (error-output (with-temp-buffer + (insert-file-contents errfile) + (delete-file errfile) + (buffer-string))) (errorp (or (not (member status ok-statuses)) (and error-regexp (save-match-data - (string-match error-regexp errput)))))) - (list errorp errput)))))) + (string-match error-regexp error-output)))))) + (list errorp error-output)))))) (defun format-all--buffer-easy (executable &rest args) "Internal helper function to implement formatters. @@ -358,6 +536,27 @@ Consult the existing formatters for examples of BODY." (:languages "Assembly") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter astyle + (:executable "astyle") + (:install (macos "brew install astyle")) + (:languages "C" "C++" "C#" "Java") + (:format (format-all--buffer-easy + executable + (let ((astylerc (format-all--locate-file ".astylerc"))) + (when astylerc (concat "--options=" astylerc)))))) + +(define-format-all-formatter atsfmt + (:executable "atsfmt") + (:install "cabal new-install ats-format --happy-options='-gcsa' -O2") + (:languages "ATS") + (:format (format-all--buffer-easy executable))) + +(define-format-all-formatter beautysh + (:executable "beautysh") + (:install "pip install beautysh") + (:languages "Shell") + (:format (format-all--buffer-easy executable "-"))) + (define-format-all-formatter bibtex-mode (:executable) (:install) @@ -380,6 +579,12 @@ Consult the existing formatters for examples of BODY." (:languages "Haskell" "Literate Haskell") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter bsrefmt + (:executable "bsrefmt") + (:install "npm install --global bs-platform") + (:languages "Reason") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter buildifier (:executable "buildifier") (:install @@ -388,12 +593,18 @@ Consult the existing formatters for examples of BODY." (:languages "Bazel") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter cabal-fmt + (:executable "cabal-fmt") + (:install "cabal install cabal-fmt") + (:languages "Cabal Config") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter clang-format (:executable "clang-format") (:install (macos "brew install clang-format") (windows "scoop install llvm")) - (:languages "C" "C++" "Java" "Objective-C" "Protocol Buffer") + (:languages "C" "C#" "C++" "GLSL" "Java" "Objective-C" "Protocol Buffer") (:format (format-all--buffer-easy executable @@ -401,7 +612,9 @@ Consult the existing formatters for examples of BODY." (or (buffer-file-name) (cdr (assoc language '(("C" . ".c") + ("C#" . ".cs") ("C++" . ".cpp") + ("GLSL" . ".glsl") ("Java" . ".java") ("Objective-C" . ".m") ("Protocol Buffer" . ".proto"))))))))) @@ -458,11 +671,11 @@ Consult the existing formatters for examples of BODY." (:install (macos "brew install elm")) (:languages "Elm") (:format - (cl-destructuring-bind (output errput) + (cl-destructuring-bind (output error-output) (format-all--buffer-hard nil nil '("elm.json" "elm-package.json") executable "--yes" "--stdin") - (let ((errput (format-all--remove-ansi-color errput))) - (list output errput))))) + (let ((error-output (format-all--remove-ansi-color error-output))) + (list output error-output))))) (define-format-all-formatter emacs-lisp (:executable) @@ -485,6 +698,12 @@ Consult the existing formatters for examples of BODY." (:languages "_Fortran 90") (:format (format-all--buffer-easy executable "--silent"))) +(define-format-all-formatter gleam + (:executable "gleam") + (:install (macos "brew install gleam")) + (:languages "_Gleam") + (:format (format-all--buffer-easy executable "format" "--stdin"))) + (define-format-all-formatter gofmt (:executable "gofmt") (:install @@ -493,6 +712,18 @@ Consult the existing formatters for examples of BODY." (:languages "Go") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter goimports + (:executable "goimports") + (:install "go get golang.org/x/tools/cmd/goimports") + (:languages "Go") + (:format (format-all--buffer-easy executable))) + +(define-format-all-formatter hindent + (:executable "hindent") + (:install "stack install hindent") + (:languages "Haskell" "Literate Haskell") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter html-tidy (:executable "tidy") (:install @@ -514,6 +745,12 @@ Consult the existing formatters for examples of BODY." (:languages "Verilog") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter jsonnetfmt + (:executable "jsonnetfmt") + (:install (macos "brew install jsonnet")) + (:languages "Jsonnet") + (:format (format-all--buffer-easy executable "-"))) + (define-format-all-formatter ktlint (:executable "ktlint") (:install (macos "brew install ktlint")) @@ -548,10 +785,8 @@ Consult the existing formatters for examples of BODY." nil nil '("mix.exs") executable "format" - (let* ((file ".formatter.exs") - (dir (and (buffer-file-name) - (locate-dominating-file (buffer-file-name) file)))) - (when dir (list "--dot-formatter" (concat dir file)))) + (let ((config-file (format-all--locate-file ".formatter.exs"))) + (when config-file (list "--dot-formatter" config-file))) "-"))) (define-format-all-formatter nixfmt @@ -560,27 +795,42 @@ Consult the existing formatters for examples of BODY." (:languages "Nix") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter nixpkgs-fmt + (:executable "nixpkgs-fmt") + (:install "nix-env -f https://github.com/nix-community/nixpkgs-fmt/archive/master.tar.gz -i") + (:languages "Nix") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter ocp-indent (:executable "ocp-indent") (:install "opam install ocp-indent") (:languages "OCaml") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter ormolu + (:executable "ormolu") + (:install "stack install ormolu") + (:languages "Haskell" "Literate Haskell") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter perltidy (:executable "perltidy") (:install "cpan install Perl::Tidy") (:languages "Perl") (:format (format-all--buffer-easy executable))) +(define-format-all-formatter pgformatter + (:executable "pg_format") + (:install) + (:languages "SQL") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter prettier (:executable "prettier") - (:install "npm install --global prettier @prettier/plugin-php prettier-plugin-solidity") + (:install "npm install --global prettier @prettier/plugin-lua @prettier/plugin-php prettier-plugin-solidity prettier-plugin-toml") (:languages - "CSS" "GraphQL" "JavaScript" "JSON" "JSX" "Less" "Markdown" "PHP" - "SCSS" "Solidity" "TSX" "TypeScript" "Vue" "YAML" - ;; TODO: Use html-tidy instead of prettier for plain HTML. Enable - ;; prettier's HTML support once we have multi-formatter support. - ;; "HTML" + "CSS" "GraphQL" "HTML" "JavaScript" "JSON" "JSX" "Less" "Lua" "Markdown" + "PHP" "SCSS" "Solidity" "TOML" "TSX" "TypeScript" "Vue" "YAML" "_Angular" "_Flow") (:format (format-all--buffer-easy @@ -593,7 +843,9 @@ Consult the existing formatters for examples of BODY." ("Solidity" . "solidity-parse") ("TSX" . "typescript"))))) (if pair (cdr pair) (downcase language))) - (when (buffer-file-name) (list "--stdin-filepath" (buffer-file-name)))))) + (when (buffer-file-name) (list "--stdin-filepath" (buffer-file-name))) + (let ((ignore-file (format-all--locate-file ".prettierignore"))) + (when ignore-file (list "--ignore-path" ignore-file)))))) (define-format-all-formatter purty (:executable "purty") @@ -601,6 +853,12 @@ Consult the existing formatters for examples of BODY." (:languages "PureScript") (:format (format-all--buffer-easy executable "-"))) +(define-format-all-formatter resfmt + (:executable "resfmt") + (:install "pip install resfmt") + (:languages "ReScript") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter rufo (:executable "rufo") (:install "gem install rufo") @@ -614,7 +872,7 @@ Consult the existing formatters for examples of BODY." (define-format-all-formatter rustfmt (:executable "rustfmt") - (:install "cargo install rustfmt") + (:install "rustup component add rustfmt") (:languages "Rust") (:format (format-all--buffer-easy executable))) @@ -635,12 +893,20 @@ Consult the existing formatters for examples of BODY." (:format (format-all--buffer-easy executable - "-ln" (cl-case (and (eql major-mode 'sh-mode) - (boundp 'sh-shell) - (symbol-value 'sh-shell)) - (bash "bash") - (mksh "mksh") - (t "posix"))))) + (if (buffer-file-name) + (list "-filename" (buffer-file-name)) + (list "-ln" (cl-case (and (eql major-mode 'sh-mode) + (boundp 'sh-shell) + (symbol-value 'sh-shell)) + (bash "bash") + (mksh "mksh") + (t "posix"))))))) + +(define-format-all-formatter snakefmt + (:executable "snakefmt") + (:install) + (:languages "_Snakemake") + (:format (format-all--buffer-easy executable "-"))) (define-format-all-formatter sqlformat (:executable "sqlformat") @@ -655,12 +921,21 @@ Consult the existing formatters for examples of BODY." 'utf-8))) (process-environment (cons (concat "PYTHONIOENCODING=" oenc) process-environment))) - (format-all--buffer-easy - executable - "--keywords" "upper" - "--reindent_aligned" - "--encoding" ienc - "-")))) + (format-all--buffer-easy executable "--encoding" ienc "-")))) + +(define-format-all-formatter standard + (:executable "standard") + (:install "npm install --global standard") + (:languages "JavaScript" "JSX") + (:format + ;; `standard --stdin` properly uses zero vs non-zero exit codes to + ;; indicate success vs error. However, it checks for quite a broad + ;; range of errors, all the way up to undeclared identifiers and + ;; such. To catch only syntax errors, we need to look specifically + ;; for the text "Parsing error:". + (format-all--buffer-hard + '(0 1) ".*?:.*?:[0-9]+:[0-9]+: Parsing error:" nil + executable "--fix" "--stdin"))) (define-format-all-formatter styler (:executable "Rscript") @@ -676,11 +951,21 @@ Consult the existing formatters for examples of BODY." " close(con);" " out")))) +(define-format-all-formatter stylish-haskell + (:executable "stylish-haskell") + (:install "stack install stylish-haskell") + (:languages "Haskell") + (:format (format-all--buffer-easy executable))) + (define-format-all-formatter swiftformat (:executable "swiftformat") (:install (macos "brew install swiftformat")) (:languages "Swift") - (:format (format-all--buffer-easy executable "--quiet"))) + (:format + (format-all--buffer-easy + executable "--quiet" + (let ((config (format-all--locate-file ".swiftformat"))) + (when config (list "--config" config)))))) (define-format-all-formatter terraform-fmt (:executable "terraform") @@ -688,6 +973,12 @@ Consult the existing formatters for examples of BODY." (:languages "Terraform") (:format (format-all--buffer-easy executable "fmt" "-no-color" "-"))) +(define-format-all-formatter yapf + (:executable "yapf") + (:install "pip install yapf") + (:languages "Python") + (:format (format-all--buffer-easy executable))) + (defun format-all--language-id-buffer () "Return the language used in the current buffer, or NIL. @@ -696,8 +987,7 @@ languages do not yet have official GitHub Linguist identifiers, yet format-all needs to know about them anyway. That's why we have this custom language-id function in format-all. The unofficial languages IDs are prefixed with \"_\"." - (or (language-id-buffer) - (and (or (equal major-mode 'angular-html-mode) + (or (and (or (equal major-mode 'angular-html-mode) (and (equal major-mode 'web-mode) (equal (symbol-value 'web-mode-content-type) "html") (equal (symbol-value 'web-mode-engine) "angular"))) @@ -707,7 +997,10 @@ unofficial languages IDs are prefixed with \"_\"." (not (null (symbol-value 'flow-minor-mode))) "_Flow") (and (equal major-mode 'f90-mode) "_Fortran 90") - (and (equal major-mode 'ledger-mode) "_Ledger"))) + (and (equal major-mode 'gleam-mode) "_Gleam") + (and (equal major-mode 'ledger-mode) "_Ledger") + (and (equal major-mode 'snakemake-mode) "_Snakemake") + (language-id-buffer))) (defun format-all--please-install (executable installer) "Internal helper function for error about missing EXECUTABLE and INSTALLER." @@ -715,13 +1008,6 @@ unofficial languages IDs are prefixed with \"_\"." (if (not installer) "" (format " You may be able to install it via %S." installer)))) -(defun format-all--probe () - "Internal helper function to get the formatter for the current buffer." - (let ((language (format-all--language-id-buffer))) - (cl-dolist (formatter (gethash language format-all--language-table) - (list nil nil)) - (cl-return (list formatter language))))) - (defun format-all--formatter-executable (formatter) "Internal helper function to get the external program for FORMATTER." (let ((executable (gethash formatter format-all--executable-table))) @@ -731,17 +1017,21 @@ unofficial languages IDs are prefixed with \"_\"." executable (gethash formatter format-all--install-table))))))) -(defun format-all--show-or-hide-errors (error-output) - "Internal helper function to update *format-all-errors* with ERROR-OUTPUT." - (save-selected-window - (with-current-buffer (get-buffer-create "*format-all-errors*") - (erase-buffer) - (cond ((not (= 0 (length error-output))) - (insert error-output) - (display-buffer (current-buffer))) - (t - (let ((error-window (get-buffer-window (current-buffer)))) - (when error-window (quit-window nil error-window)))))))) +(defun format-all--update-errors-buffer (status error-output) + "Internal helper function to update *format-all-errors*. + +STATUS and ERROR-OUTPUT come from the formatter." + (let ((show-errors-p (and (not (= 0 (length error-output))) + (or format-all-always-show-errors + (eq status :error))))) + (save-selected-window + (with-current-buffer (get-buffer-create "*format-all-errors*") + (erase-buffer) + (insert error-output) + (if show-errors-p + (display-buffer (current-buffer)) + (let ((error-window (get-buffer-window (current-buffer)))) + (when error-window (quit-window nil error-window)))))))) (defun format-all--save-line-number (thunk) "Internal helper function to run THUNK and go back to the same line." @@ -753,47 +1043,95 @@ unofficial languages IDs are prefixed with \"_\"." (let ((line-length (- (point-at-eol) (point-at-bol)))) (goto-char (+ (point) (min old-column line-length)))))) -(defun format-all-buffer--with (formatter language) - "Internal helper function to format the current buffer. - -Relies on FORMATTER and LANGUAGE from `format-all--probe'." - (when format-all-debug - (message "Format-All: Formatting %s using %S" - (buffer-name) (list formatter language))) - (let ((f-function (gethash formatter format-all--format-table)) - (executable (format-all--formatter-executable formatter))) - (cl-destructuring-bind (output errput) - (funcall f-function executable language) - (let ((status (cond ((null output) :error) - ((equal t output) :already-formatted) - (t :reformatted)))) - (when (equal :reformatted status) - (widen) - (format-all--save-line-number - (lambda () - (erase-buffer) - (insert output)))) - (format-all--show-or-hide-errors errput) - (run-hook-with-args 'format-all-after-format-functions - formatter status) - (message (cl-ecase status - (:error "Formatting error") - (:already-formatted "Already formatted") - (:reformatted "Reformatted!"))))))) - -(defun format-all-buffer--from-hook () +(defun format-all--run-chain (language chain) + "Internal function to run a formatter CHAIN on the current buffer. + +LANGUAGE is the language ID of the current buffer, from +`format-all--language-id-buffer`." + (let* ((chain (format-all--normalize-chain chain)) + (chain-tail chain) + (error-output "") + (reformatted-by '())) + (format-all--save-line-number + (lambda () + (cl-loop + (unless (and chain-tail (= 0 (length error-output))) + (cl-return)) + (let* ((formatter (car chain-tail)) + (f-name (car formatter)) + (f-args (cdr formatter)) + (f-function (gethash f-name format-all--format-table)) + (f-executable (format-all--formatter-executable f-name))) + (when format-all-debug + (message + "Format-All: Formatting %s as %s using %S%s" + (buffer-name) language f-name + (with-temp-buffer + (dolist (arg f-args) (insert " " (shell-quote-argument arg))) + (buffer-string)))) + (cl-destructuring-bind (f-output f-error-output) + (let ((format-all--user-args f-args)) + (funcall f-function f-executable language)) + (let ((f-status :already-formatted)) + (cond ((null f-output) + (setq error-output f-error-output) + (setq f-status :error)) + ((not (equal f-output t)) + (setq reformatted-by + (append reformatted-by (list f-name))) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert f-output)) + (setq f-status :reformatted))) + (run-hook-with-args 'format-all-after-format-functions + f-name f-status) + (format-all--update-errors-buffer f-status f-error-output)))) + (setq chain-tail (cdr chain-tail))) + (message "%s" + (cond ((not (= 0 (length error-output))) "Formatting error") + ((not reformatted-by) "Already formatted") + (t "Reformatted!"))))))) + +(defun format-all--get-default-chain (language) + "Internal function to get the default formatter chain for LANGUAGE." + (when language (cdr (assoc language format-all-default-formatters)))) + +(defun format-all--get-chain (language) + "Internal function to get LANGUAGE formatter chain for current buffer." + (when language (cdr (assoc language format-all-formatters)))) + +(defun format-all--set-chain (language chain) + "Internal function to set LANGUAGE formatter CHAIN for current buffer." + (cl-assert (stringp language)) + (cl-assert (listp chain)) + (setq format-all-formatters + (append (cl-remove-if (lambda (pair) (equal language (car pair))) + format-all-formatters) + (when chain (list (cons language chain)))))) + +(defun format-all--prompt-for-formatter (language) + "Internal function to choose a formatter for LANGUAGE." + (let ((f-names (gethash language format-all--language-table))) + (cond ((null f-names) (error "No supported formatters for %s" language)) + ((null (cdr f-names)) (car f-names)) + (t (let ((f-string (completing-read + (format "Formatter for %s: " language) + (mapcar #'list f-names) nil t))) + (and (not (= 0 (length f-string))) + (intern f-string))))))) + +(defun format-all--buffer-from-hook () "Internal helper function to auto-format current buffer from a hook. Format-All installs this function into `before-save-hook' to format buffers on save. This is a lenient version of `format-all-buffer' that silently succeeds instead of signaling an error if the current buffer has no formatter." - (cl-destructuring-bind (formatter language) (format-all--probe) - (when formatter - (format-all-buffer--with formatter language)))) + (let ((language (format-all--language-id-buffer))) + (format-all--run-chain language (format-all--get-chain language)))) ;;;###autoload -(defun format-all-buffer () +(defun format-all-buffer (&optional prompt) "Auto-format the source code in the current buffer. No disk files are touched - the buffer doesn't even need to be @@ -809,15 +1147,47 @@ external program. A suitable formatter is selected according to the `major-mode' of the buffer. Many popular programming languages are supported. It is fairly easy to add new languages that have an external -formatter. +formatter. When called interactively or PROMPT-P is non-nil, a +missing formatter is prompted in the minibuffer. + +If PROMPT is non-nil (or the function is called as an interactive +command), a missing formatter is prompted in the minibuffer. If +PROMPT is the symbol `always' (or a prefix argument is given), +the formatter is prompted for even if one has already been set. If any errors or warnings were encountered during formatting, they are shown in a buffer called *format-all-errors*." + (interactive (list (if current-prefix-arg 'always t))) + (let* ((language (format-all--language-id-buffer)) + (chain (format-all--get-chain language))) + (when (or (equal 'always prompt) (and prompt (not chain))) + (let ((f-name (format-all--prompt-for-formatter language))) + (when f-name + (message "Setting formatter to %S" f-name) + (setq chain (list f-name)) + (format-all--set-chain language chain)))) + (unless chain (error "No formatter")) + (format-all--run-chain language chain))) + +(defun format-all-ensure-formatter () + "Ensure current buffer has a formatter, using default if not." (interactive) - (cl-destructuring-bind (formatter language) (format-all--probe) - (if formatter - (format-all-buffer--with formatter language) - (error "Don't know how to format %S code" major-mode)))) + (let ((language (format-all--language-id-buffer))) + (unless (format-all--get-chain language) + (cond ((not language) + (message "No formatter for this language")) + ((not (gethash language format-all--language-table)) + (message "No formatter for %s" language)) + (t + (let ((default (format-all--get-default-chain language))) + (cond ((not default) + (message "No default formatter for %s" language)) + (t + (message "Using default formatter%s" + (with-temp-buffer + (dolist (formatter default (buffer-string)) + (insert (format " %S" formatter))))) + (format-all--set-chain language default))))))))) ;;;###autoload (define-minor-mode format-all-mode @@ -828,26 +1198,15 @@ automatically called to format your code each time before you save the buffer. The mode is buffer-local and needs to be enabled separately each -time a file is visited. You may want to use `add-hook' to add a -function to your personal `after-change-major-mode-hook' in your -`user-init-file' to enable the mode based on the buffer's -`major-mode' and some `buffer-file-name' patterns. For example: - - (defvar my-auto-format-modes '(js-mode python-mode)) - (defvar my-auto-format-dirs '(\"foo\" \"bar\")) +time a file is visited. You may want to use `add-hook' in your +`user-init-file' to enable the mode based on buffer modes. E.g.: - (defun my-auto-format-buffer-p () - (and (member major-mode my-auto-format-modes) - (buffer-file-name) - (save-match-data - (let ((dir (file-name-directory (buffer-file-name)))) - (cl-some (lambda (regexp) (string-match regexp dir)) - my-auto-format-dirs))))) + (add-hook 'prog-mode-hook 'format-all-mode) - (defun my-after-change-major-mode () - (format-all-mode (if (my-auto-format-buffer-p) 1 0))) +To use a default formatter for projects that don't have one, add +this too: - (add-hook 'after-change-major-mode-hook 'my-after-change-major-mode) + (add-hook 'prog-mode-hook 'format-all-ensure-formatter) When `format-all-mode' is called as a Lisp function, the mode is toggled if ARG is ‘toggle’, disabled if ARG is a negative integer @@ -856,10 +1215,10 @@ or zero, and enabled otherwise." :global nil (if format-all-mode (add-hook 'before-save-hook - 'format-all-buffer--from-hook + 'format-all--buffer-from-hook nil 'local) (remove-hook 'before-save-hook - 'format-all-buffer--from-hook + 'format-all--buffer-from-hook 'local))) (provide 'format-all) diff --git a/elpa/inheritenv-0.1/inheritenv-autoloads.el b/elpa/inheritenv-0.1/inheritenv-autoloads.el new file mode 100644 index 0000000..be1eb10 --- /dev/null +++ b/elpa/inheritenv-0.1/inheritenv-autoloads.el @@ -0,0 +1,47 @@ +;;; inheritenv-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "inheritenv" "inheritenv.el" (0 0 0 0)) +;;; Generated autoloads from inheritenv.el + +(autoload 'inheritenv-apply "inheritenv" "\ +Apply FUNC such that the environment it sees will match the current value. +This is useful if FUNC creates a temp buffer, because that will +not inherit any buffer-local values of variables `exec-path' and +`process-environment'. + +This function is designed for convenient use as an \"around\" advice. + +ARGS is as for ORIG. + +\(fn FUNC &rest ARGS)" nil nil) + +(autoload 'inheritenv "inheritenv" "\ +Wrap BODY so that the environment it sees will match the current value. +This is useful if BODY creates a temp buffer, because that will +not inherit any buffer-local values of variables `exec-path' and +`process-environment'. + +\(fn &rest BODY)" nil t) + +(autoload 'inheritenv-add-advice "inheritenv" "\ +Advise function FUNC with `inheritenv-apply'. +This will ensure that any buffers (including temporary buffers) +created by FUNC will inherit the caller's environment. + +\(fn FUNC)" nil t) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; inheritenv-autoloads.el ends here diff --git a/elpa/inheritenv-0.1/inheritenv-pkg.el b/elpa/inheritenv-0.1/inheritenv-pkg.el new file mode 100644 index 0000000..9d1e801 --- /dev/null +++ b/elpa/inheritenv-0.1/inheritenv-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from inheritenv.el -*- no-byte-compile: t -*- +(define-package "inheritenv" "0.1" "Make temp buffers inherit buffer-local environment variables" '((emacs "24.4")) :commit "bc680a2670156cd482edba83d8c81142282174ba" :authors '(("Steve Purcell" . "steve@sanityinc.com")) :maintainer '("Steve Purcell" . "steve@sanityinc.com") :keywords '("unix") :url "https://github.com/purcell/inheritenv") diff --git a/elpa/inheritenv-0.1/inheritenv.el b/elpa/inheritenv-0.1/inheritenv.el new file mode 100644 index 0000000..be5ff20 --- /dev/null +++ b/elpa/inheritenv-0.1/inheritenv.el @@ -0,0 +1,86 @@ +;;; inheritenv.el --- Make temp buffers inherit buffer-local environment variables -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Steve Purcell + +;; Author: Steve Purcell +;; URL: https://github.com/purcell/inheritenv +;; Package-Version: 0.1 +;; Package-Commit: bc680a2670156cd482edba83d8c81142282174ba +;; Package-Requires: ((emacs "24.4")) +;; Version: 0.1-pre +;; Keywords: unix + +;; 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 . + +;;; Commentary: + +;; There's a fairly common pitfall when Emacs libraries run background +;; processes on behalf of a user: the library should honour any +;; environment variables set buffer-locally, but many such libraries run +;; processes in temporary buffers that do not inherit the calling +;; buffer's environment. + +;; An example is the Emacs built-in command +;; `shell-command-to-string'. Whatever buffer-local `process-environment' +;; (or `exec-path') the user has set, that command will always use the +;; Emacs-wide default. This is *specified* behaviour, but not *expected* +;; or *helpful*, particularly if one uses a library like +;; `envrc' with "direnv". + +;; `inheritenv' provides a couple of tools for dealing with this +;; issue: + +;; 1. Library authors can wrap code that plans to execute processes in +;; temporary buffers with the `inheritenv' macro. +;; 2. End users can modify commands like `shell-command-to-string' using +;; the `inheritenv-add-advice' macro. + +;;; Code: + +(require 'cl-lib) + +;;;###autoload +(defun inheritenv-apply (func &rest args) + "Apply FUNC such that the environment it sees will match the current value. +This is useful if FUNC creates a temp buffer, because that will +not inherit any buffer-local values of variables `exec-path' and +`process-environment'. + +This function is designed for convenient use as an \"around\" advice. + +ARGS is as for ORIG." + (cl-letf* (((default-value 'process-environment) process-environment) + ((default-value 'exec-path) exec-path)) + (apply func args))) + + +;;;###autoload +(defmacro inheritenv (&rest body) + "Wrap BODY so that the environment it sees will match the current value. +This is useful if BODY creates a temp buffer, because that will +not inherit any buffer-local values of variables `exec-path' and +`process-environment'." + `(inheritenv-apply (lambda () ,@body))) + + +;;;###autoload +(defmacro inheritenv-add-advice (func) + "Advise function FUNC with `inheritenv-apply'. +This will ensure that any buffers (including temporary buffers) +created by FUNC will inherit the caller's environment." + `(advice-add ,func :around 'inheritenv-apply)) + + +(provide 'inheritenv) +;;; inheritenv.el ends here diff --git a/elpa/ivy-0.13.0/colir.el b/elpa/ivy-0.13.0/colir.el deleted file mode 100755 index 9e61273..0000000 --- a/elpa/ivy-0.13.0/colir.el +++ /dev/null @@ -1,124 +0,0 @@ -;;; colir.el --- Color blending library -*- lexical-binding: t -*- - -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel - -;; This file is part of GNU Emacs. - -;; This file 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, 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. - -;; For a full copy of the GNU General Public License -;; see . - -;;; Commentary: - -;; This package solves the problem of adding a face with a background -;; to text which may already have a background. In all conflicting -;; areas, instead of choosing either the original or the new -;; background face, their blended sum is used. -;; -;; The blend mode functions are taken from URL -;; `https://en.wikipedia.org/wiki/Blend_modes'. - -;;; Code: - -(require 'cl-lib) -(require 'color) - -(defcustom colir-compose-method #'colir-compose-alpha - "Select a method to compose two color channels." - :group 'ivy - :type '(radio - (function-item colir-compose-alpha) - (function-item colir-compose-overlay) - (function-item colir-compose-soft-light))) - -(defun colir-compose-soft-light (a b) - "Compose A and B channels." - (if (< b 0.5) - (+ (* 2 a b) (* a a (- 1 b b))) - (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1))))) - -(defun colir-compose-overlay (a b) - "Compose A and B channels." - (if (< a 0.5) - (* 2 a b) - (- 1 (* 2 (- 1 a) (- 1 b))))) - -(defun colir-compose-alpha (a b &optional alpha gamma) - "Compose A and B channels. -Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds -to the influence of A on the result. Default value is 0.5. -Optional argument GAMMA is used for gamma correction. Default value is 2.2." - (setq alpha (or alpha 0.5)) - (setq gamma (or gamma 2.2)) - (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha)))) - -(defun colir-blend (c1 c2) - "Blend the two colors C1 and C2 using `colir-compose-method'. -C1 and C2 are triples of floats in [0.0 1.0] range." - (apply #'color-rgb-to-hex - (cl-mapcar - (if (eq (frame-parameter nil 'background-mode) 'dark) - ;; this method works nicely for dark themes - 'colir-compose-soft-light - colir-compose-method) - c1 c2))) - -(defun colir-color-parse (color) - "Convert string COLOR to triple of floats in [0.0 1.0]." - (if (string-match "#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)" color) - (mapcar (lambda (v) (/ (string-to-number v 16) 255.0)) - (list (match-string 1 color) (match-string 2 color) (match-string 3 color))) - ;; does not work properly in terminal (maps color to nearest color - ;; from available color palette). - (color-name-to-rgb color))) - -(defun colir--blend-background (start next prevn face object) - (let ((background-prev (face-background prevn))) - (progn - (put-text-property - start next 'face - (if background-prev - (cons `(background-color - . ,(colir-blend - (colir-color-parse background-prev) - (colir-color-parse (face-background face nil t)))) - prevn) - (list face prevn)) - object)))) - -(defun colir-blend-face-background (start end face &optional object) - "Append to the face property of the text from START to END the face FACE. -When the text already has a face with a non-plain background, -blend it with the background of FACE. -Optional argument OBJECT is the string or buffer containing the text. -See also `font-lock-append-text-property'." - (let (next prev prevn) - (while (/= start end) - (setq next (next-single-property-change start 'face object end)) - (setq prev (get-text-property start 'face object)) - (setq prevn (if (listp prev) - (cl-find-if #'atom prev) - prev)) - (cond - ((or (keywordp (car-safe prev)) (consp (car-safe prev))) - (put-text-property start next 'face (cons face prev) object)) - ((facep prevn) - (colir--blend-background start next prevn face object)) - (t - (put-text-property start next 'face face object))) - (setq start next)))) - -(provide 'colir) - -;;; colir.el ends here diff --git a/elpa/ivy-0.13.0/ivy-autoloads.el b/elpa/ivy-0.13.0/ivy-autoloads.el deleted file mode 100755 index df1648a..0000000 --- a/elpa/ivy-0.13.0/ivy-autoloads.el +++ /dev/null @@ -1,161 +0,0 @@ -;;; ivy-autoloads.el --- automatically extracted autoloads -;; -;;; Code: - -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) - - -;;;### (autoloads nil "colir" "colir.el" (0 0 0 0)) -;;; Generated autoloads from colir.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "colir" '("colir-"))) - -;;;*** - -;;;### (autoloads nil "ivy" "ivy.el" (0 0 0 0)) -;;; Generated autoloads from ivy.el - -(autoload 'ivy-resume "ivy" "\ -Resume the last completion session." t nil) - -(autoload 'ivy-read "ivy" "\ -Read a string in the minibuffer, with completion. - -PROMPT is a string, normally ending in a colon and a space. -`ivy-count-format' is prepended to PROMPT during completion. - -COLLECTION is either a list of strings, a function, an alist, or -a hash table, supplied for `minibuffer-completion-table'. - -PREDICATE is applied to filter out the COLLECTION immediately. -This argument is for compatibility with `completing-read'. - -When REQUIRE-MATCH is non-nil, only members of COLLECTION can be -selected. - -If INITIAL-INPUT is non-nil, then insert that input in the -minibuffer initially. - -HISTORY is a name of a variable to hold the completion session -history. - -KEYMAP is composed with `ivy-minibuffer-map'. - -PRESELECT, when non-nil, determines which one of the candidates -matching INITIAL-INPUT to select initially. An integer stands -for the position of the desired candidate in the collection, -counting from zero. Otherwise, use the first occurrence of -PRESELECT in the collection. Comparison is first done with -`equal'. If that fails, and when applicable, match PRESELECT as -a regular expression. - -DEF is for compatibility with `completing-read'. - -UPDATE-FN is called each time the candidate list is re-displayed. - -When SORT is non-nil, `ivy-sort-functions-alist' determines how -to sort candidates before displaying them. - -ACTION is a function to call after selecting a candidate. -It takes one argument, the selected candidate. If COLLECTION is -an alist, the argument is a cons cell, otherwise it's a string. - -MULTI-ACTION, when non-nil, is called instead of ACTION when -there are marked candidates. It takes the list of candidates as -its only argument. When it's nil, ACTION is called on each marked -candidate. - -UNWIND is a function of no arguments to call before exiting. - -RE-BUILDER is a function transforming input text into a regex -pattern. - -MATCHER is a function which can override how candidates are -filtered based on user input. It takes a regex pattern and a -list of candidates, and returns the list of matching candidates. - -DYNAMIC-COLLECTION is a boolean specifying whether the list of -candidates is updated after each input by calling COLLECTION. - -EXTRA-PROPS can be used to store collection-specific -session-specific data. - -CALLER is a symbol to uniquely identify the caller to `ivy-read'. -It is used, along with COLLECTION, to determine which -customizations apply to the current completion session. - -\(fn PROMPT COLLECTION &key PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY PRESELECT DEF KEYMAP UPDATE-FN SORT ACTION MULTI-ACTION UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION EXTRA-PROPS CALLER)" nil nil) - -(autoload 'ivy-completing-read "ivy" "\ -Read a string in the minibuffer, with completion. - -This interface conforms to `completing-read' and can be used for -`completing-read-function'. - -PROMPT is a string that normally ends in a colon and a space. -COLLECTION is either a list of strings, an alist, an obarray, or a hash table. -PREDICATE limits completion to a subset of COLLECTION. -REQUIRE-MATCH is a boolean value. See `completing-read'. -INITIAL-INPUT is a string inserted into the minibuffer initially. -HISTORY is a list of previously selected inputs. -DEF is the default value. -INHERIT-INPUT-METHOD is currently ignored. - -\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY DEF INHERIT-INPUT-METHOD)" nil nil) - -(defvar ivy-mode nil "\ -Non-nil if Ivy mode is enabled. -See the `ivy-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 `ivy-mode'.") - -(custom-autoload 'ivy-mode "ivy" nil) - -(autoload 'ivy-mode "ivy" "\ -Toggle Ivy mode on or off. -Turn Ivy mode on if ARG is positive, off otherwise. -Turning on Ivy mode sets `completing-read-function' to -`ivy-completing-read'. - -Global bindings: -\\{ivy-mode-map} - -Minibuffer bindings: -\\{ivy-minibuffer-map} - -\(fn &optional ARG)" t nil) - -(autoload 'ivy-switch-buffer "ivy" "\ -Switch to another buffer." t nil) - -(autoload 'ivy-switch-view "ivy" "\ -Switch to one of the window views stored by `ivy-push-view'." t nil) - -(autoload 'ivy-switch-buffer-other-window "ivy" "\ -Switch to another buffer in another window." t nil) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy" '("ivy-" "with-ivy-window"))) - -;;;*** - -;;;### (autoloads nil "ivy-overlay" "ivy-overlay.el" (0 0 0 0)) -;;; Generated autoloads from ivy-overlay.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy-overlay" '("ivy-"))) - -;;;*** - -;;;### (autoloads nil nil ("elpa.el" "ivy-pkg.el") (0 0 0 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; ivy-autoloads.el ends here diff --git a/elpa/ivy-0.13.0/ivy-overlay.el b/elpa/ivy-0.13.0/ivy-overlay.el deleted file mode 100755 index 7a77bcf..0000000 --- a/elpa/ivy-0.13.0/ivy-overlay.el +++ /dev/null @@ -1,154 +0,0 @@ -;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*- - -;; Copyright (C) 2016-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel -;; Keywords: convenience - -;; 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 . - -;;; Commentary: - -;; This package allows to setup Ivy's completion at point to actually -;; show the candidates and the input at point, instead of in the -;; minibuffer. - -;;; Code: - -(defface ivy-cursor - '((((class color) (background light)) - :background "black" :foreground "white") - (((class color) (background dark)) - :background "white" :foreground "black")) - "Cursor face for inline completion." - :group 'ivy-faces) - -(defvar ivy--old-cursor-type t) - -(defvar ivy-overlay-at nil - "Overlay variable for `ivy-display-function-overlay'.") - -(declare-function ivy--truncate-string "ivy") - -(defun ivy-left-pad (str width) - "Return STR, but with each line indented by WIDTH spaces. -Lines are truncated to the window width." - (let ((padding (make-string width ?\s))) - (mapconcat (lambda (x) - (ivy--truncate-string (concat padding x) - (1- (+ (window-width) - (window-hscroll))))) - (split-string str "\n") - "\n"))) - -(defun ivy-overlay-cleanup () - "Clean up after `ivy-display-function-overlay'." - (when (overlayp ivy-overlay-at) - (delete-overlay ivy-overlay-at) - (setq ivy-overlay-at nil)) - (unless cursor-type - (setq cursor-type ivy--old-cursor-type)) - (when (fboundp 'company-abort) - (company-abort))) - -(defvar ivy-height) - -(defun ivy-overlay-show-after (str) - "Display STR in an overlay at point. - -First, fill each line of STR with spaces to the current column. -Then attach the overlay to the character before point." - (if ivy-overlay-at - (progn - (move-overlay ivy-overlay-at (1- (point)) (line-end-position)) - (overlay-put ivy-overlay-at 'invisible nil)) - (let ((available-height (count-lines (point) (window-end nil t)))) - (unless (>= available-height ivy-height) - (recenter (- (window-height) ivy-height 2)))) - (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position))) - ;; Specify face to avoid clashing with other overlays. - (overlay-put ivy-overlay-at 'face 'default) - (overlay-put ivy-overlay-at 'priority 9999)) - (overlay-put ivy-overlay-at 'display str) - (overlay-put ivy-overlay-at 'after-string "")) - -(declare-function org-current-level "org") -(declare-function org-at-heading-p "org") -(defvar org-indent-indentation-per-level) -(defvar ivy-height) -(defvar ivy-last) -(defvar ivy-text) -(defvar ivy-completion-beg) -(declare-function ivy-add-face-text-property "ivy") -(declare-function ivy--get-window "ivy") -(declare-function ivy-state-current "ivy") -(declare-function ivy-state-window "ivy") -(declare-function ivy--remove-prefix "ivy") - -(defun ivy-overlay-impossible-p (_str) - (or - (and (eq major-mode 'org-mode) - (plist-get (text-properties-at (point)) 'src-block)) - (<= (window-height) (+ ivy-height 2)) - (= (point) (point-min)) - (< (- (+ (window-width) (window-hscroll)) (current-column)) - 30))) - -(defun ivy-display-function-overlay (str) - "Called from the minibuffer, display STR in an overlay in Ivy window. -Hide the minibuffer contents and cursor." - (if (save-selected-window - (select-window (ivy-state-window ivy-last)) - (ivy-overlay-impossible-p str)) - (let ((buffer-undo-list t)) - (save-excursion - (forward-line 1) - (insert str))) - (ivy-add-face-text-property (minibuffer-prompt-end) (point-max) - '(:foreground "white")) - (setq cursor-type nil) - (with-selected-window (ivy--get-window ivy-last) - (when cursor-type - (setq ivy--old-cursor-type cursor-type)) - (setq cursor-type nil) - (let ((overlay-str - (apply - #'concat - (buffer-substring (max (point-min) (1- (point))) (point)) - ivy-text - (and (eolp) " ") - (buffer-substring (point) (line-end-position)) - (and (> (length str) 0) - (list "\n" - (ivy-left-pad - (ivy--remove-prefix "\n" str) - (+ - (if (and (eq major-mode 'org-mode) - (bound-and-true-p org-indent-mode)) - (if (org-at-heading-p) - (1- (org-current-level)) - (* org-indent-indentation-per-level (org-current-level))) - 0) - (save-excursion - (when ivy-completion-beg - (goto-char ivy-completion-beg)) - (current-column))))))))) - (let ((cursor-offset (1+ (length ivy-text)))) - (ivy-add-face-text-property cursor-offset (1+ cursor-offset) - 'ivy-cursor overlay-str t)) - (ivy-overlay-show-after overlay-str))))) - -(provide 'ivy-overlay) - -;;; ivy-overlay.el ends here diff --git a/elpa/ivy-0.13.0/ivy-pkg.el b/elpa/ivy-0.13.0/ivy-pkg.el deleted file mode 100755 index 5a91938..0000000 --- a/elpa/ivy-0.13.0/ivy-pkg.el +++ /dev/null @@ -1,12 +0,0 @@ -(define-package "ivy" "0.13.0" "Incremental Vertical completYon" - '((emacs "24.5")) - :commit "cd634c6f51458f81898ecf2821ac3169cb65a1eb" :keywords - ("matching") - :authors - (("Oleh Krehel" . "ohwoeowho@gmail.com")) - :maintainer - ("Oleh Krehel" . "ohwoeowho@gmail.com") - :url "https://github.com/abo-abo/swiper") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/ivy-0.13.0/ivy.el b/elpa/ivy-0.13.0/ivy.el deleted file mode 100755 index 1c733dd..0000000 --- a/elpa/ivy-0.13.0/ivy.el +++ /dev/null @@ -1,5056 +0,0 @@ -;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*- - -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel -;; URL: https://github.com/abo-abo/swiper -;; Version: 0.13.0 -;; Package-Requires: ((emacs "24.5")) -;; Keywords: matching - -;; This file is part of GNU Emacs. - -;; This file 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, 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. - -;; For a full copy of the GNU General Public License -;; see . - -;;; Commentary: - -;; This package provides `ivy-read' as an alternative to -;; `completing-read' and similar functions. -;; -;; There's no intricate code to determine the best candidate. -;; Instead, the user can navigate to it with `ivy-next-line' and -;; `ivy-previous-line'. -;; -;; The matching is done by splitting the input text by spaces and -;; re-building it into a regex. -;; So "for example" is transformed into "\\(for\\).*\\(example\\)". - -;;; Code: - -(require 'cl-lib) -(require 'ivy-overlay) -(require 'colir) -(require 'ring) - -;;* Customization -(defgroup ivy nil - "Incremental vertical completion." - :group 'convenience) - -(defgroup ivy-faces nil - "Font-lock faces for `ivy'." - :group 'ivy - :group 'faces) - -(defface ivy-current-match - '((((class color) (background light)) - :background "#1a4b77" :foreground "white") - (((class color) (background dark)) - :background "#65a7e2" :foreground "black")) - "Face used by Ivy for highlighting the current match.") - -(defface ivy-minibuffer-match-highlight - '((t :inherit highlight)) - "Face used by Ivy for highlighting the match under the cursor.") - -(defface ivy-minibuffer-match-face-1 - '((((class color) (background light)) - :background "#d3d3d3") - (((class color) (background dark)) - :background "#555555")) - "The background face for `ivy' minibuffer matches.") - -(defface ivy-minibuffer-match-face-2 - '((((class color) (background light)) - :background "#e99ce8" :weight bold) - (((class color) (background dark)) - :background "#777777" :weight bold)) - "Face for `ivy' minibuffer matches numbered 1 modulo 3.") - -(defface ivy-minibuffer-match-face-3 - '((((class color) (background light)) - :background "#bbbbff" :weight bold) - (((class color) (background dark)) - :background "#7777ff" :weight bold)) - "Face for `ivy' minibuffer matches numbered 2 modulo 3.") - -(defface ivy-minibuffer-match-face-4 - '((((class color) (background light)) - :background "#ffbbff" :weight bold) - (((class color) (background dark)) - :background "#8a498a" :weight bold)) - "Face for `ivy' minibuffer matches numbered 3 modulo 3.") - -(defface ivy-confirm-face - '((t :foreground "ForestGreen" :inherit minibuffer-prompt)) - "Face used by Ivy for a confirmation prompt.") - -(defface ivy-match-required-face - '((t :foreground "red" :inherit minibuffer-prompt)) - "Face used by Ivy for a match required prompt.") - -(defface ivy-subdir - '((t :inherit dired-directory)) - "Face used by Ivy for highlighting subdirs in the alternatives.") - -(defface ivy-org - '((t :inherit org-level-4)) - "Face used by Ivy for highlighting Org buffers in the alternatives.") - -(defface ivy-modified-buffer - '((t :inherit default)) - "Face used by Ivy for highlighting modified file visiting buffers.") - -(defface ivy-modified-outside-buffer - '((t :inherit default)) - "Face used by Ivy for highlighting file visiting buffers modified outside Emacs.") - -(defface ivy-remote - '((((class color) (background light)) - :foreground "#110099") - (((class color) (background dark)) - :foreground "#7B6BFF")) - "Face used by Ivy for highlighting remotes in the alternatives.") - -(defface ivy-virtual - '((t :inherit font-lock-builtin-face)) - "Face used by Ivy for matching virtual buffer names.") - -(defface ivy-action - '((t :inherit font-lock-builtin-face)) - "Face used by Ivy for displaying keys in `ivy-read-action'.") - -(defface ivy-highlight-face - '((t :inherit highlight)) - "Face used by Ivy to highlight certain candidates.") - -(defface ivy-prompt-match - '((t :inherit ivy-current-match)) - "Face used by Ivy for highlighting the selected prompt line.") - -(defface ivy-separator - '((t :inherit font-lock-doc-face)) - "Face for multiline source separator.") - -(defface ivy-grep-info - '((t :inherit compilation-info)) - "Face for highlighting grep information such as file names.") - -(defface ivy-grep-line-number - '((t :inherit compilation-line-number)) - "Face for displaying line numbers in grep messages.") - -(defface ivy-completions-annotations - '((t :inherit completions-annotations)) - "Face for displaying completion annotations.") - -(defface ivy-yanked-word - '((t :inherit highlight)) - "Face used to highlight yanked word.") - -;; Set default customization `:group' to `ivy' for the rest of the file. -(setcdr (assoc load-file-name custom-current-group-alist) 'ivy) - -(defcustom ivy-height 10 - "Number of lines for the minibuffer window. - -See also `ivy-height-alist'." - :type 'integer) - -(defcustom ivy-count-format "%-4d " - "The style to use for displaying the current candidate count for `ivy-read'. -Set this to \"\" to suppress the count visibility. -Set this to \"(%d/%d) \" to display both the index and the count." - :type '(choice - (const :tag "Count disabled" "") - (const :tag "Count matches" "%-4d ") - (const :tag "Count matches and show current match" "(%d/%d) ") - string)) - -(defcustom ivy-pre-prompt-function nil - "When non-nil, add strings before the `ivy-read' prompt." - :type '(choice - (const :tag "Do nothing" nil) - (function :tag "Custom function"))) - -(defcustom ivy-add-newline-after-prompt nil - "When non-nil, add a newline after the `ivy-read' prompt." - :type 'boolean) - -(defcustom ivy-wrap nil - "When non-nil, wrap around after the first and the last candidate." - :type 'boolean) - -(defcustom ivy-display-style (and (fboundp 'add-face-text-property) 'fancy) - "The style for formatting the minibuffer. - -By default, the matched strings are copied as is. - -The fancy display style highlights matching parts of the regexp, -a behavior similar to `swiper'. - -This setting depends on `add-face-text-property' - a C function -available since Emacs 24.4. Fancy style will render poorly in -earlier versions of Emacs." - :type '(choice - (const :tag "Plain" nil) - (const :tag "Fancy" fancy))) - -(defcustom ivy-on-del-error-function #'abort-recursive-edit - "Function to call when deletion fails during completion. -The usual reason for `ivy-backward-delete-char' to fail is when -there is no text left to delete, i.e., when it is called at the -beginning of the minibuffer. -The default setting provides a quick exit from completion." - :type '(choice - (const :tag "Exit completion" abort-recursive-edit) - (const :tag "Do nothing" ignore) - (function :tag "Custom function"))) - -(defcustom ivy-extra-directories '("../" "./") - "Add this to the front of the list when completing file names. -Only \"./\" and \"../\" apply here. They appear in reverse order." - :type '(repeat :tag "Dirs" - (choice - (const :tag "Parent Directory" "../") - (const :tag "Current Directory" "./")))) - -(defcustom ivy-use-virtual-buffers nil - "When non-nil, add recent files and/or bookmarks to `ivy-switch-buffer'. -The value `recentf' includes only recent files to the virtual -buffers list, whereas the value `bookmarks' does the same for -bookmarks. Any other non-nil value includes both." - :type '(choice - (const :tag "Don't use virtual buffers" nil) - (const :tag "Recent files" recentf) - (const :tag "Bookmarks" bookmarks) - (const :tag "All virtual buffers" t))) - -(defvar ivy--display-function nil - "The display-function is used in current.") - -(defvar ivy-display-functions-props - '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup)) - "Map Ivy display functions to their property lists. -Examples of properties include associated `:cleanup' functions.") - -(defcustom ivy-display-functions-alist - '((ivy-completion-in-region . ivy-display-function-overlay) - (t . nil)) - "An alist for customizing where to display the candidates. - -Each key is a caller symbol. When the value is nil (the default), -the candidates are shown in the minibuffer. Otherwise, the value -is a function which takes a string argument comprising the -current matching candidates and displays it somewhere. - -See also `https://github.com/abo-abo/swiper/wiki/ivy-display-function'." - :type '(alist - :key-type symbol - :value-type (choice - (const :tag "Minibuffer" nil) - (const :tag "LV" ivy-display-function-lv) - (const :tag "Popup" ivy-display-function-popup) - (const :tag "Overlay" ivy-display-function-overlay) - (function :tag "Custom function")))) - -(defvar ivy-completing-read-dynamic-collection nil - "Run `ivy-completing-read' with `:dynamic-collection t`.") - -(defcustom ivy-completing-read-handlers-alist - '((tmm-menubar . completing-read-default) - (tmm-shortcut . completing-read-default) - (bbdb-create . ivy-completing-read-with-empty-string-def) - (auto-insert . ivy-completing-read-with-empty-string-def) - (Info-on-current-buffer . ivy-completing-read-with-empty-string-def) - (Info-follow-reference . ivy-completing-read-with-empty-string-def) - (Info-menu . ivy-completing-read-with-empty-string-def) - (Info-index . ivy-completing-read-with-empty-string-def) - (Info-virtual-index . ivy-completing-read-with-empty-string-def) - (info-display-manual . ivy-completing-read-with-empty-string-def)) - "An alist of handlers to replace `completing-read' in `ivy-mode'." - :type '(alist :key-type symbol :value-type function)) - -(defcustom ivy-height-alist nil - "An alist to customize `ivy-height'. - -It is a list of (CALLER . HEIGHT). CALLER is a caller of -`ivy-read' and HEIGHT is the number of lines displayed. -HEIGHT can also be a function that returns the number of lines." - :type '(alist - :key-type function - :value-type (choice integer function))) - -(defvar ivy-completing-read-ignore-handlers-depth -1 - "Used to avoid infinite recursion. - -If `(minibuffer-depth)' equals this, `ivy-completing-read' will -act as if `ivy-completing-read-handlers-alist' is empty.") - -(defvar ivy-highlight-grep-commands nil - "List of grep-like commands.") - -(defvar ivy--actions-list nil - "A list of extra actions per command.") - -(defun ivy-set-actions (cmd actions) - "Set CMD extra exit points to ACTIONS." - (setq ivy--actions-list - (plist-put ivy--actions-list cmd actions))) - -(defun ivy-add-actions (cmd actions) - "Add extra exit points ACTIONS to CMD. -Existing exit points of CMD are overwritten by those in -ACTIONS that have the same key." - (setq ivy--actions-list - (plist-put ivy--actions-list cmd - (cl-delete-duplicates - (append (plist-get ivy--actions-list cmd) actions) - :key #'car :test #'equal)))) - -(defun ivy--compute-extra-actions (action caller) - "Add extra actions to ACTION based on CALLER." - (let ((extra-actions (cl-delete-duplicates - (append (plist-get ivy--actions-list t) - (plist-get ivy--actions-list this-command) - (plist-get ivy--actions-list caller)) - :key #'car :test #'equal))) - (if extra-actions - (cond ((functionp action) - `(1 - ("o" ,action "default") - ,@extra-actions)) - ((null action) - `(1 - ("o" identity "default") - ,@extra-actions)) - (t - (delete-dups (append action extra-actions)))) - action))) - -(defvar ivy--prompts-list nil) - -(defun ivy-set-prompt (caller prompt-fn) - "Associate CALLER with PROMPT-FN. -PROMPT-FN is a function of no arguments that returns a prompt string." - (setq ivy--prompts-list - (plist-put ivy--prompts-list caller prompt-fn))) - -(defvar ivy--display-transformers-list nil - "A list of str->str transformers per command.") - -(defun ivy-set-display-transformer (cmd transformer) - "Set CMD a displayed candidate TRANSFORMER. - -It's a lambda that takes a string one of the candidates in the -collection and returns a string for display, the same candidate -plus some extra information. - -This lambda is called only on the `ivy-height' candidates that -are about to be displayed, not on the whole collection." - (setq ivy--display-transformers-list - (plist-put ivy--display-transformers-list cmd transformer))) - -(defvar ivy--sources-list nil - "A list of extra sources per command.") - -(defun ivy-set-sources (cmd sources) - "Attach to CMD a list of extra SOURCES. - -Each static source is a function that takes no argument and -returns a list of strings. - -The (original-source) determines the position of the original -dynamic source. - -Extra dynamic sources aren't supported yet. - -Example: - - (defun small-recentf () - (cl-subseq recentf-list 0 20)) - - (ivy-set-sources - 'counsel-locate - '((small-recentf) - (original-source)))" - (setq ivy--sources-list - (plist-put ivy--sources-list cmd sources))) - -(defun ivy--compute-extra-candidates (caller) - (let ((extra-sources (or (plist-get ivy--sources-list caller) - '((original-source)))) - (result nil)) - (dolist (source extra-sources) - (cond ((equal source '(original-source)) - (push source result)) - ((null (cdr source)) - (push (list (car source) (funcall (car source))) result)))) - result)) - -(defvar ivy-current-prefix-arg nil - "Prefix arg to pass to actions. -This is a global variable that is set by ivy functions for use in -action functions.") - -;;* Keymap -(require 'delsel) -(defvar ivy-minibuffer-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-m") 'ivy-done) - (define-key map [down-mouse-1] 'ignore) - (define-key map [mouse-1] 'ivy-mouse-done) - (define-key map [mouse-3] 'ivy-mouse-dispatching-done) - (define-key map (kbd "C-M-m") 'ivy-call) - (define-key map (kbd "C-j") 'ivy-alt-done) - (define-key map (kbd "C-M-j") 'ivy-immediate-done) - (define-key map (kbd "TAB") 'ivy-partial-or-done) - (define-key map [remap next-line] 'ivy-next-line) - (define-key map [remap previous-line] 'ivy-previous-line) - (define-key map (kbd "C-s") 'ivy-next-line-or-history) - (define-key map (kbd "C-r") 'ivy-reverse-i-search) - (define-key map (kbd "SPC") 'self-insert-command) - (define-key map [remap delete-backward-char] 'ivy-backward-delete-char) - (define-key map [remap backward-delete-char-untabify] 'ivy-backward-delete-char) - (define-key map [remap backward-kill-word] 'ivy-backward-kill-word) - (define-key map [remap delete-char] 'ivy-delete-char) - (define-key map [remap forward-char] 'ivy-forward-char) - (define-key map (kbd "") 'ivy-forward-char) - (define-key map [remap kill-word] 'ivy-kill-word) - (define-key map [remap beginning-of-buffer] 'ivy-beginning-of-buffer) - (define-key map [remap end-of-buffer] 'ivy-end-of-buffer) - (define-key map (kbd "M-n") 'ivy-next-history-element) - (define-key map (kbd "M-p") 'ivy-previous-history-element) - (define-key map (kbd "C-g") 'minibuffer-keyboard-quit) - (define-key map [remap scroll-up-command] 'ivy-scroll-up-command) - (define-key map [remap scroll-down-command] 'ivy-scroll-down-command) - (define-key map (kbd "") 'ivy-scroll-up-command) - (define-key map (kbd "") 'ivy-scroll-down-command) - (define-key map (kbd "C-v") 'ivy-scroll-up-command) - (define-key map (kbd "M-v") 'ivy-scroll-down-command) - (define-key map (kbd "C-M-n") 'ivy-next-line-and-call) - (define-key map (kbd "C-M-p") 'ivy-previous-line-and-call) - (define-key map (kbd "M-r") 'ivy-toggle-regexp-quote) - (define-key map (kbd "M-j") 'ivy-yank-word) - (define-key map (kbd "M-i") 'ivy-insert-current) - (define-key map (kbd "C-M-y") 'ivy-insert-current-full) - (define-key map (kbd "C-o") 'hydra-ivy/body) - (define-key map (kbd "M-o") 'ivy-dispatching-done) - (define-key map (kbd "C-M-o") 'ivy-dispatching-call) - (define-key map [remap kill-line] 'ivy-kill-line) - (define-key map [remap kill-whole-line] 'ivy-kill-whole-line) - (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches) - (define-key map [remap kill-ring-save] 'ivy-kill-ring-save) - (define-key map (kbd "C-'") 'ivy-avy) - (define-key map (kbd "C-M-a") 'ivy-read-action) - (define-key map (kbd "C-c C-o") 'ivy-occur) - (define-key map (kbd "C-c C-a") 'ivy-toggle-ignore) - (define-key map (kbd "C-c C-s") 'ivy-rotate-sort) - (define-key map [remap describe-mode] 'ivy-help) - (define-key map "$" 'ivy-magic-read-file-env) - map) - "Keymap used in the minibuffer.") -(autoload 'hydra-ivy/body "ivy-hydra" "" t) - -(defvar ivy-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [remap switch-to-buffer] - 'ivy-switch-buffer) - (define-key map [remap switch-to-buffer-other-window] - 'ivy-switch-buffer-other-window) - map) - "Keymap for `ivy-mode'.") - -;;* Globals -(cl-defstruct ivy-state - prompt collection - predicate require-match initial-input - history preselect keymap update-fn sort - ;; The frame in which `ivy-read' was called - frame - ;; The window in which `ivy-read' was called - window - ;; The buffer in which `ivy-read' was called - buffer - ;; The value of `ivy-text' to be used by `ivy-occur' - text - action - unwind - re-builder - matcher - ;; When this is non-nil, call it for each input change to get new candidates - dynamic-collection - ;; A lambda that transforms candidates only for display - display-transformer-fn - directory - caller - current - def - ignore - multi-action - extra-props) - -(defvar ivy-last (make-ivy-state) - "The last parameters passed to `ivy-read'. - -This should eventually become a stack so that you could use -`ivy-read' recursively.") - -(defvar ivy-recursive-last nil) - -(defvar ivy-recursive-restore t - "When non-nil, restore the above state when exiting the minibuffer. -This variable is let-bound to nil by functions that take care of -the restoring themselves.") - -(defsubst ivy-set-action (action) - "Set the current `ivy-last' field to ACTION." - (setf (ivy-state-action ivy-last) action)) - -(defvar inhibit-message) - -(defun ivy-thing-at-point () - "Return a string that corresponds to the current thing at point." - (substring-no-properties - (cond - ((use-region-p) - (let* ((beg (region-beginning)) - (end (region-end)) - (eol (save-excursion (goto-char beg) (line-end-position)))) - (buffer-substring-no-properties beg (min end eol)))) - ((thing-at-point 'url)) - ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal) - (let ((inhibit-message t)) - (run-hook-with-args-until-success 'file-name-at-point-functions)))) - ((let ((s (thing-at-point 'symbol))) - (and (stringp s) - (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s) - (match-string 1 s) - s)))) - ((looking-at "(+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>") - (match-string-no-properties 1)) - (t - "")))) - -(defvar ivy-history nil - "History list of candidates entered in the minibuffer. - -Maximum length of the history list is determined by the value -of `history-length'.") - -(defvar ivy--directory nil - "Current directory when completing file names.") - -(defvar ivy--length 0 - "Store the amount of viable candidates.") - -(defvar ivy-text "" - "Store the user's string as it is typed in.") - -(defvar ivy--index 0 - "Store the index of the current candidate.") - -(defvar ivy--window-index 0 - "Store the index of the current candidate in the minibuffer window. - -This means it's between 0 and `ivy-height'.") - -(defvar ivy-exit nil - "Store `done' if the completion was successfully selected. -Otherwise, store nil.") - -(defvar ivy--all-candidates nil - "Store the candidates passed to `ivy-read'.") - -(defvar ivy--extra-candidates '((original-source)) - "Store candidates added by the extra sources. - -This is an internal-use alist. Each key is a function name, or -original-source (which represents where the current dynamic -candidates should go). - -Each value is an evaluation of the function, in case of static -sources. These values will subsequently be filtered on `ivy-text'. - -This variable is set by `ivy-read' and used by `ivy--set-candidates'.") - -(defcustom ivy-use-ignore-default t - "The default policy for user-configured candidate filtering." - :type '(choice - (const :tag "Ignore ignored always" always) - (const :tag "Ignore ignored when others exist" t) - (const :tag "Don't ignore" nil))) - -(defvar ivy-use-ignore t - "Store policy for user-configured candidate filtering. -This may be changed dynamically by `ivy-toggle-ignore'. -Use `ivy-use-ignore-default' for a permanent configuration.") - -(defvar ivy--default nil - "Default initial input.") - -(defvar ivy--prompt nil - "Store the format-style prompt. -When non-nil, it should contain at least one %d.") - -(defvar ivy--prompt-extra "" - "Temporary modifications to the prompt.") - -(defvar ivy--old-re nil - "Store the old regexp. -Either a string or a list for `ivy-re-match'.") - -(defvar ivy--old-cands nil - "Store the candidates matched by `ivy--old-re'.") - -(defvar ivy--regex-function 'ivy--regex - "Current function for building a regex.") - -(defvar ivy--highlight-function 'ivy--highlight-default - "Current function for formatting the candidates.") - -(defvar ivy--subexps 0 - "Number of groups in the current `ivy--regex'.") - -(defvar ivy--full-length nil - "The total amount of candidates when :dynamic-collection is non-nil.") - -(defvar ivy--old-text "" - "Store old `ivy-text' for dynamic completion.") - -(defvar ivy--trying-to-resume-dynamic-collection nil - "Non-nil if resuming from a dynamic collection. -When non-nil, ivy will wait until the first chunk of asynchronous -candidates has been received before selecting the last -preselected candidate.") - -(defun ivy--set-index-dynamic-collection () - (when ivy--trying-to-resume-dynamic-collection - (let ((preselect-index - (ivy--preselect-index (ivy-state-preselect ivy-last) ivy--all-candidates))) - (when preselect-index - (ivy-set-index preselect-index))) - (setq ivy--trying-to-resume-dynamic-collection nil))) - -(defcustom ivy-case-fold-search-default - (if search-upper-case - 'auto - case-fold-search) - "The default value for `case-fold-search' in Ivy operations. -The special value `auto' means case folding is performed so long -as the entire input string comprises lower-case characters. This -corresponds to the default behaviour of most Emacs search -functionality, e.g. as seen in `isearch'." - :link '(info-link "(emacs)Lax Search") - :type '(choice - (const :tag "Auto" auto) - (const :tag "Always" t) - (const :tag "Never" nil))) - -(defvar ivy-case-fold-search ivy-case-fold-search-default - "Store the current overriding `case-fold-search'.") - -(defvar ivy-more-chars-alist - '((t . 3)) - "Map commands to their minimum required input length. -That is the number of characters prompted for before fetching -candidates. The special key t is used as a fallback.") - -(defun ivy-more-chars () - "Return two fake candidates prompting for at least N input. -N is obtained from `ivy-more-chars-alist'." - (let ((diff (- (ivy-alist-setting ivy-more-chars-alist) - (length ivy-text)))) - (when (> diff 0) - (list "" (format "%d chars more" diff))))) - -(defun ivy--case-fold-p (string) - "Return nil if STRING should be matched case-sensitively." - (if (eq ivy-case-fold-search 'auto) - (string= string (downcase string)) - ivy-case-fold-search)) - -(defun ivy--case-fold-string= (s1 s2) - "Like `string=', but obeys `case-fold-search'." - (eq t (compare-strings s1 nil nil s2 nil nil case-fold-search))) - -(eval-and-compile - (unless (fboundp 'defvar-local) - (defmacro defvar-local (var val &optional docstring) - "Define VAR as a buffer-local variable with default value VAL." - (declare (debug defvar) (doc-string 3)) - (list 'progn (list 'defvar var val docstring) - (list 'make-variable-buffer-local (list 'quote var))))) - (unless (fboundp 'setq-local) - (defmacro setq-local (var val) - "Set variable VAR to value VAL in current buffer." - (list 'set (list 'make-local-variable (list 'quote var)) val)))) - -(defmacro ivy-quit-and-run (&rest body) - "Quit the minibuffer and run BODY afterwards." - (declare (indent 0)) - `(progn - (put 'quit 'error-message "") - (run-at-time nil nil - (lambda () - (put 'quit 'error-message "Quit") - (with-demoted-errors "Error: %S" - ,@body))) - (abort-recursive-edit))) - -(defun ivy-exit-with-action (action) - "Quit the minibuffer and call ACTION afterwards." - (ivy-set-action - `(lambda (x) - (funcall ',action x) - (ivy-set-action ',(ivy-state-action ivy-last)))) - (setq ivy-exit 'done) - (exit-minibuffer)) - -(defmacro with-ivy-window (&rest body) - "Execute BODY in the window from which `ivy-read' was called." - (declare (indent 0) - (debug t)) - `(with-selected-window (ivy--get-window ivy-last) - ,@body)) - -(defun ivy--done (text) - "Insert TEXT and exit minibuffer." - (if (member (ivy-state-prompt ivy-last) '("Create directory: " "Make directory: ")) - (ivy-immediate-done) - (if (stringp text) - (insert - (setf (ivy-state-current ivy-last) - (if (and ivy--directory - (not (eq (ivy-state-history ivy-last) 'grep-files-history))) - (expand-file-name text ivy--directory) - text)))) - (setq ivy-exit 'done) - (exit-minibuffer))) - -(defcustom ivy-use-selectable-prompt nil - "When non-nil, make the prompt line selectable like a candidate. - -The prompt line can be selected by calling `ivy-previous-line' when the first -regular candidate is selected. Both actions `ivy-done' and `ivy-alt-done', -when called on a selected prompt, are forwarded to `ivy-immediate-done', which -results to the same as calling `ivy-immediate-done' explicitly when a regular -candidate is selected. - -Note that if `ivy-wrap' is set to t, calling `ivy-previous-line' when the -prompt is selected wraps around to the last candidate, while calling -`ivy-next-line' on the last candidate wraps around to the first -candidate, not the prompt." - :type 'boolean) - -(defvar ivy--use-selectable-prompt nil - "Store the effective `ivy-use-selectable-prompt' for current session.") - -(defun ivy--prompt-selectable-p () - "Return t if the prompt line is selectable." - (and ivy-use-selectable-prompt - (or (memq (ivy-state-require-match ivy-last) - '(nil confirm confirm-after-completion)) - ;; :require-match is t, but "" is in the collection - (let ((coll (ivy-state-collection ivy-last))) - (and (listp coll) - (if (consp (car coll)) - (member '("") coll) - (member "" coll))))))) - -(defun ivy--prompt-selected-p () - "Return t if the prompt line is selected." - (and ivy--use-selectable-prompt - (= ivy--index -1))) - -;;* Commands -(defun ivy-done () - "Exit the minibuffer with the selected candidate." - (interactive) - (if (ivy--prompt-selected-p) - (ivy-immediate-done) - (setq ivy-current-prefix-arg current-prefix-arg) - (delete-minibuffer-contents) - (cond ((or (> ivy--length 0) - ;; the action from `ivy-dispatching-done' may not need a - ;; candidate at all - (eq this-command 'ivy-dispatching-done)) - (ivy--done (ivy-state-current ivy-last))) - ((memq (ivy-state-collection ivy-last) - '(read-file-name-internal internal-complete-buffer)) - (if (or (not (eq confirm-nonexistent-file-or-buffer t)) - (equal " (confirm)" ivy--prompt-extra)) - (ivy--done ivy-text) - (setq ivy--prompt-extra " (confirm)") - (insert ivy-text) - (ivy--exhibit))) - ((memq (ivy-state-require-match ivy-last) - '(nil confirm confirm-after-completion)) - (ivy--done ivy-text)) - (t - (setq ivy--prompt-extra " (match required)") - (insert ivy-text) - (ivy--exhibit))))) - -(defvar ivy-mouse-1-tooltip - "Exit the minibuffer with the selected candidate." - "The doc visible in the tooltip for mouse-1 binding in the minibuffer") -(defvar ivy-mouse-3-tooltip - "Display alternative actions." - "The doc visible in the tooltip for mouse-3 binding in the minibuffer") - -(defun ivy-mouse-offset (event) - "Compute the offset between the candidate at point and the selected one." - (if event - (let* ((line-number-at-point - (max 2 - (line-number-at-pos (posn-point (event-start event))))) - - (line-number-candidate ;; convert to 0 based index - (- line-number-at-point 2)) - (offset - (- line-number-candidate - ivy--window-index))) - offset) - nil)) - -(defun ivy-mouse-done (event) - (interactive "@e") - (let ((offset (ivy-mouse-offset event))) - (when offset - (ivy-next-line offset) - (ivy--exhibit) - (ivy-alt-done)))) - -(defun ivy-mouse-dispatching-done (event) - (interactive "@e") - (let ((offset (ivy-mouse-offset event))) - (when offset - (ivy-next-line offset) - (ivy--exhibit) - (ivy-dispatching-done)))) - -(defvar ivy-read-action-format-function 'ivy-read-action-format-default - "Function used to transform the actions list into a docstring.") - -(defun ivy-read-action-format-default (actions) - "Create a docstring from ACTIONS. - -ACTIONS is a list. Each list item is a list of 3 items: -key (a string), cmd and doc (a string)." - (format "%s\n%s\n" - (if (eq this-command 'ivy-read-action) - "Select action: " - (ivy-state-current ivy-last)) - (mapconcat - (lambda (x) - (format "%s: %s" - (propertize - (car x) - 'face 'ivy-action) - (nth 2 x))) - actions - "\n"))) - -(defcustom ivy-read-action-function #'ivy-read-action-by-key - "Function used to read an action." - :type '(radio - (function-item ivy-read-action-by-key) - (function-item ivy-read-action-ivy) - (function-item ivy-read-action-hydra))) - -(defun ivy-read-action () - "Change the action to one of the available ones. - -Return nil for `minibuffer-keyboard-quit' or wrong key during the -selection, non-nil otherwise." - (interactive) - (let ((actions (ivy-state-action ivy-last))) - (if (not (ivy--actionp actions)) - t - (funcall ivy-read-action-function actions)))) - -(defun ivy-read-action-by-key (actions) - (let* ((hint (funcall ivy-read-action-format-function (cdr actions))) - (resize-mini-windows t) - (key "") - action-idx) - (while (and (setq action-idx (cl-position-if - (lambda (x) - (string-prefix-p key (car x))) - (cdr actions))) - (not (string= key (car (nth action-idx (cdr actions)))))) - (setq key (concat key (string (read-key hint))))) - (ivy-shrink-after-dispatching) - (cond ((member key '("" "")) - nil) - ((null action-idx) - (message "%s is not bound" key) - nil) - (t - (message "") - (setcar actions (1+ action-idx)) - (ivy-set-action actions))))) - -(defun ivy-read-action-ivy (actions) - "Select an action from ACTIONS using Ivy." - (let ((enable-recursive-minibuffers t)) - (if (and (> (minibuffer-depth) 1) - (eq (ivy-state-caller ivy-last) 'ivy-read-action-ivy)) - (minibuffer-keyboard-quit) - (ivy-read (format "action (%s): " (ivy-state-current ivy-last)) - (cl-mapcar - (lambda (a i) (cons (format "[%s] %s" (nth 0 a) (nth 2 a)) i)) - (cdr actions) (number-sequence 1 (length (cdr actions)))) - :action (lambda (a) - (setcar actions (cdr a)) - (ivy-set-action actions)) - :caller 'ivy-read-action-ivy)))) - -(defun ivy-shrink-after-dispatching () - "Shrink the window after dispatching when action list is too large." - (window-resize nil (- ivy-height (window-height)))) - -(defun ivy-dispatching-done () - "Select one of the available actions and call `ivy-done'." - (interactive) - (when (ivy-read-action) - (ivy-done)) - (ivy-shrink-after-dispatching)) - -(defun ivy-dispatching-call () - "Select one of the available actions and call `ivy-call'." - (interactive) - (setq ivy-current-prefix-arg current-prefix-arg) - (let ((actions (copy-sequence (ivy-state-action ivy-last)))) - (unwind-protect - (when (ivy-read-action) - (ivy-call)) - (ivy-set-action actions))) - (ivy-shrink-after-dispatching)) - -(defun ivy-build-tramp-name (x) - "Reconstruct X into a path. -Is is a cons cell, related to `tramp-get-completion-function'." - (let ((user (car x)) - (domain (cadr x))) - (if user - (concat user "@" domain) - domain))) - -(declare-function Info-find-node "info") -(declare-function Info-read-node-name-1 "info") -(declare-function tramp-get-completion-function "tramp") - -(defun ivy-alt-done (&optional arg) - "Exit the minibuffer with the selected candidate. -When ARG is t, exit with current text, ignoring the candidates. -When the current candidate during file name completion is a -directory, continue completion from within that directory instead -of exiting. This function is otherwise like `ivy-done'." - (interactive "P") - (setq ivy-current-prefix-arg current-prefix-arg) - (cond ((or arg - (ivy--prompt-selected-p)) - (ivy-immediate-done)) - (ivy--directory - (ivy--directory-done)) - ((eq (ivy-state-collection ivy-last) #'Info-read-node-name-1) - (if (member (ivy-state-current ivy-last) '("(./)" "(../)")) - (ivy-quit-and-run - (ivy-read "Go to file: " #'read-file-name-internal - :action (lambda (x) - (Info-find-node - (expand-file-name x ivy--directory) - "Top")))) - (ivy-done))) - (t - (ivy-done)))) - -(defvar ivy-auto-select-single-candidate nil - "When non-nil, auto-select the candidate if it is the only one. -When t, it is the same as if the user were prompted and selected the candidate -by calling the default action. This variable has no use unless the collection -contains a single candidate.") - -(defun ivy--directory-enter () - (let (dir) - (when (and - (> ivy--length 0) - (not (string= (ivy-state-current ivy-last) "./")) - (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last)))) - (ivy--cd dir) - (ivy--exhibit)))) - -(defun ivy--handle-directory (input) - "Detect the next directory based on special values of INPUT." - (cond ((string= input "/") - "/") - ((string= input "/sudo::") - (concat input ivy--directory)))) - -(defun ivy--directory-done () - "Handle exit from the minibuffer when completing file names." - (let ((dir (ivy--handle-directory ivy-text))) - (cond - (dir - (let ((inhibit-message t)) - (ivy--cd dir))) - ((ivy--directory-enter)) - ((unless (string= ivy-text "") - (let ((file (expand-file-name - (if (> ivy--length 0) (ivy-state-current ivy-last) ivy-text) - ivy--directory))) - (when (ignore-errors (file-exists-p file)) - (if (file-directory-p file) - (ivy--cd (file-name-as-directory file)) - (ivy-done)) - ivy-text)))) - ((or (and (equal ivy--directory "/") - (string-match-p "\\`[^/]+:.*:.*\\'" ivy-text)) - (string-match-p "\\`/[^/]+:.*:.*\\'" ivy-text)) - (ivy-done)) - ((or (and (equal ivy--directory "/") - (cond ((string-match - "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'" - ivy-text) - (setq ivy-text (ivy-state-current ivy-last))) - ((string-match - "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'" - (ivy-state-current ivy-last)) - (setq ivy-text (ivy-state-current ivy-last))))) - (string-match - "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'" - ivy-text)) - (let ((method (match-string 1 ivy-text)) - (user (match-string 2 ivy-text)) - (rest (match-string 3 ivy-text)) - res) - (dolist (x (tramp-get-completion-function method)) - (setq res (append res (funcall (car x) (cadr x))))) - (setq res (delq nil res)) - (when user - (dolist (x res) - (setcar x user))) - (setq res (delete-dups res)) - (let* ((old-ivy-last ivy-last) - (enable-recursive-minibuffers t) - (host (let ((ivy-auto-select-single-candidate nil)) - (ivy-read "user@host: " - (mapcar #'ivy-build-tramp-name res) - :initial-input rest)))) - (setq ivy-last old-ivy-last) - (when host - (setq ivy--directory "/") - (ivy--cd (concat "/" method ":" host ":")))))) - (t - (ivy-done))))) - -(defun ivy-expand-file-if-directory (file-name) - "Expand FILE-NAME as directory. -When this directory doesn't exist, return nil." - (when (stringp file-name) - (let ((full-name - ;; Ignore host name must not match method "ssh" - (ignore-errors - (file-name-as-directory - (expand-file-name file-name ivy--directory))))) - (when (and full-name (file-directory-p full-name)) - full-name)))) - -(defcustom ivy-tab-space nil - "When non-nil, `ivy-partial-or-done' should insert a space." - :type 'boolean) - -(defun ivy-partial-or-done () - "Complete the minibuffer text as much as possible. -If the text hasn't changed as a result, forward to `ivy-alt-done'." - (interactive) - (cond - ((and completion-cycle-threshold (< (length ivy--all-candidates) completion-cycle-threshold)) - (let ((ivy-wrap t)) - (ivy-next-line))) - ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal) - (or (and (equal ivy--directory "/") - (string-match-p "\\`[^/]+:.*\\'" ivy-text)) - (= (string-to-char ivy-text) ?/))) - (let ((default-directory ivy--directory) - dir) - (minibuffer-complete) - (setq ivy-text (ivy--input)) - (when (setq dir (ivy-expand-file-if-directory ivy-text)) - (ivy--cd dir)))) - (t - (or (ivy-partial) - (when (or (eq this-command last-command) - (eq ivy--length 1)) - (ivy-alt-done)))))) - -(defun ivy--remove-prefix (prefix string) - "Compatibility shim for `string-remove-prefix'." - (if (string-prefix-p prefix string) - (substring string (length prefix)) - string)) - -(defun ivy--partial-cd-for-single-directory () - (when (and - (eq (ivy-state-collection ivy-last) #'read-file-name-internal) - (= 1 (length - (ivy--re-filter - (funcall ivy--regex-function ivy-text) ivy--all-candidates))) - (let ((default-directory ivy--directory)) - (file-directory-p (ivy-state-current ivy-last)))) - (ivy--directory-done))) - -(defun ivy-partial () - "Complete the minibuffer text as much as possible." - (interactive) - (let* ((parts (or (ivy--split-spaces ivy-text) (list ""))) - (tail (last parts)) - (postfix (car tail)) - (case-fold-search (ivy--case-fold-p ivy-text)) - (completion-ignore-case case-fold-search) - (new (try-completion (ivy--remove-prefix "^" postfix) - (if (ivy-state-dynamic-collection ivy-last) - ivy--all-candidates - (mapcar (lambda (str) - (let ((i (string-match-p postfix str))) - (and i (substring str i)))) - ivy--old-cands))))) - (cond ((eq new t) nil) - ((string= new ivy-text) nil) - ((string= (car tail) (car (ivy--split-spaces new))) nil) - (new - (delete-region (minibuffer-prompt-end) (point-max)) - (setcar tail - (if (= (string-to-char postfix) ?^) - (concat "^" new) - new)) - (insert - (setq ivy-text - (concat - (mapconcat #'identity parts " ") - (and ivy-tab-space (not (= (length ivy--old-cands) 1)) " ")))) - (ivy--partial-cd-for-single-directory) - t)))) - -(defvar ivy-completion-beg nil - "Completion bounds start.") - -(defvar ivy-completion-end nil - "Completion bounds end.") - -(defun ivy-immediate-done () - "Exit the minibuffer with current input instead of current candidate." - (interactive) - (delete-minibuffer-contents) - (setf (ivy-state-current ivy-last) - (cond ((or (not ivy--directory) - (eq (ivy-state-history ivy-last) 'grep-files-history)) - ivy-text) - ((and (string= ivy-text "") - (eq (ivy-state-collection ivy-last) - #'read-file-name-internal)) - (if (ivy-state-def ivy-last) - (if (and - (file-exists-p (ivy-state-def ivy-last)) - (/= (length ivy--directory) - (1+ (length (expand-file-name (ivy-state-def ivy-last)))))) - ivy--directory - (copy-sequence (ivy-state-def ivy-last))) - ivy--directory)) - (t - (expand-file-name ivy-text ivy--directory)))) - (insert (ivy-state-current ivy-last)) - (setq ivy-completion-beg ivy-completion-end) - (setq ivy-exit 'done) - (exit-minibuffer)) - -;;;###autoload -(defun ivy-resume () - "Resume the last completion session." - (interactive) - (if (null (ivy-state-action ivy-last)) - (user-error "The last session isn't compatible with `ivy-resume'") - (when (memq (ivy-state-caller ivy-last) - '(swiper swiper-isearch swiper-backward swiper-isearch-backward)) - (switch-to-buffer (ivy-state-buffer ivy-last))) - (with-current-buffer (ivy-state-buffer ivy-last) - (let ((default-directory (ivy-state-directory ivy-last)) - (ivy-use-ignore-default (ivy-state-ignore ivy-last))) - (ivy-read - (ivy-state-prompt ivy-last) - (ivy-state-collection ivy-last) - :predicate (ivy-state-predicate ivy-last) - :require-match (ivy-state-require-match ivy-last) - :initial-input ivy-text - :history (ivy-state-history ivy-last) - :preselect (ivy-state-current ivy-last) - :keymap (ivy-state-keymap ivy-last) - :update-fn (ivy-state-update-fn ivy-last) - :sort (ivy-state-sort ivy-last) - :action (ivy-state-action ivy-last) - :unwind (ivy-state-unwind ivy-last) - :re-builder (ivy-state-re-builder ivy-last) - :matcher (ivy-state-matcher ivy-last) - :dynamic-collection (ivy-state-dynamic-collection ivy-last) - :extra-props (ivy-state-extra-props ivy-last) - :caller (ivy-state-caller ivy-last)))))) - -(defvar-local ivy-calling nil - "When non-nil, call the current action when `ivy--index' changes.") - -(defun ivy-set-index (index) - "Set `ivy--index' to INDEX." - (setq ivy--index index) - (when ivy-calling - (ivy--exhibit) - (ivy-call))) - -(defun ivy-beginning-of-buffer () - "Select the first completion candidate." - (interactive) - (ivy-set-index 0)) - -(defun ivy-end-of-buffer () - "Select the last completion candidate." - (interactive) - (ivy-set-index (1- ivy--length))) - -(defun ivy-scroll-up-command () - "Scroll the candidates upward by the minibuffer height." - (interactive) - (ivy-set-index (min (1- (+ ivy--index ivy-height)) - (1- ivy--length)))) - -(defun ivy-scroll-down-command () - "Scroll the candidates downward by the minibuffer height." - (interactive) - (ivy-set-index (max (1+ (- ivy--index ivy-height)) - 0))) - -(defun ivy-minibuffer-grow () - "Grow the minibuffer window by 1 line." - (interactive) - (setq-local max-mini-window-height - (cl-incf ivy-height))) - -(defun ivy-minibuffer-shrink () - "Shrink the minibuffer window by 1 line." - (interactive) - (when (> ivy-height 2) - (setq-local max-mini-window-height - (cl-decf ivy-height)) - (window-resize nil -1))) - -(defun ivy-next-line (&optional arg) - "Move cursor vertically down ARG candidates." - (interactive "p") - (setq arg (or arg 1)) - (let ((index (+ ivy--index arg))) - (if (> index (1- ivy--length)) - (if ivy-wrap - (ivy-beginning-of-buffer) - (ivy-set-index (1- ivy--length))) - (ivy-set-index index)))) - -(defun ivy-next-line-or-history (&optional arg) - "Move cursor vertically down ARG candidates. -If the input is empty, select the previous history element instead." - (interactive "p") - (if (string= ivy-text "") - (ivy-previous-history-element 1) - (ivy-next-line arg))) - -(defun ivy-previous-line (&optional arg) - "Move cursor vertically up ARG candidates." - (interactive "p") - (setq arg (or arg 1)) - (let ((index (- ivy--index arg)) - (min-index (if ivy--use-selectable-prompt -1 0))) - (if (< index min-index) - (if ivy-wrap - (ivy-end-of-buffer) - (ivy-set-index min-index)) - (ivy-set-index index)))) - -(defun ivy-previous-line-or-history (arg) - "Move cursor vertically up ARG candidates. -If the input is empty, select the previous history element instead." - (interactive "p") - (when (string= ivy-text "") - (ivy-previous-history-element 1)) - (ivy-previous-line arg)) - -(defun ivy-toggle-calling () - "Flip `ivy-calling'." - (interactive) - (when (setq ivy-calling (not ivy-calling)) - (ivy-call))) - -(defun ivy-toggle-ignore () - "Toggle user-configured candidate filtering." - (interactive) - (setq ivy-use-ignore - (if ivy-use-ignore - nil - (or ivy-use-ignore-default t))) - (setf (ivy-state-ignore ivy-last) ivy-use-ignore) - ;; invalidate cache - (setq ivy--old-cands nil)) - -(defun ivy--get-action (state) - "Get the action function from STATE." - (let ((action (ivy-state-action state))) - (when action - (if (functionp action) - action - (cadr (nth (car action) action)))))) - -(defun ivy--get-window (state) - "Get the window from STATE." - (if (ivy-state-p state) - (let ((window (ivy-state-window state))) - (if (window-live-p window) - window - (next-window))) - (selected-window))) - -(defun ivy--actionp (x) - "Return non-nil when X is a list of actions." - (and (consp x) (not (memq (car x) '(closure lambda))))) - -(defcustom ivy-action-wrap nil - "When non-nil, `ivy-next-action' and `ivy-prev-action' wrap." - :type 'boolean) - -(defun ivy-next-action () - "When the current action is a list, scroll it forwards." - (interactive) - (let ((action (ivy-state-action ivy-last))) - (when (ivy--actionp action) - (let ((len (1- (length action))) - (idx (car action))) - (if (>= idx len) - (when ivy-action-wrap - (setf (car action) 1)) - (cl-incf (car action))))))) - -(defun ivy-prev-action () - "When the current action is a list, scroll it backwards." - (interactive) - (let ((action (ivy-state-action ivy-last))) - (when (ivy--actionp action) - (if (<= (car action) 1) - (when ivy-action-wrap - (setf (car action) (1- (length action)))) - (cl-decf (car action)))))) - -(defun ivy-action-name () - "Return the name associated with the current action." - (let ((action (ivy-state-action ivy-last))) - (if (ivy--actionp action) - (format "[%d/%d] %s" - (car action) - (1- (length action)) - (nth 2 (nth (car action) action))) - "[1/1] default"))) - -(defvar ivy-inhibit-action nil - "When non-nil, `ivy-call' does nothing. - -Example use: - - (let* ((ivy-inhibit-action t) - (str (ivy-switch-buffer))) - ;; do whatever with str - the corresponding buffer will not be opened - )") - -(defun ivy-recursive-restore () - "Restore the above state when exiting the minibuffer. -See variable `ivy-recursive-restore' for further information." - (when (and ivy-recursive-last - ivy-recursive-restore - (not (eq ivy-last ivy-recursive-last))) - (ivy--reset-state (setq ivy-last ivy-recursive-last)))) - -(defvar ivy-marked-candidates nil - "List of marked candidates. -Use `ivy-mark' to populate this. - -When this list is non-nil at the end of the session, the action -will be called for each element of this list.") - -(defvar ivy-mark-prefix ">" - "Prefix used by `ivy-mark'.") - -(defun ivy-call () - "Call the current action without exiting completion." - (interactive) - ;; Testing with `ivy-with' seems to call `ivy-call' again, - ;; in which case `this-command' is nil; so check for this. - (unless (memq this-command '(nil - ivy-done - ivy-alt-done - ivy-dispatching-done)) - (setq ivy-current-prefix-arg current-prefix-arg)) - (let ((action - (if (functionp ivy-inhibit-action) - ivy-inhibit-action - (and (not ivy-inhibit-action) - (ivy--get-action ivy-last))))) - (when action - (let* ((collection (ivy-state-collection ivy-last)) - (current (ivy-state-current ivy-last)) - (x (cond - ;; Alist type. - ((and (consp (car-safe collection)) - ;; Previously, the cdr of the selected - ;; candidate would be returned. Now, the - ;; whole candidate is returned. - (let ((idx (get-text-property 0 'idx current))) - (if idx - (nth idx collection) - (assoc current collection))))) - (ivy--directory - (expand-file-name current ivy--directory)) - ((equal current "") - ivy-text) - (t - current)))) - (if (eq action #'identity) - (prog1 x - (ivy-recursive-restore)) - (select-window (ivy--get-window ivy-last)) - (set-buffer (ivy-state-buffer ivy-last)) - (prog1 (unwind-protect - (if ivy-marked-candidates - (let ((prefix-len (length ivy-mark-prefix))) - (setq ivy-marked-candidates - (mapcar (lambda (s) (substring s prefix-len)) - ivy-marked-candidates)) - (if (ivy-state-multi-action ivy-last) - (funcall - (ivy-state-multi-action ivy-last) - ivy-marked-candidates) - (dolist (c ivy-marked-candidates) - (let ((default-directory (ivy-state-directory ivy-last))) - (funcall action c))))) - (funcall action x)) - (ivy-recursive-restore)) - (unless (or (eq ivy-exit 'done) - (minibuffer-window-active-p (selected-window)) - (null (active-minibuffer-window))) - (select-window (active-minibuffer-window))))))))) - -(defun ivy-call-and-recenter () - "Call action and recenter window according to the selected candidate." - (interactive) - (ivy-call) - (with-ivy-window - (recenter-top-bottom))) - -(defun ivy-next-line-and-call (&optional arg) - "Move cursor vertically down ARG candidates. -Call the permanent action if possible." - (interactive "p") - (ivy-next-line arg) - (ivy--exhibit) - (ivy-call)) - -(defun ivy-previous-line-and-call (&optional arg) - "Move cursor vertically up ARG candidates. -Call the permanent action if possible." - (interactive "p") - (ivy-previous-line arg) - (ivy--exhibit) - (ivy-call)) - -(defun ivy-previous-history-element (arg) - "Forward to `previous-history-element' with ARG." - (interactive "p") - (previous-history-element arg) - (ivy--cd-maybe) - (move-end-of-line 1) - (ivy--maybe-scroll-history)) - -(defun ivy--insert-symbol-boundaries () - (undo-boundary) - (beginning-of-line) - (insert "\\_<") - (end-of-line) - (insert "\\_>")) - -(defun ivy-next-history-element (arg) - "Forward to `next-history-element' with ARG." - (interactive "p") - (if (and (= minibuffer-history-position 0) - (equal ivy-text "")) - (progn - (when minibuffer-default - (setq ivy--default (car minibuffer-default))) - (insert ivy--default) - (when (and (with-ivy-window (derived-mode-p 'prog-mode)) - (eq (ivy-state-caller ivy-last) 'swiper) - (not (file-exists-p ivy--default)) - (not (ivy-ffap-url-p ivy--default)) - (not (ivy-state-dynamic-collection ivy-last)) - (> (point) (minibuffer-prompt-end))) - (ivy--insert-symbol-boundaries))) - (next-history-element arg)) - (ivy--cd-maybe) - (move-end-of-line 1) - (ivy--maybe-scroll-history)) - -(defvar ivy-ffap-url-functions nil - "List of functions that check if the point is on a URL.") - -(defun ivy--cd-maybe () - "Check if the current input points to a different directory. -If so, move to that directory, while keeping only the file name." - (when ivy--directory - (let ((input (ivy--input)) - url) - (if (setq url (or (ivy-ffap-url-p input) - (with-ivy-window - (cl-reduce - (lambda (a b) - (or a (funcall b))) - ivy-ffap-url-functions - :initial-value nil)))) - (ivy-exit-with-action - (lambda (_) - (ivy-ffap-url-fetcher url))) - (setq input (expand-file-name input)) - (let ((file (file-name-nondirectory input)) - (dir (expand-file-name (file-name-directory input)))) - (if (string= dir ivy--directory) - (progn - (delete-minibuffer-contents) - (insert file)) - (ivy--cd dir) - (insert file))))))) - -(defun ivy--maybe-scroll-history () - "If the selected history element has an index, scroll there." - (let ((idx (ignore-errors - (get-text-property - (minibuffer-prompt-end) - 'ivy-index)))) - (when idx - (ivy--exhibit) - (ivy-set-index idx)))) - -(declare-function tramp-get-completion-methods "tramp") - -(defun ivy--cd (dir) - "When completing file names, move to directory DIR." - (if (null ivy--directory) - (error "Unexpected") - (setq ivy--old-cands nil) - (setq ivy--old-re nil) - (ivy-set-index 0) - (setq ivy--all-candidates - (append - (ivy--sorted-files (setq ivy--directory dir)) - (when (and (string= dir "/") (featurep 'tramp)) - (sort - (mapcar - (lambda (s) (substring s 1)) - (tramp-get-completion-methods "")) - #'string<)))) - (setq ivy-text "") - (setf (ivy-state-directory ivy-last) dir) - (delete-minibuffer-contents))) - -(defun ivy--parent-dir (filename) - "Return parent directory of absolute FILENAME." - (file-name-directory (directory-file-name filename))) - -(defun ivy-backward-delete-char () - "Forward to `delete-backward-char'. -Call `ivy-on-del-error-function' if an error occurs, usually when -there is no more text to delete at the beginning of the -minibuffer." - (interactive) - (if (and ivy--directory (= (minibuffer-prompt-end) (point))) - (progn - (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory))) - (ivy--exhibit)) - (setq prefix-arg current-prefix-arg) - (condition-case nil - (call-interactively #'delete-backward-char) - (error - (when ivy-on-del-error-function - (funcall ivy-on-del-error-function)))))) - -(defun ivy-delete-char (arg) - "Forward to `delete-char' ARG." - (interactive "p") - (unless (eolp) - (delete-char arg))) - -(defun ivy-forward-char (arg) - "Forward to `forward-char' ARG." - (interactive "p") - (unless (eolp) - (forward-char arg))) - -(defun ivy-kill-word (arg) - "Forward to `kill-word' ARG." - (interactive "p") - (unless (eolp) - (kill-word arg))) - -(defun ivy-kill-line () - "Forward to `kill-line'." - (interactive) - (if (eolp) - (kill-region (minibuffer-prompt-end) (point)) - (kill-line))) - -(defun ivy-kill-whole-line () - "Forward to `kill-whole-line'." - (interactive) - (kill-region (minibuffer-prompt-end) (line-end-position))) - -(defun ivy-backward-kill-word () - "Forward to `backward-kill-word'." - (interactive) - (if (and ivy--directory (= (minibuffer-prompt-end) (point))) - (progn - (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory))) - (ivy--exhibit)) - (ignore-errors - (let ((pt (point))) - (forward-word -1) - (delete-region (point) pt))))) - -(defvar ivy--regexp-quote #'regexp-quote - "Store the regexp quoting state.") - -(defun ivy-toggle-regexp-quote () - "Toggle the regexp quoting." - (interactive) - (setq ivy--old-re nil) - (cl-rotatef ivy--regex-function ivy--regexp-quote)) - -(defvar avy-all-windows) -(defvar avy-action) -(defvar avy-keys) -(defvar avy-keys-alist) -(defvar avy-style) -(defvar avy-styles-alist) -(declare-function avy-process "ext:avy") -(declare-function avy--style-fn "ext:avy") - -(defcustom ivy-format-functions-alist - '((t . ivy-format-function-default)) - "An alist of functions that transform the list of candidates into a string. -This string is inserted into the minibuffer." - :type '(alist - :key-type symbol - :value-type - (choice - (const :tag "Default" ivy-format-function-default) - (const :tag "Arrow prefix" ivy-format-function-arrow) - (const :tag "Full line" ivy-format-function-line) - (function :tag "Custom function")))) - -(eval-after-load 'avy - '(add-to-list 'avy-styles-alist '(ivy-avy . pre))) - -(defun ivy--avy-candidates () - (let (candidates) - (save-excursion - (save-restriction - (narrow-to-region - (window-start) - (window-end)) - (goto-char (point-min)) - (forward-line) - (while (< (point) (point-max)) - (push - (cons (point) - (selected-window)) - candidates) - (forward-line)))) - (nreverse candidates))) - -(defun ivy--avy-action (pt) - (when (number-or-marker-p pt) - (let ((bnd (ivy--minibuffer-index-bounds - ivy--index ivy--length ivy-height))) - (ivy--done - (substring-no-properties - (nth (+ (car bnd) (- (line-number-at-pos pt) 2)) ivy--old-cands)))))) - -(defun ivy--avy-handler-function (char) - (let (cmd) - (cond ((memq char '(27 ?\C-g)) - ;; exit silently - (throw 'done 'abort)) - ((memq (setq cmd (lookup-key ivy-minibuffer-map (vector char))) - '(ivy-scroll-up-command - ivy-scroll-down-command)) - (funcall cmd) - (ivy--exhibit) - (throw 'done 'exit)) - ;; ignore wrong key - (t - (throw 'done 'restart))))) - -(defvar avy-handler-function) - -(defun ivy-avy () - "Jump to one of the current ivy candidates." - (interactive) - (unless (require 'avy nil 'noerror) - (error "Package avy isn't installed")) - (let* ((avy-all-windows nil) - (avy-keys (or (cdr (assq 'ivy-avy avy-keys-alist)) - avy-keys)) - (avy-style (or (cdr (assq 'ivy-avy avy-styles-alist)) - avy-style)) - (avy-action #'identity) - (avy-handler-function #'ivy--avy-handler-function) - res) - (while (eq (setq res (avy-process (ivy--avy-candidates))) t)) - (when res - (ivy--avy-action res)))) - -(defun ivy-sort-file-function-default (x y) - "Compare two files X and Y. -Prioritize directories." - (if (get-text-property 0 'dirp x) - (if (get-text-property 0 'dirp y) - (string< (directory-file-name x) (directory-file-name y)) - t) - (if (get-text-property 0 'dirp y) - nil - (string< x y)))) - -(defun ivy-string< (x y) - "Like `string<', but operate on CARs when given cons cells." - (string< (if (consp x) (car x) x) - (if (consp y) (car y) y))) - -(define-obsolete-function-alias 'ivy-sort-file-function-using-ido - 'ido-file-extension-lessp "<2019-10-12 Sat>") - -(defcustom ivy-sort-functions-alist - '((t . ivy-string<)) - "An alist of sorting functions for each collection function. -Interactive functions that call completion fit in here as well. - -Nil means no sorting, which is useful to turn off the sorting for -functions that have candidates in the natural buffer order, like -`org-refile' or `Man-goto-section'. - -A list can be used to associate multiple sorting functions with a -collection. The car of the list is the current sort -function. This list can be rotated with `ivy-rotate-sort'. - -The entry associated with t is used for all fall-through cases. - -See also `ivy-sort-max-size'." - :type - '(alist - :key-type (choice - (const :tag "Fall-through" t) - (symbol :tag "Collection")) - :value-type (choice - (const :tag "Plain sort" string-lessp) - (const :tag "File sort" ivy-sort-file-function-default) - (const :tag "File sort using Ido" ido-file-extension-lessp) - (const :tag "No sort" nil) - (function :tag "Custom function") - (repeat (function :tag "Custom function"))))) - -(defun ivy--sort-function (collection) - "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'." - (let ((entry (cdr (or (assq collection ivy-sort-functions-alist) - (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist) - (assq t ivy-sort-functions-alist))))) - (and (or (functionp entry) - (functionp (setq entry (car-safe entry)))) - entry))) - -(defun ivy-rotate-sort () - "Rotate through sorting functions available for current collection. -This only has an effect if multiple sorting functions are -specified for the current collection in -`ivy-sort-functions-alist'." - (interactive) - (let ((cell (or (assq (ivy-state-collection ivy-last) ivy-sort-functions-alist) - (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)))) - (when (consp (cdr cell)) - (setcdr cell (nconc (cddr cell) (list (cadr cell)))) - (ivy--reset-state ivy-last)))) - -(defvar ivy-index-functions-alist - '((t . ivy-recompute-index-zero)) - "An alist of index recomputing functions for each collection function. -When the input changes, the appropriate function returns an -integer - the index of the matched candidate that should be -selected.") - -(defvar ivy-re-builders-alist - '((t . ivy--regex-plus)) - "An alist of regex building functions for each collection function. - -Each key is (in order of priority): -1. The actual collection function, e.g. `read-file-name-internal'. -2. The symbol passed by :caller into `ivy-read'. -3. `this-command'. -4. t. - -Each value is a function that should take a string and return a -valid regex or a regex sequence (see below). - -Possible choices: `ivy--regex', `regexp-quote', -`ivy--regex-plus', `ivy--regex-fuzzy', `ivy--regex-ignore-order'. - -If a function returns a list, it should format like this: -'((\"matching-regexp\" . t) (\"non-matching-regexp\") ...). - -The matches will be filtered in a sequence, you can mix the -regexps that should match and that should not match as you -like.") - -(defvar ivy-highlight-functions-alist - '((ivy--regex-ignore-order . ivy--highlight-ignore-order) - (ivy--regex-fuzzy . ivy--highlight-fuzzy) - (ivy--regex-plus . ivy--highlight-default)) - "An alist of highlighting functions for each regex builder function.") - -(defcustom ivy-initial-inputs-alist - '((org-refile . "^") - (org-agenda-refile . "^") - (org-capture-refile . "^") - (Man-completion-table . "^") - (woman . "^")) - "An alist associating commands with their initial input. - -Each cdr is either a string or a function called in the context -of a call to `ivy-read'." - :type '(alist - :key-type (symbol) - :value-type (choice (string) (function)))) - -(defcustom ivy-hooks-alist nil - "An alist associating commands to setup functions. -Examples: `toggle-input-method', (lambda () (insert \"^\")), etc. -May supersede `ivy-initial-inputs-alist'." - :type '(alist :key-type symbol :value-type function)) - -(defvar ivy--occurs-list nil - "A list of custom occur generators per command.") - -(defun ivy-set-occur (cmd occur) - "Assign CMD a custom OCCUR function." - (setq ivy--occurs-list - (plist-put ivy--occurs-list cmd occur))) - -(defcustom ivy-update-fns-alist nil - "An alist associating commands to their :update-fn values." - :type '(alist - :key-type symbol - :value-type - (radio - (const :tag "Off" nil) - (const :tag "Call action on change" auto)))) - -(defvar ivy-unwind-fns-alist nil - "An alist associating commands to their :unwind values.") - -(defun ivy--alist-set (alist-sym key val) - (let ((cell (assoc key (symbol-value alist-sym)))) - (if cell - (setcdr cell val) - (set alist-sym (cons (cons key val) - (symbol-value alist-sym)))))) - -(declare-function counsel-set-async-exit-code "counsel") - -(cl-defun ivy-configure (caller - &key - initial-input - height - occur - update-fn - unwind-fn - index-fn - sort-fn - format-fn - display-transformer-fn - more-chars - grep-p - exit-codes) - "Configure `ivy-read' params for CALLER." - (declare (indent 1)) - (when initial-input - (ivy--alist-set 'ivy-initial-inputs-alist caller initial-input)) - (when height - (ivy--alist-set 'ivy-height-alist caller height)) - (when occur - (ivy-set-occur caller occur)) - (when update-fn - (ivy--alist-set 'ivy-update-fns-alist caller update-fn)) - (when unwind-fn - (ivy--alist-set 'ivy-unwind-fns-alist caller unwind-fn)) - (when index-fn - (ivy--alist-set 'ivy-index-functions-alist caller index-fn)) - (when sort-fn - (ivy--alist-set 'ivy-sort-functions-alist caller sort-fn)) - (when format-fn - (ivy--alist-set 'ivy-format-functions-alist caller format-fn)) - (when display-transformer-fn - (ivy-set-display-transformer caller display-transformer-fn)) - (when more-chars - (ivy--alist-set 'ivy-more-chars-alist caller more-chars)) - (when grep-p - (cl-pushnew caller ivy-highlight-grep-commands)) - (when exit-codes - (let (code msg) - (while (and (setq code (pop exit-codes)) - (setq msg (pop exit-codes))) - (counsel-set-async-exit-code caller code msg))))) - -(defcustom ivy-sort-max-size 30000 - "Sorting won't be done for collections larger than this." - :type 'integer) - -(defalias 'ivy--dirname-p - (if (fboundp 'directory-name-p) - #'directory-name-p - (lambda (name) - "Return non-nil if NAME ends with a directory separator." - (string-match-p "/\\'" name)))) - -(defun ivy--sorted-files (dir) - "Return the list of files in DIR. -Directories come first." - (let* ((default-directory dir) - (seq (condition-case nil - (mapcar (lambda (s) (replace-regexp-in-string "\\$\\$" "$" s)) - (all-completions "" #'read-file-name-internal - (ivy-state-predicate ivy-last))) - (error - (directory-files dir)))) - sort-fn) - (setq seq (delete "./" (delete "../" seq))) - (when (eq (setq sort-fn (ivy--sort-function #'read-file-name-internal)) - #'ivy-sort-file-function-default) - (setq seq (mapcar (lambda (x) - (propertize x 'dirp (ivy--dirname-p x))) - seq))) - (when sort-fn - (setq seq (sort seq sort-fn))) - (dolist (dir ivy-extra-directories) - (push dir seq)) - (if (string= dir "/") - (cl-remove-if (lambda (s) (string-match ":$" s)) (delete "../" seq)) - seq))) - -(defun ivy-alist-setting (alist &optional key) - "Return the value associated with KEY in ALIST, using `assq'. -KEY defaults to the last caller of `ivy-read'; if no entry is -found, it falls back to the key t." - (cdr (or (let ((caller (or key (ivy-state-caller ivy-last)))) - (and caller (assq caller alist))) - (assq t alist)))) - -(defun ivy--height (caller) - (let ((v (or (ivy-alist-setting ivy-height-alist caller) - ivy-height))) - (if (integerp v) - v - (if (functionp v) - (funcall v caller) - (error "Unexpected value: %S" v))))) - -(defun ivy--remove-props (str &rest props) - "Return STR with text PROPS destructively removed." - (ignore-errors - (remove-list-of-text-properties 0 (length str) props str)) - str) - -;;** Entry Point -;;;###autoload -(cl-defun ivy-read (prompt collection - &key - predicate require-match initial-input - history preselect def keymap update-fn sort - action multi-action - unwind re-builder matcher - dynamic-collection - extra-props - caller) - "Read a string in the minibuffer, with completion. - -PROMPT is a string, normally ending in a colon and a space. -`ivy-count-format' is prepended to PROMPT during completion. - -COLLECTION is either a list of strings, a function, an alist, or -a hash table, supplied for `minibuffer-completion-table'. - -PREDICATE is applied to filter out the COLLECTION immediately. -This argument is for compatibility with `completing-read'. - -When REQUIRE-MATCH is non-nil, only members of COLLECTION can be -selected. - -If INITIAL-INPUT is non-nil, then insert that input in the -minibuffer initially. - -HISTORY is a name of a variable to hold the completion session -history. - -KEYMAP is composed with `ivy-minibuffer-map'. - -PRESELECT, when non-nil, determines which one of the candidates -matching INITIAL-INPUT to select initially. An integer stands -for the position of the desired candidate in the collection, -counting from zero. Otherwise, use the first occurrence of -PRESELECT in the collection. Comparison is first done with -`equal'. If that fails, and when applicable, match PRESELECT as -a regular expression. - -DEF is for compatibility with `completing-read'. - -UPDATE-FN is called each time the candidate list is re-displayed. - -When SORT is non-nil, `ivy-sort-functions-alist' determines how -to sort candidates before displaying them. - -ACTION is a function to call after selecting a candidate. -It takes one argument, the selected candidate. If COLLECTION is -an alist, the argument is a cons cell, otherwise it's a string. - -MULTI-ACTION, when non-nil, is called instead of ACTION when -there are marked candidates. It takes the list of candidates as -its only argument. When it's nil, ACTION is called on each marked -candidate. - -UNWIND is a function of no arguments to call before exiting. - -RE-BUILDER is a function transforming input text into a regex -pattern. - -MATCHER is a function which can override how candidates are -filtered based on user input. It takes a regex pattern and a -list of candidates, and returns the list of matching candidates. - -DYNAMIC-COLLECTION is a boolean specifying whether the list of -candidates is updated after each input by calling COLLECTION. - -EXTRA-PROPS can be used to store collection-specific -session-specific data. - -CALLER is a symbol to uniquely identify the caller to `ivy-read'. -It is used, along with COLLECTION, to determine which -customizations apply to the current completion session." - ;; get un-stuck from an existing `read-key' overriding minibuffer keys - (when (equal overriding-local-map '(keymap)) - (keyboard-quit)) - (setq caller (or caller this-command)) - (let* ((ivy-recursive-last (and (active-minibuffer-window) ivy-last)) - (ivy--display-function - (when (or ivy-recursive-last - (not (window-minibuffer-p))) - (ivy-alist-setting ivy-display-functions-alist caller))) - result) - (setq update-fn (or update-fn (ivy-alist-setting ivy-update-fns-alist caller))) - (setq unwind (or unwind (ivy-alist-setting ivy-unwind-fns-alist caller))) - (setq ivy-last - (make-ivy-state - :prompt prompt - :collection collection - :predicate predicate - :require-match require-match - :initial-input initial-input - :history history - :preselect preselect - :keymap keymap - :update-fn (if (eq update-fn 'auto) - (lambda () - (with-ivy-window - (funcall - (ivy--get-action ivy-last) - (if (consp (car-safe (ivy-state-collection ivy-last))) - (assoc (ivy-state-current ivy-last) - (ivy-state-collection ivy-last)) - (ivy-state-current ivy-last))))) - update-fn) - :sort sort - :action (ivy--compute-extra-actions action caller) - :multi-action multi-action - :frame (selected-frame) - :window (selected-window) - :buffer (current-buffer) - :unwind unwind - :re-builder re-builder - :matcher matcher - :dynamic-collection dynamic-collection - :display-transformer-fn (plist-get ivy--display-transformers-list caller) - :directory default-directory - :extra-props extra-props - :caller caller - :def def)) - (ivy--reset-state ivy-last) - (unwind-protect - (minibuffer-with-setup-hook - #'ivy--minibuffer-setup - (let* ((hist (or history 'ivy-history)) - (minibuffer-completion-table collection) - (minibuffer-completion-predicate predicate) - (ivy-height (ivy--height caller)) - (resize-mini-windows (unless (display-graphic-p) - 'grow-only))) - (if (and ivy-auto-select-single-candidate - ivy--all-candidates - (null (cdr ivy--all-candidates))) - (progn - (setf (ivy-state-current ivy-last) - (car ivy--all-candidates)) - (setq ivy-exit 'done)) - (read-from-minibuffer - prompt - (ivy-state-initial-input ivy-last) - (make-composed-keymap keymap ivy-minibuffer-map) - nil - hist)) - (when (eq ivy-exit 'done) - (let ((item (if ivy--directory - (ivy-state-current ivy-last) - ivy-text))) - (unless (equal item "") - (set hist (cons (propertize item 'ivy-index ivy--index) - (delete item - (cdr (symbol-value hist)))))))) - (setq result (ivy-state-current ivy-last)))) - (ivy--cleanup)) - (ivy-call) - (ivy--remove-props (ivy-state-current ivy-last) 'idx) - result)) - -(defun ivy--cleanup () - ;; Fixes a bug in ESS, #1660 - (put 'post-command-hook 'permanent-local nil) - (remove-hook 'post-command-hook #'ivy--queue-exhibit) - (let ((cleanup (ivy--display-function-prop :cleanup)) - (unwind (ivy-state-unwind ivy-last))) - (when (functionp cleanup) - (funcall cleanup)) - (when unwind - (funcall unwind))) - (ivy--pulse-cleanup) - (unless (eq ivy-exit 'done) - (ivy-recursive-restore))) - -(defun ivy--display-function-prop (prop) - "Return PROP associated with current `ivy--display-function'." - (plist-get (cdr (assq ivy--display-function - ivy-display-functions-props)) - prop)) - -(defvar Info-complete-menu-buffer) - -(defun ivy--reset-state (state) - "Reset the ivy to STATE. -This is useful for recursive `ivy-read'." - (setq ivy-marked-candidates nil) - (unless (equal (selected-frame) (ivy-state-frame state)) - (select-window (active-minibuffer-window))) - (let* ((prompt (or (ivy-state-prompt state) "")) - (collection (ivy-state-collection state)) - (predicate (ivy-state-predicate state)) - (history (ivy-state-history state)) - (preselect (ivy-state-preselect state)) - (re-builder (ivy-state-re-builder state)) - (dynamic-collection (ivy-state-dynamic-collection state)) - (require-match (ivy-state-require-match state)) - (caller (or (ivy-state-caller state) this-command)) - (sort (or (ivy-state-sort state) (assoc caller ivy-sort-functions-alist))) - (initial-input - (or (ivy-state-initial-input state) - (let ((init (cdr (assq caller ivy-initial-inputs-alist)))) - (cond ((functionp init) - (funcall init)) - (t - init))))) - (def (ivy-state-def state))) - (setq ivy--extra-candidates (ivy--compute-extra-candidates caller)) - (setq ivy--directory nil) - (setq ivy-case-fold-search ivy-case-fold-search-default) - (setq ivy--regex-function - (or re-builder - (and (functionp collection) - (cdr (assq collection ivy-re-builders-alist))) - (ivy-alist-setting ivy-re-builders-alist) - #'ivy--regex)) - (setq ivy--subexps 0) - (setq ivy--regexp-quote #'regexp-quote) - (setq ivy--old-text "") - (setq ivy--full-length nil) - (setq ivy-text "") - (setq ivy--index 0) - (setq ivy-calling nil) - (setq ivy-use-ignore ivy-use-ignore-default) - (setf (ivy-state-ignore state) ivy-use-ignore) - (setq ivy--highlight-function - (or (cdr (assq ivy--regex-function ivy-highlight-functions-alist)) - #'ivy--highlight-default)) - (let (coll sort-fn) - (cond ((eq collection #'Info-read-node-name-1) - (setq coll - (if (equal (bound-and-true-p Info-current-file) "dir") - (mapcar (lambda (x) (format "(%s)" x)) - (delete-dups - (all-completions "(" collection predicate))) - (all-completions "" collection predicate)))) - ((eq collection #'read-file-name-internal) - (require 'tramp) - (when (and (equal def initial-input) - (member "./" ivy-extra-directories)) - (setq def nil)) - (setq ivy--directory default-directory) - (when (and initial-input - (not (equal initial-input ""))) - (cond ((file-directory-p initial-input) - (when (equal (file-name-nondirectory initial-input) "") - (setf (ivy-state-preselect state) (setq preselect nil)) - (setq def nil)) - (setq ivy--directory (file-name-as-directory initial-input)) - (setq initial-input nil) - (when preselect - (let ((preselect-directory - (file-name-directory preselect))) - (when (and preselect-directory - (not (equal - (expand-file-name - preselect-directory) - (expand-file-name ivy--directory)))) - (setf (ivy-state-preselect state) - (setq preselect nil)))))) - ((ignore-errors - (file-exists-p (file-name-directory initial-input))) - (setq ivy--directory (file-name-directory initial-input)) - (setf (ivy-state-preselect state) - (file-name-nondirectory initial-input))))) - (require 'dired) - (when preselect - (let ((preselect-directory (ivy--parent-dir preselect))) - (when (and preselect-directory - (not (string= preselect-directory - default-directory))) - (setq ivy--directory preselect-directory)) - (setq preselect (file-relative-name preselect - preselect-directory)) - (setf (ivy-state-preselect state) preselect))) - (setq sort nil) - (setq coll (ivy--sorted-files ivy--directory)) - (when initial-input - (unless (or require-match - (equal initial-input default-directory) - (equal initial-input "")) - (setq coll (cons initial-input coll))) - (when (or (not (ivy-state-action ivy-last)) - (equal (ivy--get-action ivy-last) 'identity)) - (setq initial-input nil)))) - ((eq collection #'internal-complete-buffer) - (setq prompt - (replace-regexp-in-string "RET to end" "C-M-j to end" prompt)) - (setq coll (ivy--buffer-list - "" - (and ivy-use-virtual-buffers - (member caller '(ivy-switch-buffer - ivy-switch-buffer-other-window - counsel-switch-buffer))) - predicate))) - (dynamic-collection - (setq coll (funcall collection (or initial-input "")))) - ((consp (car-safe collection)) - (setq collection (cl-remove-if-not predicate collection)) - (when (and sort (setq sort-fn (ivy--sort-function caller))) - (setq collection (sort (copy-sequence collection) sort-fn)) - (setq sort nil)) - (setf (ivy-state-collection ivy-last) collection) - (setq coll (let ((i -1)) - (mapcar (lambda (x) - (propertize x 'idx (cl-incf i))) - (all-completions "" collection))))) - ((or (functionp collection) - (byte-code-function-p collection) - (vectorp collection) - (hash-table-p collection) - (and (listp collection) (symbolp (car collection)))) - (let ((Info-complete-menu-buffer - ;; FIXME: This is a temporary workaround for issue #1803. - (or (bound-and-true-p Info-complete-menu-buffer) - (ivy-state-buffer state)))) - (setq coll (all-completions "" collection predicate)))) - (t - (setq coll (all-completions "" collection predicate)))) - (unless (ivy-state-dynamic-collection ivy-last) - (setq coll (delete "" coll))) - (when def - (cond ((stringp (car-safe def)) - (setq coll (cl-union def coll :test #'equal))) - ((and (stringp def) (not (member def coll))) - (push def coll)))) - (when (and sort - (or (functionp collection) - (not (eq history 'org-refile-history))) - (setq sort-fn (ivy--sort-function - (if (functionp collection) collection caller))) - (null (nthcdr ivy-sort-max-size coll))) - (setq coll (sort (copy-sequence coll) sort-fn))) - (setq coll (ivy--set-candidates coll)) - (setq ivy--old-re nil) - (setq ivy--old-cands nil) - (when initial-input - ;; Needed for anchor to work - (setq ivy--old-cands coll) - (setq ivy--old-cands (ivy--filter initial-input coll))) - (unless (setq ivy--trying-to-resume-dynamic-collection - (and preselect dynamic-collection)) - (when (integerp preselect) - (setq ivy--old-re "") - (ivy-set-index preselect))) - (setq ivy--all-candidates coll) - (unless (integerp preselect) - (ivy-set-index (or - (and dynamic-collection - ivy--index) - (and preselect - (ivy--preselect-index - preselect - (if initial-input - ivy--old-cands - coll))) - 0)))) - (setq ivy-exit nil) - (setq ivy--default - (if (region-active-p) - (buffer-substring (region-beginning) (region-end)) - (ivy-thing-at-point))) - (setq ivy--prompt (ivy-add-prompt-count (ivy--quote-format-string prompt))) - (setq ivy--use-selectable-prompt (ivy--prompt-selectable-p)) - (setf (ivy-state-initial-input ivy-last) initial-input))) - -(defun ivy-add-prompt-count (prompt) - "Add count information to PROMPT." - (cond ((null ivy-count-format) - (error - "`ivy-count-format' can't be nil. Set it to \"\" instead")) - ((string-match "%d.*\\(%d\\)" ivy-count-format) - (let* ((w (1+ (floor (log (max 1 (length ivy--all-candidates)) 10)))) - (s (replace-match (format "%%-%dd" w) t t ivy-count-format 1))) - (string-match "%d" s) - (concat (replace-match (format "%%%dd" w) t t s) - prompt))) - ((string-match-p "%.*d" ivy-count-format) - (concat ivy-count-format prompt)) - (ivy--directory - prompt) - (t - prompt))) - -(defun ivy--quote-format-string (str) - "Make STR suitable for `format' with no extra arguments." - (replace-regexp-in-string "%" "%%" str t t)) - -;;;###autoload -(defun ivy-completing-read (prompt collection - &optional predicate require-match initial-input - history def inherit-input-method) - "Read a string in the minibuffer, with completion. - -This interface conforms to `completing-read' and can be used for -`completing-read-function'. - -PROMPT is a string that normally ends in a colon and a space. -COLLECTION is either a list of strings, an alist, an obarray, or a hash table. -PREDICATE limits completion to a subset of COLLECTION. -REQUIRE-MATCH is a boolean value. See `completing-read'. -INITIAL-INPUT is a string inserted into the minibuffer initially. -HISTORY is a list of previously selected inputs. -DEF is the default value. -INHERIT-INPUT-METHOD is currently ignored." - (let ((handler - (and (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth)) - (assq this-command ivy-completing-read-handlers-alist)))) - (if handler - (let ((completion-in-region-function #'completion--in-region) - (ivy-completing-read-ignore-handlers-depth (1+ (minibuffer-depth)))) - (funcall (cdr handler) - prompt collection - predicate require-match - initial-input history - def inherit-input-method)) - ;; See the doc of `completing-read'. - (when (consp history) - (when (numberp (cdr history)) - (setq initial-input (nth (1- (cdr history)) - (symbol-value (car history))))) - (setq history (car history))) - (when (consp def) - (setq def (car def))) - (let ((str (ivy-read - prompt collection - :predicate predicate - :require-match (and collection require-match) - :initial-input (cond ((consp initial-input) - (car initial-input)) - ((and (stringp initial-input) - (not (eq collection #'read-file-name-internal)) - (string-match-p "\\+" initial-input)) - (replace-regexp-in-string - "\\+" "\\\\+" initial-input)) - (t - initial-input)) - :preselect def - :def def - :history history - :keymap nil - :dynamic-collection ivy-completing-read-dynamic-collection - :caller (if (and collection (symbolp collection)) - collection - this-command)))) - (if (string= str "") - ;; For `completing-read' compat, return the first element of - ;; DEFAULT, if it is a list; "", if DEFAULT is nil; or DEFAULT. - (or def "") - str))))) - -(defun ivy-completing-read-with-empty-string-def - (prompt collection - &optional predicate require-match initial-input - history def inherit-input-method) - "Same as `ivy-completing-read' but with different handling of DEF. - -Specifically, if DEF is nil, it is treated the same as if DEF was -the empty string. This mimics the behavior of -`completing-read-default'. This function can therefore be used in -place of `ivy-completing-read' for commands that rely on this -behavior." - (ivy-completing-read - prompt collection predicate require-match initial-input - history (or def "") inherit-input-method)) - -(declare-function mc/all-fake-cursors "ext:multiple-cursors-core") - -(defun ivy-completion-in-region-action (str) - "Insert STR, erasing the previous one. -The previous string is between `ivy-completion-beg' and `ivy-completion-end'." - (when (consp str) - (setq str (cdr str))) - (when (stringp str) - (let ((fake-cursors (and (require 'multiple-cursors-core nil t) - (mc/all-fake-cursors))) - (pt (point)) - (beg ivy-completion-beg) - (end ivy-completion-end)) - (when beg - (delete-region beg end)) - (setq ivy-completion-beg (point)) - (insert (substring-no-properties str)) - (completion--done str 'exact) - (setq ivy-completion-end (point)) - (save-excursion - (dolist (cursor fake-cursors) - (goto-char (overlay-start cursor)) - (delete-region (+ (point) (- beg pt)) - (+ (point) (- end pt))) - (insert (substring-no-properties str)) - ;; manually move the fake cursor - (move-overlay cursor (point) (1+ (point))) - (set-marker (overlay-get cursor 'point) (point)) - (set-marker (overlay-get cursor 'mark) (point))))))) - -(defun ivy-completion-common-length (str) - "Return the amount of characters that match in STR. - -`completion-all-completions' computes this and returns the result -via text properties. - -The first non-matching part is propertized: -- either with: (face (completions-first-difference)) -- or: (font-lock-face completions-first-difference)." - (let ((char-property-alias-alist '((face font-lock-face))) - (i (1- (length str)))) - (catch 'done - (while (>= i 0) - (when (equal (get-text-property i 'face str) - '(completions-first-difference)) - (throw 'done i)) - (cl-decf i)) - (throw 'done (length str))))) - -(defun ivy-completion-in-region (start end collection &optional predicate) - "An Ivy function suitable for `completion-in-region-function'. -The function completes the text between START and END using COLLECTION. -PREDICATE (a function called with no arguments) says when to exit. -See `completion-in-region' for further information." - (let* ((enable-recursive-minibuffers t) - (str (buffer-substring-no-properties start end)) - (completion-ignore-case (ivy--case-fold-p str)) - (comps - (completion-all-completions str collection predicate (- end start)))) - (cond ((null comps) - (message "No matches")) - ((progn - (nconc comps nil) - (and (null (cdr comps)) - (string= str (car comps)))) - (message "Sole match")) - (t - (when (eq collection 'crm--collection-fn) - (setq comps (delete-dups comps))) - (let* ((len (ivy-completion-common-length (car comps))) - (initial (cond ((= len 0) - "") - ((let ((str-len (length str))) - (when (> len str-len) - (setq len str-len) - str))) - (t - (substring str (- len)))))) - (setq ivy--old-re nil) - (unless (ivy--filter initial comps) - (setq initial nil)) - (delete-region (- end len) end) - (setq ivy-completion-beg (- end len)) - (setq ivy-completion-end ivy-completion-beg) - (if (null (cdr comps)) - (progn - (unless (minibuffer-window-active-p (selected-window)) - (setf (ivy-state-window ivy-last) (selected-window))) - (ivy-completion-in-region-action - (substring-no-properties (car comps)))) - (dolist (s comps) - ;; Remove face `completions-first-difference'. - (ivy--remove-props s 'face)) - (ivy-read (format "(%s): " str) comps - ;; Predicate was already applied by - ;; `completion-all-completions'. - :predicate nil - :initial-input initial - :action #'ivy-completion-in-region-action - :unwind (lambda () - (unless (eq ivy-exit 'done) - (goto-char ivy-completion-beg) - (when initial - (insert initial)))) - :caller 'ivy-completion-in-region) - t)))))) - -(defun ivy-completion-in-region-prompt () - "Prompt function for `ivy-completion-in-region'. -See `ivy-set-prompt'." - (and (window-minibuffer-p (ivy-state-window ivy-last)) - (ivy-add-prompt-count (ivy-state-prompt ivy-last)))) - -(ivy-set-prompt #'ivy-completion-in-region #'ivy-completion-in-region-prompt) - -(defcustom ivy-do-completion-in-region t - "When non-nil `ivy-mode' will set `completion-in-region-function'." - :type 'boolean) - -;;;###autoload -(define-minor-mode ivy-mode - "Toggle Ivy mode on or off. -Turn Ivy mode on if ARG is positive, off otherwise. -Turning on Ivy mode sets `completing-read-function' to -`ivy-completing-read'. - -Global bindings: -\\{ivy-mode-map} - -Minibuffer bindings: -\\{ivy-minibuffer-map}" - :group 'ivy - :global t - :keymap ivy-mode-map - :lighter " ivy" - (if ivy-mode - (progn - (setq completing-read-function 'ivy-completing-read) - (when ivy-do-completion-in-region - (setq completion-in-region-function 'ivy-completion-in-region))) - (setq completing-read-function 'completing-read-default) - (setq completion-in-region-function 'completion--in-region))) - -(defun ivy--preselect-index (preselect candidates) - "Return the index of PRESELECT in CANDIDATES." - (cond ((integerp preselect) - (if (integerp (car candidates)) - (cl-position preselect candidates) - preselect)) - ((cl-position preselect candidates :test #'equal)) - ((ivy--regex-p preselect) - (cl-position preselect candidates :test #'string-match-p)))) - -;;* Implementation -;;** Regex -(defun ivy-re-match (re-seq str) - "Return non-nil if RE-SEQ is matched by STR. - -RE-SEQ is a list of (RE . MATCH-P). - -RE is a regular expression. - -MATCH-P is t when RE should match STR and nil when RE should not -match STR. - -Each element of RE-SEQ must match for the function to return true. - -This concept is used to generalize regular expressions for -`ivy--regex-plus' and `ivy--regex-ignore-order'." - (let ((res t) - re) - (while (and res (setq re (pop re-seq))) - (setq res - (if (cdr re) - (string-match-p (car re) str) - (not (string-match-p (car re) str))))) - res)) - -(defvar ivy--regex-hash - (make-hash-table :test #'equal) - "Store pre-computed regex.") - -(defun ivy--split (str) - "Split STR into list of substrings bounded by spaces. -Single spaces act as splitting points. Consecutive spaces -\"quote\" their preceding spaces, i.e., guard them from being -split. This allows the literal interpretation of N spaces by -inputting N+1 spaces. Any substring not constituting a valid -regexp is passed to `regexp-quote'." - (let ((len (length str)) - start0 - (start1 0) - res s - match-len) - (while (and (string-match " +" str start1) - (< start1 len)) - (if (and (> (match-beginning 0) 2) - (string= "[^" (substring - str - (- (match-beginning 0) 2) - (match-beginning 0)))) - (progn - (setq start0 start1) - (setq start1 (match-end 0))) - (setq match-len (- (match-end 0) (match-beginning 0))) - (if (= match-len 1) - (progn - (when start0 - (setq start1 start0) - (setq start0 nil)) - (push (substring str start1 (match-beginning 0)) res) - (setq start1 (match-end 0))) - (setq str (replace-match - (make-string (1- match-len) ?\ ) - nil nil str)) - (setq start0 (or start0 start1)) - (setq start1 (1- (match-end 0)))))) - (if start0 - (push (substring str start0) res) - (setq s (substring str start1)) - (unless (= (length s) 0) - (push s res))) - (mapcar #'ivy--regex-or-literal (nreverse res)))) - -(defun ivy--trim-trailing-re (regex) - "Trim incomplete REGEX. -If REGEX ends with \\|, trim it, since then it matches an empty string." - (if (string-match "\\`\\(.*\\)[\\]|\\'" regex) - (match-string 1 regex) - regex)) - -(defun ivy--regex (str &optional greedy) - "Re-build regex pattern from STR in case it has a space. -When GREEDY is non-nil, join words in a greedy way." - (let ((hashed (unless greedy - (gethash str ivy--regex-hash)))) - (if hashed - (progn - (setq ivy--subexps (car hashed)) - (cdr hashed)) - (when (string-match-p "\\(?:[^\\]\\|^\\)\\\\\\'" str) - (setq str (substring str 0 -1))) - (setq str (ivy--trim-trailing-re str)) - (cdr (puthash str - (let ((subs (ivy--split str))) - (if (= (length subs) 1) - (cons - (setq ivy--subexps 0) - (if (string-match-p "\\`\\.[^.]" (car subs)) - (concat "\\." (substring (car subs) 1)) - (car subs))) - (cons - (setq ivy--subexps (length subs)) - (mapconcat - (lambda (x) - (if (string-match-p "\\`\\\\([^?].*\\\\)\\'" x) - x - (format "\\(%s\\)" x))) - subs - (if greedy ".*" ".*?"))))) - ivy--regex-hash))))) - -(defun ivy--regex-p (object) - "Return OBJECT if it is a valid regular expression, else nil." - (ignore-errors (string-match-p object "") object)) - -(defun ivy--regex-or-literal (str) - "If STR isn't a legal regexp, escape it." - (or (ivy--regex-p str) (regexp-quote str))) - -(defun ivy--split-negation (str) - "Split STR into text before and after ! delimiter. -Do not split if the delimiter is escaped as \\!. - -Assumes there is at most one un-escaped delimiter and discards -text after delimiter if it is empty. Modifies match data." - (unless (string= str "") - (let ((delim "\\(?:\\`\\|[^\\]\\)\\(!\\)")) - (mapcar (lambda (split) - ;; Store "\!" as "!". - (replace-regexp-in-string "\\\\!" "!" split t t)) - (if (string-match delim str) - ;; Ignore everything past first un-escaped ! rather than - ;; crashing. We can't warn or error because the minibuffer is - ;; already active. - (let* ((i (match-beginning 1)) - (j (and (string-match delim str (1+ i)) - (match-beginning 1))) - (neg (substring str (1+ i) j))) - (cons (substring str 0 i) - (and (not (string= neg "")) - (list neg)))) - (list str)))))) - -(defun ivy--split-spaces (str) - "Split STR on spaces, unless they're preceded by \\. -No un-escaped spaces are left in the output. Any substring not -constituting a valid regexp is passed to `regexp-quote'." - (when str - (let ((i 0) ; End of last search. - (j 0) ; End of last delimiter. - parts) - (while (string-match "\\(\\\\ \\)\\| +" str i) - (setq i (match-end 0)) - (if (not (match-beginning 1)) - ;; Un-escaped space(s). - (let ((delim (match-beginning 0))) - (when (< j delim) - (push (substring str j delim) parts)) - (setq j i)) - ;; Store "\ " as " ". - (setq str (replace-match " " t t str 1)) - (setq i (1- i)))) - (when (< j (length str)) - (push (substring str j) parts)) - (mapcar #'ivy--regex-or-literal (nreverse parts))))) - -(defun ivy--regex-ignore-order (str) - "Re-build regex from STR by splitting at spaces and using ! for negation. - -Examples: -foo -> matches \"foo\" -foo bar -> matches if both \"foo\" and \"bar\" match (any order) -foo !bar -> matches if \"foo\" matches and \"bar\" does not match -foo !bar baz -> matches if \"foo\" matches and neither \"bar\" nor \"baz\" match -foo[a-z] -> matches \"foo[a-z]\" - -Escaping examples: -foo\\!bar -> matches \"foo!bar\" -foo\\ bar -> matches \"foo bar\" - -Returns a list suitable for `ivy-re-match'." - (setq str (ivy--trim-trailing-re str)) - (let* (regex-parts - (raw-parts (ivy--split-negation str))) - (dolist (part (ivy--split-spaces (car raw-parts))) - (push (cons part t) regex-parts)) - (when (cdr raw-parts) - (dolist (part (ivy--split-spaces (cadr raw-parts))) - (push (cons part nil) regex-parts))) - (if regex-parts (nreverse regex-parts) - ""))) - -(defun ivy--regex-plus (str) - "Build a regex sequence from STR. -Spaces are wild card characters, everything before \"!\" should -match. Everything after \"!\" should not match." - (let ((parts (ivy--split-negation str))) - (cl-case (length parts) - (0 - "") - (1 - (if (= (aref str 0) ?!) - (list (cons "" t) - (list (ivy--regex (car parts)))) - (ivy--regex (car parts)))) - (2 - (cons - (cons (ivy--regex (car parts)) t) - (mapcar #'list (split-string (cadr parts) " " t)))) - (t (error "Unexpected: use only one !"))))) - -(defun ivy--regex-fuzzy (str) - "Build a regex sequence from STR. -Insert .* between each char." - (setq str (ivy--trim-trailing-re str)) - (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str) - (prog1 - (concat (match-string 1 str) - (let ((lst (string-to-list (match-string 2 str)))) - (apply #'concat - (cl-mapcar - #'concat - (cons "" (cdr (mapcar (lambda (c) (format "[^%c\n]*" c)) - lst))) - (mapcar (lambda (x) (format "\\(%s\\)" (regexp-quote (char-to-string x)))) - lst)))) - (match-string 3 str)) - (setq ivy--subexps (length (match-string 2 str)))) - str)) - -(defcustom ivy-fixed-height-minibuffer nil - "When non nil, fix the height of the minibuffer during ivy completion. -This effectively sets the minimum height at this level to `ivy-height' and -tries to ensure that it does not change depending on the number of candidates." - :type 'boolean) - -;;** Rest -(defcustom ivy-truncate-lines t - "Minibuffer setting for `truncate-lines'." - :type 'boolean) - -(defun ivy--minibuffer-setup () - "Setup ivy completion in the minibuffer." - (setq-local mwheel-scroll-up-function 'ivy-next-line) - (setq-local mwheel-scroll-down-function 'ivy-previous-line) - (setq-local completion-show-inline-help nil) - (setq-local line-spacing nil) - (setq-local minibuffer-default-add-function - (lambda () - (list ivy--default))) - (setq-local inhibit-field-text-motion nil) - (setq truncate-lines ivy-truncate-lines) - (setq-local max-mini-window-height ivy-height) - (let ((height (cond ((and ivy-fixed-height-minibuffer - (not (eq (ivy-state-caller ivy-last) - #'ivy-completion-in-region))) - (+ ivy-height (if ivy-add-newline-after-prompt 1 0))) - (ivy-add-newline-after-prompt 2)))) - (when height - (set-window-text-height nil height))) - (add-hook 'post-command-hook #'ivy--queue-exhibit nil t) - (let ((hook (ivy-alist-setting ivy-hooks-alist))) - (when (functionp hook) - (funcall hook)))) - -(defun ivy--input () - "Return the current minibuffer input." - ;; assume one-line minibuffer input - (save-excursion - (goto-char (minibuffer-prompt-end)) - (let ((inhibit-field-text-motion t)) - (buffer-substring-no-properties - (point) - (line-end-position))))) - -(defun ivy--minibuffer-cleanup () - "Delete the displayed completion candidates." - (save-excursion - (goto-char (minibuffer-prompt-end)) - (delete-region (line-end-position) (point-max)))) - -(defun ivy-cleanup-string (str) - "Destructively remove unwanted text properties from STR." - (ivy--remove-props str 'field)) - -(defvar ivy-set-prompt-text-properties-function - #'ivy-set-prompt-text-properties-default - "Function to set the text properties of the default ivy prompt. -Called with two arguments, PROMPT and PROPS, where PROMPT is the -string to be propertized and PROPS is a plist of default text -properties that may be applied to PROMPT. The function should -return the propertized PROMPT, which may be modified in-place.") - -(defun ivy-set-prompt-text-properties-default (prompt props) - "Propertize (confirm) and (match required) parts of PROMPT. -PROPS is a plist of default text properties to apply to these -parts beyond their respective faces `ivy-confirm-face' and -`ivy-match-required-face'." - (dolist (pair '(("confirm" . ivy-confirm-face) - ("match required" . ivy-match-required-face))) - (let ((i (string-match-p (car pair) prompt))) - (when i - (add-text-properties i (+ i (length (car pair))) - `(face ,(cdr pair) ,@props) - prompt)))) - prompt) - -(defun ivy-prompt () - "Return the current prompt." - (let* ((caller (ivy-state-caller ivy-last)) - (fn (plist-get ivy--prompts-list caller))) - (if fn - (condition-case err - (funcall fn) - (wrong-number-of-arguments - (lwarn 'ivy :error "%s - Prompt function set via `ivy-set-prompt' for caller `%s' - should take no arguments." - (error-message-string err) - caller) - ;; Old behavior. - (funcall fn (ivy-state-prompt ivy-last)))) - ivy--prompt))) - -(defun ivy--insert-prompt () - "Update the prompt according to `ivy--prompt'." - (when (setq ivy--prompt (ivy-prompt)) - (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done - counsel-find-symbol)) - (setq ivy--prompt-extra "")) - (let (head tail) - (if (string-match "\\(.*?\\)\\(:? ?\\)\\'" ivy--prompt) - (progn - (setq head (match-string 1 ivy--prompt)) - (setq tail (match-string 2 ivy--prompt))) - (setq head ivy--prompt) - (setq tail "")) - (let ((inhibit-read-only t) - (std-props '(front-sticky t rear-nonsticky t field t read-only t)) - (n-str - (concat - (if (and (bound-and-true-p minibuffer-depth-indicate-mode) - (> (minibuffer-depth) 1)) - (format "[%d] " (minibuffer-depth)) - "") - (concat - (if (string-match "%d.*%d" ivy-count-format) - (format head - (1+ ivy--index) - (or (and (ivy-state-dynamic-collection ivy-last) - ivy--full-length) - ivy--length)) - (format head - (or (and (ivy-state-dynamic-collection ivy-last) - ivy--full-length) - ivy--length))) - ivy--prompt-extra - tail))) - (d-str (if ivy--directory - (abbreviate-file-name ivy--directory) - ""))) - (save-excursion - (goto-char (point-min)) - (delete-region (point-min) (minibuffer-prompt-end)) - (let ((len-n (length n-str)) - (len-d (length d-str)) - (ww (window-width))) - (setq n-str - (cond ((> (+ len-n len-d) ww) - (concat n-str "\n" d-str "\n")) - ((> (+ len-n len-d (length ivy-text)) ww) - (concat n-str d-str "\n")) - (t - (concat n-str d-str))))) - (when ivy-pre-prompt-function - (setq n-str (concat (funcall ivy-pre-prompt-function) n-str))) - (when ivy-add-newline-after-prompt - (setq n-str (concat n-str "\n"))) - (let ((regex (format "\\([^\n]\\{%d\\}\\)[^\n]" (window-width)))) - (while (string-match regex n-str) - (setq n-str (replace-match - (concat (match-string 1 n-str) "\n") - nil t n-str 1)))) - (set-text-properties 0 (length n-str) - `(face minibuffer-prompt ,@std-props) - n-str) - (setq n-str (funcall ivy-set-prompt-text-properties-function - n-str std-props)) - (insert n-str)) - ;; Mark prompt as selected if the user moves there or it is the only - ;; option left. Since the user input stays put, we have to manually - ;; remove the face as well. - (when ivy--use-selectable-prompt - (if (= ivy--index -1) - (ivy-add-face-text-property - (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match) - (remove-list-of-text-properties - (minibuffer-prompt-end) (line-end-position) '(face)))) - ;; get out of the prompt area - (constrain-to-field nil (point-max)))))) - -(defun ivy--sort-maybe (collection) - "Sort COLLECTION if needed." - (let ((sort (ivy-state-sort ivy-last))) - (if (and sort - (or (functionp sort) - (functionp (setq sort (ivy--sort-function - (ivy-state-collection ivy-last)))))) - (sort (copy-sequence collection) sort) - collection))) - -(defcustom ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected - "Action to take when a slash is added to the end of a non existing directory. -Possible choices are 'ivy-magic-slash-non-match-cd-selected, -'ivy-magic-slash-non-match-create, or nil" - :type '(choice - (const :tag "Use currently selected directory" - ivy-magic-slash-non-match-cd-selected) - (const :tag "Create and use new directory" - ivy-magic-slash-non-match-create) - (const :tag "Do nothing" - nil))) - -(defun ivy--create-and-cd (dir) - "When completing file names, create directory DIR and move there." - (make-directory dir) - (ivy--cd dir)) - -(defun ivy--magic-file-doubleslash-directory () - "Return an appropriate directory for when two slashes are entered." - (let (remote) - (cond - ;; Windows - ((string-match "\\`[[:alpha:]]:/" ivy--directory) - (match-string 0 ivy--directory)) - ;; Remote root if on remote - ((setq remote (file-remote-p ivy--directory)) - (concat remote "/")) - ;; Local root - (t - "/")))) - -(defun ivy--magic-file-slash () - "Handle slash when completing file names." - (when (or (and (eq this-command #'self-insert-command) - (eolp)) - (eq this-command #'ivy-partial-or-done)) - (let ((canonical (expand-file-name ivy-text ivy--directory)) - (magic (not (string= ivy-text "/")))) - (cond ((member ivy-text ivy--all-candidates) - (ivy--cd canonical)) - ((string-match-p "//\\'" ivy-text) - (ivy--cd - (ivy--magic-file-doubleslash-directory))) - ((string-match-p "\\`/ssh:" ivy-text) - (ivy--cd (file-name-directory ivy-text))) - ((string-match "[[:alpha:]]:/\\'" ivy-text) - (let ((drive-root (match-string 0 ivy-text))) - (when (file-exists-p drive-root) - (ivy--cd drive-root)))) - ((and magic (file-directory-p canonical)) - (ivy--cd canonical)) - ((let ((default-directory ivy--directory)) - (and (or (> ivy--index 0) - (= ivy--length 1) - magic) - (not (ivy--prompt-selected-p)) - (not (equal (ivy-state-current ivy-last) "")) - (file-directory-p (ivy-state-current ivy-last)) - (or (eq ivy-magic-slash-non-match-action - 'ivy-magic-slash-non-match-cd-selected) - (eq this-command #'ivy-partial-or-done)))) - (ivy--cd - (expand-file-name (ivy-state-current ivy-last) ivy--directory))) - ((and (eq ivy-magic-slash-non-match-action - 'ivy-magic-slash-non-match-create) - magic) - (ivy--create-and-cd canonical)))))) - -(defun ivy-magic-read-file-env () - "If reading filename, jump to environment variable location." - (interactive) - (if (and ivy--directory - (equal ivy-text "")) - (let* ((cands (cl-loop for pair in process-environment - for (var val) = (split-string pair "=" t) - if (and val (not (equal "" val))) - if (file-exists-p - (if (file-name-absolute-p val) - val - (setq val - (expand-file-name val ivy--directory)))) - collect (cons var val))) - (enable-recursive-minibuffers t) - (x (ivy-read "Env: " cands)) - (path (cdr (assoc x cands)))) - (insert (if (file-accessible-directory-p path) - (file-name-as-directory path) - path)) - (ivy--cd-maybe)) - (insert last-input-event))) - -(defun ivy-make-magic-action (caller key) - "Return a command that does the equivalent of `ivy-read-action' and KEY. -This happens only when the input is empty. -The intention is to bind the result to keys that are typically -bound to `self-insert-command'." - (let* ((alist (assoc key - (plist-get - ivy--actions-list - caller))) - (doc (format "%s (`%S')" - (nth 2 alist) - (nth 1 alist)))) - `(lambda (&optional arg) - ,doc - (interactive "p") - (if (string= "" ivy-text) - (execute-kbd-macro - (kbd ,(concat "M-o " key))) - (self-insert-command arg))))) - -(defcustom ivy-magic-tilde t - "When non-nil, ~ will move home when selecting files. -Otherwise, ~/ will move home." - :type 'boolean) - -(defcustom ivy-dynamic-exhibit-delay-ms 0 - "Delay in ms before dynamic collections are refreshed" - :type 'integer) - -(defvar ivy--exhibit-timer nil) - -(defun ivy--queue-exhibit () - "Insert Ivy completions display, possibly after a timeout for -dynamic collections. -Should be run via minibuffer `post-command-hook'." - (if (and (> ivy-dynamic-exhibit-delay-ms 0) - (ivy-state-dynamic-collection ivy-last)) - (progn - (when ivy--exhibit-timer (cancel-timer ivy--exhibit-timer)) - (setq ivy--exhibit-timer - (run-with-timer - (/ ivy-dynamic-exhibit-delay-ms 1000.0) - nil - 'ivy--exhibit))) - (ivy--exhibit))) - -(defun ivy--magic-tilde-directory (dir) - "Return an appropriate home for DIR for when ~ or ~/ are entered." - (expand-file-name - (let (remote) - (if (and (setq remote (file-remote-p dir)) - (let ((local (file-local-name dir))) - (not (or (string= "/root/" local) - (string-match-p "/home/\\([^/]+\\)/\\'" local))))) - (concat remote "~/") - "~/")))) - -(defun ivy-update-candidates (cands) - (ivy--insert-minibuffer - (ivy--format - (setq ivy--all-candidates cands)))) - -(defun ivy--exhibit () - "Insert Ivy completions display. -Should be run via minibuffer `post-command-hook'." - (when (memq 'ivy--queue-exhibit post-command-hook) - (let ((inhibit-field-text-motion nil)) - (constrain-to-field nil (point-max))) - (setq ivy-text (ivy--input)) - (if (ivy-state-dynamic-collection ivy-last) - ;; while-no-input would cause annoying - ;; "Waiting for process to die...done" message interruptions - (let ((inhibit-message t) - coll in-progress) - (unless (equal ivy--old-text ivy-text) - (while-no-input - (setq coll (funcall (ivy-state-collection ivy-last) ivy-text)) - (when (eq coll 0) - (setq coll nil) - (setq ivy--old-re nil) - (setq in-progress t)) - (setq ivy--all-candidates (ivy--sort-maybe coll)) - (setq ivy--old-text ivy-text))) - (when (eq ivy--all-candidates 0) - (setq ivy--all-candidates nil) - (setq ivy--old-re nil) - (setq in-progress t)) - (when (or ivy--all-candidates - (and (not (get-process " *counsel*")) - (not in-progress))) - (ivy--set-index-dynamic-collection) - (ivy--insert-minibuffer - (ivy--format ivy--all-candidates)))) - (cond (ivy--directory - (cond ((or (string= "~/" ivy-text) - (and (string= "~" ivy-text) - ivy-magic-tilde)) - (ivy--cd (ivy--magic-tilde-directory ivy--directory))) - ((string-match "/\\'" ivy-text) - (ivy--magic-file-slash)))) - ((eq (ivy-state-collection ivy-last) #'internal-complete-buffer) - (when (or (and (string-match "\\` " ivy-text) - (not (string-match "\\` " ivy--old-text))) - (and (string-match "\\` " ivy--old-text) - (not (string-match "\\` " ivy-text)))) - (setq ivy--all-candidates - (if (= (string-to-char ivy-text) ?\s) - (ivy--buffer-list " ") - (ivy--buffer-list "" ivy-use-virtual-buffers))) - (setq ivy--old-re nil)))) - (ivy--insert-minibuffer - (with-current-buffer (ivy-state-buffer ivy-last) - (ivy--format - (ivy--filter ivy-text ivy--all-candidates)))) - (setq ivy--old-text ivy-text)))) - -(defun ivy-display-function-fallback (str) - (let ((buffer-undo-list t)) - (save-excursion - (forward-line 1) - (insert str)))) - -(defun ivy--insert-minibuffer (text) - "Insert TEXT into minibuffer with appropriate cleanup." - (let ((resize-mini-windows nil) - (update-fn (ivy-state-update-fn ivy-last)) - (old-mark (marker-position (mark-marker))) - (win (active-minibuffer-window)) - deactivate-mark) - (when win - (with-selected-window win - (ivy--minibuffer-cleanup) - (when update-fn - (funcall update-fn)) - (ivy--insert-prompt) - ;; Do nothing if while-no-input was aborted. - (when (stringp text) - (if ivy--display-function - (funcall ivy--display-function text) - (ivy-display-function-fallback text))) - (ivy--resize-minibuffer-to-fit) - ;; prevent region growing due to text remove/add - (when (region-active-p) - (set-mark old-mark)))))) - -(defun ivy--resize-minibuffer-to-fit () - "Resize the minibuffer window size to fit the text in the minibuffer." - (unless (frame-root-window-p (minibuffer-window)) - (with-selected-window (minibuffer-window) - (if (fboundp 'window-text-pixel-size) - (let ((text-height (cdr (window-text-pixel-size))) - (body-height (window-body-height nil t))) - (when (> text-height body-height) - ;; Note: the size increment needs to be at least - ;; frame-char-height, otherwise resizing won't do - ;; anything. - (let ((delta (max (- text-height body-height) - (frame-char-height)))) - (window-resize nil delta nil t t)))) - (let ((text-height (count-screen-lines)) - (body-height (window-body-height))) - (when (> text-height body-height) - (window-resize nil (- text-height body-height) nil t))))))) - -(defun ivy--add-face (str face) - "Propertize STR with FACE." - (let ((len (length str))) - (condition-case nil - (progn - (colir-blend-face-background 0 len face str) - (let ((foreground (face-foreground face))) - (when foreground - (ivy-add-face-text-property - 0 len (list :foreground foreground) str)))) - (error - (ignore-errors - (font-lock-append-text-property 0 len 'face face str))))) - str) - -(declare-function flx-make-string-cache "ext:flx") -(declare-function flx-score "ext:flx") - -(defvar ivy--flx-cache nil) - -(eval-after-load 'flx - '(setq ivy--flx-cache (flx-make-string-cache))) - -(defun ivy-toggle-case-fold () - "Toggle `case-fold-search' for Ivy operations. - -Instead of modifying `case-fold-search' directly, this command -toggles `ivy-case-fold-search', which can take on more values -than the former, between nil and either `auto' or t. See -`ivy-case-fold-search-default' for the meaning of these values. - -In any Ivy completion session, the case folding starts with -`ivy-case-fold-search-default'." - (interactive) - (setq ivy-case-fold-search - (and (not ivy-case-fold-search) - (or ivy-case-fold-search-default 'auto))) - ;; Reset cache so that the candidate list updates. - (setq ivy--old-re nil)) - -(defun ivy--re-filter (re candidates &optional mkpred) - "Return all RE matching CANDIDATES. -RE is a list of cons cells, with a regexp car and a boolean cdr. -When the cdr is t, the car must match. -Otherwise, the car must not match." - (if (equal re "") - candidates - (ignore-errors - (dolist (re (if (stringp re) (list (cons re t)) re)) - (let* ((re-str (car re)) - (pred - (if mkpred - (funcall mkpred re-str) - (lambda (x) (string-match-p re-str x))))) - (setq candidates - (cl-remove nil candidates - (if (cdr re) :if-not :if) - pred)))) - candidates))) - -(defun ivy--filter (name candidates) - "Return all items that match NAME in CANDIDATES. -CANDIDATES are assumed to be static." - (let ((re (funcall ivy--regex-function name))) - (if (and - ivy--old-re - ivy--old-cands - (equal re ivy--old-re)) - ;; quick caching for "C-n", "C-p" etc. - ivy--old-cands - (let* ((re-str (ivy-re-to-str re)) - (matcher (ivy-state-matcher ivy-last)) - (case-fold-search (ivy--case-fold-p name)) - (cands (cond - ((and ivy--old-re - (stringp re) - (stringp ivy--old-re) - (not (string-match-p "\\\\" ivy--old-re)) - (not (equal ivy--old-re "")) - (memq (cl-search - (if (string-match-p "\\\\)\\'" ivy--old-re) - (substring ivy--old-re 0 -2) - ivy--old-re) - re) - '(0 2)) - ivy--old-cands - (ivy--re-filter re ivy--old-cands))) - (matcher - (funcall matcher re candidates)) - (t - (ivy--re-filter re candidates))))) - (if (memq (cdr (assq (ivy-state-caller ivy-last) - ivy-index-functions-alist)) - '(ivy-recompute-index-swiper - ivy-recompute-index-swiper-async - ivy-recompute-index-swiper-async-backward - ivy-recompute-index-swiper-backward)) - (progn - (ivy--recompute-index name re-str cands) - (setq ivy--old-cands (ivy--sort name cands))) - (setq ivy--old-cands (ivy--sort name cands)) - (ivy--recompute-index name re-str ivy--old-cands)) - (setq ivy--old-re re) - ivy--old-cands)))) - -(defun ivy--set-candidates (x) - "Update `ivy--all-candidates' with X." - (let (res) - (dolist (source ivy--extra-candidates) - (if (equal source '(original-source)) - (if (null res) - (setq res x) - (setq res (append x res))) - (setq ivy--old-re nil) - (setq res (append - (ivy--filter ivy-text (cadr source)) - res)))) - (setq ivy--all-candidates res))) - -(defun ivy--shorter-matches-first (_name cands) - "Sort CANDS according to their length." - (if (< (length cands) ivy-sort-max-size) - (cl-sort - (copy-sequence cands) - (lambda (s1 s2) - (< (length s1) (length s2)))) - cands)) - -(defcustom ivy-sort-matches-functions-alist - '((t . nil) - (ivy-completion-in-region . ivy--shorter-matches-first) - (ivy-switch-buffer . ivy-sort-function-buffer)) - "An alist of functions for sorting matching candidates. - -Unlike `ivy-sort-functions-alist', which is used to sort the -whole collection only once, this alist of functions are used to -sort only matching candidates after each change in input. - -The alist KEY is either a collection function or t to match -previously unmatched collection functions. - -The alist VAL is a sorting function with the signature of -`ivy--prefix-sort'." - :type '(alist - :key-type (choice - (const :tag "Fall-through" t) - (symbol :tag "Collection")) - :value-type - (choice - (const :tag "Don't sort" nil) - (const :tag "Put prefix matches ahead" ivy--prefix-sort) - (function :tag "Custom sort function")))) - -(defun ivy--sort-files-by-date (_name candidates) - "Re-sort CANDIDATES according to file modification date." - (let ((default-directory ivy--directory)) - (sort (copy-sequence candidates) #'file-newer-than-file-p))) - -(defvar ivy--flx-featurep (require 'flx nil 'noerror)) - -(defun ivy--sort (name candidates) - "Re-sort candidates by NAME. -All CANDIDATES are assumed to match NAME." - (let (fun) - (cond ((setq fun (ivy-alist-setting ivy-sort-matches-functions-alist)) - (funcall fun name candidates)) - ((and ivy--flx-featurep - (eq ivy--regex-function 'ivy--regex-fuzzy)) - (ivy--flx-sort name candidates)) - (t - candidates)))) - -(defun ivy--prefix-sort (name candidates) - "Re-sort candidates by NAME. -All CANDIDATES are assumed to match NAME. -Prefix matches to NAME are put ahead of the list." - (if (or (string= name "") - (= (aref name 0) ?^)) - candidates - (let ((re-prefix (concat "\\`" (funcall ivy--regex-function name))) - res-prefix - res-noprefix) - (dolist (s candidates) - (if (string-match-p re-prefix s) - (push s res-prefix) - (push s res-noprefix))) - (nconc - (nreverse res-prefix) - (nreverse res-noprefix))))) - -(defvar ivy--virtual-buffers nil - "Store the virtual buffers alist.") - -(defun ivy-re-to-str (re) - "Transform RE to a string. - -Functions like `ivy--regex-ignore-order' return a cons list. -This function extracts a string from the cons list." - (if (consp re) (caar re) re)) - -(defun ivy-sort-function-buffer (name candidates) - "Re-sort candidates by NAME. -CANDIDATES is a list of buffer names each containing NAME. -Sort open buffers before virtual buffers, and prefix matches -before substring matches." - (if (or (string= name "") - (= (aref name 0) ?^)) - candidates - (let* ((base-re (ivy-re-to-str (funcall ivy--regex-function name))) - (re-star-prefix (concat "\\`\\*" base-re)) - (re-prefix (concat "\\`" base-re)) - res-prefix - res-noprefix - res-virtual-prefix - res-virtual-noprefix) - (dolist (s candidates) - (cond - ((and (assoc s ivy--virtual-buffers) - (or (string-match-p re-star-prefix s) - (string-match-p re-prefix s))) - (push s res-virtual-prefix)) - ((assoc s ivy--virtual-buffers) - (push s res-virtual-noprefix)) - ((or (string-match-p re-star-prefix s) - (string-match-p re-prefix s)) - (push s res-prefix)) - (t - (push s res-noprefix)))) - (nconc - (nreverse res-prefix) - (nreverse res-noprefix) - (nreverse res-virtual-prefix) - (nreverse res-virtual-noprefix))))) - -(defvar ivy-flx-limit 200 - "Used to conditionally turn off flx sorting. - -When the amount of matching candidates exceeds this limit, then -no sorting is done.") - -(defvar ivy--recompute-index-inhibit nil - "When non-nil, `ivy--recompute-index' is a no-op.") - -(defun ivy--recompute-index (name re-str cands) - "Recompute index of selected candidate matching NAME. -RE-STR is the regexp, CANDS are the current candidates." - (let ((caller (ivy-state-caller ivy-last)) - (func (or (ivy-alist-setting ivy-index-functions-alist) - #'ivy-recompute-index-zero)) - (case-fold-search (ivy--case-fold-p name)) - (preselect (ivy-state-preselect ivy-last)) - (current (ivy-state-current ivy-last)) - (empty (string= name ""))) - (unless (or (memq this-command '(ivy-resume ivy-partial-or-done)) - ivy--recompute-index-inhibit) - (ivy-set-index - (if (or (string= name "") - (and (> (length cands) 10000) (eq func #'ivy-recompute-index-zero))) - 0 - (or - (cl-position (ivy--remove-prefix "^" name) - cands - :test #'ivy--case-fold-string=) - (and ivy--directory - (cl-position (concat re-str "/") - cands - :test #'ivy--case-fold-string=)) - (and (eq caller 'ivy-switch-buffer) - (not empty) - 0) - (and (not empty) - (not (eq caller 'swiper)) - (not (and ivy--flx-featurep - (eq ivy--regex-function 'ivy--regex-fuzzy) - ;; Limit to configured number of candidates - (null (nthcdr ivy-flx-limit cands)))) - ;; If there was a preselected candidate, don't try to - ;; keep it selected even if the regexp still matches it. - ;; See issue #1563. See also `ivy--preselect-index', - ;; which this logic roughly mirrors. - (not (or - (and (integerp preselect) - (= ivy--index preselect)) - (equal current preselect) - (and (ivy--regex-p preselect) - (stringp current) - (string-match-p preselect current)))) - ivy--old-cands - (cl-position current cands :test #'equal)) - (funcall func re-str cands))))) - (when (or empty (string= name "^")) - (ivy-set-index - (or (ivy--preselect-index preselect cands) - ivy--index))))) - -(defun ivy-recompute-index-swiper (_re-str cands) - "Recompute index of selected candidate when using `swiper'. -CANDS are the current candidates." - (condition-case nil - (let ((tail (nthcdr ivy--index ivy--old-cands)) - idx) - (if (and tail ivy--old-cands (not (equal "^" ivy--old-re))) - (progn - (while (and tail (null idx)) - ;; Compare with eq to handle equal duplicates in cands - (setq idx (cl-position (pop tail) cands))) - (or - idx - (1- (length cands)))) - (if ivy--old-cands - ivy--index - ;; already in ivy-state-buffer - (let ((n (line-number-at-pos)) - (res 0) - (i 0)) - (dolist (c cands) - (when (eq n (get-text-property 0 'swiper-line-number c)) - (setq res i)) - (cl-incf i)) - res)))) - (error 0))) - -(defun ivy-recompute-index-swiper-backward (re-str cands) - "Recompute index of selected candidate when using `swiper-backward'. -CANDS are the current candidates." - (let ((idx (ivy-recompute-index-swiper re-str cands))) - (if (or (= idx -1) - (<= (get-text-property 0 'swiper-line-number (nth idx cands)) - (line-number-at-pos))) - idx - (- idx 1)))) - -(defun ivy-recompute-index-swiper-async (_re-str cands) - "Recompute index of selected candidate when using `swiper' asynchronously. -CANDS are the current candidates." - (if (null ivy--old-cands) - (let ((ln (with-ivy-window - (line-number-at-pos)))) - (or - ;; closest to current line going forwards - (cl-position-if (lambda (x) - (>= (string-to-number x) ln)) - cands) - ;; closest to current line going backwards - (1- (length cands)))) - (let ((tail (nthcdr ivy--index ivy--old-cands)) - idx) - (if (and tail ivy--old-cands (not (equal "^" ivy--old-re))) - (progn - (while (and tail (null idx)) - ;; Compare with `equal', since the collection is re-created - ;; each time with `split-string' - (setq idx (cl-position (pop tail) cands :test #'equal))) - (or idx 0)) - ivy--index)))) - -(defun ivy-recompute-index-swiper-async-backward (re-str cands) - "Recompute index of selected candidate when using `swiper-backward' -asynchronously. CANDS are the current candidates." - (if (= (length cands) 0) - 0 - (let ((idx (ivy-recompute-index-swiper-async re-str cands))) - (if - (<= (string-to-number (nth idx cands)) - (with-ivy-window (line-number-at-pos))) - idx - (- idx 1))))) - -(defun ivy-recompute-index-zero (_re-str _cands) - "Recompute index of selected candidate. -This function serves as a fallback when nothing else is available." - 0) - -(defcustom ivy-minibuffer-faces - '(ivy-minibuffer-match-face-1 - ivy-minibuffer-match-face-2 - ivy-minibuffer-match-face-3 - ivy-minibuffer-match-face-4) - "List of `ivy' faces for minibuffer group matches." - :type '(repeat :tag "Faces" - (choice - (const ivy-minibuffer-match-face-1) - (const ivy-minibuffer-match-face-2) - (const ivy-minibuffer-match-face-3) - (const ivy-minibuffer-match-face-4) - (face :tag "Other face")))) - -(defun ivy--minibuffer-face (n) - "Return Nth face from `ivy-minibuffer-faces'. -N wraps around, but skips the first element of the list." - (let ((tail (cdr ivy-minibuffer-faces))) - (nth (mod (+ n 2) (length tail)) tail))) - -(defun ivy--flx-propertize (x) - "X is (cons (flx-score STR ...) STR)." - (let ((str (copy-sequence (cdr x))) - (i 0) - (last-j -2)) - (dolist (j (cdar x)) - (unless (eq j (1+ last-j)) - (cl-incf i)) - (setq last-j j) - (ivy-add-face-text-property j (1+ j) (ivy--minibuffer-face i) str)) - str)) - -(defun ivy--flx-sort (name cands) - "Sort according to closeness to string NAME the string list CANDS." - (condition-case nil - (let* ((bolp (= (string-to-char name) ?^)) - ;; An optimized regex for fuzzy matching - ;; "abc" → "^[^a]*a[^b]*b[^c]*c" - (fuzzy-regex (concat "\\`" - (and bolp (regexp-quote (substring name 1 2))) - (mapconcat - (lambda (x) - (setq x (char-to-string x)) - (concat "[^" x "]*" (regexp-quote x))) - (if bolp (substring name 2) name) - ""))) - ;; Strip off the leading "^" for flx matching - (flx-name (if bolp (substring name 1) name)) - cands-left - cands-to-sort) - - ;; Filter out non-matching candidates - (dolist (cand cands) - (when (string-match-p fuzzy-regex cand) - (push cand cands-left))) - - ;; pre-sort the candidates by length before partitioning - (setq cands-left (cl-sort cands-left #'< :key #'length)) - - ;; partition the candidates into sorted and unsorted groups - (dotimes (_ (min (length cands-left) ivy-flx-limit)) - (push (pop cands-left) cands-to-sort)) - - (nconc - ;; Compute all of the flx scores in one pass and sort - (mapcar #'car - (sort (mapcar - (lambda (cand) - (cons cand - (car (flx-score cand flx-name ivy--flx-cache)))) - cands-to-sort) - (lambda (c1 c2) - ;; Break ties by length - (if (/= (cdr c1) (cdr c2)) - (> (cdr c1) - (cdr c2)) - (< (length (car c1)) - (length (car c2))))))) - - ;; Add the unsorted candidates - cands-left)) - (error cands))) - -(defun ivy--truncate-string (str width) - "Truncate STR to WIDTH." - (truncate-string-to-width str width nil nil t)) - -(defun ivy--format-function-generic (selected-fn other-fn cands separator) - "Transform candidates into a string for minibuffer. -SELECTED-FN is called for the selected candidate, OTHER-FN for the others. -Both functions take one string argument each. CANDS is a list of candidates -and SEPARATOR is used to join them." - (let ((i -1)) - (mapconcat - (lambda (str) - (let ((curr (eq (cl-incf i) ivy--window-index))) - (if curr - (funcall selected-fn str) - (funcall other-fn str)))) - cands - separator))) - -(defun ivy-format-function-default (cands) - "Transform CANDS into a string for minibuffer." - (ivy--format-function-generic - (lambda (str) - (ivy--add-face str 'ivy-current-match)) - #'identity - cands - "\n")) - -(defun ivy-format-function-arrow (cands) - "Transform CANDS into a string for minibuffer." - (ivy--format-function-generic - (lambda (str) - (concat "> " (ivy--add-face str 'ivy-current-match))) - (lambda (str) - (concat " " str)) - cands - "\n")) - -(defun ivy-format-function-line (cands) - "Transform CANDS into a string for minibuffer." - (ivy--format-function-generic - (lambda (str) - (ivy--add-face (concat str "\n") 'ivy-current-match)) - (lambda (str) - (concat str "\n")) - cands - "")) - -(defalias 'ivy-add-face-text-property - (if (fboundp 'add-face-text-property) - (lambda (start end face &optional object append) - (add-face-text-property start end face append object)) - (lambda (start end face &optional object append) - (funcall (if append - #'font-lock-append-text-property - #'font-lock-prepend-text-property) - start end 'face face object))) - "Compatibility shim for `add-face-text-property'. -Fall back on `font-lock-prepend-text-property' in Emacs versions -prior to 24.4 (`font-lock-append-text-property' when APPEND is -non-nil). -Note: The usual last two arguments are flipped for convenience.") - -(defun ivy--highlight-ignore-order (str) - "Highlight STR, using the ignore-order method." - (when (consp ivy--old-re) - (let ((i 1)) - (dolist (re ivy--old-re) - (when (string-match (car re) str) - (ivy-add-face-text-property - (match-beginning 0) (match-end 0) - (ivy--minibuffer-face i) - str)) - (cl-incf i)))) - str) - -(defun ivy--highlight-fuzzy (str) - "Highlight STR, using the fuzzy method." - (if (and ivy--flx-featurep - (eq (ivy-alist-setting ivy-re-builders-alist) 'ivy--regex-fuzzy)) - (let ((flx-name (ivy--remove-prefix "^" ivy-text))) - (ivy--flx-propertize - (cons (flx-score str flx-name ivy--flx-cache) str))) - (ivy--highlight-default str))) - -(defun ivy--highlight-default (str) - "Highlight STR, using the default method." - (unless ivy--old-re - (setq ivy--old-re (funcall ivy--regex-function ivy-text))) - (let ((regexps - (if (listp ivy--old-re) - (mapcar #'car (cl-remove-if-not #'cdr ivy--old-re)) - (list ivy--old-re))) - start) - (dolist (re regexps) - (ignore-errors - (while (and (string-match re str start) - (> (- (match-end 0) (match-beginning 0)) 0)) - (setq start (match-end 0)) - (let ((i 0) - (n 0) - prev) - (while (<= i ivy--subexps) - (let ((beg (match-beginning i)) - (end (match-end i))) - (when (and beg end) - (unless (and prev (= prev beg)) - (cl-incf n)) - (let ((face - (cond ((zerop ivy--subexps) - (cadr ivy-minibuffer-faces)) - ((zerop i) - (car ivy-minibuffer-faces)) - (t - (ivy--minibuffer-face n))))) - (ivy-add-face-text-property beg end face str)) - (unless (zerop i) - (setq prev end)))) - (cl-incf i))))))) - str) - -(defun ivy--format-minibuffer-line (str) - "Format line STR for use in minibuffer." - (let* ((str (ivy-cleanup-string (copy-sequence str))) - (str (if (eq ivy-display-style 'fancy) - (if (memq (ivy-state-caller ivy-last) - ivy-highlight-grep-commands) - (let* ((start (if (string-match "\\`[^:]+:\\(?:[^:]+:\\)?" str) - (match-end 0) 0)) - (file (substring str 0 start)) - (match (substring str start))) - (concat file (funcall ivy--highlight-function match))) - (funcall ivy--highlight-function str)) - str)) - (olen (length str)) - (annot (plist-get completion-extra-properties :annotation-function))) - (add-text-properties - 0 olen - '(mouse-face - ivy-minibuffer-match-highlight - help-echo - (format - (if tooltip-mode - "mouse-1: %s\nmouse-3: %s" - "mouse-1: %s mouse-3: %s") - ivy-mouse-1-tooltip ivy-mouse-3-tooltip)) - str) - (when annot - (setq str (concat str (funcall annot str))) - (ivy-add-face-text-property - olen (length str) 'ivy-completions-annotations str)) - str)) - -(defun ivy-read-file-transformer (str) - "Transform candidate STR when reading files." - (if (ivy--dirname-p str) - (propertize str 'face 'ivy-subdir) - str)) - -(defun ivy--minibuffer-index-bounds (idx len wnd-len) - (let* ((half-height (/ wnd-len 2)) - (start (max 0 - (min (- idx half-height) - (- len (1- wnd-len))))) - (end (min (+ start (1- wnd-len)) len))) - (list start end (- idx start)))) - -(defun ivy--format (cands) - "Return a string for CANDS suitable for display in the minibuffer. -CANDS is a list of candidates that :display-transformer can turn into strings." - (setq ivy--length (length cands)) - (when (>= ivy--index ivy--length) - (ivy-set-index (max (1- ivy--length) 0))) - (if (null cands) - (setf (ivy-state-current ivy-last) "") - (let ((cur (nth ivy--index cands))) - (setf (ivy-state-current ivy-last) (if (stringp cur) - (copy-sequence cur) - cur))) - (let* ((bnd (ivy--minibuffer-index-bounds - ivy--index ivy--length ivy-height)) - (wnd-cands (cl-subseq cands (car bnd) (cadr bnd))) - (case-fold-search (ivy--case-fold-p ivy-text)) - transformer-fn) - (setq ivy--window-index (nth 2 bnd)) - (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last)) - (with-ivy-window - (with-current-buffer (ivy-state-buffer ivy-last) - (setq wnd-cands (mapcar transformer-fn wnd-cands))))) - (ivy--wnd-cands-to-str wnd-cands)))) - -(defun ivy--wnd-cands-to-str (wnd-cands) - (let ((str (concat "\n" - (funcall (ivy-alist-setting ivy-format-functions-alist) - (condition-case nil - (mapcar - #'ivy--format-minibuffer-line - wnd-cands) - (error wnd-cands)))))) - (put-text-property 0 (length str) 'read-only nil str) - str)) - -(defvar recentf-list) -(defvar bookmark-alist) - -(defcustom ivy-virtual-abbreviate 'name - "The mode of abbreviation for virtual buffer names." - :type '(choice - (const :tag "Only name" name) - (const :tag "Abbreviated path" abbreviate) - (const :tag "Full path" full) - ;; eventually, uniquify - )) -(declare-function bookmark-maybe-load-default-file "bookmark") -(declare-function bookmark-get-filename "bookmark") - -(defun ivy--virtual-buffers () - "Adapted from `ido-add-virtual-buffers-to-list'." - (require 'bookmark) - (unless recentf-mode - (recentf-mode 1)) - (bookmark-maybe-load-default-file) - (let* ((vb-bkm (delete " - no file -" - (delq nil (mapcar #'bookmark-get-filename - bookmark-alist)))) - (vb-list (cond ((eq ivy-use-virtual-buffers 'recentf) - recentf-list) - ((eq ivy-use-virtual-buffers 'bookmarks) - vb-bkm) - (ivy-use-virtual-buffers - (append recentf-list vb-bkm)) - (t nil))) - virtual-buffers) - (dolist (head vb-list) - (let* ((file-name (if (stringp head) - head - (cdr head))) - (name (cond ((eq ivy-virtual-abbreviate 'name) - (file-name-nondirectory file-name)) - ((eq ivy-virtual-abbreviate 'abbreviate) - (abbreviate-file-name file-name)) - (t - (expand-file-name file-name))))) - (when (equal name "") - (setq name - (if (consp head) - (car head) - (file-name-nondirectory (directory-file-name file-name))))) - (unless (or (equal name "") - (get-file-buffer file-name) - (assoc name virtual-buffers)) - (push (cons (copy-sequence name) file-name) virtual-buffers)))) - (when virtual-buffers - (dolist (comp virtual-buffers) - (put-text-property 0 (length (car comp)) - 'face 'ivy-virtual - (car comp))) - (setq ivy--virtual-buffers (nreverse virtual-buffers)) - (mapcar #'car ivy--virtual-buffers)))) - -(defcustom ivy-ignore-buffers '("\\` ") - "List of regexps or functions matching buffer names to ignore." - :type '(repeat (choice regexp function))) - -(defvar ivy-switch-buffer-faces-alist '((dired-mode . ivy-subdir) - (org-mode . ivy-org)) - "Store face customizations for `ivy-switch-buffer'. -Each KEY is `major-mode', each VALUE is a face name.") - -(defun ivy--buffer-list (str &optional virtual predicate) - "Return the buffers that match STR. -If VIRTUAL is non-nil, add virtual buffers. -If optional argument PREDICATE is non-nil, use it to test each -possible match. See `all-completions' for further information." - (delete-dups - (nconc - (mapcar - (lambda (x) - (let* ((buf (get-buffer x)) - (dir (buffer-local-value 'default-directory buf)) - (face (if (and dir - (ignore-errors - (file-remote-p (abbreviate-file-name dir)))) - 'ivy-remote - (cdr (assq (buffer-local-value 'major-mode buf) - ivy-switch-buffer-faces-alist))))) - (if face - (propertize x 'face face) - x))) - (all-completions str #'internal-complete-buffer predicate)) - (and virtual - (ivy--virtual-buffers))))) - -(defvar ivy-views (and nil - `(("ivy + *scratch* {}" - (vert - (file ,(expand-file-name "ivy.el")) - (buffer "*scratch*"))) - ("swiper + *scratch* {}" - (horz - (file ,(expand-file-name "swiper.el")) - (buffer "*scratch*"))))) - "Store window configurations selectable by `ivy-switch-buffer'. - -The default value is given as an example. - -Each element is a list of (NAME TREE). NAME is a string, it's -recommended to end it with a distinctive snippet e.g. \"{}\" so -that it's easy to distinguish the window configurations. - -TREE is a nested list with the following valid cars: -- vert: split the window vertically -- horz: split the window horizontally -- file: open the specified file -- buffer: open the specified buffer - -TREE can be nested multiple times to have multiple window splits.") - -(defun ivy-default-view-name () - "Return default name for new view." - (let* ((default-view-name - (concat "{} " - (mapconcat #'identity - (sort - (mapcar (lambda (w) - (let* ((b (window-buffer w)) - (f (buffer-file-name b))) - (if f - (file-name-nondirectory f) - (buffer-name b)))) - (window-list)) - #'string-lessp) - " "))) - (view-name-re (concat "\\`" - (regexp-quote default-view-name) - " \\([0-9]+\\)")) - old-view) - (cond ((setq old-view - (cl-find-if - (lambda (x) - (string-match view-name-re (car x))) - ivy-views)) - (format "%s %d" - default-view-name - (1+ (string-to-number - (match-string 1 (car old-view)))))) - ((assoc default-view-name ivy-views) - (concat default-view-name " 1")) - (t - default-view-name)))) - -(defun ivy-push-view (&optional arg) - "Push the current window tree on `ivy-views'. - -When ARG is non-nil, replace a selected item on `ivy-views'. - -Currently, the split configuration (i.e. horizontal or vertical) -and point positions are saved, but the split positions aren't. -Use `ivy-pop-view' to delete any item from `ivy-views'." - (interactive "P") - (let* ((view (cl-labels - ((ft (tr) - (if (consp tr) - (if (eq (car tr) t) - (cons 'vert - (mapcar #'ft (cddr tr))) - (cons 'horz - (mapcar #'ft (cddr tr)))) - (with-current-buffer (window-buffer tr) - (cond (buffer-file-name - (list 'file buffer-file-name (point))) - ((eq major-mode 'dired-mode) - (list 'file default-directory (point))) - (t - (list 'buffer (buffer-name) (point)))))))) - (ft (car (window-tree))))) - (view-name - (if arg - (ivy-read "Update view: " ivy-views) - (ivy-read "Name view: " nil - :initial-input (ivy-default-view-name))))) - (when view-name - (let ((x (assoc view-name ivy-views))) - (if x - (setcdr x (list view)) - (push (list view-name view) ivy-views)))))) - -(defun ivy-pop-view-action (view) - "Delete VIEW from `ivy-views'." - (setq ivy-views (delete view ivy-views)) - (setq ivy--all-candidates - (delete (car view) ivy--all-candidates)) - (setq ivy--old-cands nil)) - -(defun ivy-pop-view () - "Delete a view to delete from `ivy-views'." - (interactive) - (ivy-read "Pop view: " ivy-views - :preselect (caar ivy-views) - :action #'ivy-pop-view-action - :caller 'ivy-pop-view)) - -(defun ivy-source-views () - "Return the name of the views saved in `ivy-views'." - (mapcar #'car ivy-views)) - -(ivy-set-sources - 'ivy-switch-buffer - '((original-source) - (ivy-source-views))) - -(defun ivy-set-view-recur (view) - "Set VIEW recursively." - (cond ((eq (car view) 'vert) - (let* ((wnd1 (selected-window)) - (wnd2 (split-window-vertically)) - (views (cdr view)) - (v (pop views)) - (temp-wnd)) - (with-selected-window wnd1 - (ivy-set-view-recur v)) - (while (setq v (pop views)) - (with-selected-window wnd2 - (when views - (setq temp-wnd (split-window-vertically))) - (ivy-set-view-recur v) - (when views - (setq wnd2 temp-wnd)))))) - ((eq (car view) 'horz) - (let* ((wnd1 (selected-window)) - (wnd2 (split-window-horizontally)) - (views (cdr view)) - (v (pop views)) - (temp-wnd)) - (with-selected-window wnd1 - (ivy-set-view-recur v)) - (while (setq v (pop views)) - (with-selected-window wnd2 - (when views - (setq temp-wnd (split-window-horizontally))) - (ivy-set-view-recur v) - (when views - (setq wnd2 temp-wnd)))))) - ((eq (car view) 'file) - (let* ((name (nth 1 view)) - (virtual (assoc name ivy--virtual-buffers)) - buffer) - (cond ((setq buffer (get-buffer name)) - (switch-to-buffer buffer nil 'force-same-window)) - (virtual - (find-file (cdr virtual))) - ((file-exists-p name) - (find-file name)))) - (when (and (> (length view) 2) - (numberp (nth 2 view))) - (goto-char (nth 2 view)))) - ((eq (car view) 'buffer) - (switch-to-buffer (nth 1 view)) - (when (and (> (length view) 2) - (numberp (nth 2 view))) - (goto-char (nth 2 view)))) - ((eq (car view) 'sexp) - (eval (nth 1 view))))) - -(defun ivy--switch-buffer-action (buffer) - "Switch to BUFFER. -BUFFER may be a string or nil." - (if (zerop (length buffer)) - (switch-to-buffer - ivy-text nil 'force-same-window) - (let ((virtual (assoc buffer ivy--virtual-buffers)) - (view (assoc buffer ivy-views))) - (cond ((and virtual - (not (get-buffer buffer))) - (find-file (cdr virtual))) - (view - (delete-other-windows) - (let ( - ;; silence "Directory has changed on disk" - (inhibit-message t)) - (ivy-set-view-recur (cadr view)))) - (t - (switch-to-buffer - buffer nil 'force-same-window)))))) - -(defun ivy--switch-buffer-other-window-action (buffer) - "Switch to BUFFER in other window. -BUFFER may be a string or nil." - (if (zerop (length buffer)) - (switch-to-buffer-other-window ivy-text) - (let ((virtual (assoc buffer ivy--virtual-buffers))) - (if (and virtual - (not (get-buffer buffer))) - (find-file-other-window (cdr virtual)) - (switch-to-buffer-other-window buffer))))) - -(defun ivy--rename-buffer-action (buffer) - "Rename BUFFER." - (let ((new-name (read-string "Rename buffer (to new name): "))) - (with-current-buffer buffer - (rename-buffer new-name)))) - -(defun ivy--find-file-action (buffer) - "Find file from BUFFER's directory." - (let* ((virtual (assoc buffer ivy--virtual-buffers)) - (default-directory (if virtual - (file-name-directory (cdr virtual)) - (buffer-local-value 'default-directory - (or (get-buffer buffer) - (current-buffer)))))) - (call-interactively (if (functionp 'counsel-find-file) - #'counsel-find-file - #'find-file)))) - -(defun ivy--kill-buffer-or-virtual (buffer) - (if (get-buffer buffer) - (kill-buffer buffer) - (setq recentf-list (delete - (cdr (assoc buffer ivy--virtual-buffers)) - recentf-list)))) - -(defun ivy--kill-current-candidate () - (setf (ivy-state-preselect ivy-last) ivy--index) - (setq ivy--old-re nil) - (setq ivy--all-candidates (delete (ivy-state-current ivy-last) ivy--all-candidates)) - (let ((ivy--recompute-index-inhibit t)) - (ivy--exhibit))) - -(defun ivy--kill-buffer-action (buffer) - "Kill BUFFER." - (ivy--kill-buffer-or-virtual buffer) - (unless (buffer-live-p (ivy-state-buffer ivy-last)) - (setf (ivy-state-buffer ivy-last) - (with-ivy-window (current-buffer)))) - (ivy--kill-current-candidate)) - -(defvar ivy-switch-buffer-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-k") 'ivy-switch-buffer-kill) - map)) - -(defun ivy-switch-buffer-kill () - "When at end-of-line, kill the current buffer in `ivy-switch-buffer'. -Otherwise, forward to `ivy-kill-line'." - (interactive) - (if (not (eolp)) - (ivy-kill-line) - (ivy--kill-buffer-action - (ivy-state-current ivy-last)))) - -(ivy-set-actions - 'ivy-switch-buffer - '(("f" - ivy--find-file-action - "find file") - ("j" - ivy--switch-buffer-other-window-action - "other window") - ("k" - ivy--kill-buffer-action - "kill") - ("r" - ivy--rename-buffer-action - "rename"))) - -(ivy-set-actions - t - `(("i" ,(lambda (x) (insert (if (stringp x) x (car x)))) "insert") - ("w" ,(lambda (x) (kill-new (if (stringp x) x (car x)))) "copy"))) - -(defun ivy--switch-buffer-matcher (regexp candidates) - "Return REGEXP matching CANDIDATES. -Skip buffers that match `ivy-ignore-buffers'." - (let ((res (ivy--re-filter regexp candidates))) - (if (or (null ivy-use-ignore) - (null ivy-ignore-buffers)) - res - (or (cl-remove-if - (lambda (buf) - (cl-find-if - (lambda (f-or-r) - (if (functionp f-or-r) - (funcall f-or-r buf) - (string-match-p f-or-r buf))) - ivy-ignore-buffers)) - res) - (and (eq ivy-use-ignore t) - res))))) - -(defun ivy-append-face (str face) - "Append to STR the property FACE." - (setq str (copy-sequence str)) - (ivy-add-face-text-property 0 (length str) face str t) - str) - -(defun ivy-switch-buffer-transformer (str) - "Transform candidate STR when switching buffers." - (let ((b (get-buffer str))) - (if (and b (buffer-file-name b)) - (cond - ((and (not (ignore-errors (file-remote-p (buffer-file-name b)))) - (not (verify-visited-file-modtime b))) - (ivy-append-face str 'ivy-modified-outside-buffer)) - ((buffer-modified-p b) - (ivy-append-face str 'ivy-modified-buffer)) - (t str)) - str))) - -(defun ivy-switch-buffer-occur (cands) - "Occur function for `ivy-switch-buffer' using `ibuffer'. -CANDS are the candidates to be displayed." - (unless cands - (setq cands (all-completions ivy-text #'internal-complete-buffer))) - (ibuffer - nil (buffer-name) - `((or ,@(cl-mapcan - (lambda (cand) - (unless (eq (get-text-property 0 'face cand) 'ivy-virtual) - `((name . ,(format "\\_<%s\\_>" (regexp-quote cand)))))) - cands))))) - -;;;###autoload -(defun ivy-switch-buffer () - "Switch to another buffer." - (interactive) - (ivy-read "Switch to buffer: " #'internal-complete-buffer - :keymap ivy-switch-buffer-map - :preselect (buffer-name (other-buffer (current-buffer))) - :action #'ivy--switch-buffer-action - :matcher #'ivy--switch-buffer-matcher - :caller 'ivy-switch-buffer)) - -(ivy-configure 'ivy-switch-buffer - :occur #'ivy-switch-buffer-occur - :display-transformer-fn #'ivy-switch-buffer-transformer) - -;;;###autoload -(defun ivy-switch-view () - "Switch to one of the window views stored by `ivy-push-view'." - (interactive) - (let ((ivy-initial-inputs-alist - '((ivy-switch-buffer . "{}")))) - (ivy-switch-buffer))) - -;;;###autoload -(defun ivy-switch-buffer-other-window () - "Switch to another buffer in another window." - (interactive) - (ivy-read "Switch to buffer in other window: " #'internal-complete-buffer - :matcher #'ivy--switch-buffer-matcher - :preselect (buffer-name (other-buffer (current-buffer))) - :action #'ivy--switch-buffer-other-window-action - :keymap ivy-switch-buffer-map - :caller 'ivy-switch-buffer-other-window)) - -(ivy-configure 'ivy-switch-buffer-other-window - :occur #'ivy-switch-buffer-occur) - -(defun ivy--yank-handle-case-fold (text) - (if (and (> (length ivy-text) 0) - (string= (downcase ivy-text) ivy-text)) - (downcase text) - text)) - -(defun ivy--yank-by (fn &rest args) - "Pull buffer text from current line into search string. -The region to extract is determined by the respective values of -point before and after applying FN to ARGS." - (let (text) - (with-ivy-window - (let ((beg (point)) - (bol (line-beginning-position)) - (eol (line-end-position)) - end) - (unwind-protect - (progn (apply fn args) - (setq end (goto-char (max bol (min (point) eol)))) - (setq text (buffer-substring-no-properties beg end)) - (ivy--pulse-region beg end)) - (unless text - (goto-char beg))))) - (when text - (insert (replace-regexp-in-string - " +" " " - (ivy--yank-handle-case-fold text) - t t))))) - -(defun ivy-yank-word (&optional arg) - "Pull next word from buffer into search string. -If optional ARG is non-nil, pull in the next ARG -words (previous if ARG is negative)." - (interactive "p") - (ivy--yank-by #'forward-word arg)) - -(defun ivy-yank-symbol (&optional arg) - "Pull next symbol from buffer into search string. -If optional ARG is non-nil, pull in the next ARG -symbols (previous if ARG is negative)." - (interactive "p") - ;; Emacs < 24.4 compatibility - (unless (fboundp 'forward-symbol) - (require 'thingatpt)) - (ivy--yank-by #'forward-symbol (or arg 1))) - -(defun ivy-yank-char (&optional arg) - "Pull next character from buffer into search string. -If optional ARG is non-nil, pull in the next ARG -characters (previous if ARG is negative)." - (interactive "p") - (ivy--yank-by #'forward-char arg)) - -(defvar ivy--pulse-overlay nil - "Overlay used to highlight yanked word.") - -(defvar ivy--pulse-timer nil - "Timer used to dispose of `ivy--pulse-overlay'.") - -(defcustom ivy-pulse-delay 0.5 - "Number of seconds to display `ivy-yanked-word' highlight. -When nil, disable highlighting." - :type '(choice - (number :tag "Delay in seconds") - (const :tag "Disable" nil))) - -(defun ivy--pulse-region (start end) - "Temporarily highlight text between START and END. -The \"pulse\" duration is determined by `ivy-pulse-delay'." - (when ivy-pulse-delay - (if ivy--pulse-overlay - (let ((ostart (overlay-start ivy--pulse-overlay)) - (oend (overlay-end ivy--pulse-overlay))) - (when (< end start) - (cl-rotatef start end)) - ;; Extend the existing overlay's region to include START..END, - ;; but only if the two regions are contiguous. - (move-overlay ivy--pulse-overlay - (if (= start oend) ostart start) - (if (= end ostart) oend end))) - (setq ivy--pulse-overlay (make-overlay start end)) - (overlay-put ivy--pulse-overlay 'face 'ivy-yanked-word)) - (when ivy--pulse-timer - (cancel-timer ivy--pulse-timer)) - (setq ivy--pulse-timer - (run-at-time ivy-pulse-delay nil #'ivy--pulse-cleanup)))) - -(defun ivy--pulse-cleanup () - "Cancel `ivy--pulse-timer' and delete `ivy--pulse-overlay'." - (when ivy--pulse-timer - (cancel-timer ivy--pulse-timer) - (setq ivy--pulse-timer nil)) - (when ivy--pulse-overlay - (delete-overlay ivy--pulse-overlay) - (setq ivy--pulse-overlay nil))) - -(defun ivy-kill-ring-save () - "Store the current candidates into the kill ring. -If the region is active, forward to `kill-ring-save' instead." - (interactive) - (if (region-active-p) - (call-interactively 'kill-ring-save) - (kill-new - (mapconcat - #'identity - ivy--old-cands - "\n")))) - -(defun ivy-insert-current () - "Make the current candidate into current input. -Don't finish completion." - (interactive) - (delete-minibuffer-contents) - (let ((end (and ivy--directory - (ivy--dirname-p (ivy-state-current ivy-last)) - -1))) - (insert (substring-no-properties - (ivy-state-current ivy-last) 0 end)))) - -(defun ivy-insert-current-full () - "Insert the full Yank the current directory into the minibuffer." - (interactive) - (insert ivy--directory)) - -(defcustom ivy-preferred-re-builders - '((ivy--regex-plus . "ivy") - (ivy--regex-ignore-order . "order") - (ivy--regex-fuzzy . "fuzzy")) - "Alist of preferred re-builders with display names. -This list can be rotated with `ivy-rotate-preferred-builders'." - :type '(alist :key-type function :value-type string)) - -(defun ivy-rotate-preferred-builders () - "Switch to the next re builder in `ivy-preferred-re-builders'." - (interactive) - (when ivy-preferred-re-builders - (setq ivy--old-re nil) - (setq ivy--regex-function - (let ((cell (assq ivy--regex-function ivy-preferred-re-builders))) - (car (or (cadr (memq cell ivy-preferred-re-builders)) - (car ivy-preferred-re-builders))))))) - -(defun ivy-toggle-fuzzy () - "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'." - (interactive) - (setq ivy--old-re nil) - (if (eq ivy--regex-function 'ivy--regex-fuzzy) - (setq ivy--regex-function 'ivy--regex-plus) - (setq ivy--regex-function 'ivy--regex-fuzzy))) - -(defvar ivy--reverse-i-search-symbol nil - "Store the history symbol.") - -(defun ivy-reverse-i-search-kill () - "Remove the current item from history" - (interactive) - (if (not (eolp)) - (ivy-kill-line) - (let ((current (ivy-state-current ivy-last))) - (if (symbolp ivy--reverse-i-search-symbol) - (set - ivy--reverse-i-search-symbol - (delete current (symbol-value ivy--reverse-i-search-symbol))) - (ring-remove - ivy--reverse-i-search-symbol - (ring-member ivy--reverse-i-search-symbol (ivy-state-current ivy-last))))) - (ivy--kill-current-candidate))) - -(defvar ivy-reverse-i-search-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-k") 'ivy-reverse-i-search-kill) - map)) - -(defun ivy-history-contents (history) - "Copy contents of HISTORY. -A copy is necessary so that we don't clobber any string attributes. -Also set `ivy--reverse-i-search-symbol' to HISTORY." - (setq ivy--reverse-i-search-symbol history) - (cond ((symbolp history) - (delete-dups - (copy-sequence (symbol-value history)))) - ((ring-p history) - (delete-dups - (when (> (ring-size history) 0) - (ring-elements history)))) - ((sequencep history) - (delete-dups - (copy-sequence history))) - (t - (error "Expected a symbol, ring, or sequence: %S" history)))) - -(defun ivy-reverse-i-search () - "Enter a recursive `ivy-read' session using the current history. -The selected history element will be inserted into the minibuffer. -\\ -You can also delete an element from history with \\[ivy-reverse-i-search-kill]." - (interactive) - (cond - ((= (minibuffer-depth) 0) - (user-error - "This command is intended to be called with \"C-r\" from `ivy-read'.")) - ;; don't recur - ((and (> (minibuffer-depth) 1) - (eq (ivy-state-caller ivy-last) 'ivy-reverse-i-search))) - (t - (let ((enable-recursive-minibuffers t) - (old-last ivy-last)) - (ivy-read "Reverse-i-search: " - (ivy-history-contents (ivy-state-history ivy-last)) - :keymap ivy-reverse-i-search-map - :action (lambda (x) - (ivy--reset-state - (setq ivy-last old-last)) - (delete-minibuffer-contents) - (insert (substring-no-properties x)) - (ivy--cd-maybe)) - :caller 'ivy-reverse-i-search))))) - -(defun ivy-restrict-to-matches () - "Restrict candidates to current input and erase input." - (interactive) - (delete-minibuffer-contents) - (if (ivy-state-dynamic-collection ivy-last) - (progn - (setf (ivy-state-dynamic-collection ivy-last) nil) - (setf (ivy-state-collection ivy-last) - (setq ivy--all-candidates ivy--old-cands))) - (setq ivy--all-candidates - (ivy--filter ivy-text ivy--all-candidates)))) - -;;* Occur -(defvar-local ivy-occur-last nil - "Buffer-local value of `ivy-last'. -Can't re-use `ivy-last' because using e.g. `swiper' in the same -buffer would modify `ivy-last'.") - -(defvar ivy-occur-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'ivy-occur-click) - (define-key map (kbd "RET") 'ivy-occur-press-and-switch) - (define-key map (kbd "j") 'ivy-occur-next-line) - (define-key map (kbd "k") 'ivy-occur-previous-line) - (define-key map (kbd "h") 'backward-char) - (define-key map (kbd "l") 'forward-char) - (define-key map (kbd "f") 'ivy-occur-press) - (define-key map (kbd "g") 'ivy-occur-revert-buffer) - (define-key map (kbd "a") 'ivy-occur-read-action) - (define-key map (kbd "o") 'ivy-occur-dispatch) - (define-key map (kbd "c") 'ivy-occur-toggle-calling) - (define-key map (kbd "q") 'quit-window) - (define-key map (kbd "R") 'read-only-mode) - (define-key map (kbd "C-d") 'ivy-occur-delete-candidate) - map) - "Keymap for Ivy Occur mode.") - -(defun ivy-occur-toggle-calling () - "Toggle `ivy-calling'." - (interactive) - (if (setq ivy-calling (not ivy-calling)) - (progn - (setq mode-name "Ivy-Occur [calling]") - (ivy-occur-press)) - (setq mode-name "Ivy-Occur")) - (force-mode-line-update)) - -(defun ivy--find-occur-buffer () - (let ((cb (current-buffer))) - (cl-find-if - (lambda (b) - (with-current-buffer b - (and (eq major-mode 'ivy-occur-grep-mode) - (equal cb (ivy-state-buffer ivy-occur-last))))) - (buffer-list)))) - -(defun ivy--select-occur-buffer () - (let* ((ob (ivy--find-occur-buffer)) - (ow (cl-find-if (lambda (w) (equal ob (window-buffer w))) - (window-list)))) - (if ow - (select-window ow) - (pop-to-buffer ob)))) - -(defun ivy-occur-next-line (&optional arg) - "Move the cursor down ARG lines. -When `ivy-calling' isn't nil, call `ivy-occur-press'." - (interactive "p") - (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5) - ((derived-mode-p 'ivy-occur-mode) 2)))) - (if offset - (progn - (if (< (line-number-at-pos) offset) - (progn - (goto-char (point-min)) - (forward-line (1- offset))) - (forward-line arg) - (when (eolp) - (forward-line -1))) - (when ivy-calling - (ivy-occur-press))) - (ivy--select-occur-buffer) - (ivy-occur-next-line arg) - (ivy-occur-press-and-switch)))) - -(defun ivy-occur-previous-line (&optional arg) - "Move the cursor up ARG lines. -When `ivy-calling' isn't nil, call `ivy-occur-press'." - (interactive "p") - (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5) - ((derived-mode-p 'ivy-occur-mode) 2)))) - (if offset - (progn - (forward-line (- arg)) - (when (< (line-number-at-pos) offset) - (goto-char (point-min)) - (forward-line (1- offset))) - (when ivy-calling - (ivy-occur-press))) - (ivy--select-occur-buffer) - (ivy-occur-previous-line arg) - (ivy-occur-press-and-switch)))) - -(defun ivy-occur-next-error (n &optional reset) - "A `next-error-function' for `ivy-occur-mode'." - (interactive "p") - (when reset - (goto-char (point-min))) - (setq n (or n 1)) - (let ((ivy-calling t)) - (cond ((< n 0) (ivy-occur-previous-line (- n))) - (t (ivy-occur-next-line n))))) - -(define-derived-mode ivy-occur-mode fundamental-mode "Ivy-Occur" - "Major mode for output from \\[ivy-occur]. - -\\{ivy-occur-mode-map}" - (setq-local view-read-only nil)) - -(defvar ivy-occur-grep-mode-map - (let ((map (copy-keymap ivy-occur-mode-map))) - (define-key map (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode) - (define-key map "w" 'ivy-wgrep-change-to-wgrep-mode) - map) - "Keymap for Ivy Occur Grep mode.") - -(defun ivy-occur-delete-candidate () - (interactive) - (let ((inhibit-read-only t)) - (delete-region (line-beginning-position) - (1+ (line-end-position))))) - -(define-derived-mode ivy-occur-grep-mode grep-mode "Ivy-Occur" - "Major mode for output from \\[ivy-occur]. - -\\{ivy-occur-grep-mode-map}" - (setq-local view-read-only nil) - (when (fboundp 'wgrep-setup) - (wgrep-setup))) - -(defun ivy--starts-with-dotslash (str) - (string-match-p "\\`\\.[/\\]" str)) - -(defun ivy--occur-insert-lines (cands) - "Insert CANDS into `ivy-occur' buffer." - (font-lock-mode -1) - (dolist (cand cands) - (setq cand - (if (string-match "\\`\\(.*:[0-9]+:\\)\\(.*\\)\\'" cand) - (let ((file-and-line (match-string 1 cand)) - (grep-line (match-string 2 cand))) - (concat - (propertize file-and-line 'face 'ivy-grep-info) - (ivy--highlight-fuzzy grep-line))) - (ivy--highlight-fuzzy (copy-sequence cand)))) - (add-text-properties - 0 (length cand) - '(mouse-face - highlight - help-echo "mouse-1: call ivy-action") - cand) - (insert (if (string-match-p "\\`.[/\\]" cand) "" " ") - cand ?\n))) - -(defun ivy--occur-default (cands) - "Insert CANDS into the current occur buffer." - (unless cands - (let ((coll (ivy-state-collection ivy-last))) - (when (arrayp coll) - (setq coll (all-completions "" coll (ivy-state-predicate ivy-last)))) - (setq cands (ivy--filter (ivy-state-text ivy-last) coll)))) - (ivy-occur-mode) - (insert (format "%d candidates:\n" (length cands))) - (ivy--occur-insert-lines cands) - (read-only-mode)) - -(defun ivy-occur () - "Stop completion and put the current candidates into a new buffer. - -The new buffer remembers current action(s). - -While in the *ivy-occur* buffer, selecting a candidate with RET or -a mouse click will call the appropriate action for that candidate. - -There is no limit on the number of *ivy-occur* buffers." - (interactive) - (if (not (window-minibuffer-p)) - (user-error "No completion session is active") - (let* ((caller (ivy-state-caller ivy-last)) - (occur-fn (or (plist-get ivy--occurs-list caller) - #'ivy--occur-default)) - (buffer - (generate-new-buffer - (format "*ivy-occur%s \"%s\"*" - (if caller - (concat " " (prin1-to-string caller)) - "") - ivy-text)))) - (with-current-buffer buffer - (funcall occur-fn ivy--old-cands) - (setf (ivy-state-text ivy-last) ivy-text) - (setq ivy-occur-last ivy-last)) - (ivy-exit-with-action - (lambda (_) - (pop-to-buffer buffer) - (setq next-error-last-buffer buffer) - (setq-local next-error-function #'ivy-occur-next-error)))))) - -(defun ivy-occur-revert-buffer () - "Refresh the buffer making it up-to date with the collection. - -Currently only works for `swiper'. In that specific case, the -*ivy-occur* buffer becomes nearly useless as the original buffer -is updated, since the line numbers no longer match. - -Calling this function is as if you called `ivy-occur' on the -updated original buffer." - (interactive) - (let ((caller (ivy-state-caller ivy-occur-last)) - (ivy-last ivy-occur-last)) - (let ((inhibit-read-only t) - (line (line-number-at-pos))) - (erase-buffer) - (funcall (or (plist-get ivy--occurs-list caller) - #'ivy--occur-default) nil) - (goto-char (point-min)) - (forward-line (1- line))) - (setq ivy-occur-last ivy-last))) - -(declare-function wgrep-change-to-wgrep-mode "ext:wgrep") - -(defun ivy-wgrep-change-to-wgrep-mode () - "Forward to `wgrep-change-to-wgrep-mode'." - (interactive) - (if (require 'wgrep nil 'noerror) - (wgrep-change-to-wgrep-mode) - (error "Package wgrep isn't installed"))) - -(defun ivy-occur-read-action () - "Select one of the available actions as the current one." - (interactive) - (let ((ivy-last ivy-occur-last)) - (ivy-read-action))) - -(defun ivy-occur-dispatch () - "Call one of the available actions on the current item." - (interactive) - (let* ((state-action (ivy-state-action ivy-occur-last)) - (actions (if (symbolp state-action) - state-action - (copy-sequence state-action)))) - (unwind-protect - (progn - (ivy-occur-read-action) - (ivy-occur-press)) - (setf (ivy-state-action ivy-occur-last) actions)))) - -(defun ivy-occur-click (event) - "Execute action for the current candidate. -EVENT gives the mouse position." - (interactive "e") - (let ((window (posn-window (event-end event))) - (pos (posn-point (event-end event)))) - (with-current-buffer (window-buffer window) - (goto-char pos) - (ivy-occur-press)))) - -(declare-function swiper--cleanup "swiper") -(declare-function swiper--add-overlays "swiper") -(defvar ivy-occur-timer nil) - -(defun ivy--occur-press-update-window () - (cond - ((memq (ivy-state-caller ivy-occur-last) - (append '(swiper swiper-isearch) ivy-highlight-grep-commands)) - (let ((window (ivy-state-window ivy-occur-last)) - (buffer (ivy-state-buffer ivy-occur-last))) - (when (buffer-live-p buffer) - (cond ((or (not (window-live-p window)) - (equal window (selected-window))) - (save-selected-window - (setf (ivy-state-window ivy-occur-last) - (display-buffer buffer)))) - ((not (equal (window-buffer window) buffer)) - (with-selected-window window - (switch-to-buffer buffer))))))) - - ((memq (ivy-state-caller ivy-occur-last) - '(counsel-describe-function counsel-describe-variable)) - (setf (ivy-state-window ivy-occur-last) - (selected-window)) - (selected-window)))) - -(defun ivy--occur-press-buffer () - (let ((buffer (ivy-state-buffer ivy-last))) - (if (buffer-live-p buffer) - buffer - (current-buffer)))) - -(defun ivy-occur-press () - "Execute action for the current candidate." - (interactive) - (ivy--occur-press-update-window) - (when (save-excursion - (beginning-of-line) - (looking-at "\\(?:./\\| \\)\\(.*\\)$")) - (let* ((ivy-last ivy-occur-last) - (ivy-text (ivy-state-text ivy-last)) - (str (buffer-substring - (match-beginning 1) - (match-end 1))) - (offset (or (get-text-property 0 'offset str) 0)) - (coll (ivy-state-collection ivy-last)) - (action (ivy--get-action ivy-last)) - (ivy-exit 'done)) - (with-ivy-window - (with-current-buffer (ivy--occur-press-buffer) - (save-restriction - (widen) - (funcall action - (if (and (consp coll) - (consp (car coll))) - (assoc str coll) - (substring str offset))))) - (if (memq (ivy-state-caller ivy-last) - (append '(swiper swiper-isearch) ivy-highlight-grep-commands)) - (with-current-buffer (window-buffer (selected-window)) - (swiper--cleanup) - (swiper--add-overlays - (ivy--regex ivy-text) - (line-beginning-position) - (line-end-position) - (selected-window)) - (when (timerp ivy-occur-timer) - (cancel-timer ivy-occur-timer)) - (setq ivy-occur-timer - (run-at-time 1.0 nil 'swiper--cleanup)))))))) - -(defun ivy-occur-press-and-switch () - "Execute action for the current candidate and switch window." - (interactive) - (ivy-occur-press) - (select-window (ivy--get-window ivy-occur-last))) - -(defun ivy--marked-p () - (member (ivy-state-current ivy-last) ivy-marked-candidates)) - -(defun ivy--unmark (cand) - (setcar (member cand ivy--all-candidates) - (setcar (member cand ivy--old-cands) - (substring cand (length ivy-mark-prefix)))) - (setq ivy-marked-candidates - (delete cand ivy-marked-candidates))) - -(defun ivy--mark (cand) - (let ((marked-cand (concat ivy-mark-prefix cand))) - (setcar (member cand ivy--all-candidates) - (setcar (member cand ivy--old-cands) marked-cand)) - (setq ivy-marked-candidates - (append ivy-marked-candidates (list marked-cand))))) - -(defun ivy-mark () - "Mark the selected candidate and move to the next one. - -In `ivy-call', :action will be called in turn for all marked -candidates. - -However, if :multi-action was supplied to `ivy-read', then it -will be called with `ivy-marked-candidates'. This way, it can -make decisions based on the whole marked list." - (interactive) - (unless (ivy--marked-p) - (ivy--mark (ivy-state-current ivy-last))) - (ivy-next-line)) - -(defun ivy-unmark () - "Unmark the selected candidate and move to the next one." - (interactive) - (when (ivy--marked-p) - (ivy--unmark (ivy-state-current ivy-last))) - (ivy-next-line)) - -(defun ivy-unmark-backward () - "Move to the previous candidate and unmark it." - (interactive) - (ivy-previous-line) - (ivy--exhibit) - (when (ivy--marked-p) - (ivy--unmark (ivy-state-current ivy-last)))) - -(defun ivy-toggle-marks () - "Toggle mark for all narrowed candidates." - (interactive) - (dolist (cand ivy--old-cands) - (if (member cand ivy-marked-candidates) - (ivy--unmark cand) - (ivy--mark cand)))) - -(defconst ivy-help-file (let ((default-directory - (if load-file-name - (file-name-directory load-file-name) - default-directory))) - (if (file-exists-p "ivy-help.org") - (expand-file-name "ivy-help.org") - (if (file-exists-p "doc/ivy-help.org") - (expand-file-name "doc/ivy-help.org")))) - "The file for `ivy-help'.") - -(defvar org-hide-emphasis-markers) - -(defun ivy-help () - "Help for `ivy'." - (interactive) - (let ((buf (get-buffer "*Ivy Help*"))) - (unless buf - (setq buf (get-buffer-create "*Ivy Help*")) - (with-current-buffer buf - (insert-file-contents ivy-help-file) - (org-mode) - (setq-local org-hide-emphasis-markers t) - (view-mode) - (goto-char (point-min)) - (let ((inhibit-message t)) - (org-cycle '(64))))) - (if (eq this-command 'ivy-help) - (switch-to-buffer buf) - (with-ivy-window - (pop-to-buffer buf))) - (view-mode) - (goto-char (point-min)))) - -(declare-function ffap-url-p "ffap") -(defvar ffap-url-fetcher) - -(defun ivy-ffap-url-p (string) - "Forward to `ffap-url-p'." - (require 'ffap) - (ffap-url-p string)) - -(defun ivy-ffap-url-fetcher (url) - "Calls `ffap-url-fetcher'." - (require 'ffap) - (funcall ffap-url-fetcher url)) - -(ivy-configure 'read-file-name-internal - :sort-fn #'ivy-sort-file-function-default - :display-transformer-fn #'ivy-read-file-transformer) - -(ivy-configure 'internal-complete-buffer - :display-transformer-fn #'ivy-switch-buffer-transformer) - -(provide 'ivy) - -;;; ivy.el ends here diff --git a/elpa/ivy-0.13.0/ivy.info b/elpa/ivy-0.13.0/ivy.info deleted file mode 100755 index caa0fd6..0000000 --- a/elpa/ivy-0.13.0/ivy.info +++ /dev/null @@ -1,1954 +0,0 @@ -This is ivy.info, produced by makeinfo version 6.5 from ivy.texi. - -Ivy manual, version 0.13.0 - - Ivy is an interactive interface for completion in Emacs. Emacs uses -completion mechanism in a variety of contexts: code, menus, commands, -variables, functions, etc. Completion entails listing, sorting, -filtering, previewing, and applying actions on selected items. When -active, ‘ivy-mode’ completes the selection process by narrowing -available choices while previewing in the minibuffer. Selecting the -final candidate is either through simple keyboard character inputs or -through powerful regular expressions. - - Copyright (C) 2015-2019 Free Software Foundation, Inc. - - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free Documentation License, - Version 1.3 or any later version published by the Free Software - Foundation; with no Invariant Sections, no Front-Cover Texts, and - no Back-Cover Texts. A copy of the license is included in the - section entitled "GNU Free Documentation License". -INFO-DIR-SECTION Emacs -START-INFO-DIR-ENTRY -* Ivy: (ivy). Using Ivy for completion. -END-INFO-DIR-ENTRY - - -File: ivy.info, Node: Top, Next: Introduction, Up: (dir) - -Ivy User Manual -*************** - -* Menu: - -* Introduction:: -* Installation:: -* Getting started:: -* Key bindings:: -* Completion Styles:: -* Customization:: -* Commands:: -* API:: -* Variable Index:: -* Keystroke Index:: - -— The Detailed Node Listing — - -Installation - -* Installing from Emacs Package Manager:: -* Installing from the Git repository:: - -Getting started - -* Basic customization:: - -Key bindings - -* Global key bindings:: -* Minibuffer key bindings:: - -Minibuffer key bindings - -* Key bindings for navigation:: -* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer. -* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open. -* Key bindings that alter the minibuffer input:: -* Other key bindings:: -* Hydra in the minibuffer:: -* Saving the current completion session to a buffer:: - -Completion Styles - -* ivy--regex-plus:: -* ivy--regex-ignore-order:: -* ivy--regex-fuzzy:: - -Customization - -* Faces:: -* Defcustoms:: -* Actions:: -* Packages:: - -Actions - -* What are actions?:: -* How can different actions be called?:: -* How to modify the actions list?:: -* Example - add two actions to each command:: -* Example - define a new command with several actions:: - -Example - add two actions to each command - -* How to undo adding the two actions:: -* How to add actions to a specific command:: - -Example - define a new command with several actions - -* Test the above function with ivy-occur:: - -Commands - -* File Name Completion:: -* Buffer Name Completion:: -* Counsel commands:: - -File Name Completion - -* Using TRAMP:: - -API - -* Required arguments for ivy-read:: -* Optional arguments for ivy-read:: -* Example - counsel-describe-function:: -* Example - counsel-locate:: -* Example - ivy-read-with-extra-properties:: - - - -File: ivy.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top - -1 Introduction -************** - -Ivy is for quick and easy selection from a list. When Emacs prompts for -a string from a list of several possible choices, Ivy springs into -action to assist in narrowing and picking the right string from a vast -number of choices. - - Ivy strives for minimalism, simplicity, customizability and -discoverability. - -Minimalism -.......... - - Uncluttered minibuffer is minimalism. Ivy shows the completion - defaults, the number of matches, and 10 candidate matches below the - input line. Customize ‘ivy-height’ to adjust the number of - candidate matches displayed in the minibuffer. - -Simplicity -.......... - - Simplicity is about Ivy’s behavior in the minibuffer. It is also - about the code interface to extend Ivy’s functionality. The - minibuffer area behaves as close to ‘fundamental-mode’ as possible. - ‘SPC’ inserts a space, for example, instead of being bound to the - more complex ‘minibuffer-complete-word’. Ivy’s code uses - easy-to-examine global variables; avoids needless complications - with branch-introducing custom macros. - -Customizability -............... - - Customizability is about being able to use different methods and - interfaces of completion to tailor the selection process. For - example, adding a custom display function that points to a selected - candidate with ‘>’, instead of highlighting the selected candidate - with the ‘ivy-current-match’ face (see - ‘ivy-format-functions-alist’). Or take the customization of - actions, say after the candidate function is selected. ‘RET’ uses - ‘counsel-describe-function’ to describe the function, whereas ‘M-o - d’ jumps to that function’s definition in the code. The ‘M-o’ - prefix can be uniformly used with characters like ‘d’ to group - similar actions. - -Discoverability -............... - - Ivy displays easily discoverable commands through the hydra - facility. ‘C-o’ in the minibuffer displays a hydra menu. It opens - up within an expanded minibuffer area. Each menu item comes with - short documentation strings and highlighted one-key completions. - So discovering even seldom used keys is simply a matter of ‘C-o’ in - the minibuffer while in the midst of the Ivy interaction. This - discoverability minimizes exiting Ivy interface for documentation - look-ups. - - -File: ivy.info, Node: Installation, Next: Getting started, Prev: Introduction, Up: Top - -2 Installation -************** - -Install Ivy automatically through Emacs’s package manager, or manually -from Ivy’s development repository. - - Emacs 24.3 is the oldest version to run Ivy. Emacs 24.4 is the -oldest version that runs Ivy with fancy faces display. - -* Menu: - -* Installing from Emacs Package Manager:: -* Installing from the Git repository:: - - -File: ivy.info, Node: Installing from Emacs Package Manager, Next: Installing from the Git repository, Up: Installation - -2.1 Installing from Emacs Package Manager -========================================= - -‘M-x’ ‘package-install’ ‘RET’ ‘ivy’ ‘RET’ - - Ivy is installed as part of ‘ivy’ package, which is available from -two different package archives, GNU ELPA and MELPA. For the latest -stable version, use the GNU ELPA archives using the above M-x command. - - For current hourly builds, use the MELPA archives. In MELPA, Ivy is -split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; you can simply -install ‘counsel’ which will bring in the other two as dependencies. -See the code below for adding MELPA to the list of package archives: - - (require 'package) - (add-to-list 'package-archives - '("melpa" . "https://melpa.org/packages/")) - - After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by -‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’. - - For package manager details, see *note (emacs)Packages::. - - -File: ivy.info, Node: Installing from the Git repository, Prev: Installing from Emacs Package Manager, Up: Installation - -2.2 Installing from the Git repository -====================================== - -Why install from Git? -..................... - - • No need to wait for MELPA’s hourly builds - • Easy to revert to previous versions - • Contribute to Ivy’s development; send patches; pull requests - -Configuration steps -................... - - First clone the Swiper repository with: - - cd ~/git && git clone https://github.com/abo-abo/swiper - cd swiper && make compile - - Second, add these lines to the Emacs init file: - - (add-to-list 'load-path "~/git/swiper/") - (require 'ivy) - - Then, update the code with: - - git pull - make - - -File: ivy.info, Node: Getting started, Next: Key bindings, Prev: Installation, Up: Top - -3 Getting started -***************** - -First enable Ivy completion everywhere: - - (ivy-mode 1) - - Note: ‘ivy-mode’ can be toggled on and off with ‘M-x’ ‘ivy-mode’. - -* Menu: - -* Basic customization:: - - -File: ivy.info, Node: Basic customization, Up: Getting started - -3.1 Basic customization -======================= - -Here are some basic settings particularly useful for new Ivy users: - - (setq ivy-use-virtual-buffers t) - (setq ivy-count-format "(%d/%d) ") - - If you want, you can go without any customizations at all. The above -settings are the most bang for the buck in terms of customization. So -users that typically don’t like customize a lot are advised to look at -these settings first. - - For more advanced customizations, refer to ‘M-x describe-variable’ -documentation. - - -File: ivy.info, Node: Key bindings, Next: Completion Styles, Prev: Getting started, Up: Top - -4 Key bindings -************** - -* Menu: - -* Global key bindings:: -* Minibuffer key bindings:: - - -File: ivy.info, Node: Global key bindings, Next: Minibuffer key bindings, Up: Key bindings - -4.1 Global key bindings -======================= - -Here is a list of commands that are useful to be bound globally, along -with some sample bindings: - -Ivy-based interface to standard commands -........................................ - - (global-set-key (kbd "C-s") 'swiper-isearch) - (global-set-key (kbd "M-x") 'counsel-M-x) - (global-set-key (kbd "C-x C-f") 'counsel-find-file) - (global-set-key (kbd "M-y") 'counsel-yank-pop) - (global-set-key (kbd " f") 'counsel-describe-function) - (global-set-key (kbd " v") 'counsel-describe-variable) - (global-set-key (kbd " l") 'counsel-find-library) - (global-set-key (kbd " i") 'counsel-info-lookup-symbol) - (global-set-key (kbd " u") 'counsel-unicode-char) - (global-set-key (kbd " j") 'counsel-set-variable) - (global-set-key (kbd "C-x b") 'ivy-switch-buffer) - (global-set-key (kbd "C-c v") 'ivy-push-view) - (global-set-key (kbd "C-c V") 'ivy-pop-view) - -Ivy-based interface to shell and system tools -............................................. - - (global-set-key (kbd "C-c c") 'counsel-compile) - (global-set-key (kbd "C-c g") 'counsel-git) - (global-set-key (kbd "C-c j") 'counsel-git-grep) - (global-set-key (kbd "C-c L") 'counsel-git-log) - (global-set-key (kbd "C-c k") 'counsel-rg) - (global-set-key (kbd "C-c m") 'counsel-linux-app) - (global-set-key (kbd "C-c n") 'counsel-fzf) - (global-set-key (kbd "C-x l") 'counsel-locate) - (global-set-key (kbd "C-c J") 'counsel-file-jump) - (global-set-key (kbd "C-S-o") 'counsel-rhythmbox) - (global-set-key (kbd "C-c w") 'counsel-wmctrl) - -Ivy-resume and other commands -............................. - - ‘ivy-resume’ resumes the last Ivy-based completion. - - (global-set-key (kbd "C-c C-r") 'ivy-resume) - (global-set-key (kbd "C-c b") 'counsel-bookmark) - (global-set-key (kbd "C-c d") 'counsel-descbinds) - (global-set-key (kbd "C-c g") 'counsel-git) - (global-set-key (kbd "C-c o") 'counsel-outline) - (global-set-key (kbd "C-c t") 'counsel-load-theme) - (global-set-key (kbd "C-c F") 'counsel-org-file) - - You can also enable ‘counsel-mode’ to make some global key binding -remapping for you. - - -File: ivy.info, Node: Minibuffer key bindings, Prev: Global key bindings, Up: Key bindings - -4.2 Minibuffer key bindings -=========================== - -Ivy includes several minibuffer bindings, which are defined in the -‘ivy-minibuffer-map’ keymap variable. The most frequently used ones are -described here. - - ‘swiper’ or ‘counsel-M-x’ add more key bindings through the ‘keymap’ -argument to ‘ivy-read’. These keys, also active in the minibuffer, are -described under their respective commands. - - A key feature of ‘ivy-minibuffer-map’ is its full editing capability -where the familiar ‘C-a’, ‘C-f’, ‘M-d’, ‘M-DEL’, ‘M-b’, ‘M-w’, ‘C-k’, -‘C-y’ key bindings work the same as in ‘fundamental-mode’. - -* Menu: - -* Key bindings for navigation:: -* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer. -* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open. -* Key bindings that alter the minibuffer input:: -* Other key bindings:: -* Hydra in the minibuffer:: -* Saving the current completion session to a buffer:: - - -File: ivy.info, Node: Key bindings for navigation, Next: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings - -4.2.1 Key bindings for navigation ---------------------------------- - - • ‘C-n’ (‘ivy-next-line’) selects the next candidate - • ‘C-p’ (‘ivy-previous-line’) selects the previous candidate - • ‘M-<’ (‘ivy-beginning-of-buffer’) selects the first candidate - • ‘M->’ (‘ivy-end-of-buffer’) selects the last candidate - • ‘C-v’ (‘ivy-scroll-up-command’) scrolls up by ‘ivy-height’ lines - • ‘M-v’ (‘ivy-scroll-down-command’) scrolls down by ‘ivy-height’ - lines - - -- User Option: ivy-wrap - Specifies the wrap-around behavior for ‘C-n’ and ‘C-p’. When - ‘ivy-wrap’ is set to ‘t’, ‘ivy-next-line’ and ‘ivy-previous-line’ - will cycle past the last and the first candidates respectively. - - Wrap-around behavior is off by default. - - -- User Option: ivy-height - Use this option to adjust the minibuffer height, which also affects - scroll size when using ‘C-v’ and ‘M-v’ key bindings. - - ‘ivy-height’ is 10 lines by default. - - -File: ivy.info, Node: Key bindings for single selection action then exit minibuffer, Next: Key bindings for multiple selections and actions keep minibuffer open, Prev: Key bindings for navigation, Up: Minibuffer key bindings - -4.2.2 Key bindings for single selection, action, then exit minibuffer ---------------------------------------------------------------------- - -Ivy can offer several actions from which to choose which action to run. -This "calling an action" operates on the selected candidate. For -example, when viewing a list of files, one action could open it for -editing, one to view it, another to invoke a special function, and so -on. Custom actions can be added to this interface. The precise action -to call on the selected candidate can be delayed until after the -narrowing is completed. No need to exit the interface if unsure which -action to run. This delayed flexibility and customization of actions -extends usability of lists in Emacs. - -‘C-m’ or ‘RET’ (‘ivy-done’) -........................... - - Calls the default action and then exits the minibuffer. - -‘M-o’ (‘ivy-dispatching-done’) -.............................. - - Presents valid actions from which to choose. When only one action - is available, there is no difference between ‘M-o’ and ‘C-m’. - -‘C-j’ (‘ivy-alt-done’) -...................... - - When completing file names, selects the current directory candidate - and starts a new completion session there. Otherwise, it is the - same as ‘ivy-done’. - -‘TAB’ (‘ivy-partial-or-done’) -............................. - - Attempts partial completion, extending current input as much as - possible. ‘TAB TAB’ is the same as ‘C-j’ (‘ivy-alt-done’). - - Example ERT test: - - (should - (equal (ivy-with - '(progn - (ivy-read "Test: " '("can do" "can't, sorry" "other")) - ivy-text) - "c ") - "can")) - -‘C-M-j’ (‘ivy-immediate-done’) -.............................. - - Exits with _the current input_ instead of _the current candidate_ - (like other commands). - - This is useful e.g. when you call ‘find-file’ to create a new - file, but the desired name matches an existing file. In that case, - using ‘C-j’ would select that existing file, which isn’t what you - want - use this command instead. - -‘C-'’ (‘ivy-avy’) -................. - - Uses avy to select one of the candidates on the current candidate - page. This can often be faster than multiple ‘C-n’ or ‘C-p’ - keystrokes followed by ‘C-m’. - - -File: ivy.info, Node: Key bindings for multiple selections and actions keep minibuffer open, Next: Key bindings that alter the minibuffer input, Prev: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings - -4.2.3 Key bindings for multiple selections and actions, keep minibuffer open ----------------------------------------------------------------------------- - -For repeatedly applying multiple actions or acting on multiple -candidates, Ivy does not close the minibuffer between commands. It -keeps the minibuffer open for applying subsequent actions. - - Adding an extra meta key to the normal key chord invokes the special -version of the regular commands that enables applying multiple actions. - -‘C-M-m’ (‘ivy-call’) -.................... - - Is the non-exiting version of ‘C-m’ (‘ivy-done’). - - Instead of closing the minibuffer, ‘C-M-m’ allows selecting another - candidate or another action. For example, ‘C-M-m’ on functions - list invokes ‘describe-function’. When combined with ‘C-n’, - function descriptions can be invoked quickly in succession. - -‘C-M-o’ (‘ivy-dispatching-call’) -................................ - - Is the non-exiting version of ‘M-o’ (‘ivy-dispatching-done’). - - For example, during the ‘counsel-rhythmbox’ completion, press - ‘C-M-o e’ to en-queue the selected candidate, followed by ‘C-n C-m’ - to play the next candidate - the current action reverts to the - default one after ‘C-M-o’. - -‘C-M-n’ (‘ivy-next-line-and-call’) -.................................. - - Combines ‘C-n’ and ‘C-M-m’. Moves to next line and applies an - action. - - Comes in handy when opening multiple files from - ‘counsel-find-file’, ‘counsel-git-grep’, ‘counsel-ag’, - ‘counsel-rg’, or ‘counsel-locate’ lists. Just hold ‘C-M-n’ for - rapid-fire default action on each successive element of the list. - -‘C-M-p’ (‘ivy-previous-line-and-call’) -...................................... - - Combines ‘C-p’ and ‘C-M-m’. - - Similar to the above except it moves through the list in the other - direction. - -‘ivy-resume’ -............ - - Recalls the state of the completion session just before its last - exit. - - Useful after an accidental ‘C-m’ (‘ivy-done’). - - -File: ivy.info, Node: Key bindings that alter the minibuffer input, Next: Other key bindings, Prev: Key bindings for multiple selections and actions keep minibuffer open, Up: Minibuffer key bindings - -4.2.4 Key bindings that alter the minibuffer input --------------------------------------------------- - -‘M-n’ (‘ivy-next-history-element’) -.................................. - - Cycles forward through the Ivy command history. - - Ivy updates an internal history list after each action. When this - history list is empty, ‘M-n’ inserts symbol (or URL) at point into - the minibuffer. - -‘M-p’ (‘ivy-previous-history-element’) -...................................... - - Cycles forward through the Ivy command history. - -‘M-i’ (‘ivy-insert-current’) -............................ - - Inserts the current candidate into the minibuffer. - - Useful for copying and renaming files, for example: ‘M-i’ to insert - the original file name string, edit it, and then ‘C-m’ to complete - the renaming. - -‘M-j’ (‘ivy-yank-word’) -....................... - - Inserts the sub-word at point into the minibuffer. - - This is similar to ‘C-s C-w’ with ‘isearch’. Ivy reserves ‘C-w’ - for ‘kill-region’. See also ‘ivy-yank-symbol’ and ‘ivy-yank-char’. - -‘S-SPC’ (‘ivy-restrict-to-matches’) -................................... - - Deletes the current input, and resets the candidates list to the - currently restricted matches. - - This is how Ivy provides narrowing in successive tiers. - -‘C-r’ (‘ivy-reverse-i-search’) -.............................. - - Starts a recursive completion session through the command’s - history. - - This works just like ‘C-r’ at the bash command prompt, where the - completion candidates are the history items. Upon completion, the - selected candidate string is inserted into the minibuffer. - - -File: ivy.info, Node: Other key bindings, Next: Hydra in the minibuffer, Prev: Key bindings that alter the minibuffer input, Up: Minibuffer key bindings - -4.2.5 Other key bindings ------------------------- - -‘M-w’ (‘ivy-kill-ring-save’) -............................ - - Copies selected candidates to the kill ring. - - Copies the region if the region is active. - - -File: ivy.info, Node: Hydra in the minibuffer, Next: Saving the current completion session to a buffer, Prev: Other key bindings, Up: Minibuffer key bindings - -4.2.6 Hydra in the minibuffer ------------------------------ - -‘C-o’ (‘hydra-ivy/body’) -........................ - - Invokes the hydra menu with short key bindings. - - When Hydra is active, minibuffer editing is disabled and menus -display short aliases: - -Short Normal Command name ------------------------------------------------- -‘o’ ‘C-g’ ‘keyboard-escape-quit’ -‘j’ ‘C-n’ ‘ivy-next-line’ -‘k’ ‘C-p’ ‘ivy-previous-line’ -‘h’ ‘M-<’ ‘ivy-beginning-of-buffer’ -‘l’ ‘M->’ ‘ivy-end-of-buffer’ -‘d’ ‘C-m’ ‘ivy-done’ -‘f’ ‘C-j’ ‘ivy-alt-done’ -‘g’ ‘C-M-m’ ‘ivy-call’ -‘u’ ‘C-c C-o’ ‘ivy-occur’ - - Hydra reduces key strokes, for example: ‘C-n C-n C-n C-n’ is ‘C-o -jjjj’ in Hydra. - - Hydra menu offers these additional bindings: - -‘c’ (‘ivy-toggle-calling’) -.......................... - - Toggle calling the action after each candidate change. It modifies - ‘j’ to ‘jg’, ‘k’ to ‘kg’ etc. - -‘m’ (‘ivy-rotate-preferred-builders’) -..................................... - - Rotate the current regexp matcher. - -‘>’ (‘ivy-minibuffer-grow’) -........................... - - Increase ‘ivy-height’ for the current minibuffer. - -‘<’ (‘ivy-minibuffer-shrink’) -............................. - - Decrease ‘ivy-height’ for the current minibuffer. - -‘w’ (‘ivy-prev-action’) -....................... - - Select the previous action. - -‘s’ (‘ivy-next-action’) -....................... - - Select the next action. - -‘a’ (‘ivy-read-action’) -....................... - - Use a menu to select an action. - -‘C’ (‘ivy-toggle-case-fold’) -............................ - - Toggle case folding (match both upper and lower case characters for - lower case input). - - Hydra menu also offers bindings for marking multiple candidates: - -Key Command name --------------------------------- -‘m’ ‘ivy-mark’ -‘u’ ‘ivy-unmark’ -‘DEL’ ‘ivy-unmark-backward’ -‘t’ ‘ivy-toggle-marks’ - - The action is called on each marked candidate one by one. - - -File: ivy.info, Node: Saving the current completion session to a buffer, Prev: Hydra in the minibuffer, Up: Minibuffer key bindings - -4.2.7 Saving the current completion session to a buffer -------------------------------------------------------- - -‘C-c C-o’ (‘ivy-occur’) -....................... - - Saves the current candidates to a new buffer and exits completion. - - The new buffer is read-only and has a few useful bindings defined. - -‘RET’ or ‘f’ (‘ivy-occur-press’) -................................ - - Call the current action on the selected candidate. - -‘mouse-1’ (‘ivy-occur-click’) -............................. - - Call the current action on the selected candidate. - -‘j’ (‘next-line’) -................. - - Move to next line. - -‘k’ (‘previous-line’) -..................... - - Move to previous line. - -‘a’ (‘ivy-occur-read-action’) -............................. - - Read an action and make it current for this buffer. - -‘o’ (‘ivy-occur-dispatch’) -.......................... - - Read an action and call it on the selected candidate. - -‘q’ (‘quit-window’) -................... - - Bury the current buffer. - - Ivy has no limit on the number of active buffers like these. - - Ivy takes care of naming buffers uniquely by constructing descriptive -names. For example: ‘*ivy-occur counsel-describe-variable "function$*’. - - -File: ivy.info, Node: Completion Styles, Next: Customization, Prev: Key bindings, Up: Top - -5 Completion Styles -******************* - -Ivy’s completion functions rely on a regex builder - a function that -transforms a string input to a string regex. All current candidates -simply have to match this regex. Each collection can be assigned its -own regex builder by customizing ‘ivy-re-builders-alist’. - - The keys of this alist are collection names, and the values are one -of the following: - • ‘ivy--regex’ - • ‘ivy--regex-plus’ - • ‘ivy--regex-ignore-order’ - • ‘ivy--regex-fuzzy’ - • ‘regexp-quote’ - - A catch-all key, ‘t’, applies to all collections that don’t have -their own key. - - The default is: - - (setq ivy-re-builders-alist - '((t . ivy--regex-plus))) - - This example shows a custom regex builder assigned to file name -completion: - - (setq ivy-re-builders-alist - '((read-file-name-internal . ivy--regex-fuzzy) - (t . ivy--regex-plus))) - - Here, ‘read-file-name-internal’ is a function that is passed as the -second argument to ‘completing-read’ for file name completion. - - The regex builder resolves as follows (in order of priority): - 1. ‘re-builder’ argument passed to ‘ivy-read’. - 2. ‘collection’ argument passed to ‘ivy-read’ is a function and has an - entry on ‘ivy-re-builders-alist’. - 3. ‘caller’ argument passed to ‘ivy-read’ has an entry on - ‘ivy-re-builders-alist’. - 4. ‘this-command’ has an entry on ‘ivy-re-builders-alist’. - 5. ‘t’ has an entry on ‘ivy-re-builders-alist’. - 6. ‘ivy--regex’. - -* Menu: - -* ivy--regex-plus:: -* ivy--regex-ignore-order:: -* ivy--regex-fuzzy:: - - -File: ivy.info, Node: ivy--regex-plus, Next: ivy--regex-ignore-order, Up: Completion Styles - -5.1 ivy–regex-plus -================== - -‘ivy--regex-plus’ is Ivy’s default completion method. - - ‘ivy--regex-plus’ matches by splitting the input by spaces and -rebuilding it into a regex. - - As the search string is typed in Ivy’s minibuffer, it is transformed -into valid regex syntax. If the string is ‘"for example"’, it is -transformed into - - "\\(for\\).*\\(example\\)" - - which in regex terminology matches ‘"for"’ followed by a wild card -and then ‘"example"’. Note how Ivy uses the space character to build -wild cards. To match a literal white space, use an extra space. So to -match one space type two spaces, to match two spaces type three spaces, -and so on. - - As Ivy transforms typed characters into regex strings, it provides an -intuitive feedback through font highlights. - - Ivy supports regexp negation with ‘"!"’. For example, ‘"define key ! -ivy quit"’ first selects everything matching ‘"define.*key"’, then -removes everything matching ‘"ivy"’, and finally removes everything -matching ‘"quit"’. What remains is the final result set of the negation -regexp. - - Since Ivy treats minibuffer input as a regexp, the standard regexp -identifiers work: ‘"^"’, ‘"$"’, ‘"\b"’ or ‘"[a-z]"’. The exceptions are -spaces, which translate to ‘".*"’, and ‘"!"’ that signal the beginning -of a negation group. - - -File: ivy.info, Node: ivy--regex-ignore-order, Next: ivy--regex-fuzzy, Prev: ivy--regex-plus, Up: Completion Styles - -5.2 ivy–regex-ignore-order -========================== - -‘ivy--regex-ignore-order’ ignores the order of regexp tokens when -searching for matching candidates. For instance, the input ‘"for -example"’ will match ‘"example test for"’. - - -File: ivy.info, Node: ivy--regex-fuzzy, Prev: ivy--regex-ignore-order, Up: Completion Styles - -5.3 ivy–regex-fuzzy -=================== - -‘ivy--regex-fuzzy’ splits each character with a wild card. Searching -for ‘"for"’ returns all ‘"f.*o.*r"’ matches, resulting in a large number -of hits. Yet some searches need these extra hits. Ivy sorts such large -lists using ‘flx’ package’s scoring mechanism, if it’s installed. - - ‘C-o m’ toggles the current regexp builder. - - -File: ivy.info, Node: Customization, Next: Commands, Prev: Completion Styles, Up: Top - -6 Customization -*************** - -* Menu: - -* Faces:: -* Defcustoms:: -* Actions:: -* Packages:: - - -File: ivy.info, Node: Faces, Next: Defcustoms, Up: Customization - -6.1 Faces -========= - -‘ivy-current-match’ -................... - - Highlights the currently selected candidate. - -‘ivy-minibuffer-match-face-1’ -............................. - - Highlights the background of the match. - -‘ivy-minibuffer-match-face-2’ -............................. - - Highlights the first (modulo 3) matched group. - -‘ivy-minibuffer-match-face-3’ -............................. - - Highlights the second (modulo 3) matched group. - -‘ivy-minibuffer-match-face-4’ -............................. - - Highlights the third (modulo 3) matched group. - -‘ivy-confirm-face’ -.................. - - Highlights the "(confirm)" part of the prompt. - - When ‘confirm-nonexistent-file-or-buffer’ set to ‘t’, then - confirming non-existent files in ‘ivy-mode’ requires an additional - ‘RET’. - - The confirmation prompt will use this face. - - For example: - - (setq confirm-nonexistent-file-or-buffer t) - - Then call ‘find-file’, enter "eldorado" and press ‘RET’ - the - prompt will be appended with "(confirm)". Press ‘RET’ once more to - confirm, or any key to continue the completion. - -‘ivy-match-required-face’ -......................... - - Highlights the "(match required)" part of the prompt. - - When completions have to match available candidates and cannot take - random input, the "(match required)" prompt signals this - constraint. - - For example, call ‘describe-variable’, enter "waldo" and press - ‘RET’ - "(match required)" is prompted. Press any key for the - prompt to disappear. - -‘ivy-subdir’ -............ - - Highlights directories when completing file names. - -‘ivy-remote’ -............ - - Highlights remote files when completing file names. - -‘ivy-virtual’ -............. - - Highlights virtual buffers when completing buffer names. - - Virtual buffers correspond to bookmarks and recent files list, - ‘recentf’. - - Enable virtual buffers with: - - (setq ivy-use-virtual-buffers t) - -‘ivy-modified-buffer’ -..................... - - Highlights modified buffers when switching buffer. - -‘ivy-modified-outside-buffer’ -............................. - - Highlights buffers modified outside Emacs when switching buffer. - - This takes precedence over ‘ivy-modified-buffer’. - - -File: ivy.info, Node: Defcustoms, Next: Actions, Prev: Faces, Up: Customization - -6.2 Defcustoms -============== - - -- User Option: ivy-count-format - A string that specifies display of number of candidates and current - candidate, if one exists. - - The number of matching candidates by default is shown as a right- - padded integer value. - - To disable showing the number of candidates: - - (setq ivy-count-format "") - - To also display the current candidate: - - (setq ivy-count-format "(%d/%d) ") - - The ‘format’-style switches this variable uses are described in the - ‘format’ documentation. - - -- User Option: ivy-display-style - Specifies highlighting candidates in the minibuffer. - - The default setting is ‘'fancy’ in Emacs versions 24.4 or newer. - - Set ‘ivy-display-style’ to ‘nil’ for a plain minibuffer. - - -- User Option: ivy-on-del-error-function - Specifies what to do when ‘DEL’ (‘ivy-backward-delete-char’) fails. - - This is usually the case when there is no text left to delete, - i.e., when ‘DEL’ is typed at the beginning of the minibuffer. - - The default behavior is to quit the completion after ‘DEL’ – a - handy key to invoke after mistakenly triggering a completion. - - -File: ivy.info, Node: Actions, Next: Packages, Prev: Defcustoms, Up: Customization - -6.3 Actions -=========== - -* Menu: - -* What are actions?:: -* How can different actions be called?:: -* How to modify the actions list?:: -* Example - add two actions to each command:: -* Example - define a new command with several actions:: - - -File: ivy.info, Node: What are actions?, Next: How can different actions be called?, Up: Actions - -6.3.1 What are actions? ------------------------ - -An action is a function that is called after you select a candidate -during completion. This function takes a single string argument, which -is the selected candidate. - -Window context when calling an action -..................................... - - Currently, the action is executed in the minibuffer window context. - This means e.g. that if you call ‘insert’ the text will be - inserted into the minibuffer. - - If you want to execute the action in the initial window from which - the completion started, use the ‘with-ivy-window’ wrapper macro. - - (defun ivy-insert-action (x) - (with-ivy-window - (insert x))) - - -File: ivy.info, Node: How can different actions be called?, Next: How to modify the actions list?, Prev: What are actions?, Up: Actions - -6.3.2 How can different actions be called? ------------------------------------------- - - • ‘C-m’ (‘ivy-done’) calls the current action. - • ‘M-o’ (‘ivy-dispatching-done’) presents available actions for - selection, calls it after selection, and then exits. - • ‘C-M-o’ (‘ivy-dispatching-call’) presents available actions for - selection, calls it after selection, and then does not exit. - - -File: ivy.info, Node: How to modify the actions list?, Next: Example - add two actions to each command, Prev: How can different actions be called?, Up: Actions - -6.3.3 How to modify the actions list? -------------------------------------- - -Currently, you can append any amount of your own actions to the default -list of actions. This can be done either for a specific command, or for -all commands at once. - - Usually, the command has only one default action. The convention is -to use single letters when selecting a command, and the letter ‘o’ is -designated for the default command. This way, ‘M-o o’ should be always -equivalent to ‘C-m’. - - -File: ivy.info, Node: Example - add two actions to each command, Next: Example - define a new command with several actions, Prev: How to modify the actions list?, Up: Actions - -6.3.4 Example - add two actions to each command ------------------------------------------------ - -The first action inserts the current candidate into the Ivy window - the -window from which ‘ivy-read’ was called. - - The second action copies the current candidate to the kill ring. - - (defun ivy-yank-action (x) - (kill-new x)) - - (defun ivy-copy-to-buffer-action (x) - (with-ivy-window - (insert x))) - - (ivy-set-actions - t - '(("i" ivy-copy-to-buffer-action "insert") - ("y" ivy-yank-action "yank"))) - - Then in any completion session, ‘M-o y’ invokes ‘ivy-yank-action’, -and ‘M-o i’ invokes ‘ivy-copy-to-buffer-action’. - -* Menu: - -* How to undo adding the two actions:: -* How to add actions to a specific command:: - - -File: ivy.info, Node: How to undo adding the two actions, Next: How to add actions to a specific command, Up: Example - add two actions to each command - -6.3.4.1 How to undo adding the two actions -.......................................... - -Since ‘ivy-set-actions’ modifies the internal dictionary with new data, -set the extra actions list to ‘nil’ by assigning ‘nil’ value to the ‘t’ -key as follows: - - (ivy-set-actions t nil) - - -File: ivy.info, Node: How to add actions to a specific command, Prev: How to undo adding the two actions, Up: Example - add two actions to each command - -6.3.4.2 How to add actions to a specific command -................................................ - -Use the command name as the key: - - (ivy-set-actions - 'swiper - '(("i" ivy-copy-to-buffer-action "insert") - ("y" ivy-yank-action "yank"))) - - -File: ivy.info, Node: Example - define a new command with several actions, Prev: Example - add two actions to each command, Up: Actions - -6.3.5 Example - define a new command with several actions ---------------------------------------------------------- - - (defun my-action-1 (x) - (message "action-1: %s" x)) - - (defun my-action-2 (x) - (message "action-2: %s" x)) - - (defun my-action-3 (x) - (message "action-3: %s" x)) - - (defun my-command-with-3-actions () - (interactive) - (ivy-read "test: " '("foo" "bar" "baz") - :action '(1 - ("o" my-action-1 "action 1") - ("j" my-action-2 "action 2") - ("k" my-action-3 "action 3")))) - - The number 1 above is the index of the default action. Each action -has its own string description for easy selection. - -* Menu: - -* Test the above function with ivy-occur:: - - -File: ivy.info, Node: Test the above function with ivy-occur, Up: Example - define a new command with several actions - -6.3.5.1 Test the above function with ‘ivy-occur’ -................................................ - -To examine each action with each candidate in a key-efficient way, try: - - • Call ‘my-command-with-3-actions’ - • Press ‘C-c C-o’ to close the completion window and move to an - ivy-occur buffer - • Press ‘kkk’ to move to the first candidate, since the point is most - likely at the end of the buffer - • Press ‘oo’ to call the first action - • Press ‘oj’ and ‘ok’ to call the second and the third actions - • Press ‘j’ to move to the next candidate - • Press ‘oo’, ‘oj’, ‘ok’ - • Press ‘j’ to move to the next candidate - • and so on... - - -File: ivy.info, Node: Packages, Prev: Actions, Up: Customization - -6.4 Packages -============ - -‘org-mode’ -.......... - - ‘org-mode’ versions 8.3.3 or later obey ‘completing-read-function’ - (which ‘ivy-mode’ sets). Try refiling headings with similar names - to appreciate ‘ivy-mode’. - -‘magit’ -....... - - Uses ivy by default if Ivy is installed. - -‘find-file-in-project’ -...................... - - Uses ivy by default if Ivy is installed. - -‘projectile’ -............ - - Projectile requires this setting for ivy completion: - - (setq projectile-completion-system 'ivy) - -‘helm-make’ -........... - - Helm-make requires this setting for ivy completion. - - (setq helm-make-completion-method 'ivy) - -automatically integrated packages -................................. - - Ivy re-uses the following packages if they are installed: ‘avy’, - ‘amx’ or ‘smex’, ‘flx’, and ‘wgrep’. - - -File: ivy.info, Node: Commands, Next: API, Prev: Customization, Up: Top - -7 Commands -********** - -* Menu: - -* File Name Completion:: -* Buffer Name Completion:: -* Counsel commands:: - - -File: ivy.info, Node: File Name Completion, Next: Buffer Name Completion, Up: Commands - -7.1 File Name Completion -======================== - -Since file name completion is ubiquitous, Ivy provides extra bindings -that work here: - -‘C-j’ (‘ivy-alt-done’) -...................... - - On a directory, restarts completion from that directory. - - On a file or ‘./’, exit completion with the selected candidate. - -‘DEL’ (‘ivy-backward-delete-char’) -.................................. - - Restart the completion in the parent directory if current input is - empty. - -‘//’ (‘self-insert-command’) -............................ - - Switch to the root directory. - -‘~’ (‘self-insert-command’) -........................... - - Switch to the home directory. - -‘/’ (‘self-insert-command’) -........................... - - If the current input matches an existing directory name exactly, - switch the completion to that directory. - -‘M-r’ (‘ivy-toggle-regexp-quote’) -................................. - - Toggle between input as regexp or not. - - Switch to matching literally since file names include ‘.’, which is - for matching any char in regexp mode. - -- User Option: ivy-extra-directories - Decide if you want to see ‘../’ and ‘./’ during file name - completion. - - Reason to remove: ‘../’ is the same as ‘DEL’. - - Reason not to remove: navigate anywhere with only ‘C-n’, ‘C-p’ and - ‘C-j’. - - Likewise, ‘./’ can be removed. - -History -....... - - File history works the same with ‘M-p’, ‘M-n’, and ‘C-r’, but uses - a custom code for file name completion that cycles through files - previously opened. It also works with TRAMP files. - -* Menu: - -* Using TRAMP:: - - -File: ivy.info, Node: Using TRAMP, Up: File Name Completion - -7.1.1 Using TRAMP ------------------ - -‘~’ (tilde) -........... - - Move to the home directory. Either the local or the remote one, - depending on the current directory. The boolean option - ‘ivy-magic-tilde’ decides whether the binding to do this is ‘~’ or - ‘~/’. - -‘//’ (double slash) -................... - - Move to the root directory. Either the local or the remote one, - depending on the current directory. Here, you can also select a - TRAMP connection method, such as ‘ssh’ or ‘scpx’. - -‘/ C-j’ -....... - - Move the the local root directory. - -‘~~’ -.... - - Move to the local home directory. - - From any directory, with the empty input, inputting ‘/ssh:’ and -pressing ‘C-j’ (or ‘RET’, which is the same thing) completes for host -and user names. - - For ‘/ssh:user@’ input, completes the domain name. - - ‘C-i’ works in a similar way to the default completion. - - You can also get sudo access for the current directory by inputting -‘/sudo::’ ‘RET’. Using ‘/sudo:’ (i.e. single colon instead of double) -will result in a completion session for the desired user. - - Multi-hopping is possible, although a bit complex. - -Example : connect to a remote host ‘cloud’ and open a file with ‘sudo’ there -............................................................................ - - • ‘C-x C-f’ ‘/ssh:cloud|sudo:root:/’. - - -File: ivy.info, Node: Buffer Name Completion, Next: Counsel commands, Prev: File Name Completion, Up: Commands - -7.2 Buffer Name Completion -========================== - - -- User Option: ivy-use-virtual-buffers - When non-nil, add ‘recentf-mode’ and bookmarks to - ‘ivy-switch-buffer’ completion candidates. - - Adding this to Emacs init file: - - (setq ivy-use-virtual-buffers t) - will add additional virtual buffers to the buffers list for recent - files. Selecting such virtual buffers, which are highlighted with - ‘ivy-virtual’ face, will open the corresponding file. - - -File: ivy.info, Node: Counsel commands, Prev: Buffer Name Completion, Up: Commands - -7.3 Counsel commands -==================== - -The main advantages of ‘counsel-’ functions over their basic equivalents -in ‘ivy-mode’ are: - - 1. Multi-actions and non-exiting actions work. - 2. ‘ivy-resume’ can resume the last completion session. - 3. Customize ‘ivy-set-actions’, ‘ivy-re-builders-alist’. - 4. Customize individual keymaps, such as ‘counsel-describe-map’, - ‘counsel-git-grep-map’, or ‘counsel-find-file-map’, instead of - customizing ‘ivy-minibuffer-map’ that applies to all completion - sessions. - - -File: ivy.info, Node: API, Next: Variable Index, Prev: Commands, Up: Top - -8 API -***** - -The main (and only) entry point is the ‘ivy-read’ function. It takes -two required arguments and many optional arguments that can be passed by -a key. The optional ‘:action’ argument is highly recommended for -features such as multi-actions, non-exiting actions, ‘ivy-occur’ and -‘ivy-resume’. - -* Menu: - -* Required arguments for ivy-read:: -* Optional arguments for ivy-read:: -* Example - counsel-describe-function:: -* Example - counsel-locate:: -* Example - ivy-read-with-extra-properties:: - - -File: ivy.info, Node: Required arguments for ivy-read, Next: Optional arguments for ivy-read, Up: API - -8.1 Required arguments for ‘ivy-read’ -===================================== - -‘prompt’ -........ - - A prompt string normally ending in a colon and a space. - ‘ivy-count-format’ is prepended to it during completion. - -‘collection’ -............ - - Either a list of strings, a function, an alist or a hash table. - - If a function, then it has to be compatible with ‘all-completions’. - - -File: ivy.info, Node: Optional arguments for ivy-read, Next: Example - counsel-describe-function, Prev: Required arguments for ivy-read, Up: API - -8.2 Optional arguments for ‘ivy-read’ -===================================== - -‘predicate’ -........... - - Is a function to filter the initial collection. It has to be - compatible with ‘all-completions’. Tip: most of the time, it’s - simpler to just apply this filter to the ‘collection’ argument - itself, e.g. ‘(cl-remove-if-not predicate collection)’. - -‘require-match’ -............... - - When set to a non-nil value, input must match one of the - candidates. Custom input is not accepted. - -‘initial-input’ -............... - - This string argument is included for compatibility with - ‘completing-read’, which inserts it into the minibuffer. - - It’s recommended to use the ‘preselect’ argument instead of this. - -‘history’ -......... - - Name of the symbol to store history. See ‘completing-read’. - -‘preselect’ -........... - - Determines which one of the candidates to initially select. - - When set to an integer value, select the candidate with that index - value. - - When set to any other non-nil value, select the first candidate - matching this value. Comparison is first done with ‘equal’. If - this fails, and when applicable, match ‘preselect’ as a regular - expression. - - Every time the input becomes empty, the item corresponding to - ‘preselect’ is selected. - -‘keymap’ -........ - - A keymap to be composed with ‘ivy-minibuffer-map’. This keymap has - priority over ‘ivy-minibuffer-map’ and can be modified at any later - stage. - -‘update-fn’ -........... - - Is the function called each time the current candidate changes. - This function takes no arguments and is called in the minibuffer’s - ‘post-command-hook’. See ‘swiper’ for an example usage. - -‘sort’ -...... - - When non-nil, use ‘ivy-sort-functions-alist’ to sort the collection - as long as the collection is not larger than ‘ivy-sort-max-size’. - -‘action’ -........ - - Is the function to call after selection. It takes a string - argument. - -‘unwind’ -........ - - Is the function to call before exiting completion. It takes no - arguments. This function is called even if the completion is - interrupted with ‘C-g’. See ‘swiper’ for an example usage. - -‘re-builder’ -............ - - Is a function that takes a string and returns a valid regex. See - ‘Completion Styles’ for details. - -‘matcher’ -......... - - Is a function that takes a regex string and a list of strings and - returns a list of strings matching the regex. Any ordinary Emacs - matching function will suffice, yet finely tuned matching functions - can be used. See ‘counsel-find-file’ for an example usage. - -‘dynamic-collection’ -.................... - - When non-nil, ‘collection’ will be used to dynamically generate the - candidates each time the input changes, instead of being used once - statically with ‘all-completions’ to generate a list of strings. - See ‘counsel-locate’ for an example usage. - -‘caller’ -........ - - Is a symbol that uniquely identifies the function that called - ‘ivy-read’, which may be useful for further customizations. - - -File: ivy.info, Node: Example - counsel-describe-function, Next: Example - counsel-locate, Prev: Optional arguments for ivy-read, Up: API - -8.3 Example - ‘counsel-describe-function’ -========================================= - -This is a typical example of a function with a non-async collection, -which is a collection where all the strings in the collection are known -prior to any input from the user. - - Only the first two arguments (along with ‘action’) are essential - -the rest of the arguments are for fine-tuning, and could be omitted. - - The ‘action’ argument could also be omitted - but then ‘ivy-read’ -would do nothing except returning the string result, which you could -later use yourself. However, it’s recommended that you use the ‘action’ -argument. - - (defun counsel-describe-function () - "Forward to `describe-function'." - (interactive) - (ivy-read "Describe function: " - (let (cands) - (mapatoms - (lambda (x) - (when (fboundp x) - (push (symbol-name x) cands)))) - cands) - :keymap counsel-describe-map - :preselect (ivy-thing-at-point) - :history 'counsel-describe-symbol-history - :require-match t - :action (lambda (x) - (describe-function - (intern x))) - :caller 'counsel-describe-function)) - - Here are the interesting features of the above function, in the order -that they appear: - - • The ‘prompt’ argument is a simple string ending in ": ". - • The ‘collection’ argument evaluates to a (large) list of strings. - • The ‘keymap’ argument is for a custom keymap to supplement - ‘ivy-minibuffer-map’. - • The ‘preselect’ is provided by ‘ivy-thing-at-point’, which returns - a symbol near the point. Ivy then selects the first candidate from - the collection that matches this symbol. To select this - pre-selected candidate, a ‘RET’ will suffice. No further user - input is necessary. - • The ‘history’ argument is for keeping the history of this command - separate from the common history in ‘ivy-history’. - • The ‘require-match’ is set to ‘t’ since it doesn’t make sense to - call ‘describe-function’ on an un-interned symbol. - • The ‘action’ argument calls ‘describe-function’ on the interned - selected candidate. - • The ‘caller’ argument identifies this completion session. This is - important, since with the collection being a list of strings and - not a function name, the only other way for ‘ivy-read’ to identify - "who’s calling" and to apply the appropriate customizations is to - examine ‘this-command’. But ‘this-command’ would be modified if - another command called ‘counsel-describe-function’. - - -File: ivy.info, Node: Example - counsel-locate, Next: Example - ivy-read-with-extra-properties, Prev: Example - counsel-describe-function, Up: API - -8.4 Example - ‘counsel-locate’ -============================== - -This is a typical example of a function with an async collection. Since -the collection function cannot pre-compute all the locatable files in -memory within reasonable limits (time or memory), it relies on user -input to filter the universe of possible candidates to a manageable size -while also continuing to search asynchronously for possible candidates. -Both the filtering and searching continues with each character change of -the input with rapid updates to the collection presented without idle -waiting times. This live update will continue as long as there are -likely candidates. Eventually updates to the minibuffer will stop after -user input, filtering, and searching have exhausted looking for possible -candidates. - - Async collections suit long-running shell commands, such as ‘locate’. -With each new input, a new process starts while the old process is -killed. The collection is refreshed anew with each new process. -Meanwhile the user can provide more input characters (for further -narrowing) or select a candidate from the visible collection. - - (defun counsel-locate-function (str) - (or - (ivy-more-chars) - (progn - (counsel--async-command - (format "locate %s '%s'" - (mapconcat #'identity counsel-locate-options " ") - (counsel--elisp-to-pcre - (ivy--regex str)))) - '("" "working...")))) - - ;;;###autoload - (defun counsel-locate (&optional initial-input) - "Call the \"locate\" shell command. - INITIAL-INPUT can be given as the initial minibuffer input." - (interactive) - (ivy-read "Locate: " #'counsel-locate-function - :initial-input initial-input - :dynamic-collection t - :history 'counsel-locate-history - :action (lambda (file) - (with-ivy-window - (when file - (find-file file)))) - :unwind #'counsel-delete-process - :caller 'counsel-locate)) - - Here are the interesting features of the above functions, in the -order that they appear: - - • ‘counsel-locate-function’ takes a string argument and returns a - list of strings. Note that it’s not compatible with - ‘all-completions’, but since we’re not using that here, might as - well use one argument instead of three. - • ‘ivy-more-chars’ is a simple function that returns e.g. ‘'("2 - chars more")’ asking the user for more input. - • ‘counsel--async-command’ is a very easy API simplification that - takes a single string argument suitable for - ‘shell-command-to-string’. So you could prototype your function as - non-async using ‘shell-command-to-string’ and ‘split-string’ to - produce a collection, then decide that you want async and simply - swap in ‘counsel--async-command’. - • ‘counsel-locate’ is an interactive function with an optional - ‘initial-input’. - • ‘#'counsel-locate-function’ is passed as the ‘collection’ argument. - • ‘dynamic-collection’ is set to t, since this is an async - collection. - • ‘action’ argument uses ‘with-ivy-window’ wrapper, since we want to - open the selected file in the same window from which - ‘counsel-locate’ was called. - • ‘unwind’ argument is set to ‘#'counsel-delete-process’: when we - press ‘C-g’ we want to kill the running process created by - ‘counsel--async-command’. - • ‘caller’ argument identifies this command for easier customization. - - -File: ivy.info, Node: Example - ivy-read-with-extra-properties, Prev: Example - counsel-locate, Up: API - -8.5 Example - ‘ivy-read-with-extra-properties’ -============================================== - -This is another example to show how to associate additional values to -each displayed strings. - - (defun find-candidates-function (str pred _) - (let ((props '(1 2)) - (strs '("foo" "foo2"))) - (cl-mapcar (lambda (s p) (propertize s 'property p)) - strs - props))) - - (defun find-candidates () - (interactive) - (ivy-read "Find symbols: " - #'find-candidates-function - :action (lambda (x) - (message "Value: %s" (get-text-property 0 'property x) - )))) - - Here are the interesting features of the above function: - - • ‘find-candidates-function’ builds up a list of strings and - associates "foo" with the value 1 and "foo2" with 2. - • ‘find-candidates’ is an interactive function. - • ‘#'find-candidates’ is passed as the ‘collection’ argument. - • ‘action’ gets passed the selected string with the associated value. - It then retrieves that value and displays it. - - -File: ivy.info, Node: Variable Index, Next: Keystroke Index, Prev: API, Up: Top - -Variable Index -************** - -[index] -* Menu: - -* ivy-alt-done: Key bindings for single selection action then exit minibuffer. - (line 30) -* ivy-alt-done <1>: File Name Completion. (line 12) -* ivy-avy: Key bindings for single selection action then exit minibuffer. - (line 64) -* ivy-backward-delete-char: File Name Completion. (line 19) -* ivy-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 16) -* ivy-confirm-face: Faces. (line 34) -* ivy-count-format: Defcustoms. (line 6) -* ivy-current-match: Faces. (line 9) -* ivy-dispatching-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 26) -* ivy-dispatching-done: Key bindings for single selection action then exit minibuffer. - (line 24) -* ivy-display-style: Defcustoms. (line 24) -* ivy-done: Key bindings for single selection action then exit minibuffer. - (line 19) -* ivy-extra-directories: File Name Completion. (line 45) -* ivy-height: Key bindings for navigation. - (line 21) -* ivy-immediate-done: Key bindings for single selection action then exit minibuffer. - (line 53) -* ivy-insert-current: Key bindings that alter the minibuffer input. - (line 23) -* ivy-kill-ring-save: Other key bindings. (line 9) -* ivy-match-required-face: Faces. (line 53) -* ivy-minibuffer-grow: Hydra in the minibuffer. - (line 45) -* ivy-minibuffer-map: Minibuffer key bindings. - (line 6) -* ivy-minibuffer-match-face-1: Faces. (line 14) -* ivy-minibuffer-match-face-2: Faces. (line 19) -* ivy-minibuffer-match-face-3: Faces. (line 24) -* ivy-minibuffer-match-face-4: Faces. (line 29) -* ivy-minibuffer-shrink: Hydra in the minibuffer. - (line 50) -* ivy-modified-buffer: Faces. (line 88) -* ivy-modified-outside-buffer: Faces. (line 93) -* ivy-next-action: Hydra in the minibuffer. - (line 60) -* ivy-next-history-element: Key bindings that alter the minibuffer input. - (line 9) -* ivy-next-line-and-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 36) -* ivy-occur: Saving the current completion session to a buffer. - (line 9) -* ivy-occur-click: Saving the current completion session to a buffer. - (line 21) -* ivy-occur-dispatch: Saving the current completion session to a buffer. - (line 41) -* ivy-occur-press: Saving the current completion session to a buffer. - (line 16) -* ivy-occur-read-action: Saving the current completion session to a buffer. - (line 36) -* ivy-on-del-error-function: Defcustoms. (line 31) -* ivy-partial-or-done: Key bindings for single selection action then exit minibuffer. - (line 37) -* ivy-prev-action: Hydra in the minibuffer. - (line 55) -* ivy-previous-history-element: Key bindings that alter the minibuffer input. - (line 18) -* ivy-previous-line-and-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 47) -* ivy-read-action: Hydra in the minibuffer. - (line 65) -* ivy-remote: Faces. (line 71) -* ivy-restrict-to-matches: Key bindings that alter the minibuffer input. - (line 40) -* ivy-resume: Key bindings for multiple selections and actions keep minibuffer open. - (line 55) -* ivy-reverse-i-search: Key bindings that alter the minibuffer input. - (line 48) -* ivy-rotate-preferred-builders: Hydra in the minibuffer. - (line 40) -* ivy-subdir: Faces. (line 66) -* ivy-toggle-calling: Hydra in the minibuffer. - (line 34) -* ivy-toggle-case-fold: Hydra in the minibuffer. - (line 70) -* ivy-toggle-regexp-quote: File Name Completion. (line 41) -* ivy-use-virtual-buffers: Buffer Name Completion. - (line 6) -* ivy-virtual: Faces. (line 76) -* ivy-wrap: Key bindings for navigation. - (line 14) -* ivy-yank-word: Key bindings that alter the minibuffer input. - (line 32) - - -File: ivy.info, Node: Keystroke Index, Prev: Variable Index, Up: Top - -Keystroke Index -*************** - -[index] -* Menu: - -* /: File Name Completion. (line 35) -* / C-j: Using TRAMP. (line 24) -* //: File Name Completion. (line 25) -* // <1>: Using TRAMP. (line 17) -* <: Hydra in the minibuffer. - (line 50) -* >: Hydra in the minibuffer. - (line 45) -* ~: File Name Completion. (line 30) -* ~ <1>: Using TRAMP. (line 9) -* ~~: Using TRAMP. (line 29) -* a: Hydra in the minibuffer. - (line 65) -* a <1>: Saving the current completion session to a buffer. - (line 36) -* c: Hydra in the minibuffer. - (line 34) -* C: Hydra in the minibuffer. - (line 70) -* C-': Key bindings for single selection action then exit minibuffer. - (line 64) -* C-c C-o: Saving the current completion session to a buffer. - (line 9) -* C-j: Key bindings for single selection action then exit minibuffer. - (line 30) -* C-j <1>: File Name Completion. (line 12) -* C-m: Key bindings for single selection action then exit minibuffer. - (line 19) -* C-M-j: Key bindings for single selection action then exit minibuffer. - (line 53) -* C-M-m: Key bindings for multiple selections and actions keep minibuffer open. - (line 16) -* C-M-n: Key bindings for multiple selections and actions keep minibuffer open. - (line 36) -* C-M-o: Key bindings for multiple selections and actions keep minibuffer open. - (line 26) -* C-M-p: Key bindings for multiple selections and actions keep minibuffer open. - (line 47) -* C-o: Hydra in the minibuffer. - (line 9) -* C-r: Key bindings that alter the minibuffer input. - (line 48) -* DEL: File Name Completion. (line 19) -* f: Saving the current completion session to a buffer. - (line 16) -* j: Saving the current completion session to a buffer. - (line 26) -* k: Saving the current completion session to a buffer. - (line 31) -* m: Hydra in the minibuffer. - (line 40) -* M-i: Key bindings that alter the minibuffer input. - (line 23) -* M-j: Key bindings that alter the minibuffer input. - (line 32) -* M-n: Key bindings that alter the minibuffer input. - (line 9) -* M-o: Key bindings for single selection action then exit minibuffer. - (line 24) -* M-p: Key bindings that alter the minibuffer input. - (line 18) -* M-r: File Name Completion. (line 41) -* M-w: Other key bindings. (line 9) -* mouse-1: Saving the current completion session to a buffer. - (line 21) -* o: Saving the current completion session to a buffer. - (line 41) -* q: Saving the current completion session to a buffer. - (line 46) -* RET: Key bindings for single selection action then exit minibuffer. - (line 19) -* RET <1>: Saving the current completion session to a buffer. - (line 16) -* s: Hydra in the minibuffer. - (line 60) -* S-SPC: Key bindings that alter the minibuffer input. - (line 40) -* TAB: Key bindings for single selection action then exit minibuffer. - (line 37) -* w: Hydra in the minibuffer. - (line 55) - - - -Tag Table: -Node: Top1189 -Node: Introduction3100 -Node: Installation5623 -Node: Installing from Emacs Package Manager6073 -Node: Installing from the Git repository7187 -Node: Getting started8007 -Node: Basic customization8314 -Node: Key bindings8909 -Node: Global key bindings9101 -Node: Minibuffer key bindings11575 -Node: Key bindings for navigation12807 -Node: Key bindings for single selection action then exit minibuffer14014 -Node: Key bindings for multiple selections and actions keep minibuffer open16661 -Node: Key bindings that alter the minibuffer input19053 -Node: Other key bindings20998 -Node: Hydra in the minibuffer21376 -Node: Saving the current completion session to a buffer23794 -Node: Completion Styles25206 -Node: ivy--regex-plus26957 -Node: ivy--regex-ignore-order28443 -Node: ivy--regex-fuzzy28811 -Node: Customization29308 -Node: Faces29494 -Node: Defcustoms31923 -Node: Actions33217 -Node: What are actions?33543 -Node: How can different actions be called?34361 -Node: How to modify the actions list?34932 -Node: Example - add two actions to each command35592 -Node: How to undo adding the two actions36551 -Node: How to add actions to a specific command37003 -Node: Example - define a new command with several actions37419 -Node: Test the above function with ivy-occur38307 -Node: Packages39149 -Node: Commands40114 -Node: File Name Completion40299 -Node: Using TRAMP42095 -Node: Buffer Name Completion43597 -Node: Counsel commands44212 -Node: API44859 -Node: Required arguments for ivy-read45457 -Node: Optional arguments for ivy-read45976 -Node: Example - counsel-describe-function49402 -Node: Example - counsel-locate52260 -Node: Example - ivy-read-with-extra-properties56010 -Node: Variable Index57218 -Node: Keystroke Index64265 - -End Tag Table - - -Local Variables: -coding: utf-8 -End: diff --git a/elpa/ivy-0.13.1.signed b/elpa/ivy-0.13.1.signed deleted file mode 100644 index f46a755..0000000 --- a/elpa/ivy-0.13.1.signed +++ /dev/null @@ -1 +0,0 @@ -Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) (trust undefined) created at 2020-06-22T16:05:01-0500 using RSA \ No newline at end of file diff --git a/elpa/ivy-0.13.1/ChangeLog b/elpa/ivy-0.13.1/ChangeLog deleted file mode 100644 index 2a71274..0000000 --- a/elpa/ivy-0.13.1/ChangeLog +++ /dev/null @@ -1,76 +0,0 @@ -2020-06-22 Oleh Krehel - - Split package ivy into ivy, swiper, counsel - - Publishing them in a single package on GNU ELPA has lead to version - conflicts. - -2019-10-16 Oleh Krehel - - Merge commit 'cd634c6f51458f81898ecf2821ac3169cb65a1eb' from ivy - -2019-07-20 Oleh Krehel - - packages/ivy/dir: Use install-info - -2019-07-20 Oleh Krehel - - Merge commit '85d1e2e779ca92e6ef8e47d08f866b13d4d87aee' from ivy - -2019-05-13 Stefan Monnier - - * avy/targets/checkdoc.el, ivy/doc/scripts.el: copyright tweak - -2019-05-11 Oleh Krehel - - Merge commit '525b2e4887dd839045313f32d3ddeb5cab4c7a7e' from ivy - -2018-01-12 Oleh Krehel - - Fix bad git subtree merge for ivy - -2017-11-30 Oleh Krehel - - Merge commit '4a2cee03519f98cf95b29905dec2566a39ff717e' from swiper - -2017-04-10 Stefan Monnier - - ivy/targets/obsolete-config.el: Satisfy check_copyright - -2017-04-10 Oleh Krehel - - Add 'packages/ivy/' from commit - 'f4b433436668ac09f3d1815fbfb4b71f3e0690fa' - - git-subtree-dir: packages/ivy git-subtree-mainline: - 6f4e442a66d625f647faa51e88e052c3d93e9657 git-subtree-split: - f4b433436668ac09f3d1815fbfb4b71f3e0690fa - -2017-04-10 Oleh Krehel - - Remove ivy 0.9.0 to add it again with subtree - -2017-04-09 Oleh Krehel - - Merge commit 'af746cad0e9c5d010ea530381111372f7daae55b' from swiper - -2017-04-08 Oleh Krehel - - Merge commit 'ace01d5603ddf49b025eb811b612af72ec38dcfb' from swiper - -2016-07-11 Paul Eggert - - Fix some quoting problems in doc strings - - Most of these are minor issues involving, e.g., quoting `like this' - instead of 'like this'. A few involve escaping ` and ' with a preceding - \= when the characters should not be turned into curved single quotes. - -2016-04-25 Oleh Krehel - - Merge commit 'db005182ad0fd05c07e8e5c085abe6c750e6c578' from ivy - -2016-04-25 Oleh Krehel - - Rename swiper -> ivy - diff --git a/elpa/ivy-0.13.1/colir.el b/elpa/ivy-0.13.1/colir.el deleted file mode 100644 index 9e61273..0000000 --- a/elpa/ivy-0.13.1/colir.el +++ /dev/null @@ -1,124 +0,0 @@ -;;; colir.el --- Color blending library -*- lexical-binding: t -*- - -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel - -;; This file is part of GNU Emacs. - -;; This file 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, 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. - -;; For a full copy of the GNU General Public License -;; see . - -;;; Commentary: - -;; This package solves the problem of adding a face with a background -;; to text which may already have a background. In all conflicting -;; areas, instead of choosing either the original or the new -;; background face, their blended sum is used. -;; -;; The blend mode functions are taken from URL -;; `https://en.wikipedia.org/wiki/Blend_modes'. - -;;; Code: - -(require 'cl-lib) -(require 'color) - -(defcustom colir-compose-method #'colir-compose-alpha - "Select a method to compose two color channels." - :group 'ivy - :type '(radio - (function-item colir-compose-alpha) - (function-item colir-compose-overlay) - (function-item colir-compose-soft-light))) - -(defun colir-compose-soft-light (a b) - "Compose A and B channels." - (if (< b 0.5) - (+ (* 2 a b) (* a a (- 1 b b))) - (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1))))) - -(defun colir-compose-overlay (a b) - "Compose A and B channels." - (if (< a 0.5) - (* 2 a b) - (- 1 (* 2 (- 1 a) (- 1 b))))) - -(defun colir-compose-alpha (a b &optional alpha gamma) - "Compose A and B channels. -Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds -to the influence of A on the result. Default value is 0.5. -Optional argument GAMMA is used for gamma correction. Default value is 2.2." - (setq alpha (or alpha 0.5)) - (setq gamma (or gamma 2.2)) - (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha)))) - -(defun colir-blend (c1 c2) - "Blend the two colors C1 and C2 using `colir-compose-method'. -C1 and C2 are triples of floats in [0.0 1.0] range." - (apply #'color-rgb-to-hex - (cl-mapcar - (if (eq (frame-parameter nil 'background-mode) 'dark) - ;; this method works nicely for dark themes - 'colir-compose-soft-light - colir-compose-method) - c1 c2))) - -(defun colir-color-parse (color) - "Convert string COLOR to triple of floats in [0.0 1.0]." - (if (string-match "#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)" color) - (mapcar (lambda (v) (/ (string-to-number v 16) 255.0)) - (list (match-string 1 color) (match-string 2 color) (match-string 3 color))) - ;; does not work properly in terminal (maps color to nearest color - ;; from available color palette). - (color-name-to-rgb color))) - -(defun colir--blend-background (start next prevn face object) - (let ((background-prev (face-background prevn))) - (progn - (put-text-property - start next 'face - (if background-prev - (cons `(background-color - . ,(colir-blend - (colir-color-parse background-prev) - (colir-color-parse (face-background face nil t)))) - prevn) - (list face prevn)) - object)))) - -(defun colir-blend-face-background (start end face &optional object) - "Append to the face property of the text from START to END the face FACE. -When the text already has a face with a non-plain background, -blend it with the background of FACE. -Optional argument OBJECT is the string or buffer containing the text. -See also `font-lock-append-text-property'." - (let (next prev prevn) - (while (/= start end) - (setq next (next-single-property-change start 'face object end)) - (setq prev (get-text-property start 'face object)) - (setq prevn (if (listp prev) - (cl-find-if #'atom prev) - prev)) - (cond - ((or (keywordp (car-safe prev)) (consp (car-safe prev))) - (put-text-property start next 'face (cons face prev) object)) - ((facep prevn) - (colir--blend-background start next prevn face object)) - (t - (put-text-property start next 'face face object))) - (setq start next)))) - -(provide 'colir) - -;;; colir.el ends here diff --git a/elpa/ivy-0.13.1/dir b/elpa/ivy-0.13.1/dir deleted file mode 100644 index b68b083..0000000 --- a/elpa/ivy-0.13.1/dir +++ /dev/null @@ -1,18 +0,0 @@ -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" 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 -* Ivy: (ivy). Using Ivy for completion. diff --git a/elpa/ivy-0.13.1/ivy-autoloads.el b/elpa/ivy-0.13.1/ivy-autoloads.el deleted file mode 100644 index e584cdc..0000000 --- a/elpa/ivy-0.13.1/ivy-autoloads.el +++ /dev/null @@ -1,168 +0,0 @@ -;;; ivy-autoloads.el --- automatically extracted autoloads -;; -;;; Code: - -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) - - -;;;### (autoloads nil "colir" "colir.el" (0 0 0 0)) -;;; Generated autoloads from colir.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "colir" '("colir-"))) - -;;;*** - -;;;### (autoloads nil "ivy" "ivy.el" (0 0 0 0)) -;;; Generated autoloads from ivy.el - -(autoload 'ivy-resume "ivy" "\ -Resume the last completion session." t nil) - -(autoload 'ivy-read "ivy" "\ -Read a string in the minibuffer, with completion. - -PROMPT is a string, normally ending in a colon and a space. -`ivy-count-format' is prepended to PROMPT during completion. - -COLLECTION is either a list of strings, a function, an alist, or -a hash table, supplied for `minibuffer-completion-table'. - -PREDICATE is applied to filter out the COLLECTION immediately. -This argument is for compatibility with `completing-read'. - -When REQUIRE-MATCH is non-nil, only members of COLLECTION can be -selected. - -If INITIAL-INPUT is non-nil, then insert that input in the -minibuffer initially. - -HISTORY is a name of a variable to hold the completion session -history. - -KEYMAP is composed with `ivy-minibuffer-map'. - -PRESELECT, when non-nil, determines which one of the candidates -matching INITIAL-INPUT to select initially. An integer stands -for the position of the desired candidate in the collection, -counting from zero. Otherwise, use the first occurrence of -PRESELECT in the collection. Comparison is first done with -`equal'. If that fails, and when applicable, match PRESELECT as -a regular expression. - -DEF is for compatibility with `completing-read'. - -UPDATE-FN is called each time the candidate list is re-displayed. - -When SORT is non-nil, `ivy-sort-functions-alist' determines how -to sort candidates before displaying them. - -ACTION is a function to call after selecting a candidate. -It takes one argument, the selected candidate. If COLLECTION is -an alist, the argument is a cons cell, otherwise it's a string. - -MULTI-ACTION, when non-nil, is called instead of ACTION when -there are marked candidates. It takes the list of candidates as -its only argument. When it's nil, ACTION is called on each marked -candidate. - -UNWIND is a function of no arguments to call before exiting. - -RE-BUILDER is a function transforming input text into a regex -pattern. - -MATCHER is a function which can override how candidates are -filtered based on user input. It takes a regex pattern and a -list of candidates, and returns the list of matching candidates. - -DYNAMIC-COLLECTION is a boolean specifying whether the list of -candidates is updated after each input by calling COLLECTION. - -EXTRA-PROPS can be used to store collection-specific -session-specific data. - -CALLER is a symbol to uniquely identify the caller to `ivy-read'. -It is used, along with COLLECTION, to determine which -customizations apply to the current completion session. - -\(fn PROMPT COLLECTION &key PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY PRESELECT DEF KEYMAP UPDATE-FN SORT ACTION MULTI-ACTION UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION EXTRA-PROPS CALLER)" nil nil) - -(autoload 'ivy-completing-read "ivy" "\ -Read a string in the minibuffer, with completion. - -This interface conforms to `completing-read' and can be used for -`completing-read-function'. - -PROMPT is a string that normally ends in a colon and a space. -COLLECTION is either a list of strings, an alist, an obarray, or a hash table. -PREDICATE limits completion to a subset of COLLECTION. -REQUIRE-MATCH is a boolean value. See `completing-read'. -INITIAL-INPUT is a string inserted into the minibuffer initially. -HISTORY is a list of previously selected inputs. -DEF is the default value. -INHERIT-INPUT-METHOD is currently ignored. - -\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY DEF INHERIT-INPUT-METHOD)" nil nil) - -(defvar ivy-mode nil "\ -Non-nil if Ivy mode is enabled. -See the `ivy-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 `ivy-mode'.") - -(custom-autoload 'ivy-mode "ivy" nil) - -(autoload 'ivy-mode "ivy" "\ -Toggle Ivy mode on or off. -Turn Ivy mode on if ARG is positive, off otherwise. -Turning on Ivy mode sets `completing-read-function' to -`ivy-completing-read'. - -Global bindings: -\\{ivy-mode-map} - -Minibuffer bindings: -\\{ivy-minibuffer-map} - -\(fn &optional ARG)" t nil) - -(autoload 'ivy-switch-buffer "ivy" "\ -Switch to another buffer." t nil) - -(autoload 'ivy-switch-view "ivy" "\ -Switch to one of the window views stored by `ivy-push-view'." t nil) - -(autoload 'ivy-switch-buffer-other-window "ivy" "\ -Switch to another buffer in another window." t nil) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy" '("ivy-" "with-ivy-window"))) - -;;;*** - -;;;### (autoloads nil "ivy-hydra" "ivy-hydra.el" (0 0 0 0)) -;;; Generated autoloads from ivy-hydra.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy-hydra" '("hydra-ivy" "ivy-"))) - -;;;*** - -;;;### (autoloads nil "ivy-overlay" "ivy-overlay.el" (0 0 0 0)) -;;; Generated autoloads from ivy-overlay.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy-overlay" '("ivy-"))) - -;;;*** - -;;;### (autoloads nil nil ("ivy-pkg.el") (0 0 0 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; ivy-autoloads.el ends here diff --git a/elpa/ivy-0.13.1/ivy-overlay.el b/elpa/ivy-0.13.1/ivy-overlay.el deleted file mode 100644 index 7a77bcf..0000000 --- a/elpa/ivy-0.13.1/ivy-overlay.el +++ /dev/null @@ -1,154 +0,0 @@ -;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*- - -;; Copyright (C) 2016-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel -;; Keywords: convenience - -;; 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 . - -;;; Commentary: - -;; This package allows to setup Ivy's completion at point to actually -;; show the candidates and the input at point, instead of in the -;; minibuffer. - -;;; Code: - -(defface ivy-cursor - '((((class color) (background light)) - :background "black" :foreground "white") - (((class color) (background dark)) - :background "white" :foreground "black")) - "Cursor face for inline completion." - :group 'ivy-faces) - -(defvar ivy--old-cursor-type t) - -(defvar ivy-overlay-at nil - "Overlay variable for `ivy-display-function-overlay'.") - -(declare-function ivy--truncate-string "ivy") - -(defun ivy-left-pad (str width) - "Return STR, but with each line indented by WIDTH spaces. -Lines are truncated to the window width." - (let ((padding (make-string width ?\s))) - (mapconcat (lambda (x) - (ivy--truncate-string (concat padding x) - (1- (+ (window-width) - (window-hscroll))))) - (split-string str "\n") - "\n"))) - -(defun ivy-overlay-cleanup () - "Clean up after `ivy-display-function-overlay'." - (when (overlayp ivy-overlay-at) - (delete-overlay ivy-overlay-at) - (setq ivy-overlay-at nil)) - (unless cursor-type - (setq cursor-type ivy--old-cursor-type)) - (when (fboundp 'company-abort) - (company-abort))) - -(defvar ivy-height) - -(defun ivy-overlay-show-after (str) - "Display STR in an overlay at point. - -First, fill each line of STR with spaces to the current column. -Then attach the overlay to the character before point." - (if ivy-overlay-at - (progn - (move-overlay ivy-overlay-at (1- (point)) (line-end-position)) - (overlay-put ivy-overlay-at 'invisible nil)) - (let ((available-height (count-lines (point) (window-end nil t)))) - (unless (>= available-height ivy-height) - (recenter (- (window-height) ivy-height 2)))) - (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position))) - ;; Specify face to avoid clashing with other overlays. - (overlay-put ivy-overlay-at 'face 'default) - (overlay-put ivy-overlay-at 'priority 9999)) - (overlay-put ivy-overlay-at 'display str) - (overlay-put ivy-overlay-at 'after-string "")) - -(declare-function org-current-level "org") -(declare-function org-at-heading-p "org") -(defvar org-indent-indentation-per-level) -(defvar ivy-height) -(defvar ivy-last) -(defvar ivy-text) -(defvar ivy-completion-beg) -(declare-function ivy-add-face-text-property "ivy") -(declare-function ivy--get-window "ivy") -(declare-function ivy-state-current "ivy") -(declare-function ivy-state-window "ivy") -(declare-function ivy--remove-prefix "ivy") - -(defun ivy-overlay-impossible-p (_str) - (or - (and (eq major-mode 'org-mode) - (plist-get (text-properties-at (point)) 'src-block)) - (<= (window-height) (+ ivy-height 2)) - (= (point) (point-min)) - (< (- (+ (window-width) (window-hscroll)) (current-column)) - 30))) - -(defun ivy-display-function-overlay (str) - "Called from the minibuffer, display STR in an overlay in Ivy window. -Hide the minibuffer contents and cursor." - (if (save-selected-window - (select-window (ivy-state-window ivy-last)) - (ivy-overlay-impossible-p str)) - (let ((buffer-undo-list t)) - (save-excursion - (forward-line 1) - (insert str))) - (ivy-add-face-text-property (minibuffer-prompt-end) (point-max) - '(:foreground "white")) - (setq cursor-type nil) - (with-selected-window (ivy--get-window ivy-last) - (when cursor-type - (setq ivy--old-cursor-type cursor-type)) - (setq cursor-type nil) - (let ((overlay-str - (apply - #'concat - (buffer-substring (max (point-min) (1- (point))) (point)) - ivy-text - (and (eolp) " ") - (buffer-substring (point) (line-end-position)) - (and (> (length str) 0) - (list "\n" - (ivy-left-pad - (ivy--remove-prefix "\n" str) - (+ - (if (and (eq major-mode 'org-mode) - (bound-and-true-p org-indent-mode)) - (if (org-at-heading-p) - (1- (org-current-level)) - (* org-indent-indentation-per-level (org-current-level))) - 0) - (save-excursion - (when ivy-completion-beg - (goto-char ivy-completion-beg)) - (current-column))))))))) - (let ((cursor-offset (1+ (length ivy-text)))) - (ivy-add-face-text-property cursor-offset (1+ cursor-offset) - 'ivy-cursor overlay-str t)) - (ivy-overlay-show-after overlay-str))))) - -(provide 'ivy-overlay) - -;;; ivy-overlay.el ends here diff --git a/elpa/ivy-0.13.1/ivy-pkg.el b/elpa/ivy-0.13.1/ivy-pkg.el deleted file mode 100644 index 33ff7a9..0000000 --- a/elpa/ivy-0.13.1/ivy-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;; Generated package description from ivy.el -*- no-byte-compile: t -*- -(define-package "ivy" "0.13.1" "Incremental Vertical completYon" '((emacs "24.5")) :keywords '("matching") :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/ivy-0.13.1/ivy.el b/elpa/ivy-0.13.1/ivy.el deleted file mode 100644 index 04ef620..0000000 --- a/elpa/ivy-0.13.1/ivy.el +++ /dev/null @@ -1,5056 +0,0 @@ -;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*- - -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel -;; URL: https://github.com/abo-abo/swiper -;; Version: 0.13.1 -;; Package-Requires: ((emacs "24.5")) -;; Keywords: matching - -;; This file is part of GNU Emacs. - -;; This file 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, 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. - -;; For a full copy of the GNU General Public License -;; see . - -;;; Commentary: - -;; This package provides `ivy-read' as an alternative to -;; `completing-read' and similar functions. -;; -;; There's no intricate code to determine the best candidate. -;; Instead, the user can navigate to it with `ivy-next-line' and -;; `ivy-previous-line'. -;; -;; The matching is done by splitting the input text by spaces and -;; re-building it into a regex. -;; So "for example" is transformed into "\\(for\\).*\\(example\\)". - -;;; Code: - -(require 'cl-lib) -(require 'ivy-overlay) -(require 'colir) -(require 'ring) - -;;* Customization -(defgroup ivy nil - "Incremental vertical completion." - :group 'convenience) - -(defgroup ivy-faces nil - "Font-lock faces for `ivy'." - :group 'ivy - :group 'faces) - -(defface ivy-current-match - '((((class color) (background light)) - :background "#1a4b77" :foreground "white") - (((class color) (background dark)) - :background "#65a7e2" :foreground "black")) - "Face used by Ivy for highlighting the current match.") - -(defface ivy-minibuffer-match-highlight - '((t :inherit highlight)) - "Face used by Ivy for highlighting the match under the cursor.") - -(defface ivy-minibuffer-match-face-1 - '((((class color) (background light)) - :background "#d3d3d3") - (((class color) (background dark)) - :background "#555555")) - "The background face for `ivy' minibuffer matches.") - -(defface ivy-minibuffer-match-face-2 - '((((class color) (background light)) - :background "#e99ce8" :weight bold) - (((class color) (background dark)) - :background "#777777" :weight bold)) - "Face for `ivy' minibuffer matches numbered 1 modulo 3.") - -(defface ivy-minibuffer-match-face-3 - '((((class color) (background light)) - :background "#bbbbff" :weight bold) - (((class color) (background dark)) - :background "#7777ff" :weight bold)) - "Face for `ivy' minibuffer matches numbered 2 modulo 3.") - -(defface ivy-minibuffer-match-face-4 - '((((class color) (background light)) - :background "#ffbbff" :weight bold) - (((class color) (background dark)) - :background "#8a498a" :weight bold)) - "Face for `ivy' minibuffer matches numbered 3 modulo 3.") - -(defface ivy-confirm-face - '((t :foreground "ForestGreen" :inherit minibuffer-prompt)) - "Face used by Ivy for a confirmation prompt.") - -(defface ivy-match-required-face - '((t :foreground "red" :inherit minibuffer-prompt)) - "Face used by Ivy for a match required prompt.") - -(defface ivy-subdir - '((t :inherit dired-directory)) - "Face used by Ivy for highlighting subdirs in the alternatives.") - -(defface ivy-org - '((t :inherit org-level-4)) - "Face used by Ivy for highlighting Org buffers in the alternatives.") - -(defface ivy-modified-buffer - '((t :inherit default)) - "Face used by Ivy for highlighting modified file visiting buffers.") - -(defface ivy-modified-outside-buffer - '((t :inherit default)) - "Face used by Ivy for highlighting file visiting buffers modified outside Emacs.") - -(defface ivy-remote - '((((class color) (background light)) - :foreground "#110099") - (((class color) (background dark)) - :foreground "#7B6BFF")) - "Face used by Ivy for highlighting remotes in the alternatives.") - -(defface ivy-virtual - '((t :inherit font-lock-builtin-face)) - "Face used by Ivy for matching virtual buffer names.") - -(defface ivy-action - '((t :inherit font-lock-builtin-face)) - "Face used by Ivy for displaying keys in `ivy-read-action'.") - -(defface ivy-highlight-face - '((t :inherit highlight)) - "Face used by Ivy to highlight certain candidates.") - -(defface ivy-prompt-match - '((t :inherit ivy-current-match)) - "Face used by Ivy for highlighting the selected prompt line.") - -(defface ivy-separator - '((t :inherit font-lock-doc-face)) - "Face for multiline source separator.") - -(defface ivy-grep-info - '((t :inherit compilation-info)) - "Face for highlighting grep information such as file names.") - -(defface ivy-grep-line-number - '((t :inherit compilation-line-number)) - "Face for displaying line numbers in grep messages.") - -(defface ivy-completions-annotations - '((t :inherit completions-annotations)) - "Face for displaying completion annotations.") - -(defface ivy-yanked-word - '((t :inherit highlight)) - "Face used to highlight yanked word.") - -;; Set default customization `:group' to `ivy' for the rest of the file. -(setcdr (assoc load-file-name custom-current-group-alist) 'ivy) - -(defcustom ivy-height 10 - "Number of lines for the minibuffer window. - -See also `ivy-height-alist'." - :type 'integer) - -(defcustom ivy-count-format "%-4d " - "The style to use for displaying the current candidate count for `ivy-read'. -Set this to \"\" to suppress the count visibility. -Set this to \"(%d/%d) \" to display both the index and the count." - :type '(choice - (const :tag "Count disabled" "") - (const :tag "Count matches" "%-4d ") - (const :tag "Count matches and show current match" "(%d/%d) ") - string)) - -(defcustom ivy-pre-prompt-function nil - "When non-nil, add strings before the `ivy-read' prompt." - :type '(choice - (const :tag "Do nothing" nil) - (function :tag "Custom function"))) - -(defcustom ivy-add-newline-after-prompt nil - "When non-nil, add a newline after the `ivy-read' prompt." - :type 'boolean) - -(defcustom ivy-wrap nil - "When non-nil, wrap around after the first and the last candidate." - :type 'boolean) - -(defcustom ivy-display-style (and (fboundp 'add-face-text-property) 'fancy) - "The style for formatting the minibuffer. - -By default, the matched strings are copied as is. - -The fancy display style highlights matching parts of the regexp, -a behavior similar to `swiper'. - -This setting depends on `add-face-text-property' - a C function -available since Emacs 24.4. Fancy style will render poorly in -earlier versions of Emacs." - :type '(choice - (const :tag "Plain" nil) - (const :tag "Fancy" fancy))) - -(defcustom ivy-on-del-error-function #'abort-recursive-edit - "Function to call when deletion fails during completion. -The usual reason for `ivy-backward-delete-char' to fail is when -there is no text left to delete, i.e., when it is called at the -beginning of the minibuffer. -The default setting provides a quick exit from completion." - :type '(choice - (const :tag "Exit completion" abort-recursive-edit) - (const :tag "Do nothing" ignore) - (function :tag "Custom function"))) - -(defcustom ivy-extra-directories '("../" "./") - "Add this to the front of the list when completing file names. -Only \"./\" and \"../\" apply here. They appear in reverse order." - :type '(repeat :tag "Dirs" - (choice - (const :tag "Parent Directory" "../") - (const :tag "Current Directory" "./")))) - -(defcustom ivy-use-virtual-buffers nil - "When non-nil, add recent files and/or bookmarks to `ivy-switch-buffer'. -The value `recentf' includes only recent files to the virtual -buffers list, whereas the value `bookmarks' does the same for -bookmarks. Any other non-nil value includes both." - :type '(choice - (const :tag "Don't use virtual buffers" nil) - (const :tag "Recent files" recentf) - (const :tag "Bookmarks" bookmarks) - (const :tag "All virtual buffers" t))) - -(defvar ivy--display-function nil - "The display-function is used in current.") - -(defvar ivy-display-functions-props - '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup)) - "Map Ivy display functions to their property lists. -Examples of properties include associated `:cleanup' functions.") - -(defcustom ivy-display-functions-alist - '((ivy-completion-in-region . ivy-display-function-overlay) - (t . nil)) - "An alist for customizing where to display the candidates. - -Each key is a caller symbol. When the value is nil (the default), -the candidates are shown in the minibuffer. Otherwise, the value -is a function which takes a string argument comprising the -current matching candidates and displays it somewhere. - -See also `https://github.com/abo-abo/swiper/wiki/ivy-display-function'." - :type '(alist - :key-type symbol - :value-type (choice - (const :tag "Minibuffer" nil) - (const :tag "LV" ivy-display-function-lv) - (const :tag "Popup" ivy-display-function-popup) - (const :tag "Overlay" ivy-display-function-overlay) - (function :tag "Custom function")))) - -(defvar ivy-completing-read-dynamic-collection nil - "Run `ivy-completing-read' with `:dynamic-collection t`.") - -(defcustom ivy-completing-read-handlers-alist - '((tmm-menubar . completing-read-default) - (tmm-shortcut . completing-read-default) - (bbdb-create . ivy-completing-read-with-empty-string-def) - (auto-insert . ivy-completing-read-with-empty-string-def) - (Info-on-current-buffer . ivy-completing-read-with-empty-string-def) - (Info-follow-reference . ivy-completing-read-with-empty-string-def) - (Info-menu . ivy-completing-read-with-empty-string-def) - (Info-index . ivy-completing-read-with-empty-string-def) - (Info-virtual-index . ivy-completing-read-with-empty-string-def) - (info-display-manual . ivy-completing-read-with-empty-string-def)) - "An alist of handlers to replace `completing-read' in `ivy-mode'." - :type '(alist :key-type symbol :value-type function)) - -(defcustom ivy-height-alist nil - "An alist to customize `ivy-height'. - -It is a list of (CALLER . HEIGHT). CALLER is a caller of -`ivy-read' and HEIGHT is the number of lines displayed. -HEIGHT can also be a function that returns the number of lines." - :type '(alist - :key-type function - :value-type (choice integer function))) - -(defvar ivy-completing-read-ignore-handlers-depth -1 - "Used to avoid infinite recursion. - -If `(minibuffer-depth)' equals this, `ivy-completing-read' will -act as if `ivy-completing-read-handlers-alist' is empty.") - -(defvar ivy-highlight-grep-commands nil - "List of grep-like commands.") - -(defvar ivy--actions-list nil - "A list of extra actions per command.") - -(defun ivy-set-actions (cmd actions) - "Set CMD extra exit points to ACTIONS." - (setq ivy--actions-list - (plist-put ivy--actions-list cmd actions))) - -(defun ivy-add-actions (cmd actions) - "Add extra exit points ACTIONS to CMD. -Existing exit points of CMD are overwritten by those in -ACTIONS that have the same key." - (setq ivy--actions-list - (plist-put ivy--actions-list cmd - (cl-delete-duplicates - (append (plist-get ivy--actions-list cmd) actions) - :key #'car :test #'equal)))) - -(defun ivy--compute-extra-actions (action caller) - "Add extra actions to ACTION based on CALLER." - (let ((extra-actions (cl-delete-duplicates - (append (plist-get ivy--actions-list t) - (plist-get ivy--actions-list this-command) - (plist-get ivy--actions-list caller)) - :key #'car :test #'equal))) - (if extra-actions - (cond ((functionp action) - `(1 - ("o" ,action "default") - ,@extra-actions)) - ((null action) - `(1 - ("o" identity "default") - ,@extra-actions)) - (t - (delete-dups (append action extra-actions)))) - action))) - -(defvar ivy--prompts-list nil) - -(defun ivy-set-prompt (caller prompt-fn) - "Associate CALLER with PROMPT-FN. -PROMPT-FN is a function of no arguments that returns a prompt string." - (setq ivy--prompts-list - (plist-put ivy--prompts-list caller prompt-fn))) - -(defvar ivy--display-transformers-list nil - "A list of str->str transformers per command.") - -(defun ivy-set-display-transformer (cmd transformer) - "Set CMD a displayed candidate TRANSFORMER. - -It's a lambda that takes a string one of the candidates in the -collection and returns a string for display, the same candidate -plus some extra information. - -This lambda is called only on the `ivy-height' candidates that -are about to be displayed, not on the whole collection." - (setq ivy--display-transformers-list - (plist-put ivy--display-transformers-list cmd transformer))) - -(defvar ivy--sources-list nil - "A list of extra sources per command.") - -(defun ivy-set-sources (cmd sources) - "Attach to CMD a list of extra SOURCES. - -Each static source is a function that takes no argument and -returns a list of strings. - -The (original-source) determines the position of the original -dynamic source. - -Extra dynamic sources aren't supported yet. - -Example: - - (defun small-recentf () - (cl-subseq recentf-list 0 20)) - - (ivy-set-sources - 'counsel-locate - '((small-recentf) - (original-source)))" - (setq ivy--sources-list - (plist-put ivy--sources-list cmd sources))) - -(defun ivy--compute-extra-candidates (caller) - (let ((extra-sources (or (plist-get ivy--sources-list caller) - '((original-source)))) - (result nil)) - (dolist (source extra-sources) - (cond ((equal source '(original-source)) - (push source result)) - ((null (cdr source)) - (push (list (car source) (funcall (car source))) result)))) - result)) - -(defvar ivy-current-prefix-arg nil - "Prefix arg to pass to actions. -This is a global variable that is set by ivy functions for use in -action functions.") - -;;* Keymap -(require 'delsel) -(defvar ivy-minibuffer-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-m") 'ivy-done) - (define-key map [down-mouse-1] 'ignore) - (define-key map [mouse-1] 'ivy-mouse-done) - (define-key map [mouse-3] 'ivy-mouse-dispatching-done) - (define-key map (kbd "C-M-m") 'ivy-call) - (define-key map (kbd "C-j") 'ivy-alt-done) - (define-key map (kbd "C-M-j") 'ivy-immediate-done) - (define-key map (kbd "TAB") 'ivy-partial-or-done) - (define-key map [remap next-line] 'ivy-next-line) - (define-key map [remap previous-line] 'ivy-previous-line) - (define-key map (kbd "C-s") 'ivy-next-line-or-history) - (define-key map (kbd "C-r") 'ivy-reverse-i-search) - (define-key map (kbd "SPC") 'self-insert-command) - (define-key map [remap delete-backward-char] 'ivy-backward-delete-char) - (define-key map [remap backward-delete-char-untabify] 'ivy-backward-delete-char) - (define-key map [remap backward-kill-word] 'ivy-backward-kill-word) - (define-key map [remap delete-char] 'ivy-delete-char) - (define-key map [remap forward-char] 'ivy-forward-char) - (define-key map (kbd "") 'ivy-forward-char) - (define-key map [remap kill-word] 'ivy-kill-word) - (define-key map [remap beginning-of-buffer] 'ivy-beginning-of-buffer) - (define-key map [remap end-of-buffer] 'ivy-end-of-buffer) - (define-key map (kbd "M-n") 'ivy-next-history-element) - (define-key map (kbd "M-p") 'ivy-previous-history-element) - (define-key map (kbd "C-g") 'minibuffer-keyboard-quit) - (define-key map [remap scroll-up-command] 'ivy-scroll-up-command) - (define-key map [remap scroll-down-command] 'ivy-scroll-down-command) - (define-key map (kbd "") 'ivy-scroll-up-command) - (define-key map (kbd "") 'ivy-scroll-down-command) - (define-key map (kbd "C-v") 'ivy-scroll-up-command) - (define-key map (kbd "M-v") 'ivy-scroll-down-command) - (define-key map (kbd "C-M-n") 'ivy-next-line-and-call) - (define-key map (kbd "C-M-p") 'ivy-previous-line-and-call) - (define-key map (kbd "M-r") 'ivy-toggle-regexp-quote) - (define-key map (kbd "M-j") 'ivy-yank-word) - (define-key map (kbd "M-i") 'ivy-insert-current) - (define-key map (kbd "C-M-y") 'ivy-insert-current-full) - (define-key map (kbd "C-o") 'hydra-ivy/body) - (define-key map (kbd "M-o") 'ivy-dispatching-done) - (define-key map (kbd "C-M-o") 'ivy-dispatching-call) - (define-key map [remap kill-line] 'ivy-kill-line) - (define-key map [remap kill-whole-line] 'ivy-kill-whole-line) - (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches) - (define-key map [remap kill-ring-save] 'ivy-kill-ring-save) - (define-key map (kbd "C-'") 'ivy-avy) - (define-key map (kbd "C-M-a") 'ivy-read-action) - (define-key map (kbd "C-c C-o") 'ivy-occur) - (define-key map (kbd "C-c C-a") 'ivy-toggle-ignore) - (define-key map (kbd "C-c C-s") 'ivy-rotate-sort) - (define-key map [remap describe-mode] 'ivy-help) - (define-key map "$" 'ivy-magic-read-file-env) - map) - "Keymap used in the minibuffer.") -(autoload 'hydra-ivy/body "ivy-hydra" "" t) - -(defvar ivy-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [remap switch-to-buffer] - 'ivy-switch-buffer) - (define-key map [remap switch-to-buffer-other-window] - 'ivy-switch-buffer-other-window) - map) - "Keymap for `ivy-mode'.") - -;;* Globals -(cl-defstruct ivy-state - prompt collection - predicate require-match initial-input - history preselect keymap update-fn sort - ;; The frame in which `ivy-read' was called - frame - ;; The window in which `ivy-read' was called - window - ;; The buffer in which `ivy-read' was called - buffer - ;; The value of `ivy-text' to be used by `ivy-occur' - text - action - unwind - re-builder - matcher - ;; When this is non-nil, call it for each input change to get new candidates - dynamic-collection - ;; A lambda that transforms candidates only for display - display-transformer-fn - directory - caller - current - def - ignore - multi-action - extra-props) - -(defvar ivy-last (make-ivy-state) - "The last parameters passed to `ivy-read'. - -This should eventually become a stack so that you could use -`ivy-read' recursively.") - -(defvar ivy-recursive-last nil) - -(defvar ivy-recursive-restore t - "When non-nil, restore the above state when exiting the minibuffer. -This variable is let-bound to nil by functions that take care of -the restoring themselves.") - -(defsubst ivy-set-action (action) - "Set the current `ivy-last' field to ACTION." - (setf (ivy-state-action ivy-last) action)) - -(defvar inhibit-message) - -(defun ivy-thing-at-point () - "Return a string that corresponds to the current thing at point." - (substring-no-properties - (cond - ((use-region-p) - (let* ((beg (region-beginning)) - (end (region-end)) - (eol (save-excursion (goto-char beg) (line-end-position)))) - (buffer-substring-no-properties beg (min end eol)))) - ((thing-at-point 'url)) - ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal) - (let ((inhibit-message t)) - (run-hook-with-args-until-success 'file-name-at-point-functions)))) - ((let ((s (thing-at-point 'symbol))) - (and (stringp s) - (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s) - (match-string 1 s) - s)))) - ((looking-at "(+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>") - (match-string-no-properties 1)) - (t - "")))) - -(defvar ivy-history nil - "History list of candidates entered in the minibuffer. - -Maximum length of the history list is determined by the value -of `history-length'.") - -(defvar ivy--directory nil - "Current directory when completing file names.") - -(defvar ivy--length 0 - "Store the amount of viable candidates.") - -(defvar ivy-text "" - "Store the user's string as it is typed in.") - -(defvar ivy--index 0 - "Store the index of the current candidate.") - -(defvar ivy--window-index 0 - "Store the index of the current candidate in the minibuffer window. - -This means it's between 0 and `ivy-height'.") - -(defvar ivy-exit nil - "Store `done' if the completion was successfully selected. -Otherwise, store nil.") - -(defvar ivy--all-candidates nil - "Store the candidates passed to `ivy-read'.") - -(defvar ivy--extra-candidates '((original-source)) - "Store candidates added by the extra sources. - -This is an internal-use alist. Each key is a function name, or -original-source (which represents where the current dynamic -candidates should go). - -Each value is an evaluation of the function, in case of static -sources. These values will subsequently be filtered on `ivy-text'. - -This variable is set by `ivy-read' and used by `ivy--set-candidates'.") - -(defcustom ivy-use-ignore-default t - "The default policy for user-configured candidate filtering." - :type '(choice - (const :tag "Ignore ignored always" always) - (const :tag "Ignore ignored when others exist" t) - (const :tag "Don't ignore" nil))) - -(defvar ivy-use-ignore t - "Store policy for user-configured candidate filtering. -This may be changed dynamically by `ivy-toggle-ignore'. -Use `ivy-use-ignore-default' for a permanent configuration.") - -(defvar ivy--default nil - "Default initial input.") - -(defvar ivy--prompt nil - "Store the format-style prompt. -When non-nil, it should contain at least one %d.") - -(defvar ivy--prompt-extra "" - "Temporary modifications to the prompt.") - -(defvar ivy--old-re nil - "Store the old regexp. -Either a string or a list for `ivy-re-match'.") - -(defvar ivy--old-cands nil - "Store the candidates matched by `ivy--old-re'.") - -(defvar ivy--regex-function 'ivy--regex - "Current function for building a regex.") - -(defvar ivy--highlight-function 'ivy--highlight-default - "Current function for formatting the candidates.") - -(defvar ivy--subexps 0 - "Number of groups in the current `ivy--regex'.") - -(defvar ivy--full-length nil - "The total amount of candidates when :dynamic-collection is non-nil.") - -(defvar ivy--old-text "" - "Store old `ivy-text' for dynamic completion.") - -(defvar ivy--trying-to-resume-dynamic-collection nil - "Non-nil if resuming from a dynamic collection. -When non-nil, ivy will wait until the first chunk of asynchronous -candidates has been received before selecting the last -preselected candidate.") - -(defun ivy--set-index-dynamic-collection () - (when ivy--trying-to-resume-dynamic-collection - (let ((preselect-index - (ivy--preselect-index (ivy-state-preselect ivy-last) ivy--all-candidates))) - (when preselect-index - (ivy-set-index preselect-index))) - (setq ivy--trying-to-resume-dynamic-collection nil))) - -(defcustom ivy-case-fold-search-default - (if search-upper-case - 'auto - case-fold-search) - "The default value for `case-fold-search' in Ivy operations. -The special value `auto' means case folding is performed so long -as the entire input string comprises lower-case characters. This -corresponds to the default behaviour of most Emacs search -functionality, e.g. as seen in `isearch'." - :link '(info-link "(emacs)Lax Search") - :type '(choice - (const :tag "Auto" auto) - (const :tag "Always" t) - (const :tag "Never" nil))) - -(defvar ivy-case-fold-search ivy-case-fold-search-default - "Store the current overriding `case-fold-search'.") - -(defvar ivy-more-chars-alist - '((t . 3)) - "Map commands to their minimum required input length. -That is the number of characters prompted for before fetching -candidates. The special key t is used as a fallback.") - -(defun ivy-more-chars () - "Return two fake candidates prompting for at least N input. -N is obtained from `ivy-more-chars-alist'." - (let ((diff (- (ivy-alist-setting ivy-more-chars-alist) - (length ivy-text)))) - (when (> diff 0) - (list "" (format "%d chars more" diff))))) - -(defun ivy--case-fold-p (string) - "Return nil if STRING should be matched case-sensitively." - (if (eq ivy-case-fold-search 'auto) - (string= string (downcase string)) - ivy-case-fold-search)) - -(defun ivy--case-fold-string= (s1 s2) - "Like `string=', but obeys `case-fold-search'." - (eq t (compare-strings s1 nil nil s2 nil nil case-fold-search))) - -(eval-and-compile - (unless (fboundp 'defvar-local) - (defmacro defvar-local (var val &optional docstring) - "Define VAR as a buffer-local variable with default value VAL." - (declare (debug defvar) (doc-string 3)) - (list 'progn (list 'defvar var val docstring) - (list 'make-variable-buffer-local (list 'quote var))))) - (unless (fboundp 'setq-local) - (defmacro setq-local (var val) - "Set variable VAR to value VAL in current buffer." - (list 'set (list 'make-local-variable (list 'quote var)) val)))) - -(defmacro ivy-quit-and-run (&rest body) - "Quit the minibuffer and run BODY afterwards." - (declare (indent 0)) - `(progn - (put 'quit 'error-message "") - (run-at-time nil nil - (lambda () - (put 'quit 'error-message "Quit") - (with-demoted-errors "Error: %S" - ,@body))) - (abort-recursive-edit))) - -(defun ivy-exit-with-action (action) - "Quit the minibuffer and call ACTION afterwards." - (ivy-set-action - `(lambda (x) - (funcall ',action x) - (ivy-set-action ',(ivy-state-action ivy-last)))) - (setq ivy-exit 'done) - (exit-minibuffer)) - -(defmacro with-ivy-window (&rest body) - "Execute BODY in the window from which `ivy-read' was called." - (declare (indent 0) - (debug t)) - `(with-selected-window (ivy--get-window ivy-last) - ,@body)) - -(defun ivy--done (text) - "Insert TEXT and exit minibuffer." - (if (member (ivy-state-prompt ivy-last) '("Create directory: " "Make directory: ")) - (ivy-immediate-done) - (if (stringp text) - (insert - (setf (ivy-state-current ivy-last) - (if (and ivy--directory - (not (eq (ivy-state-history ivy-last) 'grep-files-history))) - (expand-file-name text ivy--directory) - text)))) - (setq ivy-exit 'done) - (exit-minibuffer))) - -(defcustom ivy-use-selectable-prompt nil - "When non-nil, make the prompt line selectable like a candidate. - -The prompt line can be selected by calling `ivy-previous-line' when the first -regular candidate is selected. Both actions `ivy-done' and `ivy-alt-done', -when called on a selected prompt, are forwarded to `ivy-immediate-done', which -results to the same as calling `ivy-immediate-done' explicitly when a regular -candidate is selected. - -Note that if `ivy-wrap' is set to t, calling `ivy-previous-line' when the -prompt is selected wraps around to the last candidate, while calling -`ivy-next-line' on the last candidate wraps around to the first -candidate, not the prompt." - :type 'boolean) - -(defvar ivy--use-selectable-prompt nil - "Store the effective `ivy-use-selectable-prompt' for current session.") - -(defun ivy--prompt-selectable-p () - "Return t if the prompt line is selectable." - (and ivy-use-selectable-prompt - (or (memq (ivy-state-require-match ivy-last) - '(nil confirm confirm-after-completion)) - ;; :require-match is t, but "" is in the collection - (let ((coll (ivy-state-collection ivy-last))) - (and (listp coll) - (if (consp (car coll)) - (member '("") coll) - (member "" coll))))))) - -(defun ivy--prompt-selected-p () - "Return t if the prompt line is selected." - (and ivy--use-selectable-prompt - (= ivy--index -1))) - -;;* Commands -(defun ivy-done () - "Exit the minibuffer with the selected candidate." - (interactive) - (if (ivy--prompt-selected-p) - (ivy-immediate-done) - (setq ivy-current-prefix-arg current-prefix-arg) - (delete-minibuffer-contents) - (cond ((or (> ivy--length 0) - ;; the action from `ivy-dispatching-done' may not need a - ;; candidate at all - (eq this-command 'ivy-dispatching-done)) - (ivy--done (ivy-state-current ivy-last))) - ((memq (ivy-state-collection ivy-last) - '(read-file-name-internal internal-complete-buffer)) - (if (or (not (eq confirm-nonexistent-file-or-buffer t)) - (equal " (confirm)" ivy--prompt-extra)) - (ivy--done ivy-text) - (setq ivy--prompt-extra " (confirm)") - (insert ivy-text) - (ivy--exhibit))) - ((memq (ivy-state-require-match ivy-last) - '(nil confirm confirm-after-completion)) - (ivy--done ivy-text)) - (t - (setq ivy--prompt-extra " (match required)") - (insert ivy-text) - (ivy--exhibit))))) - -(defvar ivy-mouse-1-tooltip - "Exit the minibuffer with the selected candidate." - "The doc visible in the tooltip for mouse-1 binding in the minibuffer") -(defvar ivy-mouse-3-tooltip - "Display alternative actions." - "The doc visible in the tooltip for mouse-3 binding in the minibuffer") - -(defun ivy-mouse-offset (event) - "Compute the offset between the candidate at point and the selected one." - (if event - (let* ((line-number-at-point - (max 2 - (line-number-at-pos (posn-point (event-start event))))) - - (line-number-candidate ;; convert to 0 based index - (- line-number-at-point 2)) - (offset - (- line-number-candidate - ivy--window-index))) - offset) - nil)) - -(defun ivy-mouse-done (event) - (interactive "@e") - (let ((offset (ivy-mouse-offset event))) - (when offset - (ivy-next-line offset) - (ivy--exhibit) - (ivy-alt-done)))) - -(defun ivy-mouse-dispatching-done (event) - (interactive "@e") - (let ((offset (ivy-mouse-offset event))) - (when offset - (ivy-next-line offset) - (ivy--exhibit) - (ivy-dispatching-done)))) - -(defvar ivy-read-action-format-function 'ivy-read-action-format-default - "Function used to transform the actions list into a docstring.") - -(defun ivy-read-action-format-default (actions) - "Create a docstring from ACTIONS. - -ACTIONS is a list. Each list item is a list of 3 items: -key (a string), cmd and doc (a string)." - (format "%s\n%s\n" - (if (eq this-command 'ivy-read-action) - "Select action: " - (ivy-state-current ivy-last)) - (mapconcat - (lambda (x) - (format "%s: %s" - (propertize - (car x) - 'face 'ivy-action) - (nth 2 x))) - actions - "\n"))) - -(defcustom ivy-read-action-function #'ivy-read-action-by-key - "Function used to read an action." - :type '(radio - (function-item ivy-read-action-by-key) - (function-item ivy-read-action-ivy) - (function-item ivy-read-action-hydra))) - -(defun ivy-read-action () - "Change the action to one of the available ones. - -Return nil for `minibuffer-keyboard-quit' or wrong key during the -selection, non-nil otherwise." - (interactive) - (let ((actions (ivy-state-action ivy-last))) - (if (not (ivy--actionp actions)) - t - (funcall ivy-read-action-function actions)))) - -(defun ivy-read-action-by-key (actions) - (let* ((hint (funcall ivy-read-action-format-function (cdr actions))) - (resize-mini-windows t) - (key "") - action-idx) - (while (and (setq action-idx (cl-position-if - (lambda (x) - (string-prefix-p key (car x))) - (cdr actions))) - (not (string= key (car (nth action-idx (cdr actions)))))) - (setq key (concat key (string (read-key hint))))) - (ivy-shrink-after-dispatching) - (cond ((member key '("" "")) - nil) - ((null action-idx) - (message "%s is not bound" key) - nil) - (t - (message "") - (setcar actions (1+ action-idx)) - (ivy-set-action actions))))) - -(defun ivy-read-action-ivy (actions) - "Select an action from ACTIONS using Ivy." - (let ((enable-recursive-minibuffers t)) - (if (and (> (minibuffer-depth) 1) - (eq (ivy-state-caller ivy-last) 'ivy-read-action-ivy)) - (minibuffer-keyboard-quit) - (ivy-read (format "action (%s): " (ivy-state-current ivy-last)) - (cl-mapcar - (lambda (a i) (cons (format "[%s] %s" (nth 0 a) (nth 2 a)) i)) - (cdr actions) (number-sequence 1 (length (cdr actions)))) - :action (lambda (a) - (setcar actions (cdr a)) - (ivy-set-action actions)) - :caller 'ivy-read-action-ivy)))) - -(defun ivy-shrink-after-dispatching () - "Shrink the window after dispatching when action list is too large." - (window-resize nil (- ivy-height (window-height)))) - -(defun ivy-dispatching-done () - "Select one of the available actions and call `ivy-done'." - (interactive) - (when (ivy-read-action) - (ivy-done)) - (ivy-shrink-after-dispatching)) - -(defun ivy-dispatching-call () - "Select one of the available actions and call `ivy-call'." - (interactive) - (setq ivy-current-prefix-arg current-prefix-arg) - (let ((actions (copy-sequence (ivy-state-action ivy-last)))) - (unwind-protect - (when (ivy-read-action) - (ivy-call)) - (ivy-set-action actions))) - (ivy-shrink-after-dispatching)) - -(defun ivy-build-tramp-name (x) - "Reconstruct X into a path. -Is is a cons cell, related to `tramp-get-completion-function'." - (let ((user (car x)) - (domain (cadr x))) - (if user - (concat user "@" domain) - domain))) - -(declare-function Info-find-node "info") -(declare-function Info-read-node-name-1 "info") -(declare-function tramp-get-completion-function "tramp") - -(defun ivy-alt-done (&optional arg) - "Exit the minibuffer with the selected candidate. -When ARG is t, exit with current text, ignoring the candidates. -When the current candidate during file name completion is a -directory, continue completion from within that directory instead -of exiting. This function is otherwise like `ivy-done'." - (interactive "P") - (setq ivy-current-prefix-arg current-prefix-arg) - (cond ((or arg - (ivy--prompt-selected-p)) - (ivy-immediate-done)) - (ivy--directory - (ivy--directory-done)) - ((eq (ivy-state-collection ivy-last) #'Info-read-node-name-1) - (if (member (ivy-state-current ivy-last) '("(./)" "(../)")) - (ivy-quit-and-run - (ivy-read "Go to file: " #'read-file-name-internal - :action (lambda (x) - (Info-find-node - (expand-file-name x ivy--directory) - "Top")))) - (ivy-done))) - (t - (ivy-done)))) - -(defvar ivy-auto-select-single-candidate nil - "When non-nil, auto-select the candidate if it is the only one. -When t, it is the same as if the user were prompted and selected the candidate -by calling the default action. This variable has no use unless the collection -contains a single candidate.") - -(defun ivy--directory-enter () - (let (dir) - (when (and - (> ivy--length 0) - (not (string= (ivy-state-current ivy-last) "./")) - (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last)))) - (ivy--cd dir) - (ivy--exhibit)))) - -(defun ivy--handle-directory (input) - "Detect the next directory based on special values of INPUT." - (cond ((string= input "/") - "/") - ((string= input "/sudo::") - (concat input ivy--directory)))) - -(defun ivy--directory-done () - "Handle exit from the minibuffer when completing file names." - (let ((dir (ivy--handle-directory ivy-text))) - (cond - (dir - (let ((inhibit-message t)) - (ivy--cd dir))) - ((ivy--directory-enter)) - ((unless (string= ivy-text "") - (let ((file (expand-file-name - (if (> ivy--length 0) (ivy-state-current ivy-last) ivy-text) - ivy--directory))) - (when (ignore-errors (file-exists-p file)) - (if (file-directory-p file) - (ivy--cd (file-name-as-directory file)) - (ivy-done)) - ivy-text)))) - ((or (and (equal ivy--directory "/") - (string-match-p "\\`[^/]+:.*:.*\\'" ivy-text)) - (string-match-p "\\`/[^/]+:.*:.*\\'" ivy-text)) - (ivy-done)) - ((or (and (equal ivy--directory "/") - (cond ((string-match - "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'" - ivy-text) - (setq ivy-text (ivy-state-current ivy-last))) - ((string-match - "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'" - (ivy-state-current ivy-last)) - (setq ivy-text (ivy-state-current ivy-last))))) - (string-match - "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'" - ivy-text)) - (let ((method (match-string 1 ivy-text)) - (user (match-string 2 ivy-text)) - (rest (match-string 3 ivy-text)) - res) - (dolist (x (tramp-get-completion-function method)) - (setq res (append res (funcall (car x) (cadr x))))) - (setq res (delq nil res)) - (when user - (dolist (x res) - (setcar x user))) - (setq res (delete-dups res)) - (let* ((old-ivy-last ivy-last) - (enable-recursive-minibuffers t) - (host (let ((ivy-auto-select-single-candidate nil)) - (ivy-read "user@host: " - (mapcar #'ivy-build-tramp-name res) - :initial-input rest)))) - (setq ivy-last old-ivy-last) - (when host - (setq ivy--directory "/") - (ivy--cd (concat "/" method ":" host ":")))))) - (t - (ivy-done))))) - -(defun ivy-expand-file-if-directory (file-name) - "Expand FILE-NAME as directory. -When this directory doesn't exist, return nil." - (when (stringp file-name) - (let ((full-name - ;; Ignore host name must not match method "ssh" - (ignore-errors - (file-name-as-directory - (expand-file-name file-name ivy--directory))))) - (when (and full-name (file-directory-p full-name)) - full-name)))) - -(defcustom ivy-tab-space nil - "When non-nil, `ivy-partial-or-done' should insert a space." - :type 'boolean) - -(defun ivy-partial-or-done () - "Complete the minibuffer text as much as possible. -If the text hasn't changed as a result, forward to `ivy-alt-done'." - (interactive) - (cond - ((and completion-cycle-threshold (< (length ivy--all-candidates) completion-cycle-threshold)) - (let ((ivy-wrap t)) - (ivy-next-line))) - ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal) - (or (and (equal ivy--directory "/") - (string-match-p "\\`[^/]+:.*\\'" ivy-text)) - (= (string-to-char ivy-text) ?/))) - (let ((default-directory ivy--directory) - dir) - (minibuffer-complete) - (setq ivy-text (ivy--input)) - (when (setq dir (ivy-expand-file-if-directory ivy-text)) - (ivy--cd dir)))) - (t - (or (ivy-partial) - (when (or (eq this-command last-command) - (eq ivy--length 1)) - (ivy-alt-done)))))) - -(defun ivy--remove-prefix (prefix string) - "Compatibility shim for `string-remove-prefix'." - (if (string-prefix-p prefix string) - (substring string (length prefix)) - string)) - -(defun ivy--partial-cd-for-single-directory () - (when (and - (eq (ivy-state-collection ivy-last) #'read-file-name-internal) - (= 1 (length - (ivy--re-filter - (funcall ivy--regex-function ivy-text) ivy--all-candidates))) - (let ((default-directory ivy--directory)) - (file-directory-p (ivy-state-current ivy-last)))) - (ivy--directory-done))) - -(defun ivy-partial () - "Complete the minibuffer text as much as possible." - (interactive) - (let* ((parts (or (ivy--split-spaces ivy-text) (list ""))) - (tail (last parts)) - (postfix (car tail)) - (case-fold-search (ivy--case-fold-p ivy-text)) - (completion-ignore-case case-fold-search) - (new (try-completion (ivy--remove-prefix "^" postfix) - (if (ivy-state-dynamic-collection ivy-last) - ivy--all-candidates - (mapcar (lambda (str) - (let ((i (string-match-p postfix str))) - (and i (substring str i)))) - ivy--old-cands))))) - (cond ((eq new t) nil) - ((string= new ivy-text) nil) - ((string= (car tail) (car (ivy--split-spaces new))) nil) - (new - (delete-region (minibuffer-prompt-end) (point-max)) - (setcar tail - (if (= (string-to-char postfix) ?^) - (concat "^" new) - new)) - (insert - (setq ivy-text - (concat - (mapconcat #'identity parts " ") - (and ivy-tab-space (not (= (length ivy--old-cands) 1)) " ")))) - (ivy--partial-cd-for-single-directory) - t)))) - -(defvar ivy-completion-beg nil - "Completion bounds start.") - -(defvar ivy-completion-end nil - "Completion bounds end.") - -(defun ivy-immediate-done () - "Exit the minibuffer with current input instead of current candidate." - (interactive) - (delete-minibuffer-contents) - (setf (ivy-state-current ivy-last) - (cond ((or (not ivy--directory) - (eq (ivy-state-history ivy-last) 'grep-files-history)) - ivy-text) - ((and (string= ivy-text "") - (eq (ivy-state-collection ivy-last) - #'read-file-name-internal)) - (if (ivy-state-def ivy-last) - (if (and - (file-exists-p (ivy-state-def ivy-last)) - (/= (length ivy--directory) - (1+ (length (expand-file-name (ivy-state-def ivy-last)))))) - ivy--directory - (copy-sequence (ivy-state-def ivy-last))) - ivy--directory)) - (t - (expand-file-name ivy-text ivy--directory)))) - (insert (ivy-state-current ivy-last)) - (setq ivy-completion-beg ivy-completion-end) - (setq ivy-exit 'done) - (exit-minibuffer)) - -;;;###autoload -(defun ivy-resume () - "Resume the last completion session." - (interactive) - (if (null (ivy-state-action ivy-last)) - (user-error "The last session isn't compatible with `ivy-resume'") - (when (memq (ivy-state-caller ivy-last) - '(swiper swiper-isearch swiper-backward swiper-isearch-backward)) - (switch-to-buffer (ivy-state-buffer ivy-last))) - (with-current-buffer (ivy-state-buffer ivy-last) - (let ((default-directory (ivy-state-directory ivy-last)) - (ivy-use-ignore-default (ivy-state-ignore ivy-last))) - (ivy-read - (ivy-state-prompt ivy-last) - (ivy-state-collection ivy-last) - :predicate (ivy-state-predicate ivy-last) - :require-match (ivy-state-require-match ivy-last) - :initial-input ivy-text - :history (ivy-state-history ivy-last) - :preselect (ivy-state-current ivy-last) - :keymap (ivy-state-keymap ivy-last) - :update-fn (ivy-state-update-fn ivy-last) - :sort (ivy-state-sort ivy-last) - :action (ivy-state-action ivy-last) - :unwind (ivy-state-unwind ivy-last) - :re-builder (ivy-state-re-builder ivy-last) - :matcher (ivy-state-matcher ivy-last) - :dynamic-collection (ivy-state-dynamic-collection ivy-last) - :extra-props (ivy-state-extra-props ivy-last) - :caller (ivy-state-caller ivy-last)))))) - -(defvar-local ivy-calling nil - "When non-nil, call the current action when `ivy--index' changes.") - -(defun ivy-set-index (index) - "Set `ivy--index' to INDEX." - (setq ivy--index index) - (when ivy-calling - (ivy--exhibit) - (ivy-call))) - -(defun ivy-beginning-of-buffer () - "Select the first completion candidate." - (interactive) - (ivy-set-index 0)) - -(defun ivy-end-of-buffer () - "Select the last completion candidate." - (interactive) - (ivy-set-index (1- ivy--length))) - -(defun ivy-scroll-up-command () - "Scroll the candidates upward by the minibuffer height." - (interactive) - (ivy-set-index (min (1- (+ ivy--index ivy-height)) - (1- ivy--length)))) - -(defun ivy-scroll-down-command () - "Scroll the candidates downward by the minibuffer height." - (interactive) - (ivy-set-index (max (1+ (- ivy--index ivy-height)) - 0))) - -(defun ivy-minibuffer-grow () - "Grow the minibuffer window by 1 line." - (interactive) - (setq-local max-mini-window-height - (cl-incf ivy-height))) - -(defun ivy-minibuffer-shrink () - "Shrink the minibuffer window by 1 line." - (interactive) - (when (> ivy-height 2) - (setq-local max-mini-window-height - (cl-decf ivy-height)) - (window-resize nil -1))) - -(defun ivy-next-line (&optional arg) - "Move cursor vertically down ARG candidates." - (interactive "p") - (setq arg (or arg 1)) - (let ((index (+ ivy--index arg))) - (if (> index (1- ivy--length)) - (if ivy-wrap - (ivy-beginning-of-buffer) - (ivy-set-index (1- ivy--length))) - (ivy-set-index index)))) - -(defun ivy-next-line-or-history (&optional arg) - "Move cursor vertically down ARG candidates. -If the input is empty, select the previous history element instead." - (interactive "p") - (if (string= ivy-text "") - (ivy-previous-history-element 1) - (ivy-next-line arg))) - -(defun ivy-previous-line (&optional arg) - "Move cursor vertically up ARG candidates." - (interactive "p") - (setq arg (or arg 1)) - (let ((index (- ivy--index arg)) - (min-index (if ivy--use-selectable-prompt -1 0))) - (if (< index min-index) - (if ivy-wrap - (ivy-end-of-buffer) - (ivy-set-index min-index)) - (ivy-set-index index)))) - -(defun ivy-previous-line-or-history (arg) - "Move cursor vertically up ARG candidates. -If the input is empty, select the previous history element instead." - (interactive "p") - (when (string= ivy-text "") - (ivy-previous-history-element 1)) - (ivy-previous-line arg)) - -(defun ivy-toggle-calling () - "Flip `ivy-calling'." - (interactive) - (when (setq ivy-calling (not ivy-calling)) - (ivy-call))) - -(defun ivy-toggle-ignore () - "Toggle user-configured candidate filtering." - (interactive) - (setq ivy-use-ignore - (if ivy-use-ignore - nil - (or ivy-use-ignore-default t))) - (setf (ivy-state-ignore ivy-last) ivy-use-ignore) - ;; invalidate cache - (setq ivy--old-cands nil)) - -(defun ivy--get-action (state) - "Get the action function from STATE." - (let ((action (ivy-state-action state))) - (when action - (if (functionp action) - action - (cadr (nth (car action) action)))))) - -(defun ivy--get-window (state) - "Get the window from STATE." - (if (ivy-state-p state) - (let ((window (ivy-state-window state))) - (if (window-live-p window) - window - (next-window))) - (selected-window))) - -(defun ivy--actionp (x) - "Return non-nil when X is a list of actions." - (and (consp x) (not (memq (car x) '(closure lambda))))) - -(defcustom ivy-action-wrap nil - "When non-nil, `ivy-next-action' and `ivy-prev-action' wrap." - :type 'boolean) - -(defun ivy-next-action () - "When the current action is a list, scroll it forwards." - (interactive) - (let ((action (ivy-state-action ivy-last))) - (when (ivy--actionp action) - (let ((len (1- (length action))) - (idx (car action))) - (if (>= idx len) - (when ivy-action-wrap - (setf (car action) 1)) - (cl-incf (car action))))))) - -(defun ivy-prev-action () - "When the current action is a list, scroll it backwards." - (interactive) - (let ((action (ivy-state-action ivy-last))) - (when (ivy--actionp action) - (if (<= (car action) 1) - (when ivy-action-wrap - (setf (car action) (1- (length action)))) - (cl-decf (car action)))))) - -(defun ivy-action-name () - "Return the name associated with the current action." - (let ((action (ivy-state-action ivy-last))) - (if (ivy--actionp action) - (format "[%d/%d] %s" - (car action) - (1- (length action)) - (nth 2 (nth (car action) action))) - "[1/1] default"))) - -(defvar ivy-inhibit-action nil - "When non-nil, `ivy-call' does nothing. - -Example use: - - (let* ((ivy-inhibit-action t) - (str (ivy-switch-buffer))) - ;; do whatever with str - the corresponding buffer will not be opened - )") - -(defun ivy-recursive-restore () - "Restore the above state when exiting the minibuffer. -See variable `ivy-recursive-restore' for further information." - (when (and ivy-recursive-last - ivy-recursive-restore - (not (eq ivy-last ivy-recursive-last))) - (ivy--reset-state (setq ivy-last ivy-recursive-last)))) - -(defvar ivy-marked-candidates nil - "List of marked candidates. -Use `ivy-mark' to populate this. - -When this list is non-nil at the end of the session, the action -will be called for each element of this list.") - -(defvar ivy-mark-prefix ">" - "Prefix used by `ivy-mark'.") - -(defun ivy-call () - "Call the current action without exiting completion." - (interactive) - ;; Testing with `ivy-with' seems to call `ivy-call' again, - ;; in which case `this-command' is nil; so check for this. - (unless (memq this-command '(nil - ivy-done - ivy-alt-done - ivy-dispatching-done)) - (setq ivy-current-prefix-arg current-prefix-arg)) - (let ((action - (if (functionp ivy-inhibit-action) - ivy-inhibit-action - (and (not ivy-inhibit-action) - (ivy--get-action ivy-last))))) - (when action - (let* ((collection (ivy-state-collection ivy-last)) - (current (ivy-state-current ivy-last)) - (x (cond - ;; Alist type. - ((and (consp (car-safe collection)) - ;; Previously, the cdr of the selected - ;; candidate would be returned. Now, the - ;; whole candidate is returned. - (let ((idx (get-text-property 0 'idx current))) - (if idx - (nth idx collection) - (assoc current collection))))) - (ivy--directory - (expand-file-name current ivy--directory)) - ((equal current "") - ivy-text) - (t - current)))) - (if (eq action #'identity) - (prog1 x - (ivy-recursive-restore)) - (select-window (ivy--get-window ivy-last)) - (set-buffer (ivy-state-buffer ivy-last)) - (prog1 (unwind-protect - (if ivy-marked-candidates - (let ((prefix-len (length ivy-mark-prefix))) - (setq ivy-marked-candidates - (mapcar (lambda (s) (substring s prefix-len)) - ivy-marked-candidates)) - (if (ivy-state-multi-action ivy-last) - (funcall - (ivy-state-multi-action ivy-last) - ivy-marked-candidates) - (dolist (c ivy-marked-candidates) - (let ((default-directory (ivy-state-directory ivy-last))) - (funcall action c))))) - (funcall action x)) - (ivy-recursive-restore)) - (unless (or (eq ivy-exit 'done) - (minibuffer-window-active-p (selected-window)) - (null (active-minibuffer-window))) - (select-window (active-minibuffer-window))))))))) - -(defun ivy-call-and-recenter () - "Call action and recenter window according to the selected candidate." - (interactive) - (ivy-call) - (with-ivy-window - (recenter-top-bottom))) - -(defun ivy-next-line-and-call (&optional arg) - "Move cursor vertically down ARG candidates. -Call the permanent action if possible." - (interactive "p") - (ivy-next-line arg) - (ivy--exhibit) - (ivy-call)) - -(defun ivy-previous-line-and-call (&optional arg) - "Move cursor vertically up ARG candidates. -Call the permanent action if possible." - (interactive "p") - (ivy-previous-line arg) - (ivy--exhibit) - (ivy-call)) - -(defun ivy-previous-history-element (arg) - "Forward to `previous-history-element' with ARG." - (interactive "p") - (previous-history-element arg) - (ivy--cd-maybe) - (move-end-of-line 1) - (ivy--maybe-scroll-history)) - -(defun ivy--insert-symbol-boundaries () - (undo-boundary) - (beginning-of-line) - (insert "\\_<") - (end-of-line) - (insert "\\_>")) - -(defun ivy-next-history-element (arg) - "Forward to `next-history-element' with ARG." - (interactive "p") - (if (and (= minibuffer-history-position 0) - (equal ivy-text "")) - (progn - (when minibuffer-default - (setq ivy--default (car minibuffer-default))) - (insert ivy--default) - (when (and (with-ivy-window (derived-mode-p 'prog-mode)) - (eq (ivy-state-caller ivy-last) 'swiper) - (not (file-exists-p ivy--default)) - (not (ivy-ffap-url-p ivy--default)) - (not (ivy-state-dynamic-collection ivy-last)) - (> (point) (minibuffer-prompt-end))) - (ivy--insert-symbol-boundaries))) - (next-history-element arg)) - (ivy--cd-maybe) - (move-end-of-line 1) - (ivy--maybe-scroll-history)) - -(defvar ivy-ffap-url-functions nil - "List of functions that check if the point is on a URL.") - -(defun ivy--cd-maybe () - "Check if the current input points to a different directory. -If so, move to that directory, while keeping only the file name." - (when ivy--directory - (let ((input (ivy--input)) - url) - (if (setq url (or (ivy-ffap-url-p input) - (with-ivy-window - (cl-reduce - (lambda (a b) - (or a (funcall b))) - ivy-ffap-url-functions - :initial-value nil)))) - (ivy-exit-with-action - (lambda (_) - (ivy-ffap-url-fetcher url))) - (setq input (expand-file-name input)) - (let ((file (file-name-nondirectory input)) - (dir (expand-file-name (file-name-directory input)))) - (if (string= dir ivy--directory) - (progn - (delete-minibuffer-contents) - (insert file)) - (ivy--cd dir) - (insert file))))))) - -(defun ivy--maybe-scroll-history () - "If the selected history element has an index, scroll there." - (let ((idx (ignore-errors - (get-text-property - (minibuffer-prompt-end) - 'ivy-index)))) - (when idx - (ivy--exhibit) - (ivy-set-index idx)))) - -(declare-function tramp-get-completion-methods "tramp") - -(defun ivy--cd (dir) - "When completing file names, move to directory DIR." - (if (null ivy--directory) - (error "Unexpected") - (setq ivy--old-cands nil) - (setq ivy--old-re nil) - (ivy-set-index 0) - (setq ivy--all-candidates - (append - (ivy--sorted-files (setq ivy--directory dir)) - (when (and (string= dir "/") (featurep 'tramp)) - (sort - (mapcar - (lambda (s) (substring s 1)) - (tramp-get-completion-methods "")) - #'string<)))) - (setq ivy-text "") - (setf (ivy-state-directory ivy-last) dir) - (delete-minibuffer-contents))) - -(defun ivy--parent-dir (filename) - "Return parent directory of absolute FILENAME." - (file-name-directory (directory-file-name filename))) - -(defun ivy-backward-delete-char () - "Forward to `delete-backward-char'. -Call `ivy-on-del-error-function' if an error occurs, usually when -there is no more text to delete at the beginning of the -minibuffer." - (interactive) - (if (and ivy--directory (= (minibuffer-prompt-end) (point))) - (progn - (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory))) - (ivy--exhibit)) - (setq prefix-arg current-prefix-arg) - (condition-case nil - (call-interactively #'delete-backward-char) - (error - (when ivy-on-del-error-function - (funcall ivy-on-del-error-function)))))) - -(defun ivy-delete-char (arg) - "Forward to `delete-char' ARG." - (interactive "p") - (unless (eolp) - (delete-char arg))) - -(defun ivy-forward-char (arg) - "Forward to `forward-char' ARG." - (interactive "p") - (unless (eolp) - (forward-char arg))) - -(defun ivy-kill-word (arg) - "Forward to `kill-word' ARG." - (interactive "p") - (unless (eolp) - (kill-word arg))) - -(defun ivy-kill-line () - "Forward to `kill-line'." - (interactive) - (if (eolp) - (kill-region (minibuffer-prompt-end) (point)) - (kill-line))) - -(defun ivy-kill-whole-line () - "Forward to `kill-whole-line'." - (interactive) - (kill-region (minibuffer-prompt-end) (line-end-position))) - -(defun ivy-backward-kill-word () - "Forward to `backward-kill-word'." - (interactive) - (if (and ivy--directory (= (minibuffer-prompt-end) (point))) - (progn - (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory))) - (ivy--exhibit)) - (ignore-errors - (let ((pt (point))) - (forward-word -1) - (delete-region (point) pt))))) - -(defvar ivy--regexp-quote #'regexp-quote - "Store the regexp quoting state.") - -(defun ivy-toggle-regexp-quote () - "Toggle the regexp quoting." - (interactive) - (setq ivy--old-re nil) - (cl-rotatef ivy--regex-function ivy--regexp-quote)) - -(defvar avy-all-windows) -(defvar avy-action) -(defvar avy-keys) -(defvar avy-keys-alist) -(defvar avy-style) -(defvar avy-styles-alist) -(declare-function avy-process "ext:avy") -(declare-function avy--style-fn "ext:avy") - -(defcustom ivy-format-functions-alist - '((t . ivy-format-function-default)) - "An alist of functions that transform the list of candidates into a string. -This string is inserted into the minibuffer." - :type '(alist - :key-type symbol - :value-type - (choice - (const :tag "Default" ivy-format-function-default) - (const :tag "Arrow prefix" ivy-format-function-arrow) - (const :tag "Full line" ivy-format-function-line) - (function :tag "Custom function")))) - -(eval-after-load 'avy - '(add-to-list 'avy-styles-alist '(ivy-avy . pre))) - -(defun ivy--avy-candidates () - (let (candidates) - (save-excursion - (save-restriction - (narrow-to-region - (window-start) - (window-end)) - (goto-char (point-min)) - (forward-line) - (while (< (point) (point-max)) - (push - (cons (point) - (selected-window)) - candidates) - (forward-line)))) - (nreverse candidates))) - -(defun ivy--avy-action (pt) - (when (number-or-marker-p pt) - (let ((bnd (ivy--minibuffer-index-bounds - ivy--index ivy--length ivy-height))) - (ivy--done - (substring-no-properties - (nth (+ (car bnd) (- (line-number-at-pos pt) 2)) ivy--old-cands)))))) - -(defun ivy--avy-handler-function (char) - (let (cmd) - (cond ((memq char '(27 ?\C-g)) - ;; exit silently - (throw 'done 'abort)) - ((memq (setq cmd (lookup-key ivy-minibuffer-map (vector char))) - '(ivy-scroll-up-command - ivy-scroll-down-command)) - (funcall cmd) - (ivy--exhibit) - (throw 'done 'exit)) - ;; ignore wrong key - (t - (throw 'done 'restart))))) - -(defvar avy-handler-function) - -(defun ivy-avy () - "Jump to one of the current ivy candidates." - (interactive) - (unless (require 'avy nil 'noerror) - (error "Package avy isn't installed")) - (let* ((avy-all-windows nil) - (avy-keys (or (cdr (assq 'ivy-avy avy-keys-alist)) - avy-keys)) - (avy-style (or (cdr (assq 'ivy-avy avy-styles-alist)) - avy-style)) - (avy-action #'identity) - (avy-handler-function #'ivy--avy-handler-function) - res) - (while (eq (setq res (avy-process (ivy--avy-candidates))) t)) - (when res - (ivy--avy-action res)))) - -(defun ivy-sort-file-function-default (x y) - "Compare two files X and Y. -Prioritize directories." - (if (get-text-property 0 'dirp x) - (if (get-text-property 0 'dirp y) - (string< (directory-file-name x) (directory-file-name y)) - t) - (if (get-text-property 0 'dirp y) - nil - (string< x y)))) - -(defun ivy-string< (x y) - "Like `string<', but operate on CARs when given cons cells." - (string< (if (consp x) (car x) x) - (if (consp y) (car y) y))) - -(define-obsolete-function-alias 'ivy-sort-file-function-using-ido - 'ido-file-extension-lessp "<2019-10-12 Sat>") - -(defcustom ivy-sort-functions-alist - '((t . ivy-string<)) - "An alist of sorting functions for each collection function. -Interactive functions that call completion fit in here as well. - -Nil means no sorting, which is useful to turn off the sorting for -functions that have candidates in the natural buffer order, like -`org-refile' or `Man-goto-section'. - -A list can be used to associate multiple sorting functions with a -collection. The car of the list is the current sort -function. This list can be rotated with `ivy-rotate-sort'. - -The entry associated with t is used for all fall-through cases. - -See also `ivy-sort-max-size'." - :type - '(alist - :key-type (choice - (const :tag "Fall-through" t) - (symbol :tag "Collection")) - :value-type (choice - (const :tag "Plain sort" string-lessp) - (const :tag "File sort" ivy-sort-file-function-default) - (const :tag "File sort using Ido" ido-file-extension-lessp) - (const :tag "No sort" nil) - (function :tag "Custom function") - (repeat (function :tag "Custom function"))))) - -(defun ivy--sort-function (collection) - "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'." - (let ((entry (cdr (or (assq collection ivy-sort-functions-alist) - (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist) - (assq t ivy-sort-functions-alist))))) - (and (or (functionp entry) - (functionp (setq entry (car-safe entry)))) - entry))) - -(defun ivy-rotate-sort () - "Rotate through sorting functions available for current collection. -This only has an effect if multiple sorting functions are -specified for the current collection in -`ivy-sort-functions-alist'." - (interactive) - (let ((cell (or (assq (ivy-state-collection ivy-last) ivy-sort-functions-alist) - (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)))) - (when (consp (cdr cell)) - (setcdr cell (nconc (cddr cell) (list (cadr cell)))) - (ivy--reset-state ivy-last)))) - -(defvar ivy-index-functions-alist - '((t . ivy-recompute-index-zero)) - "An alist of index recomputing functions for each collection function. -When the input changes, the appropriate function returns an -integer - the index of the matched candidate that should be -selected.") - -(defvar ivy-re-builders-alist - '((t . ivy--regex-plus)) - "An alist of regex building functions for each collection function. - -Each key is (in order of priority): -1. The actual collection function, e.g. `read-file-name-internal'. -2. The symbol passed by :caller into `ivy-read'. -3. `this-command'. -4. t. - -Each value is a function that should take a string and return a -valid regex or a regex sequence (see below). - -Possible choices: `ivy--regex', `regexp-quote', -`ivy--regex-plus', `ivy--regex-fuzzy', `ivy--regex-ignore-order'. - -If a function returns a list, it should format like this: -'((\"matching-regexp\" . t) (\"non-matching-regexp\") ...). - -The matches will be filtered in a sequence, you can mix the -regexps that should match and that should not match as you -like.") - -(defvar ivy-highlight-functions-alist - '((ivy--regex-ignore-order . ivy--highlight-ignore-order) - (ivy--regex-fuzzy . ivy--highlight-fuzzy) - (ivy--regex-plus . ivy--highlight-default)) - "An alist of highlighting functions for each regex builder function.") - -(defcustom ivy-initial-inputs-alist - '((org-refile . "^") - (org-agenda-refile . "^") - (org-capture-refile . "^") - (Man-completion-table . "^") - (woman . "^")) - "An alist associating commands with their initial input. - -Each cdr is either a string or a function called in the context -of a call to `ivy-read'." - :type '(alist - :key-type (symbol) - :value-type (choice (string) (function)))) - -(defcustom ivy-hooks-alist nil - "An alist associating commands to setup functions. -Examples: `toggle-input-method', (lambda () (insert \"^\")), etc. -May supersede `ivy-initial-inputs-alist'." - :type '(alist :key-type symbol :value-type function)) - -(defvar ivy--occurs-list nil - "A list of custom occur generators per command.") - -(defun ivy-set-occur (cmd occur) - "Assign CMD a custom OCCUR function." - (setq ivy--occurs-list - (plist-put ivy--occurs-list cmd occur))) - -(defcustom ivy-update-fns-alist nil - "An alist associating commands to their :update-fn values." - :type '(alist - :key-type symbol - :value-type - (radio - (const :tag "Off" nil) - (const :tag "Call action on change" auto)))) - -(defvar ivy-unwind-fns-alist nil - "An alist associating commands to their :unwind values.") - -(defun ivy--alist-set (alist-sym key val) - (let ((cell (assoc key (symbol-value alist-sym)))) - (if cell - (setcdr cell val) - (set alist-sym (cons (cons key val) - (symbol-value alist-sym)))))) - -(declare-function counsel-set-async-exit-code "counsel") - -(cl-defun ivy-configure (caller - &key - initial-input - height - occur - update-fn - unwind-fn - index-fn - sort-fn - format-fn - display-transformer-fn - more-chars - grep-p - exit-codes) - "Configure `ivy-read' params for CALLER." - (declare (indent 1)) - (when initial-input - (ivy--alist-set 'ivy-initial-inputs-alist caller initial-input)) - (when height - (ivy--alist-set 'ivy-height-alist caller height)) - (when occur - (ivy-set-occur caller occur)) - (when update-fn - (ivy--alist-set 'ivy-update-fns-alist caller update-fn)) - (when unwind-fn - (ivy--alist-set 'ivy-unwind-fns-alist caller unwind-fn)) - (when index-fn - (ivy--alist-set 'ivy-index-functions-alist caller index-fn)) - (when sort-fn - (ivy--alist-set 'ivy-sort-functions-alist caller sort-fn)) - (when format-fn - (ivy--alist-set 'ivy-format-functions-alist caller format-fn)) - (when display-transformer-fn - (ivy-set-display-transformer caller display-transformer-fn)) - (when more-chars - (ivy--alist-set 'ivy-more-chars-alist caller more-chars)) - (when grep-p - (cl-pushnew caller ivy-highlight-grep-commands)) - (when exit-codes - (let (code msg) - (while (and (setq code (pop exit-codes)) - (setq msg (pop exit-codes))) - (counsel-set-async-exit-code caller code msg))))) - -(defcustom ivy-sort-max-size 30000 - "Sorting won't be done for collections larger than this." - :type 'integer) - -(defalias 'ivy--dirname-p - (if (fboundp 'directory-name-p) - #'directory-name-p - (lambda (name) - "Return non-nil if NAME ends with a directory separator." - (string-match-p "/\\'" name)))) - -(defun ivy--sorted-files (dir) - "Return the list of files in DIR. -Directories come first." - (let* ((default-directory dir) - (seq (condition-case nil - (mapcar (lambda (s) (replace-regexp-in-string "\\$\\$" "$" s)) - (all-completions "" #'read-file-name-internal - (ivy-state-predicate ivy-last))) - (error - (directory-files dir)))) - sort-fn) - (setq seq (delete "./" (delete "../" seq))) - (when (eq (setq sort-fn (ivy--sort-function #'read-file-name-internal)) - #'ivy-sort-file-function-default) - (setq seq (mapcar (lambda (x) - (propertize x 'dirp (ivy--dirname-p x))) - seq))) - (when sort-fn - (setq seq (sort seq sort-fn))) - (dolist (dir ivy-extra-directories) - (push dir seq)) - (if (string= dir "/") - (cl-remove-if (lambda (s) (string-match ":$" s)) (delete "../" seq)) - seq))) - -(defun ivy-alist-setting (alist &optional key) - "Return the value associated with KEY in ALIST, using `assq'. -KEY defaults to the last caller of `ivy-read'; if no entry is -found, it falls back to the key t." - (cdr (or (let ((caller (or key (ivy-state-caller ivy-last)))) - (and caller (assq caller alist))) - (assq t alist)))) - -(defun ivy--height (caller) - (let ((v (or (ivy-alist-setting ivy-height-alist caller) - ivy-height))) - (if (integerp v) - v - (if (functionp v) - (funcall v caller) - (error "Unexpected value: %S" v))))) - -(defun ivy--remove-props (str &rest props) - "Return STR with text PROPS destructively removed." - (ignore-errors - (remove-list-of-text-properties 0 (length str) props str)) - str) - -;;** Entry Point -;;;###autoload -(cl-defun ivy-read (prompt collection - &key - predicate require-match initial-input - history preselect def keymap update-fn sort - action multi-action - unwind re-builder matcher - dynamic-collection - extra-props - caller) - "Read a string in the minibuffer, with completion. - -PROMPT is a string, normally ending in a colon and a space. -`ivy-count-format' is prepended to PROMPT during completion. - -COLLECTION is either a list of strings, a function, an alist, or -a hash table, supplied for `minibuffer-completion-table'. - -PREDICATE is applied to filter out the COLLECTION immediately. -This argument is for compatibility with `completing-read'. - -When REQUIRE-MATCH is non-nil, only members of COLLECTION can be -selected. - -If INITIAL-INPUT is non-nil, then insert that input in the -minibuffer initially. - -HISTORY is a name of a variable to hold the completion session -history. - -KEYMAP is composed with `ivy-minibuffer-map'. - -PRESELECT, when non-nil, determines which one of the candidates -matching INITIAL-INPUT to select initially. An integer stands -for the position of the desired candidate in the collection, -counting from zero. Otherwise, use the first occurrence of -PRESELECT in the collection. Comparison is first done with -`equal'. If that fails, and when applicable, match PRESELECT as -a regular expression. - -DEF is for compatibility with `completing-read'. - -UPDATE-FN is called each time the candidate list is re-displayed. - -When SORT is non-nil, `ivy-sort-functions-alist' determines how -to sort candidates before displaying them. - -ACTION is a function to call after selecting a candidate. -It takes one argument, the selected candidate. If COLLECTION is -an alist, the argument is a cons cell, otherwise it's a string. - -MULTI-ACTION, when non-nil, is called instead of ACTION when -there are marked candidates. It takes the list of candidates as -its only argument. When it's nil, ACTION is called on each marked -candidate. - -UNWIND is a function of no arguments to call before exiting. - -RE-BUILDER is a function transforming input text into a regex -pattern. - -MATCHER is a function which can override how candidates are -filtered based on user input. It takes a regex pattern and a -list of candidates, and returns the list of matching candidates. - -DYNAMIC-COLLECTION is a boolean specifying whether the list of -candidates is updated after each input by calling COLLECTION. - -EXTRA-PROPS can be used to store collection-specific -session-specific data. - -CALLER is a symbol to uniquely identify the caller to `ivy-read'. -It is used, along with COLLECTION, to determine which -customizations apply to the current completion session." - ;; get un-stuck from an existing `read-key' overriding minibuffer keys - (when (equal overriding-local-map '(keymap)) - (keyboard-quit)) - (setq caller (or caller this-command)) - (let* ((ivy-recursive-last (and (active-minibuffer-window) ivy-last)) - (ivy--display-function - (when (or ivy-recursive-last - (not (window-minibuffer-p))) - (ivy-alist-setting ivy-display-functions-alist caller))) - result) - (setq update-fn (or update-fn (ivy-alist-setting ivy-update-fns-alist caller))) - (setq unwind (or unwind (ivy-alist-setting ivy-unwind-fns-alist caller))) - (setq ivy-last - (make-ivy-state - :prompt prompt - :collection collection - :predicate predicate - :require-match require-match - :initial-input initial-input - :history history - :preselect preselect - :keymap keymap - :update-fn (if (eq update-fn 'auto) - (lambda () - (with-ivy-window - (funcall - (ivy--get-action ivy-last) - (if (consp (car-safe (ivy-state-collection ivy-last))) - (assoc (ivy-state-current ivy-last) - (ivy-state-collection ivy-last)) - (ivy-state-current ivy-last))))) - update-fn) - :sort sort - :action (ivy--compute-extra-actions action caller) - :multi-action multi-action - :frame (selected-frame) - :window (selected-window) - :buffer (current-buffer) - :unwind unwind - :re-builder re-builder - :matcher matcher - :dynamic-collection dynamic-collection - :display-transformer-fn (plist-get ivy--display-transformers-list caller) - :directory default-directory - :extra-props extra-props - :caller caller - :def def)) - (ivy--reset-state ivy-last) - (unwind-protect - (minibuffer-with-setup-hook - #'ivy--minibuffer-setup - (let* ((hist (or history 'ivy-history)) - (minibuffer-completion-table collection) - (minibuffer-completion-predicate predicate) - (ivy-height (ivy--height caller)) - (resize-mini-windows (unless (display-graphic-p) - 'grow-only))) - (if (and ivy-auto-select-single-candidate - ivy--all-candidates - (null (cdr ivy--all-candidates))) - (progn - (setf (ivy-state-current ivy-last) - (car ivy--all-candidates)) - (setq ivy-exit 'done)) - (read-from-minibuffer - prompt - (ivy-state-initial-input ivy-last) - (make-composed-keymap keymap ivy-minibuffer-map) - nil - hist)) - (when (eq ivy-exit 'done) - (let ((item (if ivy--directory - (ivy-state-current ivy-last) - ivy-text))) - (unless (equal item "") - (set hist (cons (propertize item 'ivy-index ivy--index) - (delete item - (cdr (symbol-value hist)))))))) - (setq result (ivy-state-current ivy-last)))) - (ivy--cleanup)) - (ivy-call) - (ivy--remove-props (ivy-state-current ivy-last) 'idx) - result)) - -(defun ivy--cleanup () - ;; Fixes a bug in ESS, #1660 - (put 'post-command-hook 'permanent-local nil) - (remove-hook 'post-command-hook #'ivy--queue-exhibit) - (let ((cleanup (ivy--display-function-prop :cleanup)) - (unwind (ivy-state-unwind ivy-last))) - (when (functionp cleanup) - (funcall cleanup)) - (when unwind - (funcall unwind))) - (ivy--pulse-cleanup) - (unless (eq ivy-exit 'done) - (ivy-recursive-restore))) - -(defun ivy--display-function-prop (prop) - "Return PROP associated with current `ivy--display-function'." - (plist-get (cdr (assq ivy--display-function - ivy-display-functions-props)) - prop)) - -(defvar Info-complete-menu-buffer) - -(defun ivy--reset-state (state) - "Reset the ivy to STATE. -This is useful for recursive `ivy-read'." - (setq ivy-marked-candidates nil) - (unless (equal (selected-frame) (ivy-state-frame state)) - (select-window (active-minibuffer-window))) - (let* ((prompt (or (ivy-state-prompt state) "")) - (collection (ivy-state-collection state)) - (predicate (ivy-state-predicate state)) - (history (ivy-state-history state)) - (preselect (ivy-state-preselect state)) - (re-builder (ivy-state-re-builder state)) - (dynamic-collection (ivy-state-dynamic-collection state)) - (require-match (ivy-state-require-match state)) - (caller (or (ivy-state-caller state) this-command)) - (sort (or (ivy-state-sort state) (assoc caller ivy-sort-functions-alist))) - (initial-input - (or (ivy-state-initial-input state) - (let ((init (cdr (assq caller ivy-initial-inputs-alist)))) - (cond ((functionp init) - (funcall init)) - (t - init))))) - (def (ivy-state-def state))) - (setq ivy--extra-candidates (ivy--compute-extra-candidates caller)) - (setq ivy--directory nil) - (setq ivy-case-fold-search ivy-case-fold-search-default) - (setq ivy--regex-function - (or re-builder - (and (functionp collection) - (cdr (assq collection ivy-re-builders-alist))) - (ivy-alist-setting ivy-re-builders-alist) - #'ivy--regex)) - (setq ivy--subexps 0) - (setq ivy--regexp-quote #'regexp-quote) - (setq ivy--old-text "") - (setq ivy--full-length nil) - (setq ivy-text "") - (setq ivy--index 0) - (setq ivy-calling nil) - (setq ivy-use-ignore ivy-use-ignore-default) - (setf (ivy-state-ignore state) ivy-use-ignore) - (setq ivy--highlight-function - (or (cdr (assq ivy--regex-function ivy-highlight-functions-alist)) - #'ivy--highlight-default)) - (let (coll sort-fn) - (cond ((eq collection #'Info-read-node-name-1) - (setq coll - (if (equal (bound-and-true-p Info-current-file) "dir") - (mapcar (lambda (x) (format "(%s)" x)) - (delete-dups - (all-completions "(" collection predicate))) - (all-completions "" collection predicate)))) - ((eq collection #'read-file-name-internal) - (require 'tramp) - (when (and (equal def initial-input) - (member "./" ivy-extra-directories)) - (setq def nil)) - (setq ivy--directory default-directory) - (when (and initial-input - (not (equal initial-input ""))) - (cond ((file-directory-p initial-input) - (when (equal (file-name-nondirectory initial-input) "") - (setf (ivy-state-preselect state) (setq preselect nil)) - (setq def nil)) - (setq ivy--directory (file-name-as-directory initial-input)) - (setq initial-input nil) - (when preselect - (let ((preselect-directory - (file-name-directory preselect))) - (when (and preselect-directory - (not (equal - (expand-file-name - preselect-directory) - (expand-file-name ivy--directory)))) - (setf (ivy-state-preselect state) - (setq preselect nil)))))) - ((ignore-errors - (file-exists-p (file-name-directory initial-input))) - (setq ivy--directory (file-name-directory initial-input)) - (setf (ivy-state-preselect state) - (file-name-nondirectory initial-input))))) - (require 'dired) - (when preselect - (let ((preselect-directory (ivy--parent-dir preselect))) - (when (and preselect-directory - (not (string= preselect-directory - default-directory))) - (setq ivy--directory preselect-directory)) - (setq preselect (file-relative-name preselect - preselect-directory)) - (setf (ivy-state-preselect state) preselect))) - (setq sort nil) - (setq coll (ivy--sorted-files ivy--directory)) - (when initial-input - (unless (or require-match - (equal initial-input default-directory) - (equal initial-input "")) - (setq coll (cons initial-input coll))) - (when (or (not (ivy-state-action ivy-last)) - (equal (ivy--get-action ivy-last) 'identity)) - (setq initial-input nil)))) - ((eq collection #'internal-complete-buffer) - (setq prompt - (replace-regexp-in-string "RET to end" "C-M-j to end" prompt)) - (setq coll (ivy--buffer-list - "" - (and ivy-use-virtual-buffers - (member caller '(ivy-switch-buffer - ivy-switch-buffer-other-window - counsel-switch-buffer))) - predicate))) - (dynamic-collection - (setq coll (funcall collection (or initial-input "")))) - ((consp (car-safe collection)) - (setq collection (cl-remove-if-not predicate collection)) - (when (and sort (setq sort-fn (ivy--sort-function caller))) - (setq collection (sort (copy-sequence collection) sort-fn)) - (setq sort nil)) - (setf (ivy-state-collection ivy-last) collection) - (setq coll (let ((i -1)) - (mapcar (lambda (x) - (propertize x 'idx (cl-incf i))) - (all-completions "" collection))))) - ((or (functionp collection) - (byte-code-function-p collection) - (vectorp collection) - (hash-table-p collection) - (and (listp collection) (symbolp (car collection)))) - (let ((Info-complete-menu-buffer - ;; FIXME: This is a temporary workaround for issue #1803. - (or (bound-and-true-p Info-complete-menu-buffer) - (ivy-state-buffer state)))) - (setq coll (all-completions "" collection predicate)))) - (t - (setq coll (all-completions "" collection predicate)))) - (unless (ivy-state-dynamic-collection ivy-last) - (setq coll (delete "" coll))) - (when def - (cond ((stringp (car-safe def)) - (setq coll (cl-union def coll :test #'equal))) - ((and (stringp def) (not (member def coll))) - (push def coll)))) - (when (and sort - (or (functionp collection) - (not (eq history 'org-refile-history))) - (setq sort-fn (ivy--sort-function - (if (functionp collection) collection caller))) - (null (nthcdr ivy-sort-max-size coll))) - (setq coll (sort (copy-sequence coll) sort-fn))) - (setq coll (ivy--set-candidates coll)) - (setq ivy--old-re nil) - (setq ivy--old-cands nil) - (when initial-input - ;; Needed for anchor to work - (setq ivy--old-cands coll) - (setq ivy--old-cands (ivy--filter initial-input coll))) - (unless (setq ivy--trying-to-resume-dynamic-collection - (and preselect dynamic-collection)) - (when (integerp preselect) - (setq ivy--old-re "") - (ivy-set-index preselect))) - (setq ivy--all-candidates coll) - (unless (integerp preselect) - (ivy-set-index (or - (and dynamic-collection - ivy--index) - (and preselect - (ivy--preselect-index - preselect - (if initial-input - ivy--old-cands - coll))) - 0)))) - (setq ivy-exit nil) - (setq ivy--default - (if (region-active-p) - (buffer-substring (region-beginning) (region-end)) - (ivy-thing-at-point))) - (setq ivy--prompt (ivy-add-prompt-count (ivy--quote-format-string prompt))) - (setq ivy--use-selectable-prompt (ivy--prompt-selectable-p)) - (setf (ivy-state-initial-input ivy-last) initial-input))) - -(defun ivy-add-prompt-count (prompt) - "Add count information to PROMPT." - (cond ((null ivy-count-format) - (error - "`ivy-count-format' can't be nil. Set it to \"\" instead")) - ((string-match "%d.*\\(%d\\)" ivy-count-format) - (let* ((w (1+ (floor (log (max 1 (length ivy--all-candidates)) 10)))) - (s (replace-match (format "%%-%dd" w) t t ivy-count-format 1))) - (string-match "%d" s) - (concat (replace-match (format "%%%dd" w) t t s) - prompt))) - ((string-match-p "%.*d" ivy-count-format) - (concat ivy-count-format prompt)) - (ivy--directory - prompt) - (t - prompt))) - -(defun ivy--quote-format-string (str) - "Make STR suitable for `format' with no extra arguments." - (replace-regexp-in-string "%" "%%" str t t)) - -;;;###autoload -(defun ivy-completing-read (prompt collection - &optional predicate require-match initial-input - history def inherit-input-method) - "Read a string in the minibuffer, with completion. - -This interface conforms to `completing-read' and can be used for -`completing-read-function'. - -PROMPT is a string that normally ends in a colon and a space. -COLLECTION is either a list of strings, an alist, an obarray, or a hash table. -PREDICATE limits completion to a subset of COLLECTION. -REQUIRE-MATCH is a boolean value. See `completing-read'. -INITIAL-INPUT is a string inserted into the minibuffer initially. -HISTORY is a list of previously selected inputs. -DEF is the default value. -INHERIT-INPUT-METHOD is currently ignored." - (let ((handler - (and (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth)) - (assq this-command ivy-completing-read-handlers-alist)))) - (if handler - (let ((completion-in-region-function #'completion--in-region) - (ivy-completing-read-ignore-handlers-depth (1+ (minibuffer-depth)))) - (funcall (cdr handler) - prompt collection - predicate require-match - initial-input history - def inherit-input-method)) - ;; See the doc of `completing-read'. - (when (consp history) - (when (numberp (cdr history)) - (setq initial-input (nth (1- (cdr history)) - (symbol-value (car history))))) - (setq history (car history))) - (when (consp def) - (setq def (car def))) - (let ((str (ivy-read - prompt collection - :predicate predicate - :require-match (and collection require-match) - :initial-input (cond ((consp initial-input) - (car initial-input)) - ((and (stringp initial-input) - (not (eq collection #'read-file-name-internal)) - (string-match-p "\\+" initial-input)) - (replace-regexp-in-string - "\\+" "\\\\+" initial-input)) - (t - initial-input)) - :preselect def - :def def - :history history - :keymap nil - :dynamic-collection ivy-completing-read-dynamic-collection - :caller (if (and collection (symbolp collection)) - collection - this-command)))) - (if (string= str "") - ;; For `completing-read' compat, return the first element of - ;; DEFAULT, if it is a list; "", if DEFAULT is nil; or DEFAULT. - (or def "") - str))))) - -(defun ivy-completing-read-with-empty-string-def - (prompt collection - &optional predicate require-match initial-input - history def inherit-input-method) - "Same as `ivy-completing-read' but with different handling of DEF. - -Specifically, if DEF is nil, it is treated the same as if DEF was -the empty string. This mimics the behavior of -`completing-read-default'. This function can therefore be used in -place of `ivy-completing-read' for commands that rely on this -behavior." - (ivy-completing-read - prompt collection predicate require-match initial-input - history (or def "") inherit-input-method)) - -(declare-function mc/all-fake-cursors "ext:multiple-cursors-core") - -(defun ivy-completion-in-region-action (str) - "Insert STR, erasing the previous one. -The previous string is between `ivy-completion-beg' and `ivy-completion-end'." - (when (consp str) - (setq str (cdr str))) - (when (stringp str) - (let ((fake-cursors (and (require 'multiple-cursors-core nil t) - (mc/all-fake-cursors))) - (pt (point)) - (beg ivy-completion-beg) - (end ivy-completion-end)) - (when beg - (delete-region beg end)) - (setq ivy-completion-beg (point)) - (insert (substring-no-properties str)) - (completion--done str 'exact) - (setq ivy-completion-end (point)) - (save-excursion - (dolist (cursor fake-cursors) - (goto-char (overlay-start cursor)) - (delete-region (+ (point) (- beg pt)) - (+ (point) (- end pt))) - (insert (substring-no-properties str)) - ;; manually move the fake cursor - (move-overlay cursor (point) (1+ (point))) - (set-marker (overlay-get cursor 'point) (point)) - (set-marker (overlay-get cursor 'mark) (point))))))) - -(defun ivy-completion-common-length (str) - "Return the amount of characters that match in STR. - -`completion-all-completions' computes this and returns the result -via text properties. - -The first non-matching part is propertized: -- either with: (face (completions-first-difference)) -- or: (font-lock-face completions-first-difference)." - (let ((char-property-alias-alist '((face font-lock-face))) - (i (1- (length str)))) - (catch 'done - (while (>= i 0) - (when (equal (get-text-property i 'face str) - '(completions-first-difference)) - (throw 'done i)) - (cl-decf i)) - (throw 'done (length str))))) - -(defun ivy-completion-in-region (start end collection &optional predicate) - "An Ivy function suitable for `completion-in-region-function'. -The function completes the text between START and END using COLLECTION. -PREDICATE (a function called with no arguments) says when to exit. -See `completion-in-region' for further information." - (let* ((enable-recursive-minibuffers t) - (str (buffer-substring-no-properties start end)) - (completion-ignore-case (ivy--case-fold-p str)) - (comps - (completion-all-completions str collection predicate (- end start)))) - (cond ((null comps) - (message "No matches")) - ((progn - (nconc comps nil) - (and (null (cdr comps)) - (string= str (car comps)))) - (message "Sole match")) - (t - (when (eq collection 'crm--collection-fn) - (setq comps (delete-dups comps))) - (let* ((len (ivy-completion-common-length (car comps))) - (initial (cond ((= len 0) - "") - ((let ((str-len (length str))) - (when (> len str-len) - (setq len str-len) - str))) - (t - (substring str (- len)))))) - (setq ivy--old-re nil) - (unless (ivy--filter initial comps) - (setq initial nil)) - (delete-region (- end len) end) - (setq ivy-completion-beg (- end len)) - (setq ivy-completion-end ivy-completion-beg) - (if (null (cdr comps)) - (progn - (unless (minibuffer-window-active-p (selected-window)) - (setf (ivy-state-window ivy-last) (selected-window))) - (ivy-completion-in-region-action - (substring-no-properties (car comps)))) - (dolist (s comps) - ;; Remove face `completions-first-difference'. - (ivy--remove-props s 'face)) - (ivy-read (format "(%s): " str) comps - ;; Predicate was already applied by - ;; `completion-all-completions'. - :predicate nil - :initial-input initial - :action #'ivy-completion-in-region-action - :unwind (lambda () - (unless (eq ivy-exit 'done) - (goto-char ivy-completion-beg) - (when initial - (insert initial)))) - :caller 'ivy-completion-in-region) - t)))))) - -(defun ivy-completion-in-region-prompt () - "Prompt function for `ivy-completion-in-region'. -See `ivy-set-prompt'." - (and (window-minibuffer-p (ivy-state-window ivy-last)) - (ivy-add-prompt-count (ivy-state-prompt ivy-last)))) - -(ivy-set-prompt #'ivy-completion-in-region #'ivy-completion-in-region-prompt) - -(defcustom ivy-do-completion-in-region t - "When non-nil `ivy-mode' will set `completion-in-region-function'." - :type 'boolean) - -;;;###autoload -(define-minor-mode ivy-mode - "Toggle Ivy mode on or off. -Turn Ivy mode on if ARG is positive, off otherwise. -Turning on Ivy mode sets `completing-read-function' to -`ivy-completing-read'. - -Global bindings: -\\{ivy-mode-map} - -Minibuffer bindings: -\\{ivy-minibuffer-map}" - :group 'ivy - :global t - :keymap ivy-mode-map - :lighter " ivy" - (if ivy-mode - (progn - (setq completing-read-function 'ivy-completing-read) - (when ivy-do-completion-in-region - (setq completion-in-region-function 'ivy-completion-in-region))) - (setq completing-read-function 'completing-read-default) - (setq completion-in-region-function 'completion--in-region))) - -(defun ivy--preselect-index (preselect candidates) - "Return the index of PRESELECT in CANDIDATES." - (cond ((integerp preselect) - (if (integerp (car candidates)) - (cl-position preselect candidates) - preselect)) - ((cl-position preselect candidates :test #'equal)) - ((ivy--regex-p preselect) - (cl-position preselect candidates :test #'string-match-p)))) - -;;* Implementation -;;** Regex -(defun ivy-re-match (re-seq str) - "Return non-nil if RE-SEQ is matched by STR. - -RE-SEQ is a list of (RE . MATCH-P). - -RE is a regular expression. - -MATCH-P is t when RE should match STR and nil when RE should not -match STR. - -Each element of RE-SEQ must match for the function to return true. - -This concept is used to generalize regular expressions for -`ivy--regex-plus' and `ivy--regex-ignore-order'." - (let ((res t) - re) - (while (and res (setq re (pop re-seq))) - (setq res - (if (cdr re) - (string-match-p (car re) str) - (not (string-match-p (car re) str))))) - res)) - -(defvar ivy--regex-hash - (make-hash-table :test #'equal) - "Store pre-computed regex.") - -(defun ivy--split (str) - "Split STR into list of substrings bounded by spaces. -Single spaces act as splitting points. Consecutive spaces -\"quote\" their preceding spaces, i.e., guard them from being -split. This allows the literal interpretation of N spaces by -inputting N+1 spaces. Any substring not constituting a valid -regexp is passed to `regexp-quote'." - (let ((len (length str)) - start0 - (start1 0) - res s - match-len) - (while (and (string-match " +" str start1) - (< start1 len)) - (if (and (> (match-beginning 0) 2) - (string= "[^" (substring - str - (- (match-beginning 0) 2) - (match-beginning 0)))) - (progn - (setq start0 start1) - (setq start1 (match-end 0))) - (setq match-len (- (match-end 0) (match-beginning 0))) - (if (= match-len 1) - (progn - (when start0 - (setq start1 start0) - (setq start0 nil)) - (push (substring str start1 (match-beginning 0)) res) - (setq start1 (match-end 0))) - (setq str (replace-match - (make-string (1- match-len) ?\ ) - nil nil str)) - (setq start0 (or start0 start1)) - (setq start1 (1- (match-end 0)))))) - (if start0 - (push (substring str start0) res) - (setq s (substring str start1)) - (unless (= (length s) 0) - (push s res))) - (mapcar #'ivy--regex-or-literal (nreverse res)))) - -(defun ivy--trim-trailing-re (regex) - "Trim incomplete REGEX. -If REGEX ends with \\|, trim it, since then it matches an empty string." - (if (string-match "\\`\\(.*\\)[\\]|\\'" regex) - (match-string 1 regex) - regex)) - -(defun ivy--regex (str &optional greedy) - "Re-build regex pattern from STR in case it has a space. -When GREEDY is non-nil, join words in a greedy way." - (let ((hashed (unless greedy - (gethash str ivy--regex-hash)))) - (if hashed - (progn - (setq ivy--subexps (car hashed)) - (cdr hashed)) - (when (string-match-p "\\(?:[^\\]\\|^\\)\\\\\\'" str) - (setq str (substring str 0 -1))) - (setq str (ivy--trim-trailing-re str)) - (cdr (puthash str - (let ((subs (ivy--split str))) - (if (= (length subs) 1) - (cons - (setq ivy--subexps 0) - (if (string-match-p "\\`\\.[^.]" (car subs)) - (concat "\\." (substring (car subs) 1)) - (car subs))) - (cons - (setq ivy--subexps (length subs)) - (mapconcat - (lambda (x) - (if (string-match-p "\\`\\\\([^?].*\\\\)\\'" x) - x - (format "\\(%s\\)" x))) - subs - (if greedy ".*" ".*?"))))) - ivy--regex-hash))))) - -(defun ivy--regex-p (object) - "Return OBJECT if it is a valid regular expression, else nil." - (ignore-errors (string-match-p object "") object)) - -(defun ivy--regex-or-literal (str) - "If STR isn't a legal regexp, escape it." - (or (ivy--regex-p str) (regexp-quote str))) - -(defun ivy--split-negation (str) - "Split STR into text before and after ! delimiter. -Do not split if the delimiter is escaped as \\!. - -Assumes there is at most one un-escaped delimiter and discards -text after delimiter if it is empty. Modifies match data." - (unless (string= str "") - (let ((delim "\\(?:\\`\\|[^\\]\\)\\(!\\)")) - (mapcar (lambda (split) - ;; Store "\!" as "!". - (replace-regexp-in-string "\\\\!" "!" split t t)) - (if (string-match delim str) - ;; Ignore everything past first un-escaped ! rather than - ;; crashing. We can't warn or error because the minibuffer is - ;; already active. - (let* ((i (match-beginning 1)) - (j (and (string-match delim str (1+ i)) - (match-beginning 1))) - (neg (substring str (1+ i) j))) - (cons (substring str 0 i) - (and (not (string= neg "")) - (list neg)))) - (list str)))))) - -(defun ivy--split-spaces (str) - "Split STR on spaces, unless they're preceded by \\. -No un-escaped spaces are left in the output. Any substring not -constituting a valid regexp is passed to `regexp-quote'." - (when str - (let ((i 0) ; End of last search. - (j 0) ; End of last delimiter. - parts) - (while (string-match "\\(\\\\ \\)\\| +" str i) - (setq i (match-end 0)) - (if (not (match-beginning 1)) - ;; Un-escaped space(s). - (let ((delim (match-beginning 0))) - (when (< j delim) - (push (substring str j delim) parts)) - (setq j i)) - ;; Store "\ " as " ". - (setq str (replace-match " " t t str 1)) - (setq i (1- i)))) - (when (< j (length str)) - (push (substring str j) parts)) - (mapcar #'ivy--regex-or-literal (nreverse parts))))) - -(defun ivy--regex-ignore-order (str) - "Re-build regex from STR by splitting at spaces and using ! for negation. - -Examples: -foo -> matches \"foo\" -foo bar -> matches if both \"foo\" and \"bar\" match (any order) -foo !bar -> matches if \"foo\" matches and \"bar\" does not match -foo !bar baz -> matches if \"foo\" matches and neither \"bar\" nor \"baz\" match -foo[a-z] -> matches \"foo[a-z]\" - -Escaping examples: -foo\\!bar -> matches \"foo!bar\" -foo\\ bar -> matches \"foo bar\" - -Returns a list suitable for `ivy-re-match'." - (setq str (ivy--trim-trailing-re str)) - (let* (regex-parts - (raw-parts (ivy--split-negation str))) - (dolist (part (ivy--split-spaces (car raw-parts))) - (push (cons part t) regex-parts)) - (when (cdr raw-parts) - (dolist (part (ivy--split-spaces (cadr raw-parts))) - (push (cons part nil) regex-parts))) - (if regex-parts (nreverse regex-parts) - ""))) - -(defun ivy--regex-plus (str) - "Build a regex sequence from STR. -Spaces are wild card characters, everything before \"!\" should -match. Everything after \"!\" should not match." - (let ((parts (ivy--split-negation str))) - (cl-case (length parts) - (0 - "") - (1 - (if (= (aref str 0) ?!) - (list (cons "" t) - (list (ivy--regex (car parts)))) - (ivy--regex (car parts)))) - (2 - (cons - (cons (ivy--regex (car parts)) t) - (mapcar #'list (split-string (cadr parts) " " t)))) - (t (error "Unexpected: use only one !"))))) - -(defun ivy--regex-fuzzy (str) - "Build a regex sequence from STR. -Insert .* between each char." - (setq str (ivy--trim-trailing-re str)) - (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str) - (prog1 - (concat (match-string 1 str) - (let ((lst (string-to-list (match-string 2 str)))) - (apply #'concat - (cl-mapcar - #'concat - (cons "" (cdr (mapcar (lambda (c) (format "[^%c\n]*" c)) - lst))) - (mapcar (lambda (x) (format "\\(%s\\)" (regexp-quote (char-to-string x)))) - lst)))) - (match-string 3 str)) - (setq ivy--subexps (length (match-string 2 str)))) - str)) - -(defcustom ivy-fixed-height-minibuffer nil - "When non nil, fix the height of the minibuffer during ivy completion. -This effectively sets the minimum height at this level to `ivy-height' and -tries to ensure that it does not change depending on the number of candidates." - :type 'boolean) - -;;** Rest -(defcustom ivy-truncate-lines t - "Minibuffer setting for `truncate-lines'." - :type 'boolean) - -(defun ivy--minibuffer-setup () - "Setup ivy completion in the minibuffer." - (setq-local mwheel-scroll-up-function 'ivy-next-line) - (setq-local mwheel-scroll-down-function 'ivy-previous-line) - (setq-local completion-show-inline-help nil) - (setq-local line-spacing nil) - (setq-local minibuffer-default-add-function - (lambda () - (list ivy--default))) - (setq-local inhibit-field-text-motion nil) - (setq truncate-lines ivy-truncate-lines) - (setq-local max-mini-window-height ivy-height) - (let ((height (cond ((and ivy-fixed-height-minibuffer - (not (eq (ivy-state-caller ivy-last) - #'ivy-completion-in-region))) - (+ ivy-height (if ivy-add-newline-after-prompt 1 0))) - (ivy-add-newline-after-prompt 2)))) - (when height - (set-window-text-height nil height))) - (add-hook 'post-command-hook #'ivy--queue-exhibit nil t) - (let ((hook (ivy-alist-setting ivy-hooks-alist))) - (when (functionp hook) - (funcall hook)))) - -(defun ivy--input () - "Return the current minibuffer input." - ;; assume one-line minibuffer input - (save-excursion - (goto-char (minibuffer-prompt-end)) - (let ((inhibit-field-text-motion t)) - (buffer-substring-no-properties - (point) - (line-end-position))))) - -(defun ivy--minibuffer-cleanup () - "Delete the displayed completion candidates." - (save-excursion - (goto-char (minibuffer-prompt-end)) - (delete-region (line-end-position) (point-max)))) - -(defun ivy-cleanup-string (str) - "Destructively remove unwanted text properties from STR." - (ivy--remove-props str 'field)) - -(defvar ivy-set-prompt-text-properties-function - #'ivy-set-prompt-text-properties-default - "Function to set the text properties of the default ivy prompt. -Called with two arguments, PROMPT and PROPS, where PROMPT is the -string to be propertized and PROPS is a plist of default text -properties that may be applied to PROMPT. The function should -return the propertized PROMPT, which may be modified in-place.") - -(defun ivy-set-prompt-text-properties-default (prompt props) - "Propertize (confirm) and (match required) parts of PROMPT. -PROPS is a plist of default text properties to apply to these -parts beyond their respective faces `ivy-confirm-face' and -`ivy-match-required-face'." - (dolist (pair '(("confirm" . ivy-confirm-face) - ("match required" . ivy-match-required-face))) - (let ((i (string-match-p (car pair) prompt))) - (when i - (add-text-properties i (+ i (length (car pair))) - `(face ,(cdr pair) ,@props) - prompt)))) - prompt) - -(defun ivy-prompt () - "Return the current prompt." - (let* ((caller (ivy-state-caller ivy-last)) - (fn (plist-get ivy--prompts-list caller))) - (if fn - (condition-case err - (funcall fn) - (wrong-number-of-arguments - (lwarn 'ivy :error "%s - Prompt function set via `ivy-set-prompt' for caller `%s' - should take no arguments." - (error-message-string err) - caller) - ;; Old behavior. - (funcall fn (ivy-state-prompt ivy-last)))) - ivy--prompt))) - -(defun ivy--insert-prompt () - "Update the prompt according to `ivy--prompt'." - (when (setq ivy--prompt (ivy-prompt)) - (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done - counsel-find-symbol)) - (setq ivy--prompt-extra "")) - (let (head tail) - (if (string-match "\\(.*?\\)\\(:? ?\\)\\'" ivy--prompt) - (progn - (setq head (match-string 1 ivy--prompt)) - (setq tail (match-string 2 ivy--prompt))) - (setq head ivy--prompt) - (setq tail "")) - (let ((inhibit-read-only t) - (std-props '(front-sticky t rear-nonsticky t field t read-only t)) - (n-str - (concat - (if (and (bound-and-true-p minibuffer-depth-indicate-mode) - (> (minibuffer-depth) 1)) - (format "[%d] " (minibuffer-depth)) - "") - (concat - (if (string-match "%d.*%d" ivy-count-format) - (format head - (1+ ivy--index) - (or (and (ivy-state-dynamic-collection ivy-last) - ivy--full-length) - ivy--length)) - (format head - (or (and (ivy-state-dynamic-collection ivy-last) - ivy--full-length) - ivy--length))) - ivy--prompt-extra - tail))) - (d-str (if ivy--directory - (abbreviate-file-name ivy--directory) - ""))) - (save-excursion - (goto-char (point-min)) - (delete-region (point-min) (minibuffer-prompt-end)) - (let ((len-n (length n-str)) - (len-d (length d-str)) - (ww (window-width))) - (setq n-str - (cond ((> (+ len-n len-d) ww) - (concat n-str "\n" d-str "\n")) - ((> (+ len-n len-d (length ivy-text)) ww) - (concat n-str d-str "\n")) - (t - (concat n-str d-str))))) - (when ivy-pre-prompt-function - (setq n-str (concat (funcall ivy-pre-prompt-function) n-str))) - (when ivy-add-newline-after-prompt - (setq n-str (concat n-str "\n"))) - (let ((regex (format "\\([^\n]\\{%d\\}\\)[^\n]" (window-width)))) - (while (string-match regex n-str) - (setq n-str (replace-match - (concat (match-string 1 n-str) "\n") - nil t n-str 1)))) - (set-text-properties 0 (length n-str) - `(face minibuffer-prompt ,@std-props) - n-str) - (setq n-str (funcall ivy-set-prompt-text-properties-function - n-str std-props)) - (insert n-str)) - ;; Mark prompt as selected if the user moves there or it is the only - ;; option left. Since the user input stays put, we have to manually - ;; remove the face as well. - (when ivy--use-selectable-prompt - (if (= ivy--index -1) - (ivy-add-face-text-property - (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match) - (remove-list-of-text-properties - (minibuffer-prompt-end) (line-end-position) '(face)))) - ;; get out of the prompt area - (constrain-to-field nil (point-max)))))) - -(defun ivy--sort-maybe (collection) - "Sort COLLECTION if needed." - (let ((sort (ivy-state-sort ivy-last))) - (if (and sort - (or (functionp sort) - (functionp (setq sort (ivy--sort-function - (ivy-state-collection ivy-last)))))) - (sort (copy-sequence collection) sort) - collection))) - -(defcustom ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected - "Action to take when a slash is added to the end of a non existing directory. -Possible choices are 'ivy-magic-slash-non-match-cd-selected, -'ivy-magic-slash-non-match-create, or nil" - :type '(choice - (const :tag "Use currently selected directory" - ivy-magic-slash-non-match-cd-selected) - (const :tag "Create and use new directory" - ivy-magic-slash-non-match-create) - (const :tag "Do nothing" - nil))) - -(defun ivy--create-and-cd (dir) - "When completing file names, create directory DIR and move there." - (make-directory dir) - (ivy--cd dir)) - -(defun ivy--magic-file-doubleslash-directory () - "Return an appropriate directory for when two slashes are entered." - (let (remote) - (cond - ;; Windows - ((string-match "\\`[[:alpha:]]:/" ivy--directory) - (match-string 0 ivy--directory)) - ;; Remote root if on remote - ((setq remote (file-remote-p ivy--directory)) - (concat remote "/")) - ;; Local root - (t - "/")))) - -(defun ivy--magic-file-slash () - "Handle slash when completing file names." - (when (or (and (eq this-command #'self-insert-command) - (eolp)) - (eq this-command #'ivy-partial-or-done)) - (let ((canonical (expand-file-name ivy-text ivy--directory)) - (magic (not (string= ivy-text "/")))) - (cond ((member ivy-text ivy--all-candidates) - (ivy--cd canonical)) - ((string-match-p "//\\'" ivy-text) - (ivy--cd - (ivy--magic-file-doubleslash-directory))) - ((string-match-p "\\`/ssh:" ivy-text) - (ivy--cd (file-name-directory ivy-text))) - ((string-match "[[:alpha:]]:/\\'" ivy-text) - (let ((drive-root (match-string 0 ivy-text))) - (when (file-exists-p drive-root) - (ivy--cd drive-root)))) - ((and magic (file-directory-p canonical)) - (ivy--cd canonical)) - ((let ((default-directory ivy--directory)) - (and (or (> ivy--index 0) - (= ivy--length 1) - magic) - (not (ivy--prompt-selected-p)) - (not (equal (ivy-state-current ivy-last) "")) - (file-directory-p (ivy-state-current ivy-last)) - (or (eq ivy-magic-slash-non-match-action - 'ivy-magic-slash-non-match-cd-selected) - (eq this-command #'ivy-partial-or-done)))) - (ivy--cd - (expand-file-name (ivy-state-current ivy-last) ivy--directory))) - ((and (eq ivy-magic-slash-non-match-action - 'ivy-magic-slash-non-match-create) - magic) - (ivy--create-and-cd canonical)))))) - -(defun ivy-magic-read-file-env () - "If reading filename, jump to environment variable location." - (interactive) - (if (and ivy--directory - (equal ivy-text "")) - (let* ((cands (cl-loop for pair in process-environment - for (var val) = (split-string pair "=" t) - if (and val (not (equal "" val))) - if (file-exists-p - (if (file-name-absolute-p val) - val - (setq val - (expand-file-name val ivy--directory)))) - collect (cons var val))) - (enable-recursive-minibuffers t) - (x (ivy-read "Env: " cands)) - (path (cdr (assoc x cands)))) - (insert (if (file-accessible-directory-p path) - (file-name-as-directory path) - path)) - (ivy--cd-maybe)) - (insert last-input-event))) - -(defun ivy-make-magic-action (caller key) - "Return a command that does the equivalent of `ivy-read-action' and KEY. -This happens only when the input is empty. -The intention is to bind the result to keys that are typically -bound to `self-insert-command'." - (let* ((alist (assoc key - (plist-get - ivy--actions-list - caller))) - (doc (format "%s (`%S')" - (nth 2 alist) - (nth 1 alist)))) - `(lambda (&optional arg) - ,doc - (interactive "p") - (if (string= "" ivy-text) - (execute-kbd-macro - (kbd ,(concat "M-o " key))) - (self-insert-command arg))))) - -(defcustom ivy-magic-tilde t - "When non-nil, ~ will move home when selecting files. -Otherwise, ~/ will move home." - :type 'boolean) - -(defcustom ivy-dynamic-exhibit-delay-ms 0 - "Delay in ms before dynamic collections are refreshed" - :type 'integer) - -(defvar ivy--exhibit-timer nil) - -(defun ivy--queue-exhibit () - "Insert Ivy completions display, possibly after a timeout for -dynamic collections. -Should be run via minibuffer `post-command-hook'." - (if (and (> ivy-dynamic-exhibit-delay-ms 0) - (ivy-state-dynamic-collection ivy-last)) - (progn - (when ivy--exhibit-timer (cancel-timer ivy--exhibit-timer)) - (setq ivy--exhibit-timer - (run-with-timer - (/ ivy-dynamic-exhibit-delay-ms 1000.0) - nil - 'ivy--exhibit))) - (ivy--exhibit))) - -(defun ivy--magic-tilde-directory (dir) - "Return an appropriate home for DIR for when ~ or ~/ are entered." - (expand-file-name - (let (remote) - (if (and (setq remote (file-remote-p dir)) - (let ((local (file-local-name dir))) - (not (or (string= "/root/" local) - (string-match-p "/home/\\([^/]+\\)/\\'" local))))) - (concat remote "~/") - "~/")))) - -(defun ivy-update-candidates (cands) - (ivy--insert-minibuffer - (ivy--format - (setq ivy--all-candidates cands)))) - -(defun ivy--exhibit () - "Insert Ivy completions display. -Should be run via minibuffer `post-command-hook'." - (when (memq 'ivy--queue-exhibit post-command-hook) - (let ((inhibit-field-text-motion nil)) - (constrain-to-field nil (point-max))) - (setq ivy-text (ivy--input)) - (if (ivy-state-dynamic-collection ivy-last) - ;; while-no-input would cause annoying - ;; "Waiting for process to die...done" message interruptions - (let ((inhibit-message t) - coll in-progress) - (unless (equal ivy--old-text ivy-text) - (while-no-input - (setq coll (funcall (ivy-state-collection ivy-last) ivy-text)) - (when (eq coll 0) - (setq coll nil) - (setq ivy--old-re nil) - (setq in-progress t)) - (setq ivy--all-candidates (ivy--sort-maybe coll)) - (setq ivy--old-text ivy-text))) - (when (eq ivy--all-candidates 0) - (setq ivy--all-candidates nil) - (setq ivy--old-re nil) - (setq in-progress t)) - (when (or ivy--all-candidates - (and (not (get-process " *counsel*")) - (not in-progress))) - (ivy--set-index-dynamic-collection) - (ivy--insert-minibuffer - (ivy--format ivy--all-candidates)))) - (cond (ivy--directory - (cond ((or (string= "~/" ivy-text) - (and (string= "~" ivy-text) - ivy-magic-tilde)) - (ivy--cd (ivy--magic-tilde-directory ivy--directory))) - ((string-match "/\\'" ivy-text) - (ivy--magic-file-slash)))) - ((eq (ivy-state-collection ivy-last) #'internal-complete-buffer) - (when (or (and (string-match "\\` " ivy-text) - (not (string-match "\\` " ivy--old-text))) - (and (string-match "\\` " ivy--old-text) - (not (string-match "\\` " ivy-text)))) - (setq ivy--all-candidates - (if (= (string-to-char ivy-text) ?\s) - (ivy--buffer-list " ") - (ivy--buffer-list "" ivy-use-virtual-buffers))) - (setq ivy--old-re nil)))) - (ivy--insert-minibuffer - (with-current-buffer (ivy-state-buffer ivy-last) - (ivy--format - (ivy--filter ivy-text ivy--all-candidates)))) - (setq ivy--old-text ivy-text)))) - -(defun ivy-display-function-fallback (str) - (let ((buffer-undo-list t)) - (save-excursion - (forward-line 1) - (insert str)))) - -(defun ivy--insert-minibuffer (text) - "Insert TEXT into minibuffer with appropriate cleanup." - (let ((resize-mini-windows nil) - (update-fn (ivy-state-update-fn ivy-last)) - (old-mark (marker-position (mark-marker))) - (win (active-minibuffer-window)) - deactivate-mark) - (when win - (with-selected-window win - (ivy--minibuffer-cleanup) - (when update-fn - (funcall update-fn)) - (ivy--insert-prompt) - ;; Do nothing if while-no-input was aborted. - (when (stringp text) - (if ivy--display-function - (funcall ivy--display-function text) - (ivy-display-function-fallback text))) - (ivy--resize-minibuffer-to-fit) - ;; prevent region growing due to text remove/add - (when (region-active-p) - (set-mark old-mark)))))) - -(defun ivy--resize-minibuffer-to-fit () - "Resize the minibuffer window size to fit the text in the minibuffer." - (unless (frame-root-window-p (minibuffer-window)) - (with-selected-window (minibuffer-window) - (if (fboundp 'window-text-pixel-size) - (let ((text-height (cdr (window-text-pixel-size))) - (body-height (window-body-height nil t))) - (when (> text-height body-height) - ;; Note: the size increment needs to be at least - ;; frame-char-height, otherwise resizing won't do - ;; anything. - (let ((delta (max (- text-height body-height) - (frame-char-height)))) - (window-resize nil delta nil t t)))) - (let ((text-height (count-screen-lines)) - (body-height (window-body-height))) - (when (> text-height body-height) - (window-resize nil (- text-height body-height) nil t))))))) - -(defun ivy--add-face (str face) - "Propertize STR with FACE." - (let ((len (length str))) - (condition-case nil - (progn - (colir-blend-face-background 0 len face str) - (let ((foreground (face-foreground face))) - (when foreground - (ivy-add-face-text-property - 0 len (list :foreground foreground) str)))) - (error - (ignore-errors - (font-lock-append-text-property 0 len 'face face str))))) - str) - -(declare-function flx-make-string-cache "ext:flx") -(declare-function flx-score "ext:flx") - -(defvar ivy--flx-cache nil) - -(eval-after-load 'flx - '(setq ivy--flx-cache (flx-make-string-cache))) - -(defun ivy-toggle-case-fold () - "Toggle `case-fold-search' for Ivy operations. - -Instead of modifying `case-fold-search' directly, this command -toggles `ivy-case-fold-search', which can take on more values -than the former, between nil and either `auto' or t. See -`ivy-case-fold-search-default' for the meaning of these values. - -In any Ivy completion session, the case folding starts with -`ivy-case-fold-search-default'." - (interactive) - (setq ivy-case-fold-search - (and (not ivy-case-fold-search) - (or ivy-case-fold-search-default 'auto))) - ;; Reset cache so that the candidate list updates. - (setq ivy--old-re nil)) - -(defun ivy--re-filter (re candidates &optional mkpred) - "Return all RE matching CANDIDATES. -RE is a list of cons cells, with a regexp car and a boolean cdr. -When the cdr is t, the car must match. -Otherwise, the car must not match." - (if (equal re "") - candidates - (ignore-errors - (dolist (re (if (stringp re) (list (cons re t)) re)) - (let* ((re-str (car re)) - (pred - (if mkpred - (funcall mkpred re-str) - (lambda (x) (string-match-p re-str x))))) - (setq candidates - (cl-remove nil candidates - (if (cdr re) :if-not :if) - pred)))) - candidates))) - -(defun ivy--filter (name candidates) - "Return all items that match NAME in CANDIDATES. -CANDIDATES are assumed to be static." - (let ((re (funcall ivy--regex-function name))) - (if (and - ivy--old-re - ivy--old-cands - (equal re ivy--old-re)) - ;; quick caching for "C-n", "C-p" etc. - ivy--old-cands - (let* ((re-str (ivy-re-to-str re)) - (matcher (ivy-state-matcher ivy-last)) - (case-fold-search (ivy--case-fold-p name)) - (cands (cond - ((and ivy--old-re - (stringp re) - (stringp ivy--old-re) - (not (string-match-p "\\\\" ivy--old-re)) - (not (equal ivy--old-re "")) - (memq (cl-search - (if (string-match-p "\\\\)\\'" ivy--old-re) - (substring ivy--old-re 0 -2) - ivy--old-re) - re) - '(0 2)) - ivy--old-cands - (ivy--re-filter re ivy--old-cands))) - (matcher - (funcall matcher re candidates)) - (t - (ivy--re-filter re candidates))))) - (if (memq (cdr (assq (ivy-state-caller ivy-last) - ivy-index-functions-alist)) - '(ivy-recompute-index-swiper - ivy-recompute-index-swiper-async - ivy-recompute-index-swiper-async-backward - ivy-recompute-index-swiper-backward)) - (progn - (ivy--recompute-index name re-str cands) - (setq ivy--old-cands (ivy--sort name cands))) - (setq ivy--old-cands (ivy--sort name cands)) - (ivy--recompute-index name re-str ivy--old-cands)) - (setq ivy--old-re re) - ivy--old-cands)))) - -(defun ivy--set-candidates (x) - "Update `ivy--all-candidates' with X." - (let (res) - (dolist (source ivy--extra-candidates) - (if (equal source '(original-source)) - (if (null res) - (setq res x) - (setq res (append x res))) - (setq ivy--old-re nil) - (setq res (append - (ivy--filter ivy-text (cadr source)) - res)))) - (setq ivy--all-candidates res))) - -(defun ivy--shorter-matches-first (_name cands) - "Sort CANDS according to their length." - (if (< (length cands) ivy-sort-max-size) - (cl-sort - (copy-sequence cands) - (lambda (s1 s2) - (< (length s1) (length s2)))) - cands)) - -(defcustom ivy-sort-matches-functions-alist - '((t . nil) - (ivy-completion-in-region . ivy--shorter-matches-first) - (ivy-switch-buffer . ivy-sort-function-buffer)) - "An alist of functions for sorting matching candidates. - -Unlike `ivy-sort-functions-alist', which is used to sort the -whole collection only once, this alist of functions are used to -sort only matching candidates after each change in input. - -The alist KEY is either a collection function or t to match -previously unmatched collection functions. - -The alist VAL is a sorting function with the signature of -`ivy--prefix-sort'." - :type '(alist - :key-type (choice - (const :tag "Fall-through" t) - (symbol :tag "Collection")) - :value-type - (choice - (const :tag "Don't sort" nil) - (const :tag "Put prefix matches ahead" ivy--prefix-sort) - (function :tag "Custom sort function")))) - -(defun ivy--sort-files-by-date (_name candidates) - "Re-sort CANDIDATES according to file modification date." - (let ((default-directory ivy--directory)) - (sort (copy-sequence candidates) #'file-newer-than-file-p))) - -(defvar ivy--flx-featurep (require 'flx nil 'noerror)) - -(defun ivy--sort (name candidates) - "Re-sort candidates by NAME. -All CANDIDATES are assumed to match NAME." - (let (fun) - (cond ((setq fun (ivy-alist-setting ivy-sort-matches-functions-alist)) - (funcall fun name candidates)) - ((and ivy--flx-featurep - (eq ivy--regex-function 'ivy--regex-fuzzy)) - (ivy--flx-sort name candidates)) - (t - candidates)))) - -(defun ivy--prefix-sort (name candidates) - "Re-sort candidates by NAME. -All CANDIDATES are assumed to match NAME. -Prefix matches to NAME are put ahead of the list." - (if (or (string= name "") - (= (aref name 0) ?^)) - candidates - (let ((re-prefix (concat "\\`" (funcall ivy--regex-function name))) - res-prefix - res-noprefix) - (dolist (s candidates) - (if (string-match-p re-prefix s) - (push s res-prefix) - (push s res-noprefix))) - (nconc - (nreverse res-prefix) - (nreverse res-noprefix))))) - -(defvar ivy--virtual-buffers nil - "Store the virtual buffers alist.") - -(defun ivy-re-to-str (re) - "Transform RE to a string. - -Functions like `ivy--regex-ignore-order' return a cons list. -This function extracts a string from the cons list." - (if (consp re) (caar re) re)) - -(defun ivy-sort-function-buffer (name candidates) - "Re-sort candidates by NAME. -CANDIDATES is a list of buffer names each containing NAME. -Sort open buffers before virtual buffers, and prefix matches -before substring matches." - (if (or (string= name "") - (= (aref name 0) ?^)) - candidates - (let* ((base-re (ivy-re-to-str (funcall ivy--regex-function name))) - (re-star-prefix (concat "\\`\\*" base-re)) - (re-prefix (concat "\\`" base-re)) - res-prefix - res-noprefix - res-virtual-prefix - res-virtual-noprefix) - (dolist (s candidates) - (cond - ((and (assoc s ivy--virtual-buffers) - (or (string-match-p re-star-prefix s) - (string-match-p re-prefix s))) - (push s res-virtual-prefix)) - ((assoc s ivy--virtual-buffers) - (push s res-virtual-noprefix)) - ((or (string-match-p re-star-prefix s) - (string-match-p re-prefix s)) - (push s res-prefix)) - (t - (push s res-noprefix)))) - (nconc - (nreverse res-prefix) - (nreverse res-noprefix) - (nreverse res-virtual-prefix) - (nreverse res-virtual-noprefix))))) - -(defvar ivy-flx-limit 200 - "Used to conditionally turn off flx sorting. - -When the amount of matching candidates exceeds this limit, then -no sorting is done.") - -(defvar ivy--recompute-index-inhibit nil - "When non-nil, `ivy--recompute-index' is a no-op.") - -(defun ivy--recompute-index (name re-str cands) - "Recompute index of selected candidate matching NAME. -RE-STR is the regexp, CANDS are the current candidates." - (let ((caller (ivy-state-caller ivy-last)) - (func (or (ivy-alist-setting ivy-index-functions-alist) - #'ivy-recompute-index-zero)) - (case-fold-search (ivy--case-fold-p name)) - (preselect (ivy-state-preselect ivy-last)) - (current (ivy-state-current ivy-last)) - (empty (string= name ""))) - (unless (or (memq this-command '(ivy-resume ivy-partial-or-done)) - ivy--recompute-index-inhibit) - (ivy-set-index - (if (or (string= name "") - (and (> (length cands) 10000) (eq func #'ivy-recompute-index-zero))) - 0 - (or - (cl-position (ivy--remove-prefix "^" name) - cands - :test #'ivy--case-fold-string=) - (and ivy--directory - (cl-position (concat re-str "/") - cands - :test #'ivy--case-fold-string=)) - (and (eq caller 'ivy-switch-buffer) - (not empty) - 0) - (and (not empty) - (not (eq caller 'swiper)) - (not (and ivy--flx-featurep - (eq ivy--regex-function 'ivy--regex-fuzzy) - ;; Limit to configured number of candidates - (null (nthcdr ivy-flx-limit cands)))) - ;; If there was a preselected candidate, don't try to - ;; keep it selected even if the regexp still matches it. - ;; See issue #1563. See also `ivy--preselect-index', - ;; which this logic roughly mirrors. - (not (or - (and (integerp preselect) - (= ivy--index preselect)) - (equal current preselect) - (and (ivy--regex-p preselect) - (stringp current) - (string-match-p preselect current)))) - ivy--old-cands - (cl-position current cands :test #'equal)) - (funcall func re-str cands))))) - (when (or empty (string= name "^")) - (ivy-set-index - (or (ivy--preselect-index preselect cands) - ivy--index))))) - -(defun ivy-recompute-index-swiper (_re-str cands) - "Recompute index of selected candidate when using `swiper'. -CANDS are the current candidates." - (condition-case nil - (let ((tail (nthcdr ivy--index ivy--old-cands)) - idx) - (if (and tail ivy--old-cands (not (equal "^" ivy--old-re))) - (progn - (while (and tail (null idx)) - ;; Compare with eq to handle equal duplicates in cands - (setq idx (cl-position (pop tail) cands))) - (or - idx - (1- (length cands)))) - (if ivy--old-cands - ivy--index - ;; already in ivy-state-buffer - (let ((n (line-number-at-pos)) - (res 0) - (i 0)) - (dolist (c cands) - (when (eq n (get-text-property 0 'swiper-line-number c)) - (setq res i)) - (cl-incf i)) - res)))) - (error 0))) - -(defun ivy-recompute-index-swiper-backward (re-str cands) - "Recompute index of selected candidate when using `swiper-backward'. -CANDS are the current candidates." - (let ((idx (ivy-recompute-index-swiper re-str cands))) - (if (or (= idx -1) - (<= (get-text-property 0 'swiper-line-number (nth idx cands)) - (line-number-at-pos))) - idx - (- idx 1)))) - -(defun ivy-recompute-index-swiper-async (_re-str cands) - "Recompute index of selected candidate when using `swiper' asynchronously. -CANDS are the current candidates." - (if (null ivy--old-cands) - (let ((ln (with-ivy-window - (line-number-at-pos)))) - (or - ;; closest to current line going forwards - (cl-position-if (lambda (x) - (>= (string-to-number x) ln)) - cands) - ;; closest to current line going backwards - (1- (length cands)))) - (let ((tail (nthcdr ivy--index ivy--old-cands)) - idx) - (if (and tail ivy--old-cands (not (equal "^" ivy--old-re))) - (progn - (while (and tail (null idx)) - ;; Compare with `equal', since the collection is re-created - ;; each time with `split-string' - (setq idx (cl-position (pop tail) cands :test #'equal))) - (or idx 0)) - ivy--index)))) - -(defun ivy-recompute-index-swiper-async-backward (re-str cands) - "Recompute index of selected candidate when using `swiper-backward' -asynchronously. CANDS are the current candidates." - (if (= (length cands) 0) - 0 - (let ((idx (ivy-recompute-index-swiper-async re-str cands))) - (if - (<= (string-to-number (nth idx cands)) - (with-ivy-window (line-number-at-pos))) - idx - (- idx 1))))) - -(defun ivy-recompute-index-zero (_re-str _cands) - "Recompute index of selected candidate. -This function serves as a fallback when nothing else is available." - 0) - -(defcustom ivy-minibuffer-faces - '(ivy-minibuffer-match-face-1 - ivy-minibuffer-match-face-2 - ivy-minibuffer-match-face-3 - ivy-minibuffer-match-face-4) - "List of `ivy' faces for minibuffer group matches." - :type '(repeat :tag "Faces" - (choice - (const ivy-minibuffer-match-face-1) - (const ivy-minibuffer-match-face-2) - (const ivy-minibuffer-match-face-3) - (const ivy-minibuffer-match-face-4) - (face :tag "Other face")))) - -(defun ivy--minibuffer-face (n) - "Return Nth face from `ivy-minibuffer-faces'. -N wraps around, but skips the first element of the list." - (let ((tail (cdr ivy-minibuffer-faces))) - (nth (mod (+ n 2) (length tail)) tail))) - -(defun ivy--flx-propertize (x) - "X is (cons (flx-score STR ...) STR)." - (let ((str (copy-sequence (cdr x))) - (i 0) - (last-j -2)) - (dolist (j (cdar x)) - (unless (eq j (1+ last-j)) - (cl-incf i)) - (setq last-j j) - (ivy-add-face-text-property j (1+ j) (ivy--minibuffer-face i) str)) - str)) - -(defun ivy--flx-sort (name cands) - "Sort according to closeness to string NAME the string list CANDS." - (condition-case nil - (let* ((bolp (= (string-to-char name) ?^)) - ;; An optimized regex for fuzzy matching - ;; "abc" → "^[^a]*a[^b]*b[^c]*c" - (fuzzy-regex (concat "\\`" - (and bolp (regexp-quote (substring name 1 2))) - (mapconcat - (lambda (x) - (setq x (char-to-string x)) - (concat "[^" x "]*" (regexp-quote x))) - (if bolp (substring name 2) name) - ""))) - ;; Strip off the leading "^" for flx matching - (flx-name (if bolp (substring name 1) name)) - cands-left - cands-to-sort) - - ;; Filter out non-matching candidates - (dolist (cand cands) - (when (string-match-p fuzzy-regex cand) - (push cand cands-left))) - - ;; pre-sort the candidates by length before partitioning - (setq cands-left (cl-sort cands-left #'< :key #'length)) - - ;; partition the candidates into sorted and unsorted groups - (dotimes (_ (min (length cands-left) ivy-flx-limit)) - (push (pop cands-left) cands-to-sort)) - - (nconc - ;; Compute all of the flx scores in one pass and sort - (mapcar #'car - (sort (mapcar - (lambda (cand) - (cons cand - (car (flx-score cand flx-name ivy--flx-cache)))) - cands-to-sort) - (lambda (c1 c2) - ;; Break ties by length - (if (/= (cdr c1) (cdr c2)) - (> (cdr c1) - (cdr c2)) - (< (length (car c1)) - (length (car c2))))))) - - ;; Add the unsorted candidates - cands-left)) - (error cands))) - -(defun ivy--truncate-string (str width) - "Truncate STR to WIDTH." - (truncate-string-to-width str width nil nil t)) - -(defun ivy--format-function-generic (selected-fn other-fn cands separator) - "Transform candidates into a string for minibuffer. -SELECTED-FN is called for the selected candidate, OTHER-FN for the others. -Both functions take one string argument each. CANDS is a list of candidates -and SEPARATOR is used to join them." - (let ((i -1)) - (mapconcat - (lambda (str) - (let ((curr (eq (cl-incf i) ivy--window-index))) - (if curr - (funcall selected-fn str) - (funcall other-fn str)))) - cands - separator))) - -(defun ivy-format-function-default (cands) - "Transform CANDS into a string for minibuffer." - (ivy--format-function-generic - (lambda (str) - (ivy--add-face str 'ivy-current-match)) - #'identity - cands - "\n")) - -(defun ivy-format-function-arrow (cands) - "Transform CANDS into a string for minibuffer." - (ivy--format-function-generic - (lambda (str) - (concat "> " (ivy--add-face str 'ivy-current-match))) - (lambda (str) - (concat " " str)) - cands - "\n")) - -(defun ivy-format-function-line (cands) - "Transform CANDS into a string for minibuffer." - (ivy--format-function-generic - (lambda (str) - (ivy--add-face (concat str "\n") 'ivy-current-match)) - (lambda (str) - (concat str "\n")) - cands - "")) - -(defalias 'ivy-add-face-text-property - (if (fboundp 'add-face-text-property) - (lambda (start end face &optional object append) - (add-face-text-property start end face append object)) - (lambda (start end face &optional object append) - (funcall (if append - #'font-lock-append-text-property - #'font-lock-prepend-text-property) - start end 'face face object))) - "Compatibility shim for `add-face-text-property'. -Fall back on `font-lock-prepend-text-property' in Emacs versions -prior to 24.4 (`font-lock-append-text-property' when APPEND is -non-nil). -Note: The usual last two arguments are flipped for convenience.") - -(defun ivy--highlight-ignore-order (str) - "Highlight STR, using the ignore-order method." - (when (consp ivy--old-re) - (let ((i 1)) - (dolist (re ivy--old-re) - (when (string-match (car re) str) - (ivy-add-face-text-property - (match-beginning 0) (match-end 0) - (ivy--minibuffer-face i) - str)) - (cl-incf i)))) - str) - -(defun ivy--highlight-fuzzy (str) - "Highlight STR, using the fuzzy method." - (if (and ivy--flx-featurep - (eq (ivy-alist-setting ivy-re-builders-alist) 'ivy--regex-fuzzy)) - (let ((flx-name (ivy--remove-prefix "^" ivy-text))) - (ivy--flx-propertize - (cons (flx-score str flx-name ivy--flx-cache) str))) - (ivy--highlight-default str))) - -(defun ivy--highlight-default (str) - "Highlight STR, using the default method." - (unless ivy--old-re - (setq ivy--old-re (funcall ivy--regex-function ivy-text))) - (let ((regexps - (if (listp ivy--old-re) - (mapcar #'car (cl-remove-if-not #'cdr ivy--old-re)) - (list ivy--old-re))) - start) - (dolist (re regexps) - (ignore-errors - (while (and (string-match re str start) - (> (- (match-end 0) (match-beginning 0)) 0)) - (setq start (match-end 0)) - (let ((i 0) - (n 0) - prev) - (while (<= i ivy--subexps) - (let ((beg (match-beginning i)) - (end (match-end i))) - (when (and beg end) - (unless (and prev (= prev beg)) - (cl-incf n)) - (let ((face - (cond ((zerop ivy--subexps) - (cadr ivy-minibuffer-faces)) - ((zerop i) - (car ivy-minibuffer-faces)) - (t - (ivy--minibuffer-face n))))) - (ivy-add-face-text-property beg end face str)) - (unless (zerop i) - (setq prev end)))) - (cl-incf i))))))) - str) - -(defun ivy--format-minibuffer-line (str) - "Format line STR for use in minibuffer." - (let* ((str (ivy-cleanup-string (copy-sequence str))) - (str (if (eq ivy-display-style 'fancy) - (if (memq (ivy-state-caller ivy-last) - ivy-highlight-grep-commands) - (let* ((start (if (string-match "\\`[^:]+:\\(?:[^:]+:\\)?" str) - (match-end 0) 0)) - (file (substring str 0 start)) - (match (substring str start))) - (concat file (funcall ivy--highlight-function match))) - (funcall ivy--highlight-function str)) - str)) - (olen (length str)) - (annot (plist-get completion-extra-properties :annotation-function))) - (add-text-properties - 0 olen - '(mouse-face - ivy-minibuffer-match-highlight - help-echo - (format - (if tooltip-mode - "mouse-1: %s\nmouse-3: %s" - "mouse-1: %s mouse-3: %s") - ivy-mouse-1-tooltip ivy-mouse-3-tooltip)) - str) - (when annot - (setq str (concat str (funcall annot str))) - (ivy-add-face-text-property - olen (length str) 'ivy-completions-annotations str)) - str)) - -(defun ivy-read-file-transformer (str) - "Transform candidate STR when reading files." - (if (ivy--dirname-p str) - (propertize str 'face 'ivy-subdir) - str)) - -(defun ivy--minibuffer-index-bounds (idx len wnd-len) - (let* ((half-height (/ wnd-len 2)) - (start (max 0 - (min (- idx half-height) - (- len (1- wnd-len))))) - (end (min (+ start (1- wnd-len)) len))) - (list start end (- idx start)))) - -(defun ivy--format (cands) - "Return a string for CANDS suitable for display in the minibuffer. -CANDS is a list of candidates that :display-transformer can turn into strings." - (setq ivy--length (length cands)) - (when (>= ivy--index ivy--length) - (ivy-set-index (max (1- ivy--length) 0))) - (if (null cands) - (setf (ivy-state-current ivy-last) "") - (let ((cur (nth ivy--index cands))) - (setf (ivy-state-current ivy-last) (if (stringp cur) - (copy-sequence cur) - cur))) - (let* ((bnd (ivy--minibuffer-index-bounds - ivy--index ivy--length ivy-height)) - (wnd-cands (cl-subseq cands (car bnd) (cadr bnd))) - (case-fold-search (ivy--case-fold-p ivy-text)) - transformer-fn) - (setq ivy--window-index (nth 2 bnd)) - (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last)) - (with-ivy-window - (with-current-buffer (ivy-state-buffer ivy-last) - (setq wnd-cands (mapcar transformer-fn wnd-cands))))) - (ivy--wnd-cands-to-str wnd-cands)))) - -(defun ivy--wnd-cands-to-str (wnd-cands) - (let ((str (concat "\n" - (funcall (ivy-alist-setting ivy-format-functions-alist) - (condition-case nil - (mapcar - #'ivy--format-minibuffer-line - wnd-cands) - (error wnd-cands)))))) - (put-text-property 0 (length str) 'read-only nil str) - str)) - -(defvar recentf-list) -(defvar bookmark-alist) - -(defcustom ivy-virtual-abbreviate 'name - "The mode of abbreviation for virtual buffer names." - :type '(choice - (const :tag "Only name" name) - (const :tag "Abbreviated path" abbreviate) - (const :tag "Full path" full) - ;; eventually, uniquify - )) -(declare-function bookmark-maybe-load-default-file "bookmark") -(declare-function bookmark-get-filename "bookmark") - -(defun ivy--virtual-buffers () - "Adapted from `ido-add-virtual-buffers-to-list'." - (require 'bookmark) - (unless recentf-mode - (recentf-mode 1)) - (bookmark-maybe-load-default-file) - (let* ((vb-bkm (delete " - no file -" - (delq nil (mapcar #'bookmark-get-filename - bookmark-alist)))) - (vb-list (cond ((eq ivy-use-virtual-buffers 'recentf) - recentf-list) - ((eq ivy-use-virtual-buffers 'bookmarks) - vb-bkm) - (ivy-use-virtual-buffers - (append recentf-list vb-bkm)) - (t nil))) - virtual-buffers) - (dolist (head vb-list) - (let* ((file-name (if (stringp head) - head - (cdr head))) - (name (cond ((eq ivy-virtual-abbreviate 'name) - (file-name-nondirectory file-name)) - ((eq ivy-virtual-abbreviate 'abbreviate) - (abbreviate-file-name file-name)) - (t - (expand-file-name file-name))))) - (when (equal name "") - (setq name - (if (consp head) - (car head) - (file-name-nondirectory (directory-file-name file-name))))) - (unless (or (equal name "") - (get-file-buffer file-name) - (assoc name virtual-buffers)) - (push (cons (copy-sequence name) file-name) virtual-buffers)))) - (when virtual-buffers - (dolist (comp virtual-buffers) - (put-text-property 0 (length (car comp)) - 'face 'ivy-virtual - (car comp))) - (setq ivy--virtual-buffers (nreverse virtual-buffers)) - (mapcar #'car ivy--virtual-buffers)))) - -(defcustom ivy-ignore-buffers '("\\` ") - "List of regexps or functions matching buffer names to ignore." - :type '(repeat (choice regexp function))) - -(defvar ivy-switch-buffer-faces-alist '((dired-mode . ivy-subdir) - (org-mode . ivy-org)) - "Store face customizations for `ivy-switch-buffer'. -Each KEY is `major-mode', each VALUE is a face name.") - -(defun ivy--buffer-list (str &optional virtual predicate) - "Return the buffers that match STR. -If VIRTUAL is non-nil, add virtual buffers. -If optional argument PREDICATE is non-nil, use it to test each -possible match. See `all-completions' for further information." - (delete-dups - (nconc - (mapcar - (lambda (x) - (let* ((buf (get-buffer x)) - (dir (buffer-local-value 'default-directory buf)) - (face (if (and dir - (ignore-errors - (file-remote-p (abbreviate-file-name dir)))) - 'ivy-remote - (cdr (assq (buffer-local-value 'major-mode buf) - ivy-switch-buffer-faces-alist))))) - (if face - (propertize x 'face face) - x))) - (all-completions str #'internal-complete-buffer predicate)) - (and virtual - (ivy--virtual-buffers))))) - -(defvar ivy-views (and nil - `(("ivy + *scratch* {}" - (vert - (file ,(expand-file-name "ivy.el")) - (buffer "*scratch*"))) - ("swiper + *scratch* {}" - (horz - (file ,(expand-file-name "swiper.el")) - (buffer "*scratch*"))))) - "Store window configurations selectable by `ivy-switch-buffer'. - -The default value is given as an example. - -Each element is a list of (NAME TREE). NAME is a string, it's -recommended to end it with a distinctive snippet e.g. \"{}\" so -that it's easy to distinguish the window configurations. - -TREE is a nested list with the following valid cars: -- vert: split the window vertically -- horz: split the window horizontally -- file: open the specified file -- buffer: open the specified buffer - -TREE can be nested multiple times to have multiple window splits.") - -(defun ivy-default-view-name () - "Return default name for new view." - (let* ((default-view-name - (concat "{} " - (mapconcat #'identity - (sort - (mapcar (lambda (w) - (let* ((b (window-buffer w)) - (f (buffer-file-name b))) - (if f - (file-name-nondirectory f) - (buffer-name b)))) - (window-list)) - #'string-lessp) - " "))) - (view-name-re (concat "\\`" - (regexp-quote default-view-name) - " \\([0-9]+\\)")) - old-view) - (cond ((setq old-view - (cl-find-if - (lambda (x) - (string-match view-name-re (car x))) - ivy-views)) - (format "%s %d" - default-view-name - (1+ (string-to-number - (match-string 1 (car old-view)))))) - ((assoc default-view-name ivy-views) - (concat default-view-name " 1")) - (t - default-view-name)))) - -(defun ivy-push-view (&optional arg) - "Push the current window tree on `ivy-views'. - -When ARG is non-nil, replace a selected item on `ivy-views'. - -Currently, the split configuration (i.e. horizontal or vertical) -and point positions are saved, but the split positions aren't. -Use `ivy-pop-view' to delete any item from `ivy-views'." - (interactive "P") - (let* ((view (cl-labels - ((ft (tr) - (if (consp tr) - (if (eq (car tr) t) - (cons 'vert - (mapcar #'ft (cddr tr))) - (cons 'horz - (mapcar #'ft (cddr tr)))) - (with-current-buffer (window-buffer tr) - (cond (buffer-file-name - (list 'file buffer-file-name (point))) - ((eq major-mode 'dired-mode) - (list 'file default-directory (point))) - (t - (list 'buffer (buffer-name) (point)))))))) - (ft (car (window-tree))))) - (view-name - (if arg - (ivy-read "Update view: " ivy-views) - (ivy-read "Name view: " nil - :initial-input (ivy-default-view-name))))) - (when view-name - (let ((x (assoc view-name ivy-views))) - (if x - (setcdr x (list view)) - (push (list view-name view) ivy-views)))))) - -(defun ivy-pop-view-action (view) - "Delete VIEW from `ivy-views'." - (setq ivy-views (delete view ivy-views)) - (setq ivy--all-candidates - (delete (car view) ivy--all-candidates)) - (setq ivy--old-cands nil)) - -(defun ivy-pop-view () - "Delete a view to delete from `ivy-views'." - (interactive) - (ivy-read "Pop view: " ivy-views - :preselect (caar ivy-views) - :action #'ivy-pop-view-action - :caller 'ivy-pop-view)) - -(defun ivy-source-views () - "Return the name of the views saved in `ivy-views'." - (mapcar #'car ivy-views)) - -(ivy-set-sources - 'ivy-switch-buffer - '((original-source) - (ivy-source-views))) - -(defun ivy-set-view-recur (view) - "Set VIEW recursively." - (cond ((eq (car view) 'vert) - (let* ((wnd1 (selected-window)) - (wnd2 (split-window-vertically)) - (views (cdr view)) - (v (pop views)) - (temp-wnd)) - (with-selected-window wnd1 - (ivy-set-view-recur v)) - (while (setq v (pop views)) - (with-selected-window wnd2 - (when views - (setq temp-wnd (split-window-vertically))) - (ivy-set-view-recur v) - (when views - (setq wnd2 temp-wnd)))))) - ((eq (car view) 'horz) - (let* ((wnd1 (selected-window)) - (wnd2 (split-window-horizontally)) - (views (cdr view)) - (v (pop views)) - (temp-wnd)) - (with-selected-window wnd1 - (ivy-set-view-recur v)) - (while (setq v (pop views)) - (with-selected-window wnd2 - (when views - (setq temp-wnd (split-window-horizontally))) - (ivy-set-view-recur v) - (when views - (setq wnd2 temp-wnd)))))) - ((eq (car view) 'file) - (let* ((name (nth 1 view)) - (virtual (assoc name ivy--virtual-buffers)) - buffer) - (cond ((setq buffer (get-buffer name)) - (switch-to-buffer buffer nil 'force-same-window)) - (virtual - (find-file (cdr virtual))) - ((file-exists-p name) - (find-file name)))) - (when (and (> (length view) 2) - (numberp (nth 2 view))) - (goto-char (nth 2 view)))) - ((eq (car view) 'buffer) - (switch-to-buffer (nth 1 view)) - (when (and (> (length view) 2) - (numberp (nth 2 view))) - (goto-char (nth 2 view)))) - ((eq (car view) 'sexp) - (eval (nth 1 view))))) - -(defun ivy--switch-buffer-action (buffer) - "Switch to BUFFER. -BUFFER may be a string or nil." - (if (zerop (length buffer)) - (switch-to-buffer - ivy-text nil 'force-same-window) - (let ((virtual (assoc buffer ivy--virtual-buffers)) - (view (assoc buffer ivy-views))) - (cond ((and virtual - (not (get-buffer buffer))) - (find-file (cdr virtual))) - (view - (delete-other-windows) - (let ( - ;; silence "Directory has changed on disk" - (inhibit-message t)) - (ivy-set-view-recur (cadr view)))) - (t - (switch-to-buffer - buffer nil 'force-same-window)))))) - -(defun ivy--switch-buffer-other-window-action (buffer) - "Switch to BUFFER in other window. -BUFFER may be a string or nil." - (if (zerop (length buffer)) - (switch-to-buffer-other-window ivy-text) - (let ((virtual (assoc buffer ivy--virtual-buffers))) - (if (and virtual - (not (get-buffer buffer))) - (find-file-other-window (cdr virtual)) - (switch-to-buffer-other-window buffer))))) - -(defun ivy--rename-buffer-action (buffer) - "Rename BUFFER." - (let ((new-name (read-string "Rename buffer (to new name): "))) - (with-current-buffer buffer - (rename-buffer new-name)))) - -(defun ivy--find-file-action (buffer) - "Find file from BUFFER's directory." - (let* ((virtual (assoc buffer ivy--virtual-buffers)) - (default-directory (if virtual - (file-name-directory (cdr virtual)) - (buffer-local-value 'default-directory - (or (get-buffer buffer) - (current-buffer)))))) - (call-interactively (if (functionp 'counsel-find-file) - #'counsel-find-file - #'find-file)))) - -(defun ivy--kill-buffer-or-virtual (buffer) - (if (get-buffer buffer) - (kill-buffer buffer) - (setq recentf-list (delete - (cdr (assoc buffer ivy--virtual-buffers)) - recentf-list)))) - -(defun ivy--kill-current-candidate () - (setf (ivy-state-preselect ivy-last) ivy--index) - (setq ivy--old-re nil) - (setq ivy--all-candidates (delete (ivy-state-current ivy-last) ivy--all-candidates)) - (let ((ivy--recompute-index-inhibit t)) - (ivy--exhibit))) - -(defun ivy--kill-buffer-action (buffer) - "Kill BUFFER." - (ivy--kill-buffer-or-virtual buffer) - (unless (buffer-live-p (ivy-state-buffer ivy-last)) - (setf (ivy-state-buffer ivy-last) - (with-ivy-window (current-buffer)))) - (ivy--kill-current-candidate)) - -(defvar ivy-switch-buffer-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-k") 'ivy-switch-buffer-kill) - map)) - -(defun ivy-switch-buffer-kill () - "When at end-of-line, kill the current buffer in `ivy-switch-buffer'. -Otherwise, forward to `ivy-kill-line'." - (interactive) - (if (not (eolp)) - (ivy-kill-line) - (ivy--kill-buffer-action - (ivy-state-current ivy-last)))) - -(ivy-set-actions - 'ivy-switch-buffer - '(("f" - ivy--find-file-action - "find file") - ("j" - ivy--switch-buffer-other-window-action - "other window") - ("k" - ivy--kill-buffer-action - "kill") - ("r" - ivy--rename-buffer-action - "rename"))) - -(ivy-set-actions - t - `(("i" ,(lambda (x) (insert (if (stringp x) x (car x)))) "insert") - ("w" ,(lambda (x) (kill-new (if (stringp x) x (car x)))) "copy"))) - -(defun ivy--switch-buffer-matcher (regexp candidates) - "Return REGEXP matching CANDIDATES. -Skip buffers that match `ivy-ignore-buffers'." - (let ((res (ivy--re-filter regexp candidates))) - (if (or (null ivy-use-ignore) - (null ivy-ignore-buffers)) - res - (or (cl-remove-if - (lambda (buf) - (cl-find-if - (lambda (f-or-r) - (if (functionp f-or-r) - (funcall f-or-r buf) - (string-match-p f-or-r buf))) - ivy-ignore-buffers)) - res) - (and (eq ivy-use-ignore t) - res))))) - -(defun ivy-append-face (str face) - "Append to STR the property FACE." - (setq str (copy-sequence str)) - (ivy-add-face-text-property 0 (length str) face str t) - str) - -(defun ivy-switch-buffer-transformer (str) - "Transform candidate STR when switching buffers." - (let ((b (get-buffer str))) - (if (and b (buffer-file-name b)) - (cond - ((and (not (ignore-errors (file-remote-p (buffer-file-name b)))) - (not (verify-visited-file-modtime b))) - (ivy-append-face str 'ivy-modified-outside-buffer)) - ((buffer-modified-p b) - (ivy-append-face str 'ivy-modified-buffer)) - (t str)) - str))) - -(defun ivy-switch-buffer-occur (cands) - "Occur function for `ivy-switch-buffer' using `ibuffer'. -CANDS are the candidates to be displayed." - (unless cands - (setq cands (all-completions ivy-text #'internal-complete-buffer))) - (ibuffer - nil (buffer-name) - `((or ,@(cl-mapcan - (lambda (cand) - (unless (eq (get-text-property 0 'face cand) 'ivy-virtual) - `((name . ,(format "\\_<%s\\_>" (regexp-quote cand)))))) - cands))))) - -;;;###autoload -(defun ivy-switch-buffer () - "Switch to another buffer." - (interactive) - (ivy-read "Switch to buffer: " #'internal-complete-buffer - :keymap ivy-switch-buffer-map - :preselect (buffer-name (other-buffer (current-buffer))) - :action #'ivy--switch-buffer-action - :matcher #'ivy--switch-buffer-matcher - :caller 'ivy-switch-buffer)) - -(ivy-configure 'ivy-switch-buffer - :occur #'ivy-switch-buffer-occur - :display-transformer-fn #'ivy-switch-buffer-transformer) - -;;;###autoload -(defun ivy-switch-view () - "Switch to one of the window views stored by `ivy-push-view'." - (interactive) - (let ((ivy-initial-inputs-alist - '((ivy-switch-buffer . "{}")))) - (ivy-switch-buffer))) - -;;;###autoload -(defun ivy-switch-buffer-other-window () - "Switch to another buffer in another window." - (interactive) - (ivy-read "Switch to buffer in other window: " #'internal-complete-buffer - :matcher #'ivy--switch-buffer-matcher - :preselect (buffer-name (other-buffer (current-buffer))) - :action #'ivy--switch-buffer-other-window-action - :keymap ivy-switch-buffer-map - :caller 'ivy-switch-buffer-other-window)) - -(ivy-configure 'ivy-switch-buffer-other-window - :occur #'ivy-switch-buffer-occur) - -(defun ivy--yank-handle-case-fold (text) - (if (and (> (length ivy-text) 0) - (string= (downcase ivy-text) ivy-text)) - (downcase text) - text)) - -(defun ivy--yank-by (fn &rest args) - "Pull buffer text from current line into search string. -The region to extract is determined by the respective values of -point before and after applying FN to ARGS." - (let (text) - (with-ivy-window - (let ((beg (point)) - (bol (line-beginning-position)) - (eol (line-end-position)) - end) - (unwind-protect - (progn (apply fn args) - (setq end (goto-char (max bol (min (point) eol)))) - (setq text (buffer-substring-no-properties beg end)) - (ivy--pulse-region beg end)) - (unless text - (goto-char beg))))) - (when text - (insert (replace-regexp-in-string - " +" " " - (ivy--yank-handle-case-fold text) - t t))))) - -(defun ivy-yank-word (&optional arg) - "Pull next word from buffer into search string. -If optional ARG is non-nil, pull in the next ARG -words (previous if ARG is negative)." - (interactive "p") - (ivy--yank-by #'forward-word arg)) - -(defun ivy-yank-symbol (&optional arg) - "Pull next symbol from buffer into search string. -If optional ARG is non-nil, pull in the next ARG -symbols (previous if ARG is negative)." - (interactive "p") - ;; Emacs < 24.4 compatibility - (unless (fboundp 'forward-symbol) - (require 'thingatpt)) - (ivy--yank-by #'forward-symbol (or arg 1))) - -(defun ivy-yank-char (&optional arg) - "Pull next character from buffer into search string. -If optional ARG is non-nil, pull in the next ARG -characters (previous if ARG is negative)." - (interactive "p") - (ivy--yank-by #'forward-char arg)) - -(defvar ivy--pulse-overlay nil - "Overlay used to highlight yanked word.") - -(defvar ivy--pulse-timer nil - "Timer used to dispose of `ivy--pulse-overlay'.") - -(defcustom ivy-pulse-delay 0.5 - "Number of seconds to display `ivy-yanked-word' highlight. -When nil, disable highlighting." - :type '(choice - (number :tag "Delay in seconds") - (const :tag "Disable" nil))) - -(defun ivy--pulse-region (start end) - "Temporarily highlight text between START and END. -The \"pulse\" duration is determined by `ivy-pulse-delay'." - (when ivy-pulse-delay - (if ivy--pulse-overlay - (let ((ostart (overlay-start ivy--pulse-overlay)) - (oend (overlay-end ivy--pulse-overlay))) - (when (< end start) - (cl-rotatef start end)) - ;; Extend the existing overlay's region to include START..END, - ;; but only if the two regions are contiguous. - (move-overlay ivy--pulse-overlay - (if (= start oend) ostart start) - (if (= end ostart) oend end))) - (setq ivy--pulse-overlay (make-overlay start end)) - (overlay-put ivy--pulse-overlay 'face 'ivy-yanked-word)) - (when ivy--pulse-timer - (cancel-timer ivy--pulse-timer)) - (setq ivy--pulse-timer - (run-at-time ivy-pulse-delay nil #'ivy--pulse-cleanup)))) - -(defun ivy--pulse-cleanup () - "Cancel `ivy--pulse-timer' and delete `ivy--pulse-overlay'." - (when ivy--pulse-timer - (cancel-timer ivy--pulse-timer) - (setq ivy--pulse-timer nil)) - (when ivy--pulse-overlay - (delete-overlay ivy--pulse-overlay) - (setq ivy--pulse-overlay nil))) - -(defun ivy-kill-ring-save () - "Store the current candidates into the kill ring. -If the region is active, forward to `kill-ring-save' instead." - (interactive) - (if (region-active-p) - (call-interactively 'kill-ring-save) - (kill-new - (mapconcat - #'identity - ivy--old-cands - "\n")))) - -(defun ivy-insert-current () - "Make the current candidate into current input. -Don't finish completion." - (interactive) - (delete-minibuffer-contents) - (let ((end (and ivy--directory - (ivy--dirname-p (ivy-state-current ivy-last)) - -1))) - (insert (substring-no-properties - (ivy-state-current ivy-last) 0 end)))) - -(defun ivy-insert-current-full () - "Insert the full Yank the current directory into the minibuffer." - (interactive) - (insert ivy--directory)) - -(defcustom ivy-preferred-re-builders - '((ivy--regex-plus . "ivy") - (ivy--regex-ignore-order . "order") - (ivy--regex-fuzzy . "fuzzy")) - "Alist of preferred re-builders with display names. -This list can be rotated with `ivy-rotate-preferred-builders'." - :type '(alist :key-type function :value-type string)) - -(defun ivy-rotate-preferred-builders () - "Switch to the next re builder in `ivy-preferred-re-builders'." - (interactive) - (when ivy-preferred-re-builders - (setq ivy--old-re nil) - (setq ivy--regex-function - (let ((cell (assq ivy--regex-function ivy-preferred-re-builders))) - (car (or (cadr (memq cell ivy-preferred-re-builders)) - (car ivy-preferred-re-builders))))))) - -(defun ivy-toggle-fuzzy () - "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'." - (interactive) - (setq ivy--old-re nil) - (if (eq ivy--regex-function 'ivy--regex-fuzzy) - (setq ivy--regex-function 'ivy--regex-plus) - (setq ivy--regex-function 'ivy--regex-fuzzy))) - -(defvar ivy--reverse-i-search-symbol nil - "Store the history symbol.") - -(defun ivy-reverse-i-search-kill () - "Remove the current item from history" - (interactive) - (if (not (eolp)) - (ivy-kill-line) - (let ((current (ivy-state-current ivy-last))) - (if (symbolp ivy--reverse-i-search-symbol) - (set - ivy--reverse-i-search-symbol - (delete current (symbol-value ivy--reverse-i-search-symbol))) - (ring-remove - ivy--reverse-i-search-symbol - (ring-member ivy--reverse-i-search-symbol (ivy-state-current ivy-last))))) - (ivy--kill-current-candidate))) - -(defvar ivy-reverse-i-search-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-k") 'ivy-reverse-i-search-kill) - map)) - -(defun ivy-history-contents (history) - "Copy contents of HISTORY. -A copy is necessary so that we don't clobber any string attributes. -Also set `ivy--reverse-i-search-symbol' to HISTORY." - (setq ivy--reverse-i-search-symbol history) - (cond ((symbolp history) - (delete-dups - (copy-sequence (symbol-value history)))) - ((ring-p history) - (delete-dups - (when (> (ring-size history) 0) - (ring-elements history)))) - ((sequencep history) - (delete-dups - (copy-sequence history))) - (t - (error "Expected a symbol, ring, or sequence: %S" history)))) - -(defun ivy-reverse-i-search () - "Enter a recursive `ivy-read' session using the current history. -The selected history element will be inserted into the minibuffer. -\\ -You can also delete an element from history with \\[ivy-reverse-i-search-kill]." - (interactive) - (cond - ((= (minibuffer-depth) 0) - (user-error - "This command is intended to be called with \"C-r\" from `ivy-read'.")) - ;; don't recur - ((and (> (minibuffer-depth) 1) - (eq (ivy-state-caller ivy-last) 'ivy-reverse-i-search))) - (t - (let ((enable-recursive-minibuffers t) - (old-last ivy-last)) - (ivy-read "Reverse-i-search: " - (ivy-history-contents (ivy-state-history ivy-last)) - :keymap ivy-reverse-i-search-map - :action (lambda (x) - (ivy--reset-state - (setq ivy-last old-last)) - (delete-minibuffer-contents) - (insert (substring-no-properties x)) - (ivy--cd-maybe)) - :caller 'ivy-reverse-i-search))))) - -(defun ivy-restrict-to-matches () - "Restrict candidates to current input and erase input." - (interactive) - (delete-minibuffer-contents) - (if (ivy-state-dynamic-collection ivy-last) - (progn - (setf (ivy-state-dynamic-collection ivy-last) nil) - (setf (ivy-state-collection ivy-last) - (setq ivy--all-candidates ivy--old-cands))) - (setq ivy--all-candidates - (ivy--filter ivy-text ivy--all-candidates)))) - -;;* Occur -(defvar-local ivy-occur-last nil - "Buffer-local value of `ivy-last'. -Can't re-use `ivy-last' because using e.g. `swiper' in the same -buffer would modify `ivy-last'.") - -(defvar ivy-occur-mode-map - (let ((map (make-sparse-keymap))) - (define-key map [mouse-1] 'ivy-occur-click) - (define-key map (kbd "RET") 'ivy-occur-press-and-switch) - (define-key map (kbd "j") 'ivy-occur-next-line) - (define-key map (kbd "k") 'ivy-occur-previous-line) - (define-key map (kbd "h") 'backward-char) - (define-key map (kbd "l") 'forward-char) - (define-key map (kbd "f") 'ivy-occur-press) - (define-key map (kbd "g") 'ivy-occur-revert-buffer) - (define-key map (kbd "a") 'ivy-occur-read-action) - (define-key map (kbd "o") 'ivy-occur-dispatch) - (define-key map (kbd "c") 'ivy-occur-toggle-calling) - (define-key map (kbd "q") 'quit-window) - (define-key map (kbd "R") 'read-only-mode) - (define-key map (kbd "C-d") 'ivy-occur-delete-candidate) - map) - "Keymap for Ivy Occur mode.") - -(defun ivy-occur-toggle-calling () - "Toggle `ivy-calling'." - (interactive) - (if (setq ivy-calling (not ivy-calling)) - (progn - (setq mode-name "Ivy-Occur [calling]") - (ivy-occur-press)) - (setq mode-name "Ivy-Occur")) - (force-mode-line-update)) - -(defun ivy--find-occur-buffer () - (let ((cb (current-buffer))) - (cl-find-if - (lambda (b) - (with-current-buffer b - (and (eq major-mode 'ivy-occur-grep-mode) - (equal cb (ivy-state-buffer ivy-occur-last))))) - (buffer-list)))) - -(defun ivy--select-occur-buffer () - (let* ((ob (ivy--find-occur-buffer)) - (ow (cl-find-if (lambda (w) (equal ob (window-buffer w))) - (window-list)))) - (if ow - (select-window ow) - (pop-to-buffer ob)))) - -(defun ivy-occur-next-line (&optional arg) - "Move the cursor down ARG lines. -When `ivy-calling' isn't nil, call `ivy-occur-press'." - (interactive "p") - (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5) - ((derived-mode-p 'ivy-occur-mode) 2)))) - (if offset - (progn - (if (< (line-number-at-pos) offset) - (progn - (goto-char (point-min)) - (forward-line (1- offset))) - (forward-line arg) - (when (eolp) - (forward-line -1))) - (when ivy-calling - (ivy-occur-press))) - (ivy--select-occur-buffer) - (ivy-occur-next-line arg) - (ivy-occur-press-and-switch)))) - -(defun ivy-occur-previous-line (&optional arg) - "Move the cursor up ARG lines. -When `ivy-calling' isn't nil, call `ivy-occur-press'." - (interactive "p") - (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5) - ((derived-mode-p 'ivy-occur-mode) 2)))) - (if offset - (progn - (forward-line (- arg)) - (when (< (line-number-at-pos) offset) - (goto-char (point-min)) - (forward-line (1- offset))) - (when ivy-calling - (ivy-occur-press))) - (ivy--select-occur-buffer) - (ivy-occur-previous-line arg) - (ivy-occur-press-and-switch)))) - -(defun ivy-occur-next-error (n &optional reset) - "A `next-error-function' for `ivy-occur-mode'." - (interactive "p") - (when reset - (goto-char (point-min))) - (setq n (or n 1)) - (let ((ivy-calling t)) - (cond ((< n 0) (ivy-occur-previous-line (- n))) - (t (ivy-occur-next-line n))))) - -(define-derived-mode ivy-occur-mode fundamental-mode "Ivy-Occur" - "Major mode for output from \\[ivy-occur]. - -\\{ivy-occur-mode-map}" - (setq-local view-read-only nil)) - -(defvar ivy-occur-grep-mode-map - (let ((map (copy-keymap ivy-occur-mode-map))) - (define-key map (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode) - (define-key map "w" 'ivy-wgrep-change-to-wgrep-mode) - map) - "Keymap for Ivy Occur Grep mode.") - -(defun ivy-occur-delete-candidate () - (interactive) - (let ((inhibit-read-only t)) - (delete-region (line-beginning-position) - (1+ (line-end-position))))) - -(define-derived-mode ivy-occur-grep-mode grep-mode "Ivy-Occur" - "Major mode for output from \\[ivy-occur]. - -\\{ivy-occur-grep-mode-map}" - (setq-local view-read-only nil) - (when (fboundp 'wgrep-setup) - (wgrep-setup))) - -(defun ivy--starts-with-dotslash (str) - (string-match-p "\\`\\.[/\\]" str)) - -(defun ivy--occur-insert-lines (cands) - "Insert CANDS into `ivy-occur' buffer." - (font-lock-mode -1) - (dolist (cand cands) - (setq cand - (if (string-match "\\`\\(.*:[0-9]+:\\)\\(.*\\)\\'" cand) - (let ((file-and-line (match-string 1 cand)) - (grep-line (match-string 2 cand))) - (concat - (propertize file-and-line 'face 'ivy-grep-info) - (ivy--highlight-fuzzy grep-line))) - (ivy--highlight-fuzzy (copy-sequence cand)))) - (add-text-properties - 0 (length cand) - '(mouse-face - highlight - help-echo "mouse-1: call ivy-action") - cand) - (insert (if (string-match-p "\\`.[/\\]" cand) "" " ") - cand ?\n))) - -(defun ivy--occur-default (cands) - "Insert CANDS into the current occur buffer." - (unless cands - (let ((coll (ivy-state-collection ivy-last))) - (when (arrayp coll) - (setq coll (all-completions "" coll (ivy-state-predicate ivy-last)))) - (setq cands (ivy--filter (ivy-state-text ivy-last) coll)))) - (ivy-occur-mode) - (insert (format "%d candidates:\n" (length cands))) - (ivy--occur-insert-lines cands) - (read-only-mode)) - -(defun ivy-occur () - "Stop completion and put the current candidates into a new buffer. - -The new buffer remembers current action(s). - -While in the *ivy-occur* buffer, selecting a candidate with RET or -a mouse click will call the appropriate action for that candidate. - -There is no limit on the number of *ivy-occur* buffers." - (interactive) - (if (not (window-minibuffer-p)) - (user-error "No completion session is active") - (let* ((caller (ivy-state-caller ivy-last)) - (occur-fn (or (plist-get ivy--occurs-list caller) - #'ivy--occur-default)) - (buffer - (generate-new-buffer - (format "*ivy-occur%s \"%s\"*" - (if caller - (concat " " (prin1-to-string caller)) - "") - ivy-text)))) - (with-current-buffer buffer - (funcall occur-fn ivy--old-cands) - (setf (ivy-state-text ivy-last) ivy-text) - (setq ivy-occur-last ivy-last)) - (ivy-exit-with-action - (lambda (_) - (pop-to-buffer buffer) - (setq next-error-last-buffer buffer) - (setq-local next-error-function #'ivy-occur-next-error)))))) - -(defun ivy-occur-revert-buffer () - "Refresh the buffer making it up-to date with the collection. - -Currently only works for `swiper'. In that specific case, the -*ivy-occur* buffer becomes nearly useless as the original buffer -is updated, since the line numbers no longer match. - -Calling this function is as if you called `ivy-occur' on the -updated original buffer." - (interactive) - (let ((caller (ivy-state-caller ivy-occur-last)) - (ivy-last ivy-occur-last)) - (let ((inhibit-read-only t) - (line (line-number-at-pos))) - (erase-buffer) - (funcall (or (plist-get ivy--occurs-list caller) - #'ivy--occur-default) nil) - (goto-char (point-min)) - (forward-line (1- line))) - (setq ivy-occur-last ivy-last))) - -(declare-function wgrep-change-to-wgrep-mode "ext:wgrep") - -(defun ivy-wgrep-change-to-wgrep-mode () - "Forward to `wgrep-change-to-wgrep-mode'." - (interactive) - (if (require 'wgrep nil 'noerror) - (wgrep-change-to-wgrep-mode) - (error "Package wgrep isn't installed"))) - -(defun ivy-occur-read-action () - "Select one of the available actions as the current one." - (interactive) - (let ((ivy-last ivy-occur-last)) - (ivy-read-action))) - -(defun ivy-occur-dispatch () - "Call one of the available actions on the current item." - (interactive) - (let* ((state-action (ivy-state-action ivy-occur-last)) - (actions (if (symbolp state-action) - state-action - (copy-sequence state-action)))) - (unwind-protect - (progn - (ivy-occur-read-action) - (ivy-occur-press)) - (setf (ivy-state-action ivy-occur-last) actions)))) - -(defun ivy-occur-click (event) - "Execute action for the current candidate. -EVENT gives the mouse position." - (interactive "e") - (let ((window (posn-window (event-end event))) - (pos (posn-point (event-end event)))) - (with-current-buffer (window-buffer window) - (goto-char pos) - (ivy-occur-press)))) - -(declare-function swiper--cleanup "swiper") -(declare-function swiper--add-overlays "swiper") -(defvar ivy-occur-timer nil) - -(defun ivy--occur-press-update-window () - (cond - ((memq (ivy-state-caller ivy-occur-last) - (append '(swiper swiper-isearch) ivy-highlight-grep-commands)) - (let ((window (ivy-state-window ivy-occur-last)) - (buffer (ivy-state-buffer ivy-occur-last))) - (when (buffer-live-p buffer) - (cond ((or (not (window-live-p window)) - (equal window (selected-window))) - (save-selected-window - (setf (ivy-state-window ivy-occur-last) - (display-buffer buffer)))) - ((not (equal (window-buffer window) buffer)) - (with-selected-window window - (switch-to-buffer buffer))))))) - - ((memq (ivy-state-caller ivy-occur-last) - '(counsel-describe-function counsel-describe-variable)) - (setf (ivy-state-window ivy-occur-last) - (selected-window)) - (selected-window)))) - -(defun ivy--occur-press-buffer () - (let ((buffer (ivy-state-buffer ivy-last))) - (if (buffer-live-p buffer) - buffer - (current-buffer)))) - -(defun ivy-occur-press () - "Execute action for the current candidate." - (interactive) - (ivy--occur-press-update-window) - (when (save-excursion - (beginning-of-line) - (looking-at "\\(?:./\\| \\)\\(.*\\)$")) - (let* ((ivy-last ivy-occur-last) - (ivy-text (ivy-state-text ivy-last)) - (str (buffer-substring - (match-beginning 1) - (match-end 1))) - (offset (or (get-text-property 0 'offset str) 0)) - (coll (ivy-state-collection ivy-last)) - (action (ivy--get-action ivy-last)) - (ivy-exit 'done)) - (with-ivy-window - (with-current-buffer (ivy--occur-press-buffer) - (save-restriction - (widen) - (funcall action - (if (and (consp coll) - (consp (car coll))) - (assoc str coll) - (substring str offset))))) - (if (memq (ivy-state-caller ivy-last) - (append '(swiper swiper-isearch) ivy-highlight-grep-commands)) - (with-current-buffer (window-buffer (selected-window)) - (swiper--cleanup) - (swiper--add-overlays - (ivy--regex ivy-text) - (line-beginning-position) - (line-end-position) - (selected-window)) - (when (timerp ivy-occur-timer) - (cancel-timer ivy-occur-timer)) - (setq ivy-occur-timer - (run-at-time 1.0 nil 'swiper--cleanup)))))))) - -(defun ivy-occur-press-and-switch () - "Execute action for the current candidate and switch window." - (interactive) - (ivy-occur-press) - (select-window (ivy--get-window ivy-occur-last))) - -(defun ivy--marked-p () - (member (ivy-state-current ivy-last) ivy-marked-candidates)) - -(defun ivy--unmark (cand) - (setcar (member cand ivy--all-candidates) - (setcar (member cand ivy--old-cands) - (substring cand (length ivy-mark-prefix)))) - (setq ivy-marked-candidates - (delete cand ivy-marked-candidates))) - -(defun ivy--mark (cand) - (let ((marked-cand (concat ivy-mark-prefix cand))) - (setcar (member cand ivy--all-candidates) - (setcar (member cand ivy--old-cands) marked-cand)) - (setq ivy-marked-candidates - (append ivy-marked-candidates (list marked-cand))))) - -(defun ivy-mark () - "Mark the selected candidate and move to the next one. - -In `ivy-call', :action will be called in turn for all marked -candidates. - -However, if :multi-action was supplied to `ivy-read', then it -will be called with `ivy-marked-candidates'. This way, it can -make decisions based on the whole marked list." - (interactive) - (unless (ivy--marked-p) - (ivy--mark (ivy-state-current ivy-last))) - (ivy-next-line)) - -(defun ivy-unmark () - "Unmark the selected candidate and move to the next one." - (interactive) - (when (ivy--marked-p) - (ivy--unmark (ivy-state-current ivy-last))) - (ivy-next-line)) - -(defun ivy-unmark-backward () - "Move to the previous candidate and unmark it." - (interactive) - (ivy-previous-line) - (ivy--exhibit) - (when (ivy--marked-p) - (ivy--unmark (ivy-state-current ivy-last)))) - -(defun ivy-toggle-marks () - "Toggle mark for all narrowed candidates." - (interactive) - (dolist (cand ivy--old-cands) - (if (member cand ivy-marked-candidates) - (ivy--unmark cand) - (ivy--mark cand)))) - -(defconst ivy-help-file (let ((default-directory - (if load-file-name - (file-name-directory load-file-name) - default-directory))) - (if (file-exists-p "ivy-help.org") - (expand-file-name "ivy-help.org") - (if (file-exists-p "doc/ivy-help.org") - (expand-file-name "doc/ivy-help.org")))) - "The file for `ivy-help'.") - -(defvar org-hide-emphasis-markers) - -(defun ivy-help () - "Help for `ivy'." - (interactive) - (let ((buf (get-buffer "*Ivy Help*"))) - (unless buf - (setq buf (get-buffer-create "*Ivy Help*")) - (with-current-buffer buf - (insert-file-contents ivy-help-file) - (org-mode) - (setq-local org-hide-emphasis-markers t) - (view-mode) - (goto-char (point-min)) - (let ((inhibit-message t)) - (org-cycle '(64))))) - (if (eq this-command 'ivy-help) - (switch-to-buffer buf) - (with-ivy-window - (pop-to-buffer buf))) - (view-mode) - (goto-char (point-min)))) - -(declare-function ffap-url-p "ffap") -(defvar ffap-url-fetcher) - -(defun ivy-ffap-url-p (string) - "Forward to `ffap-url-p'." - (require 'ffap) - (ffap-url-p string)) - -(defun ivy-ffap-url-fetcher (url) - "Calls `ffap-url-fetcher'." - (require 'ffap) - (funcall ffap-url-fetcher url)) - -(ivy-configure 'read-file-name-internal - :sort-fn #'ivy-sort-file-function-default - :display-transformer-fn #'ivy-read-file-transformer) - -(ivy-configure 'internal-complete-buffer - :display-transformer-fn #'ivy-switch-buffer-transformer) - -(provide 'ivy) - -;;; ivy.el ends here diff --git a/elpa/ivy-0.13.1/ivy.info b/elpa/ivy-0.13.1/ivy.info deleted file mode 100644 index caa0fd6..0000000 --- a/elpa/ivy-0.13.1/ivy.info +++ /dev/null @@ -1,1954 +0,0 @@ -This is ivy.info, produced by makeinfo version 6.5 from ivy.texi. - -Ivy manual, version 0.13.0 - - Ivy is an interactive interface for completion in Emacs. Emacs uses -completion mechanism in a variety of contexts: code, menus, commands, -variables, functions, etc. Completion entails listing, sorting, -filtering, previewing, and applying actions on selected items. When -active, ‘ivy-mode’ completes the selection process by narrowing -available choices while previewing in the minibuffer. Selecting the -final candidate is either through simple keyboard character inputs or -through powerful regular expressions. - - Copyright (C) 2015-2019 Free Software Foundation, Inc. - - Permission is granted to copy, distribute and/or modify this - document under the terms of the GNU Free Documentation License, - Version 1.3 or any later version published by the Free Software - Foundation; with no Invariant Sections, no Front-Cover Texts, and - no Back-Cover Texts. A copy of the license is included in the - section entitled "GNU Free Documentation License". -INFO-DIR-SECTION Emacs -START-INFO-DIR-ENTRY -* Ivy: (ivy). Using Ivy for completion. -END-INFO-DIR-ENTRY - - -File: ivy.info, Node: Top, Next: Introduction, Up: (dir) - -Ivy User Manual -*************** - -* Menu: - -* Introduction:: -* Installation:: -* Getting started:: -* Key bindings:: -* Completion Styles:: -* Customization:: -* Commands:: -* API:: -* Variable Index:: -* Keystroke Index:: - -— The Detailed Node Listing — - -Installation - -* Installing from Emacs Package Manager:: -* Installing from the Git repository:: - -Getting started - -* Basic customization:: - -Key bindings - -* Global key bindings:: -* Minibuffer key bindings:: - -Minibuffer key bindings - -* Key bindings for navigation:: -* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer. -* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open. -* Key bindings that alter the minibuffer input:: -* Other key bindings:: -* Hydra in the minibuffer:: -* Saving the current completion session to a buffer:: - -Completion Styles - -* ivy--regex-plus:: -* ivy--regex-ignore-order:: -* ivy--regex-fuzzy:: - -Customization - -* Faces:: -* Defcustoms:: -* Actions:: -* Packages:: - -Actions - -* What are actions?:: -* How can different actions be called?:: -* How to modify the actions list?:: -* Example - add two actions to each command:: -* Example - define a new command with several actions:: - -Example - add two actions to each command - -* How to undo adding the two actions:: -* How to add actions to a specific command:: - -Example - define a new command with several actions - -* Test the above function with ivy-occur:: - -Commands - -* File Name Completion:: -* Buffer Name Completion:: -* Counsel commands:: - -File Name Completion - -* Using TRAMP:: - -API - -* Required arguments for ivy-read:: -* Optional arguments for ivy-read:: -* Example - counsel-describe-function:: -* Example - counsel-locate:: -* Example - ivy-read-with-extra-properties:: - - - -File: ivy.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top - -1 Introduction -************** - -Ivy is for quick and easy selection from a list. When Emacs prompts for -a string from a list of several possible choices, Ivy springs into -action to assist in narrowing and picking the right string from a vast -number of choices. - - Ivy strives for minimalism, simplicity, customizability and -discoverability. - -Minimalism -.......... - - Uncluttered minibuffer is minimalism. Ivy shows the completion - defaults, the number of matches, and 10 candidate matches below the - input line. Customize ‘ivy-height’ to adjust the number of - candidate matches displayed in the minibuffer. - -Simplicity -.......... - - Simplicity is about Ivy’s behavior in the minibuffer. It is also - about the code interface to extend Ivy’s functionality. The - minibuffer area behaves as close to ‘fundamental-mode’ as possible. - ‘SPC’ inserts a space, for example, instead of being bound to the - more complex ‘minibuffer-complete-word’. Ivy’s code uses - easy-to-examine global variables; avoids needless complications - with branch-introducing custom macros. - -Customizability -............... - - Customizability is about being able to use different methods and - interfaces of completion to tailor the selection process. For - example, adding a custom display function that points to a selected - candidate with ‘>’, instead of highlighting the selected candidate - with the ‘ivy-current-match’ face (see - ‘ivy-format-functions-alist’). Or take the customization of - actions, say after the candidate function is selected. ‘RET’ uses - ‘counsel-describe-function’ to describe the function, whereas ‘M-o - d’ jumps to that function’s definition in the code. The ‘M-o’ - prefix can be uniformly used with characters like ‘d’ to group - similar actions. - -Discoverability -............... - - Ivy displays easily discoverable commands through the hydra - facility. ‘C-o’ in the minibuffer displays a hydra menu. It opens - up within an expanded minibuffer area. Each menu item comes with - short documentation strings and highlighted one-key completions. - So discovering even seldom used keys is simply a matter of ‘C-o’ in - the minibuffer while in the midst of the Ivy interaction. This - discoverability minimizes exiting Ivy interface for documentation - look-ups. - - -File: ivy.info, Node: Installation, Next: Getting started, Prev: Introduction, Up: Top - -2 Installation -************** - -Install Ivy automatically through Emacs’s package manager, or manually -from Ivy’s development repository. - - Emacs 24.3 is the oldest version to run Ivy. Emacs 24.4 is the -oldest version that runs Ivy with fancy faces display. - -* Menu: - -* Installing from Emacs Package Manager:: -* Installing from the Git repository:: - - -File: ivy.info, Node: Installing from Emacs Package Manager, Next: Installing from the Git repository, Up: Installation - -2.1 Installing from Emacs Package Manager -========================================= - -‘M-x’ ‘package-install’ ‘RET’ ‘ivy’ ‘RET’ - - Ivy is installed as part of ‘ivy’ package, which is available from -two different package archives, GNU ELPA and MELPA. For the latest -stable version, use the GNU ELPA archives using the above M-x command. - - For current hourly builds, use the MELPA archives. In MELPA, Ivy is -split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; you can simply -install ‘counsel’ which will bring in the other two as dependencies. -See the code below for adding MELPA to the list of package archives: - - (require 'package) - (add-to-list 'package-archives - '("melpa" . "https://melpa.org/packages/")) - - After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by -‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’. - - For package manager details, see *note (emacs)Packages::. - - -File: ivy.info, Node: Installing from the Git repository, Prev: Installing from Emacs Package Manager, Up: Installation - -2.2 Installing from the Git repository -====================================== - -Why install from Git? -..................... - - • No need to wait for MELPA’s hourly builds - • Easy to revert to previous versions - • Contribute to Ivy’s development; send patches; pull requests - -Configuration steps -................... - - First clone the Swiper repository with: - - cd ~/git && git clone https://github.com/abo-abo/swiper - cd swiper && make compile - - Second, add these lines to the Emacs init file: - - (add-to-list 'load-path "~/git/swiper/") - (require 'ivy) - - Then, update the code with: - - git pull - make - - -File: ivy.info, Node: Getting started, Next: Key bindings, Prev: Installation, Up: Top - -3 Getting started -***************** - -First enable Ivy completion everywhere: - - (ivy-mode 1) - - Note: ‘ivy-mode’ can be toggled on and off with ‘M-x’ ‘ivy-mode’. - -* Menu: - -* Basic customization:: - - -File: ivy.info, Node: Basic customization, Up: Getting started - -3.1 Basic customization -======================= - -Here are some basic settings particularly useful for new Ivy users: - - (setq ivy-use-virtual-buffers t) - (setq ivy-count-format "(%d/%d) ") - - If you want, you can go without any customizations at all. The above -settings are the most bang for the buck in terms of customization. So -users that typically don’t like customize a lot are advised to look at -these settings first. - - For more advanced customizations, refer to ‘M-x describe-variable’ -documentation. - - -File: ivy.info, Node: Key bindings, Next: Completion Styles, Prev: Getting started, Up: Top - -4 Key bindings -************** - -* Menu: - -* Global key bindings:: -* Minibuffer key bindings:: - - -File: ivy.info, Node: Global key bindings, Next: Minibuffer key bindings, Up: Key bindings - -4.1 Global key bindings -======================= - -Here is a list of commands that are useful to be bound globally, along -with some sample bindings: - -Ivy-based interface to standard commands -........................................ - - (global-set-key (kbd "C-s") 'swiper-isearch) - (global-set-key (kbd "M-x") 'counsel-M-x) - (global-set-key (kbd "C-x C-f") 'counsel-find-file) - (global-set-key (kbd "M-y") 'counsel-yank-pop) - (global-set-key (kbd " f") 'counsel-describe-function) - (global-set-key (kbd " v") 'counsel-describe-variable) - (global-set-key (kbd " l") 'counsel-find-library) - (global-set-key (kbd " i") 'counsel-info-lookup-symbol) - (global-set-key (kbd " u") 'counsel-unicode-char) - (global-set-key (kbd " j") 'counsel-set-variable) - (global-set-key (kbd "C-x b") 'ivy-switch-buffer) - (global-set-key (kbd "C-c v") 'ivy-push-view) - (global-set-key (kbd "C-c V") 'ivy-pop-view) - -Ivy-based interface to shell and system tools -............................................. - - (global-set-key (kbd "C-c c") 'counsel-compile) - (global-set-key (kbd "C-c g") 'counsel-git) - (global-set-key (kbd "C-c j") 'counsel-git-grep) - (global-set-key (kbd "C-c L") 'counsel-git-log) - (global-set-key (kbd "C-c k") 'counsel-rg) - (global-set-key (kbd "C-c m") 'counsel-linux-app) - (global-set-key (kbd "C-c n") 'counsel-fzf) - (global-set-key (kbd "C-x l") 'counsel-locate) - (global-set-key (kbd "C-c J") 'counsel-file-jump) - (global-set-key (kbd "C-S-o") 'counsel-rhythmbox) - (global-set-key (kbd "C-c w") 'counsel-wmctrl) - -Ivy-resume and other commands -............................. - - ‘ivy-resume’ resumes the last Ivy-based completion. - - (global-set-key (kbd "C-c C-r") 'ivy-resume) - (global-set-key (kbd "C-c b") 'counsel-bookmark) - (global-set-key (kbd "C-c d") 'counsel-descbinds) - (global-set-key (kbd "C-c g") 'counsel-git) - (global-set-key (kbd "C-c o") 'counsel-outline) - (global-set-key (kbd "C-c t") 'counsel-load-theme) - (global-set-key (kbd "C-c F") 'counsel-org-file) - - You can also enable ‘counsel-mode’ to make some global key binding -remapping for you. - - -File: ivy.info, Node: Minibuffer key bindings, Prev: Global key bindings, Up: Key bindings - -4.2 Minibuffer key bindings -=========================== - -Ivy includes several minibuffer bindings, which are defined in the -‘ivy-minibuffer-map’ keymap variable. The most frequently used ones are -described here. - - ‘swiper’ or ‘counsel-M-x’ add more key bindings through the ‘keymap’ -argument to ‘ivy-read’. These keys, also active in the minibuffer, are -described under their respective commands. - - A key feature of ‘ivy-minibuffer-map’ is its full editing capability -where the familiar ‘C-a’, ‘C-f’, ‘M-d’, ‘M-DEL’, ‘M-b’, ‘M-w’, ‘C-k’, -‘C-y’ key bindings work the same as in ‘fundamental-mode’. - -* Menu: - -* Key bindings for navigation:: -* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer. -* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open. -* Key bindings that alter the minibuffer input:: -* Other key bindings:: -* Hydra in the minibuffer:: -* Saving the current completion session to a buffer:: - - -File: ivy.info, Node: Key bindings for navigation, Next: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings - -4.2.1 Key bindings for navigation ---------------------------------- - - • ‘C-n’ (‘ivy-next-line’) selects the next candidate - • ‘C-p’ (‘ivy-previous-line’) selects the previous candidate - • ‘M-<’ (‘ivy-beginning-of-buffer’) selects the first candidate - • ‘M->’ (‘ivy-end-of-buffer’) selects the last candidate - • ‘C-v’ (‘ivy-scroll-up-command’) scrolls up by ‘ivy-height’ lines - • ‘M-v’ (‘ivy-scroll-down-command’) scrolls down by ‘ivy-height’ - lines - - -- User Option: ivy-wrap - Specifies the wrap-around behavior for ‘C-n’ and ‘C-p’. When - ‘ivy-wrap’ is set to ‘t’, ‘ivy-next-line’ and ‘ivy-previous-line’ - will cycle past the last and the first candidates respectively. - - Wrap-around behavior is off by default. - - -- User Option: ivy-height - Use this option to adjust the minibuffer height, which also affects - scroll size when using ‘C-v’ and ‘M-v’ key bindings. - - ‘ivy-height’ is 10 lines by default. - - -File: ivy.info, Node: Key bindings for single selection action then exit minibuffer, Next: Key bindings for multiple selections and actions keep minibuffer open, Prev: Key bindings for navigation, Up: Minibuffer key bindings - -4.2.2 Key bindings for single selection, action, then exit minibuffer ---------------------------------------------------------------------- - -Ivy can offer several actions from which to choose which action to run. -This "calling an action" operates on the selected candidate. For -example, when viewing a list of files, one action could open it for -editing, one to view it, another to invoke a special function, and so -on. Custom actions can be added to this interface. The precise action -to call on the selected candidate can be delayed until after the -narrowing is completed. No need to exit the interface if unsure which -action to run. This delayed flexibility and customization of actions -extends usability of lists in Emacs. - -‘C-m’ or ‘RET’ (‘ivy-done’) -........................... - - Calls the default action and then exits the minibuffer. - -‘M-o’ (‘ivy-dispatching-done’) -.............................. - - Presents valid actions from which to choose. When only one action - is available, there is no difference between ‘M-o’ and ‘C-m’. - -‘C-j’ (‘ivy-alt-done’) -...................... - - When completing file names, selects the current directory candidate - and starts a new completion session there. Otherwise, it is the - same as ‘ivy-done’. - -‘TAB’ (‘ivy-partial-or-done’) -............................. - - Attempts partial completion, extending current input as much as - possible. ‘TAB TAB’ is the same as ‘C-j’ (‘ivy-alt-done’). - - Example ERT test: - - (should - (equal (ivy-with - '(progn - (ivy-read "Test: " '("can do" "can't, sorry" "other")) - ivy-text) - "c ") - "can")) - -‘C-M-j’ (‘ivy-immediate-done’) -.............................. - - Exits with _the current input_ instead of _the current candidate_ - (like other commands). - - This is useful e.g. when you call ‘find-file’ to create a new - file, but the desired name matches an existing file. In that case, - using ‘C-j’ would select that existing file, which isn’t what you - want - use this command instead. - -‘C-'’ (‘ivy-avy’) -................. - - Uses avy to select one of the candidates on the current candidate - page. This can often be faster than multiple ‘C-n’ or ‘C-p’ - keystrokes followed by ‘C-m’. - - -File: ivy.info, Node: Key bindings for multiple selections and actions keep minibuffer open, Next: Key bindings that alter the minibuffer input, Prev: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings - -4.2.3 Key bindings for multiple selections and actions, keep minibuffer open ----------------------------------------------------------------------------- - -For repeatedly applying multiple actions or acting on multiple -candidates, Ivy does not close the minibuffer between commands. It -keeps the minibuffer open for applying subsequent actions. - - Adding an extra meta key to the normal key chord invokes the special -version of the regular commands that enables applying multiple actions. - -‘C-M-m’ (‘ivy-call’) -.................... - - Is the non-exiting version of ‘C-m’ (‘ivy-done’). - - Instead of closing the minibuffer, ‘C-M-m’ allows selecting another - candidate or another action. For example, ‘C-M-m’ on functions - list invokes ‘describe-function’. When combined with ‘C-n’, - function descriptions can be invoked quickly in succession. - -‘C-M-o’ (‘ivy-dispatching-call’) -................................ - - Is the non-exiting version of ‘M-o’ (‘ivy-dispatching-done’). - - For example, during the ‘counsel-rhythmbox’ completion, press - ‘C-M-o e’ to en-queue the selected candidate, followed by ‘C-n C-m’ - to play the next candidate - the current action reverts to the - default one after ‘C-M-o’. - -‘C-M-n’ (‘ivy-next-line-and-call’) -.................................. - - Combines ‘C-n’ and ‘C-M-m’. Moves to next line and applies an - action. - - Comes in handy when opening multiple files from - ‘counsel-find-file’, ‘counsel-git-grep’, ‘counsel-ag’, - ‘counsel-rg’, or ‘counsel-locate’ lists. Just hold ‘C-M-n’ for - rapid-fire default action on each successive element of the list. - -‘C-M-p’ (‘ivy-previous-line-and-call’) -...................................... - - Combines ‘C-p’ and ‘C-M-m’. - - Similar to the above except it moves through the list in the other - direction. - -‘ivy-resume’ -............ - - Recalls the state of the completion session just before its last - exit. - - Useful after an accidental ‘C-m’ (‘ivy-done’). - - -File: ivy.info, Node: Key bindings that alter the minibuffer input, Next: Other key bindings, Prev: Key bindings for multiple selections and actions keep minibuffer open, Up: Minibuffer key bindings - -4.2.4 Key bindings that alter the minibuffer input --------------------------------------------------- - -‘M-n’ (‘ivy-next-history-element’) -.................................. - - Cycles forward through the Ivy command history. - - Ivy updates an internal history list after each action. When this - history list is empty, ‘M-n’ inserts symbol (or URL) at point into - the minibuffer. - -‘M-p’ (‘ivy-previous-history-element’) -...................................... - - Cycles forward through the Ivy command history. - -‘M-i’ (‘ivy-insert-current’) -............................ - - Inserts the current candidate into the minibuffer. - - Useful for copying and renaming files, for example: ‘M-i’ to insert - the original file name string, edit it, and then ‘C-m’ to complete - the renaming. - -‘M-j’ (‘ivy-yank-word’) -....................... - - Inserts the sub-word at point into the minibuffer. - - This is similar to ‘C-s C-w’ with ‘isearch’. Ivy reserves ‘C-w’ - for ‘kill-region’. See also ‘ivy-yank-symbol’ and ‘ivy-yank-char’. - -‘S-SPC’ (‘ivy-restrict-to-matches’) -................................... - - Deletes the current input, and resets the candidates list to the - currently restricted matches. - - This is how Ivy provides narrowing in successive tiers. - -‘C-r’ (‘ivy-reverse-i-search’) -.............................. - - Starts a recursive completion session through the command’s - history. - - This works just like ‘C-r’ at the bash command prompt, where the - completion candidates are the history items. Upon completion, the - selected candidate string is inserted into the minibuffer. - - -File: ivy.info, Node: Other key bindings, Next: Hydra in the minibuffer, Prev: Key bindings that alter the minibuffer input, Up: Minibuffer key bindings - -4.2.5 Other key bindings ------------------------- - -‘M-w’ (‘ivy-kill-ring-save’) -............................ - - Copies selected candidates to the kill ring. - - Copies the region if the region is active. - - -File: ivy.info, Node: Hydra in the minibuffer, Next: Saving the current completion session to a buffer, Prev: Other key bindings, Up: Minibuffer key bindings - -4.2.6 Hydra in the minibuffer ------------------------------ - -‘C-o’ (‘hydra-ivy/body’) -........................ - - Invokes the hydra menu with short key bindings. - - When Hydra is active, minibuffer editing is disabled and menus -display short aliases: - -Short Normal Command name ------------------------------------------------- -‘o’ ‘C-g’ ‘keyboard-escape-quit’ -‘j’ ‘C-n’ ‘ivy-next-line’ -‘k’ ‘C-p’ ‘ivy-previous-line’ -‘h’ ‘M-<’ ‘ivy-beginning-of-buffer’ -‘l’ ‘M->’ ‘ivy-end-of-buffer’ -‘d’ ‘C-m’ ‘ivy-done’ -‘f’ ‘C-j’ ‘ivy-alt-done’ -‘g’ ‘C-M-m’ ‘ivy-call’ -‘u’ ‘C-c C-o’ ‘ivy-occur’ - - Hydra reduces key strokes, for example: ‘C-n C-n C-n C-n’ is ‘C-o -jjjj’ in Hydra. - - Hydra menu offers these additional bindings: - -‘c’ (‘ivy-toggle-calling’) -.......................... - - Toggle calling the action after each candidate change. It modifies - ‘j’ to ‘jg’, ‘k’ to ‘kg’ etc. - -‘m’ (‘ivy-rotate-preferred-builders’) -..................................... - - Rotate the current regexp matcher. - -‘>’ (‘ivy-minibuffer-grow’) -........................... - - Increase ‘ivy-height’ for the current minibuffer. - -‘<’ (‘ivy-minibuffer-shrink’) -............................. - - Decrease ‘ivy-height’ for the current minibuffer. - -‘w’ (‘ivy-prev-action’) -....................... - - Select the previous action. - -‘s’ (‘ivy-next-action’) -....................... - - Select the next action. - -‘a’ (‘ivy-read-action’) -....................... - - Use a menu to select an action. - -‘C’ (‘ivy-toggle-case-fold’) -............................ - - Toggle case folding (match both upper and lower case characters for - lower case input). - - Hydra menu also offers bindings for marking multiple candidates: - -Key Command name --------------------------------- -‘m’ ‘ivy-mark’ -‘u’ ‘ivy-unmark’ -‘DEL’ ‘ivy-unmark-backward’ -‘t’ ‘ivy-toggle-marks’ - - The action is called on each marked candidate one by one. - - -File: ivy.info, Node: Saving the current completion session to a buffer, Prev: Hydra in the minibuffer, Up: Minibuffer key bindings - -4.2.7 Saving the current completion session to a buffer -------------------------------------------------------- - -‘C-c C-o’ (‘ivy-occur’) -....................... - - Saves the current candidates to a new buffer and exits completion. - - The new buffer is read-only and has a few useful bindings defined. - -‘RET’ or ‘f’ (‘ivy-occur-press’) -................................ - - Call the current action on the selected candidate. - -‘mouse-1’ (‘ivy-occur-click’) -............................. - - Call the current action on the selected candidate. - -‘j’ (‘next-line’) -................. - - Move to next line. - -‘k’ (‘previous-line’) -..................... - - Move to previous line. - -‘a’ (‘ivy-occur-read-action’) -............................. - - Read an action and make it current for this buffer. - -‘o’ (‘ivy-occur-dispatch’) -.......................... - - Read an action and call it on the selected candidate. - -‘q’ (‘quit-window’) -................... - - Bury the current buffer. - - Ivy has no limit on the number of active buffers like these. - - Ivy takes care of naming buffers uniquely by constructing descriptive -names. For example: ‘*ivy-occur counsel-describe-variable "function$*’. - - -File: ivy.info, Node: Completion Styles, Next: Customization, Prev: Key bindings, Up: Top - -5 Completion Styles -******************* - -Ivy’s completion functions rely on a regex builder - a function that -transforms a string input to a string regex. All current candidates -simply have to match this regex. Each collection can be assigned its -own regex builder by customizing ‘ivy-re-builders-alist’. - - The keys of this alist are collection names, and the values are one -of the following: - • ‘ivy--regex’ - • ‘ivy--regex-plus’ - • ‘ivy--regex-ignore-order’ - • ‘ivy--regex-fuzzy’ - • ‘regexp-quote’ - - A catch-all key, ‘t’, applies to all collections that don’t have -their own key. - - The default is: - - (setq ivy-re-builders-alist - '((t . ivy--regex-plus))) - - This example shows a custom regex builder assigned to file name -completion: - - (setq ivy-re-builders-alist - '((read-file-name-internal . ivy--regex-fuzzy) - (t . ivy--regex-plus))) - - Here, ‘read-file-name-internal’ is a function that is passed as the -second argument to ‘completing-read’ for file name completion. - - The regex builder resolves as follows (in order of priority): - 1. ‘re-builder’ argument passed to ‘ivy-read’. - 2. ‘collection’ argument passed to ‘ivy-read’ is a function and has an - entry on ‘ivy-re-builders-alist’. - 3. ‘caller’ argument passed to ‘ivy-read’ has an entry on - ‘ivy-re-builders-alist’. - 4. ‘this-command’ has an entry on ‘ivy-re-builders-alist’. - 5. ‘t’ has an entry on ‘ivy-re-builders-alist’. - 6. ‘ivy--regex’. - -* Menu: - -* ivy--regex-plus:: -* ivy--regex-ignore-order:: -* ivy--regex-fuzzy:: - - -File: ivy.info, Node: ivy--regex-plus, Next: ivy--regex-ignore-order, Up: Completion Styles - -5.1 ivy–regex-plus -================== - -‘ivy--regex-plus’ is Ivy’s default completion method. - - ‘ivy--regex-plus’ matches by splitting the input by spaces and -rebuilding it into a regex. - - As the search string is typed in Ivy’s minibuffer, it is transformed -into valid regex syntax. If the string is ‘"for example"’, it is -transformed into - - "\\(for\\).*\\(example\\)" - - which in regex terminology matches ‘"for"’ followed by a wild card -and then ‘"example"’. Note how Ivy uses the space character to build -wild cards. To match a literal white space, use an extra space. So to -match one space type two spaces, to match two spaces type three spaces, -and so on. - - As Ivy transforms typed characters into regex strings, it provides an -intuitive feedback through font highlights. - - Ivy supports regexp negation with ‘"!"’. For example, ‘"define key ! -ivy quit"’ first selects everything matching ‘"define.*key"’, then -removes everything matching ‘"ivy"’, and finally removes everything -matching ‘"quit"’. What remains is the final result set of the negation -regexp. - - Since Ivy treats minibuffer input as a regexp, the standard regexp -identifiers work: ‘"^"’, ‘"$"’, ‘"\b"’ or ‘"[a-z]"’. The exceptions are -spaces, which translate to ‘".*"’, and ‘"!"’ that signal the beginning -of a negation group. - - -File: ivy.info, Node: ivy--regex-ignore-order, Next: ivy--regex-fuzzy, Prev: ivy--regex-plus, Up: Completion Styles - -5.2 ivy–regex-ignore-order -========================== - -‘ivy--regex-ignore-order’ ignores the order of regexp tokens when -searching for matching candidates. For instance, the input ‘"for -example"’ will match ‘"example test for"’. - - -File: ivy.info, Node: ivy--regex-fuzzy, Prev: ivy--regex-ignore-order, Up: Completion Styles - -5.3 ivy–regex-fuzzy -=================== - -‘ivy--regex-fuzzy’ splits each character with a wild card. Searching -for ‘"for"’ returns all ‘"f.*o.*r"’ matches, resulting in a large number -of hits. Yet some searches need these extra hits. Ivy sorts such large -lists using ‘flx’ package’s scoring mechanism, if it’s installed. - - ‘C-o m’ toggles the current regexp builder. - - -File: ivy.info, Node: Customization, Next: Commands, Prev: Completion Styles, Up: Top - -6 Customization -*************** - -* Menu: - -* Faces:: -* Defcustoms:: -* Actions:: -* Packages:: - - -File: ivy.info, Node: Faces, Next: Defcustoms, Up: Customization - -6.1 Faces -========= - -‘ivy-current-match’ -................... - - Highlights the currently selected candidate. - -‘ivy-minibuffer-match-face-1’ -............................. - - Highlights the background of the match. - -‘ivy-minibuffer-match-face-2’ -............................. - - Highlights the first (modulo 3) matched group. - -‘ivy-minibuffer-match-face-3’ -............................. - - Highlights the second (modulo 3) matched group. - -‘ivy-minibuffer-match-face-4’ -............................. - - Highlights the third (modulo 3) matched group. - -‘ivy-confirm-face’ -.................. - - Highlights the "(confirm)" part of the prompt. - - When ‘confirm-nonexistent-file-or-buffer’ set to ‘t’, then - confirming non-existent files in ‘ivy-mode’ requires an additional - ‘RET’. - - The confirmation prompt will use this face. - - For example: - - (setq confirm-nonexistent-file-or-buffer t) - - Then call ‘find-file’, enter "eldorado" and press ‘RET’ - the - prompt will be appended with "(confirm)". Press ‘RET’ once more to - confirm, or any key to continue the completion. - -‘ivy-match-required-face’ -......................... - - Highlights the "(match required)" part of the prompt. - - When completions have to match available candidates and cannot take - random input, the "(match required)" prompt signals this - constraint. - - For example, call ‘describe-variable’, enter "waldo" and press - ‘RET’ - "(match required)" is prompted. Press any key for the - prompt to disappear. - -‘ivy-subdir’ -............ - - Highlights directories when completing file names. - -‘ivy-remote’ -............ - - Highlights remote files when completing file names. - -‘ivy-virtual’ -............. - - Highlights virtual buffers when completing buffer names. - - Virtual buffers correspond to bookmarks and recent files list, - ‘recentf’. - - Enable virtual buffers with: - - (setq ivy-use-virtual-buffers t) - -‘ivy-modified-buffer’ -..................... - - Highlights modified buffers when switching buffer. - -‘ivy-modified-outside-buffer’ -............................. - - Highlights buffers modified outside Emacs when switching buffer. - - This takes precedence over ‘ivy-modified-buffer’. - - -File: ivy.info, Node: Defcustoms, Next: Actions, Prev: Faces, Up: Customization - -6.2 Defcustoms -============== - - -- User Option: ivy-count-format - A string that specifies display of number of candidates and current - candidate, if one exists. - - The number of matching candidates by default is shown as a right- - padded integer value. - - To disable showing the number of candidates: - - (setq ivy-count-format "") - - To also display the current candidate: - - (setq ivy-count-format "(%d/%d) ") - - The ‘format’-style switches this variable uses are described in the - ‘format’ documentation. - - -- User Option: ivy-display-style - Specifies highlighting candidates in the minibuffer. - - The default setting is ‘'fancy’ in Emacs versions 24.4 or newer. - - Set ‘ivy-display-style’ to ‘nil’ for a plain minibuffer. - - -- User Option: ivy-on-del-error-function - Specifies what to do when ‘DEL’ (‘ivy-backward-delete-char’) fails. - - This is usually the case when there is no text left to delete, - i.e., when ‘DEL’ is typed at the beginning of the minibuffer. - - The default behavior is to quit the completion after ‘DEL’ – a - handy key to invoke after mistakenly triggering a completion. - - -File: ivy.info, Node: Actions, Next: Packages, Prev: Defcustoms, Up: Customization - -6.3 Actions -=========== - -* Menu: - -* What are actions?:: -* How can different actions be called?:: -* How to modify the actions list?:: -* Example - add two actions to each command:: -* Example - define a new command with several actions:: - - -File: ivy.info, Node: What are actions?, Next: How can different actions be called?, Up: Actions - -6.3.1 What are actions? ------------------------ - -An action is a function that is called after you select a candidate -during completion. This function takes a single string argument, which -is the selected candidate. - -Window context when calling an action -..................................... - - Currently, the action is executed in the minibuffer window context. - This means e.g. that if you call ‘insert’ the text will be - inserted into the minibuffer. - - If you want to execute the action in the initial window from which - the completion started, use the ‘with-ivy-window’ wrapper macro. - - (defun ivy-insert-action (x) - (with-ivy-window - (insert x))) - - -File: ivy.info, Node: How can different actions be called?, Next: How to modify the actions list?, Prev: What are actions?, Up: Actions - -6.3.2 How can different actions be called? ------------------------------------------- - - • ‘C-m’ (‘ivy-done’) calls the current action. - • ‘M-o’ (‘ivy-dispatching-done’) presents available actions for - selection, calls it after selection, and then exits. - • ‘C-M-o’ (‘ivy-dispatching-call’) presents available actions for - selection, calls it after selection, and then does not exit. - - -File: ivy.info, Node: How to modify the actions list?, Next: Example - add two actions to each command, Prev: How can different actions be called?, Up: Actions - -6.3.3 How to modify the actions list? -------------------------------------- - -Currently, you can append any amount of your own actions to the default -list of actions. This can be done either for a specific command, or for -all commands at once. - - Usually, the command has only one default action. The convention is -to use single letters when selecting a command, and the letter ‘o’ is -designated for the default command. This way, ‘M-o o’ should be always -equivalent to ‘C-m’. - - -File: ivy.info, Node: Example - add two actions to each command, Next: Example - define a new command with several actions, Prev: How to modify the actions list?, Up: Actions - -6.3.4 Example - add two actions to each command ------------------------------------------------ - -The first action inserts the current candidate into the Ivy window - the -window from which ‘ivy-read’ was called. - - The second action copies the current candidate to the kill ring. - - (defun ivy-yank-action (x) - (kill-new x)) - - (defun ivy-copy-to-buffer-action (x) - (with-ivy-window - (insert x))) - - (ivy-set-actions - t - '(("i" ivy-copy-to-buffer-action "insert") - ("y" ivy-yank-action "yank"))) - - Then in any completion session, ‘M-o y’ invokes ‘ivy-yank-action’, -and ‘M-o i’ invokes ‘ivy-copy-to-buffer-action’. - -* Menu: - -* How to undo adding the two actions:: -* How to add actions to a specific command:: - - -File: ivy.info, Node: How to undo adding the two actions, Next: How to add actions to a specific command, Up: Example - add two actions to each command - -6.3.4.1 How to undo adding the two actions -.......................................... - -Since ‘ivy-set-actions’ modifies the internal dictionary with new data, -set the extra actions list to ‘nil’ by assigning ‘nil’ value to the ‘t’ -key as follows: - - (ivy-set-actions t nil) - - -File: ivy.info, Node: How to add actions to a specific command, Prev: How to undo adding the two actions, Up: Example - add two actions to each command - -6.3.4.2 How to add actions to a specific command -................................................ - -Use the command name as the key: - - (ivy-set-actions - 'swiper - '(("i" ivy-copy-to-buffer-action "insert") - ("y" ivy-yank-action "yank"))) - - -File: ivy.info, Node: Example - define a new command with several actions, Prev: Example - add two actions to each command, Up: Actions - -6.3.5 Example - define a new command with several actions ---------------------------------------------------------- - - (defun my-action-1 (x) - (message "action-1: %s" x)) - - (defun my-action-2 (x) - (message "action-2: %s" x)) - - (defun my-action-3 (x) - (message "action-3: %s" x)) - - (defun my-command-with-3-actions () - (interactive) - (ivy-read "test: " '("foo" "bar" "baz") - :action '(1 - ("o" my-action-1 "action 1") - ("j" my-action-2 "action 2") - ("k" my-action-3 "action 3")))) - - The number 1 above is the index of the default action. Each action -has its own string description for easy selection. - -* Menu: - -* Test the above function with ivy-occur:: - - -File: ivy.info, Node: Test the above function with ivy-occur, Up: Example - define a new command with several actions - -6.3.5.1 Test the above function with ‘ivy-occur’ -................................................ - -To examine each action with each candidate in a key-efficient way, try: - - • Call ‘my-command-with-3-actions’ - • Press ‘C-c C-o’ to close the completion window and move to an - ivy-occur buffer - • Press ‘kkk’ to move to the first candidate, since the point is most - likely at the end of the buffer - • Press ‘oo’ to call the first action - • Press ‘oj’ and ‘ok’ to call the second and the third actions - • Press ‘j’ to move to the next candidate - • Press ‘oo’, ‘oj’, ‘ok’ - • Press ‘j’ to move to the next candidate - • and so on... - - -File: ivy.info, Node: Packages, Prev: Actions, Up: Customization - -6.4 Packages -============ - -‘org-mode’ -.......... - - ‘org-mode’ versions 8.3.3 or later obey ‘completing-read-function’ - (which ‘ivy-mode’ sets). Try refiling headings with similar names - to appreciate ‘ivy-mode’. - -‘magit’ -....... - - Uses ivy by default if Ivy is installed. - -‘find-file-in-project’ -...................... - - Uses ivy by default if Ivy is installed. - -‘projectile’ -............ - - Projectile requires this setting for ivy completion: - - (setq projectile-completion-system 'ivy) - -‘helm-make’ -........... - - Helm-make requires this setting for ivy completion. - - (setq helm-make-completion-method 'ivy) - -automatically integrated packages -................................. - - Ivy re-uses the following packages if they are installed: ‘avy’, - ‘amx’ or ‘smex’, ‘flx’, and ‘wgrep’. - - -File: ivy.info, Node: Commands, Next: API, Prev: Customization, Up: Top - -7 Commands -********** - -* Menu: - -* File Name Completion:: -* Buffer Name Completion:: -* Counsel commands:: - - -File: ivy.info, Node: File Name Completion, Next: Buffer Name Completion, Up: Commands - -7.1 File Name Completion -======================== - -Since file name completion is ubiquitous, Ivy provides extra bindings -that work here: - -‘C-j’ (‘ivy-alt-done’) -...................... - - On a directory, restarts completion from that directory. - - On a file or ‘./’, exit completion with the selected candidate. - -‘DEL’ (‘ivy-backward-delete-char’) -.................................. - - Restart the completion in the parent directory if current input is - empty. - -‘//’ (‘self-insert-command’) -............................ - - Switch to the root directory. - -‘~’ (‘self-insert-command’) -........................... - - Switch to the home directory. - -‘/’ (‘self-insert-command’) -........................... - - If the current input matches an existing directory name exactly, - switch the completion to that directory. - -‘M-r’ (‘ivy-toggle-regexp-quote’) -................................. - - Toggle between input as regexp or not. - - Switch to matching literally since file names include ‘.’, which is - for matching any char in regexp mode. - -- User Option: ivy-extra-directories - Decide if you want to see ‘../’ and ‘./’ during file name - completion. - - Reason to remove: ‘../’ is the same as ‘DEL’. - - Reason not to remove: navigate anywhere with only ‘C-n’, ‘C-p’ and - ‘C-j’. - - Likewise, ‘./’ can be removed. - -History -....... - - File history works the same with ‘M-p’, ‘M-n’, and ‘C-r’, but uses - a custom code for file name completion that cycles through files - previously opened. It also works with TRAMP files. - -* Menu: - -* Using TRAMP:: - - -File: ivy.info, Node: Using TRAMP, Up: File Name Completion - -7.1.1 Using TRAMP ------------------ - -‘~’ (tilde) -........... - - Move to the home directory. Either the local or the remote one, - depending on the current directory. The boolean option - ‘ivy-magic-tilde’ decides whether the binding to do this is ‘~’ or - ‘~/’. - -‘//’ (double slash) -................... - - Move to the root directory. Either the local or the remote one, - depending on the current directory. Here, you can also select a - TRAMP connection method, such as ‘ssh’ or ‘scpx’. - -‘/ C-j’ -....... - - Move the the local root directory. - -‘~~’ -.... - - Move to the local home directory. - - From any directory, with the empty input, inputting ‘/ssh:’ and -pressing ‘C-j’ (or ‘RET’, which is the same thing) completes for host -and user names. - - For ‘/ssh:user@’ input, completes the domain name. - - ‘C-i’ works in a similar way to the default completion. - - You can also get sudo access for the current directory by inputting -‘/sudo::’ ‘RET’. Using ‘/sudo:’ (i.e. single colon instead of double) -will result in a completion session for the desired user. - - Multi-hopping is possible, although a bit complex. - -Example : connect to a remote host ‘cloud’ and open a file with ‘sudo’ there -............................................................................ - - • ‘C-x C-f’ ‘/ssh:cloud|sudo:root:/’. - - -File: ivy.info, Node: Buffer Name Completion, Next: Counsel commands, Prev: File Name Completion, Up: Commands - -7.2 Buffer Name Completion -========================== - - -- User Option: ivy-use-virtual-buffers - When non-nil, add ‘recentf-mode’ and bookmarks to - ‘ivy-switch-buffer’ completion candidates. - - Adding this to Emacs init file: - - (setq ivy-use-virtual-buffers t) - will add additional virtual buffers to the buffers list for recent - files. Selecting such virtual buffers, which are highlighted with - ‘ivy-virtual’ face, will open the corresponding file. - - -File: ivy.info, Node: Counsel commands, Prev: Buffer Name Completion, Up: Commands - -7.3 Counsel commands -==================== - -The main advantages of ‘counsel-’ functions over their basic equivalents -in ‘ivy-mode’ are: - - 1. Multi-actions and non-exiting actions work. - 2. ‘ivy-resume’ can resume the last completion session. - 3. Customize ‘ivy-set-actions’, ‘ivy-re-builders-alist’. - 4. Customize individual keymaps, such as ‘counsel-describe-map’, - ‘counsel-git-grep-map’, or ‘counsel-find-file-map’, instead of - customizing ‘ivy-minibuffer-map’ that applies to all completion - sessions. - - -File: ivy.info, Node: API, Next: Variable Index, Prev: Commands, Up: Top - -8 API -***** - -The main (and only) entry point is the ‘ivy-read’ function. It takes -two required arguments and many optional arguments that can be passed by -a key. The optional ‘:action’ argument is highly recommended for -features such as multi-actions, non-exiting actions, ‘ivy-occur’ and -‘ivy-resume’. - -* Menu: - -* Required arguments for ivy-read:: -* Optional arguments for ivy-read:: -* Example - counsel-describe-function:: -* Example - counsel-locate:: -* Example - ivy-read-with-extra-properties:: - - -File: ivy.info, Node: Required arguments for ivy-read, Next: Optional arguments for ivy-read, Up: API - -8.1 Required arguments for ‘ivy-read’ -===================================== - -‘prompt’ -........ - - A prompt string normally ending in a colon and a space. - ‘ivy-count-format’ is prepended to it during completion. - -‘collection’ -............ - - Either a list of strings, a function, an alist or a hash table. - - If a function, then it has to be compatible with ‘all-completions’. - - -File: ivy.info, Node: Optional arguments for ivy-read, Next: Example - counsel-describe-function, Prev: Required arguments for ivy-read, Up: API - -8.2 Optional arguments for ‘ivy-read’ -===================================== - -‘predicate’ -........... - - Is a function to filter the initial collection. It has to be - compatible with ‘all-completions’. Tip: most of the time, it’s - simpler to just apply this filter to the ‘collection’ argument - itself, e.g. ‘(cl-remove-if-not predicate collection)’. - -‘require-match’ -............... - - When set to a non-nil value, input must match one of the - candidates. Custom input is not accepted. - -‘initial-input’ -............... - - This string argument is included for compatibility with - ‘completing-read’, which inserts it into the minibuffer. - - It’s recommended to use the ‘preselect’ argument instead of this. - -‘history’ -......... - - Name of the symbol to store history. See ‘completing-read’. - -‘preselect’ -........... - - Determines which one of the candidates to initially select. - - When set to an integer value, select the candidate with that index - value. - - When set to any other non-nil value, select the first candidate - matching this value. Comparison is first done with ‘equal’. If - this fails, and when applicable, match ‘preselect’ as a regular - expression. - - Every time the input becomes empty, the item corresponding to - ‘preselect’ is selected. - -‘keymap’ -........ - - A keymap to be composed with ‘ivy-minibuffer-map’. This keymap has - priority over ‘ivy-minibuffer-map’ and can be modified at any later - stage. - -‘update-fn’ -........... - - Is the function called each time the current candidate changes. - This function takes no arguments and is called in the minibuffer’s - ‘post-command-hook’. See ‘swiper’ for an example usage. - -‘sort’ -...... - - When non-nil, use ‘ivy-sort-functions-alist’ to sort the collection - as long as the collection is not larger than ‘ivy-sort-max-size’. - -‘action’ -........ - - Is the function to call after selection. It takes a string - argument. - -‘unwind’ -........ - - Is the function to call before exiting completion. It takes no - arguments. This function is called even if the completion is - interrupted with ‘C-g’. See ‘swiper’ for an example usage. - -‘re-builder’ -............ - - Is a function that takes a string and returns a valid regex. See - ‘Completion Styles’ for details. - -‘matcher’ -......... - - Is a function that takes a regex string and a list of strings and - returns a list of strings matching the regex. Any ordinary Emacs - matching function will suffice, yet finely tuned matching functions - can be used. See ‘counsel-find-file’ for an example usage. - -‘dynamic-collection’ -.................... - - When non-nil, ‘collection’ will be used to dynamically generate the - candidates each time the input changes, instead of being used once - statically with ‘all-completions’ to generate a list of strings. - See ‘counsel-locate’ for an example usage. - -‘caller’ -........ - - Is a symbol that uniquely identifies the function that called - ‘ivy-read’, which may be useful for further customizations. - - -File: ivy.info, Node: Example - counsel-describe-function, Next: Example - counsel-locate, Prev: Optional arguments for ivy-read, Up: API - -8.3 Example - ‘counsel-describe-function’ -========================================= - -This is a typical example of a function with a non-async collection, -which is a collection where all the strings in the collection are known -prior to any input from the user. - - Only the first two arguments (along with ‘action’) are essential - -the rest of the arguments are for fine-tuning, and could be omitted. - - The ‘action’ argument could also be omitted - but then ‘ivy-read’ -would do nothing except returning the string result, which you could -later use yourself. However, it’s recommended that you use the ‘action’ -argument. - - (defun counsel-describe-function () - "Forward to `describe-function'." - (interactive) - (ivy-read "Describe function: " - (let (cands) - (mapatoms - (lambda (x) - (when (fboundp x) - (push (symbol-name x) cands)))) - cands) - :keymap counsel-describe-map - :preselect (ivy-thing-at-point) - :history 'counsel-describe-symbol-history - :require-match t - :action (lambda (x) - (describe-function - (intern x))) - :caller 'counsel-describe-function)) - - Here are the interesting features of the above function, in the order -that they appear: - - • The ‘prompt’ argument is a simple string ending in ": ". - • The ‘collection’ argument evaluates to a (large) list of strings. - • The ‘keymap’ argument is for a custom keymap to supplement - ‘ivy-minibuffer-map’. - • The ‘preselect’ is provided by ‘ivy-thing-at-point’, which returns - a symbol near the point. Ivy then selects the first candidate from - the collection that matches this symbol. To select this - pre-selected candidate, a ‘RET’ will suffice. No further user - input is necessary. - • The ‘history’ argument is for keeping the history of this command - separate from the common history in ‘ivy-history’. - • The ‘require-match’ is set to ‘t’ since it doesn’t make sense to - call ‘describe-function’ on an un-interned symbol. - • The ‘action’ argument calls ‘describe-function’ on the interned - selected candidate. - • The ‘caller’ argument identifies this completion session. This is - important, since with the collection being a list of strings and - not a function name, the only other way for ‘ivy-read’ to identify - "who’s calling" and to apply the appropriate customizations is to - examine ‘this-command’. But ‘this-command’ would be modified if - another command called ‘counsel-describe-function’. - - -File: ivy.info, Node: Example - counsel-locate, Next: Example - ivy-read-with-extra-properties, Prev: Example - counsel-describe-function, Up: API - -8.4 Example - ‘counsel-locate’ -============================== - -This is a typical example of a function with an async collection. Since -the collection function cannot pre-compute all the locatable files in -memory within reasonable limits (time or memory), it relies on user -input to filter the universe of possible candidates to a manageable size -while also continuing to search asynchronously for possible candidates. -Both the filtering and searching continues with each character change of -the input with rapid updates to the collection presented without idle -waiting times. This live update will continue as long as there are -likely candidates. Eventually updates to the minibuffer will stop after -user input, filtering, and searching have exhausted looking for possible -candidates. - - Async collections suit long-running shell commands, such as ‘locate’. -With each new input, a new process starts while the old process is -killed. The collection is refreshed anew with each new process. -Meanwhile the user can provide more input characters (for further -narrowing) or select a candidate from the visible collection. - - (defun counsel-locate-function (str) - (or - (ivy-more-chars) - (progn - (counsel--async-command - (format "locate %s '%s'" - (mapconcat #'identity counsel-locate-options " ") - (counsel--elisp-to-pcre - (ivy--regex str)))) - '("" "working...")))) - - ;;;###autoload - (defun counsel-locate (&optional initial-input) - "Call the \"locate\" shell command. - INITIAL-INPUT can be given as the initial minibuffer input." - (interactive) - (ivy-read "Locate: " #'counsel-locate-function - :initial-input initial-input - :dynamic-collection t - :history 'counsel-locate-history - :action (lambda (file) - (with-ivy-window - (when file - (find-file file)))) - :unwind #'counsel-delete-process - :caller 'counsel-locate)) - - Here are the interesting features of the above functions, in the -order that they appear: - - • ‘counsel-locate-function’ takes a string argument and returns a - list of strings. Note that it’s not compatible with - ‘all-completions’, but since we’re not using that here, might as - well use one argument instead of three. - • ‘ivy-more-chars’ is a simple function that returns e.g. ‘'("2 - chars more")’ asking the user for more input. - • ‘counsel--async-command’ is a very easy API simplification that - takes a single string argument suitable for - ‘shell-command-to-string’. So you could prototype your function as - non-async using ‘shell-command-to-string’ and ‘split-string’ to - produce a collection, then decide that you want async and simply - swap in ‘counsel--async-command’. - • ‘counsel-locate’ is an interactive function with an optional - ‘initial-input’. - • ‘#'counsel-locate-function’ is passed as the ‘collection’ argument. - • ‘dynamic-collection’ is set to t, since this is an async - collection. - • ‘action’ argument uses ‘with-ivy-window’ wrapper, since we want to - open the selected file in the same window from which - ‘counsel-locate’ was called. - • ‘unwind’ argument is set to ‘#'counsel-delete-process’: when we - press ‘C-g’ we want to kill the running process created by - ‘counsel--async-command’. - • ‘caller’ argument identifies this command for easier customization. - - -File: ivy.info, Node: Example - ivy-read-with-extra-properties, Prev: Example - counsel-locate, Up: API - -8.5 Example - ‘ivy-read-with-extra-properties’ -============================================== - -This is another example to show how to associate additional values to -each displayed strings. - - (defun find-candidates-function (str pred _) - (let ((props '(1 2)) - (strs '("foo" "foo2"))) - (cl-mapcar (lambda (s p) (propertize s 'property p)) - strs - props))) - - (defun find-candidates () - (interactive) - (ivy-read "Find symbols: " - #'find-candidates-function - :action (lambda (x) - (message "Value: %s" (get-text-property 0 'property x) - )))) - - Here are the interesting features of the above function: - - • ‘find-candidates-function’ builds up a list of strings and - associates "foo" with the value 1 and "foo2" with 2. - • ‘find-candidates’ is an interactive function. - • ‘#'find-candidates’ is passed as the ‘collection’ argument. - • ‘action’ gets passed the selected string with the associated value. - It then retrieves that value and displays it. - - -File: ivy.info, Node: Variable Index, Next: Keystroke Index, Prev: API, Up: Top - -Variable Index -************** - -[index] -* Menu: - -* ivy-alt-done: Key bindings for single selection action then exit minibuffer. - (line 30) -* ivy-alt-done <1>: File Name Completion. (line 12) -* ivy-avy: Key bindings for single selection action then exit minibuffer. - (line 64) -* ivy-backward-delete-char: File Name Completion. (line 19) -* ivy-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 16) -* ivy-confirm-face: Faces. (line 34) -* ivy-count-format: Defcustoms. (line 6) -* ivy-current-match: Faces. (line 9) -* ivy-dispatching-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 26) -* ivy-dispatching-done: Key bindings for single selection action then exit minibuffer. - (line 24) -* ivy-display-style: Defcustoms. (line 24) -* ivy-done: Key bindings for single selection action then exit minibuffer. - (line 19) -* ivy-extra-directories: File Name Completion. (line 45) -* ivy-height: Key bindings for navigation. - (line 21) -* ivy-immediate-done: Key bindings for single selection action then exit minibuffer. - (line 53) -* ivy-insert-current: Key bindings that alter the minibuffer input. - (line 23) -* ivy-kill-ring-save: Other key bindings. (line 9) -* ivy-match-required-face: Faces. (line 53) -* ivy-minibuffer-grow: Hydra in the minibuffer. - (line 45) -* ivy-minibuffer-map: Minibuffer key bindings. - (line 6) -* ivy-minibuffer-match-face-1: Faces. (line 14) -* ivy-minibuffer-match-face-2: Faces. (line 19) -* ivy-minibuffer-match-face-3: Faces. (line 24) -* ivy-minibuffer-match-face-4: Faces. (line 29) -* ivy-minibuffer-shrink: Hydra in the minibuffer. - (line 50) -* ivy-modified-buffer: Faces. (line 88) -* ivy-modified-outside-buffer: Faces. (line 93) -* ivy-next-action: Hydra in the minibuffer. - (line 60) -* ivy-next-history-element: Key bindings that alter the minibuffer input. - (line 9) -* ivy-next-line-and-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 36) -* ivy-occur: Saving the current completion session to a buffer. - (line 9) -* ivy-occur-click: Saving the current completion session to a buffer. - (line 21) -* ivy-occur-dispatch: Saving the current completion session to a buffer. - (line 41) -* ivy-occur-press: Saving the current completion session to a buffer. - (line 16) -* ivy-occur-read-action: Saving the current completion session to a buffer. - (line 36) -* ivy-on-del-error-function: Defcustoms. (line 31) -* ivy-partial-or-done: Key bindings for single selection action then exit minibuffer. - (line 37) -* ivy-prev-action: Hydra in the minibuffer. - (line 55) -* ivy-previous-history-element: Key bindings that alter the minibuffer input. - (line 18) -* ivy-previous-line-and-call: Key bindings for multiple selections and actions keep minibuffer open. - (line 47) -* ivy-read-action: Hydra in the minibuffer. - (line 65) -* ivy-remote: Faces. (line 71) -* ivy-restrict-to-matches: Key bindings that alter the minibuffer input. - (line 40) -* ivy-resume: Key bindings for multiple selections and actions keep minibuffer open. - (line 55) -* ivy-reverse-i-search: Key bindings that alter the minibuffer input. - (line 48) -* ivy-rotate-preferred-builders: Hydra in the minibuffer. - (line 40) -* ivy-subdir: Faces. (line 66) -* ivy-toggle-calling: Hydra in the minibuffer. - (line 34) -* ivy-toggle-case-fold: Hydra in the minibuffer. - (line 70) -* ivy-toggle-regexp-quote: File Name Completion. (line 41) -* ivy-use-virtual-buffers: Buffer Name Completion. - (line 6) -* ivy-virtual: Faces. (line 76) -* ivy-wrap: Key bindings for navigation. - (line 14) -* ivy-yank-word: Key bindings that alter the minibuffer input. - (line 32) - - -File: ivy.info, Node: Keystroke Index, Prev: Variable Index, Up: Top - -Keystroke Index -*************** - -[index] -* Menu: - -* /: File Name Completion. (line 35) -* / C-j: Using TRAMP. (line 24) -* //: File Name Completion. (line 25) -* // <1>: Using TRAMP. (line 17) -* <: Hydra in the minibuffer. - (line 50) -* >: Hydra in the minibuffer. - (line 45) -* ~: File Name Completion. (line 30) -* ~ <1>: Using TRAMP. (line 9) -* ~~: Using TRAMP. (line 29) -* a: Hydra in the minibuffer. - (line 65) -* a <1>: Saving the current completion session to a buffer. - (line 36) -* c: Hydra in the minibuffer. - (line 34) -* C: Hydra in the minibuffer. - (line 70) -* C-': Key bindings for single selection action then exit minibuffer. - (line 64) -* C-c C-o: Saving the current completion session to a buffer. - (line 9) -* C-j: Key bindings for single selection action then exit minibuffer. - (line 30) -* C-j <1>: File Name Completion. (line 12) -* C-m: Key bindings for single selection action then exit minibuffer. - (line 19) -* C-M-j: Key bindings for single selection action then exit minibuffer. - (line 53) -* C-M-m: Key bindings for multiple selections and actions keep minibuffer open. - (line 16) -* C-M-n: Key bindings for multiple selections and actions keep minibuffer open. - (line 36) -* C-M-o: Key bindings for multiple selections and actions keep minibuffer open. - (line 26) -* C-M-p: Key bindings for multiple selections and actions keep minibuffer open. - (line 47) -* C-o: Hydra in the minibuffer. - (line 9) -* C-r: Key bindings that alter the minibuffer input. - (line 48) -* DEL: File Name Completion. (line 19) -* f: Saving the current completion session to a buffer. - (line 16) -* j: Saving the current completion session to a buffer. - (line 26) -* k: Saving the current completion session to a buffer. - (line 31) -* m: Hydra in the minibuffer. - (line 40) -* M-i: Key bindings that alter the minibuffer input. - (line 23) -* M-j: Key bindings that alter the minibuffer input. - (line 32) -* M-n: Key bindings that alter the minibuffer input. - (line 9) -* M-o: Key bindings for single selection action then exit minibuffer. - (line 24) -* M-p: Key bindings that alter the minibuffer input. - (line 18) -* M-r: File Name Completion. (line 41) -* M-w: Other key bindings. (line 9) -* mouse-1: Saving the current completion session to a buffer. - (line 21) -* o: Saving the current completion session to a buffer. - (line 41) -* q: Saving the current completion session to a buffer. - (line 46) -* RET: Key bindings for single selection action then exit minibuffer. - (line 19) -* RET <1>: Saving the current completion session to a buffer. - (line 16) -* s: Hydra in the minibuffer. - (line 60) -* S-SPC: Key bindings that alter the minibuffer input. - (line 40) -* TAB: Key bindings for single selection action then exit minibuffer. - (line 37) -* w: Hydra in the minibuffer. - (line 55) - - - -Tag Table: -Node: Top1189 -Node: Introduction3100 -Node: Installation5623 -Node: Installing from Emacs Package Manager6073 -Node: Installing from the Git repository7187 -Node: Getting started8007 -Node: Basic customization8314 -Node: Key bindings8909 -Node: Global key bindings9101 -Node: Minibuffer key bindings11575 -Node: Key bindings for navigation12807 -Node: Key bindings for single selection action then exit minibuffer14014 -Node: Key bindings for multiple selections and actions keep minibuffer open16661 -Node: Key bindings that alter the minibuffer input19053 -Node: Other key bindings20998 -Node: Hydra in the minibuffer21376 -Node: Saving the current completion session to a buffer23794 -Node: Completion Styles25206 -Node: ivy--regex-plus26957 -Node: ivy--regex-ignore-order28443 -Node: ivy--regex-fuzzy28811 -Node: Customization29308 -Node: Faces29494 -Node: Defcustoms31923 -Node: Actions33217 -Node: What are actions?33543 -Node: How can different actions be called?34361 -Node: How to modify the actions list?34932 -Node: Example - add two actions to each command35592 -Node: How to undo adding the two actions36551 -Node: How to add actions to a specific command37003 -Node: Example - define a new command with several actions37419 -Node: Test the above function with ivy-occur38307 -Node: Packages39149 -Node: Commands40114 -Node: File Name Completion40299 -Node: Using TRAMP42095 -Node: Buffer Name Completion43597 -Node: Counsel commands44212 -Node: API44859 -Node: Required arguments for ivy-read45457 -Node: Optional arguments for ivy-read45976 -Node: Example - counsel-describe-function49402 -Node: Example - counsel-locate52260 -Node: Example - ivy-read-with-extra-properties56010 -Node: Variable Index57218 -Node: Keystroke Index64265 - -End Tag Table - - -Local Variables: -coding: utf-8 -End: diff --git a/elpa/ivy-20210216.1611/dir b/elpa/ivy-20210216.1611/dir deleted file mode 100644 index b68b083..0000000 --- a/elpa/ivy-20210216.1611/dir +++ /dev/null @@ -1,18 +0,0 @@ -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" 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 -* Ivy: (ivy). Using Ivy for completion. diff --git a/elpa/ivy-20210216.1611/elpa.el b/elpa/ivy-20210216.1611/elpa.el deleted file mode 100644 index e49b8d4..0000000 --- a/elpa/ivy-20210216.1611/elpa.el +++ /dev/null @@ -1,6 +0,0 @@ -(setq package-user-dir - (expand-file-name - (format "~/.elpa/%s/elpa" - (concat emacs-version (when (getenv "MELPA_STABLE") "-stable"))))) -(package-initialize) -(add-to-list 'load-path default-directory) diff --git a/elpa/ivy-20210216.1611/ivy-help.org b/elpa/ivy-20210216.1611/ivy-help.org deleted file mode 100644 index 3a94118..0000000 --- a/elpa/ivy-20210216.1611/ivy-help.org +++ /dev/null @@ -1,138 +0,0 @@ -* Ivy Generic Help - -=ivy= is an Emacs incremental completion framework. - -- Narrow the list by typing some pattern, -- Multiple patterns are allowed by separating with a space, -- Select with ~C-n~ and ~C-p~, choose with ~RET~. - -** Help - -- ~C-h m~ :: Pop to this generic help buffer. - -** Basic Operations -*** Key bindings for navigation - -- ~C-n~ (=ivy-next-line=) :: next candidate. -- ~C-p~ (=ivy-previous-line=) :: previous candidate. -- ~C-v~ (=ivy-scroll-up-command=) :: next page. -- ~M-v~ (=ivy-scroll-down-command=) :: previous page. -- ~M-<~ (=ivy-beginning-of-buffer=) :: first candidate. -- ~M->~ (=ivy-end-of-buffer=) :: last candidate. - -*** Key bindings for single selection - -When selecting a candidate, an action is called on it. You can think -of an action as a function that takes the selected candidate as an -argument and does something with it. - -Ivy can offer several actions from which to choose. This can be -independently composed with whether you want to end completion when -the action is called. Depending on this, the short term is either -"calling an action" or "exiting with action". - -~C-m~ or ~RET~ (=ivy-done=) - exit with the current action. - -~M-o~ (=ivy-dispatching-done=) - select an action and exit with it. - -~C-j~ (=ivy-alt-done=) - when the candidate is a directory, enter -it. Otherwise, exit with the current action. - -~TAB~ (=ivy-partial-or-done=) - attempt partial completion, extending -the current input as much as possible. ~TAB TAB~ is the same as ~C-j~. - -~C-M-j~ (=ivy-immediate-done=) - exit with the current action, calling -it on the /current input/ instead of the current candidate. This is -useful especially when creating new files or directories - often the -input will match an existing file, which you don't want to select. - -~C-'~ (=ivy-avy=) - select a candidate from the current page with avy -and exit with the current action. - -** Advanced Operations -*** Key bindings for multiple selection - -For repeatedly applying multiple actions or acting on multiple -candidates, Ivy does not close the minibuffer between commands. It -keeps the minibuffer open for applying subsequent actions. - -Adding an extra meta key to the normal key chord invokes the special -version of the regular commands that enables applying multiple -actions. - -~C-M-m~ (=ivy-call=) is the non-exiting version of ~C-m~ (=ivy-done=). - -~C-M-n~ (=ivy-next-line-and-call=) combines ~C-n~ and ~C-M-m~. - -~C-M-p~ (=ivy-previous-line-and-call=) combines ~C-p~ and ~C-M-m~. - -~C-M-o~ (=ivy-dispatching-call=) is a non-exiting version of ~M-o~ -(=ivy-dispatching-done=). - -*** Key bindings that alter the minibuffer input - -~M-n~ (=ivy-next-history-element=) select the next history element or -symbol/URL at point. - -~M-p~ (=ivy-previous-history-element=) select the previous history -element. - -~C-r~ (=ivy-reverse-i-search=) start a recursive completion session to -select a history element. - -~M-i~ (=ivy-insert-current=) insert the current candidate into the -minibuffer. Useful for copying and renaming files, for example: ~M-i~ -to insert the original file name string, edit it, and then ~C-m~ to -complete the renaming. - -~M-j~ (=ivy-yank-word=) insert the sub-word at point into the -minibuffer. - -~S-SPC~ (=ivy-restrict-to-matches=) deletes the current input, and -resets the candidates list to the currently restricted matches. This -is how Ivy provides narrowing in successive tiers. - -*** Other key bindings - -~M-w~ (=ivy-kill-ring-save=) copies the selected candidates to the -kill ring; when the region is active, copies the active region. - -*** Saving the current completion session to a buffer - -~C-c C-o~ (=ivy-occur=) saves the current candidates to a new buffer; -the list is active in the new buffer. - -~RET~ or ~mouse-1~ in the new buffer calls the appropriate action on -the selected candidate. - -Ivy has no limit on the number of active buffers like these. - -Ivy takes care of making these buffer names unique. It applies -descriptive names, for example: =*ivy-occur counsel-describe-variable -"function$*=. - -*** Global key bindings - -=ivy-resume= recalls the state of the completion session just before -its last exit. Useful after an accidental ~C-m~ (=ivy-done=). -Recommended global binding: ~C-c C-r~. - -*** Hydra in the minibuffer - -~C-o~ (=hydra-ivy/body=) invokes Hydra menus with key shortcuts. - -When in Hydra, ~C-o~ or ~i~ resumes editing. - -Hydra reduces key strokes, for example: ~C-n C-n C-n C-n~ is ~C-o -jjjj~ in Hydra. Besides certain shorter keys, Hydra shows useful info -such as case folding and the current action. - -Additionally, here are the keys that are otherwise not bound: - -- ~<~ and ~>~ adjust the height of the minibuffer. -- ~c~ (=ivy-toggle-calling=) - toggle calling the current action each - time a different candidate is selected. -- ~M~ (=ivy-rotate-preferred-builders=) - rotate regex matcher. -- ~w~ and ~s~ scroll the actions list. - -Minibuffer editing is disabled when Hydra is active. diff --git a/elpa/ivy-20210216.1611/colir.el b/elpa/ivy-20210311.1638/colir.el similarity index 98% rename from elpa/ivy-20210216.1611/colir.el rename to elpa/ivy-20210311.1638/colir.el index 9e61273..09b4f5c 100644 --- a/elpa/ivy-20210216.1611/colir.el +++ b/elpa/ivy-20210311.1638/colir.el @@ -1,6 +1,6 @@ ;;; colir.el --- Color blending library -*- lexical-binding: t -*- -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. +;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel diff --git a/elpa/ivy-0.13.0/dir b/elpa/ivy-20210311.1638/dir old mode 100755 new mode 100644 similarity index 100% rename from elpa/ivy-0.13.0/dir rename to elpa/ivy-20210311.1638/dir diff --git a/elpa/ivy-0.13.0/elpa.el b/elpa/ivy-20210311.1638/elpa.el old mode 100755 new mode 100644 similarity index 100% rename from elpa/ivy-0.13.0/elpa.el rename to elpa/ivy-20210311.1638/elpa.el diff --git a/elpa/ivy-20210216.1611/ivy-autoloads.el b/elpa/ivy-20210311.1638/ivy-autoloads.el similarity index 100% rename from elpa/ivy-20210216.1611/ivy-autoloads.el rename to elpa/ivy-20210311.1638/ivy-autoloads.el diff --git a/elpa/ivy-20210216.1611/ivy-faces.el b/elpa/ivy-20210311.1638/ivy-faces.el similarity index 98% rename from elpa/ivy-20210216.1611/ivy-faces.el rename to elpa/ivy-20210311.1638/ivy-faces.el index 54492c4..bedb9cb 100644 --- a/elpa/ivy-20210216.1611/ivy-faces.el +++ b/elpa/ivy-20210311.1638/ivy-faces.el @@ -1,6 +1,6 @@ ;;; ivy-faces.el --- Faces for Ivy -*- lexical-binding: t -*- -;; Copyright (C) 2020 Free Software Foundation, Inc. +;; Copyright (C) 2020-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; Keywords: convenience diff --git a/elpa/ivy-0.13.0/ivy-help.org b/elpa/ivy-20210311.1638/ivy-help.org old mode 100755 new mode 100644 similarity index 100% rename from elpa/ivy-0.13.0/ivy-help.org rename to elpa/ivy-20210311.1638/ivy-help.org diff --git a/elpa/ivy-20210216.1611/ivy-overlay.el b/elpa/ivy-20210311.1638/ivy-overlay.el similarity index 98% rename from elpa/ivy-20210216.1611/ivy-overlay.el rename to elpa/ivy-20210311.1638/ivy-overlay.el index ed77fc0..f537358 100644 --- a/elpa/ivy-20210216.1611/ivy-overlay.el +++ b/elpa/ivy-20210311.1638/ivy-overlay.el @@ -1,6 +1,6 @@ ;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*- -;; Copyright (C) 2016-2019 Free Software Foundation, Inc. +;; Copyright (C) 2016-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; Keywords: convenience diff --git a/elpa/ivy-20210216.1611/ivy-pkg.el b/elpa/ivy-20210311.1638/ivy-pkg.el similarity index 66% rename from elpa/ivy-20210216.1611/ivy-pkg.el rename to elpa/ivy-20210311.1638/ivy-pkg.el index a188e20..ff75692 100644 --- a/elpa/ivy-20210216.1611/ivy-pkg.el +++ b/elpa/ivy-20210311.1638/ivy-pkg.el @@ -1,6 +1,6 @@ -(define-package "ivy" "20210216.1611" "Incremental Vertical completYon" +(define-package "ivy" "20210311.1638" "Incremental Vertical completYon" '((emacs "24.5")) - :commit "0965e2375e2539fcc62b44b7b8f680d40c0b535a" :authors + :commit "bb7965aa645982c9a80bd9e772538a210b645942" :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") diff --git a/elpa/ivy-20210216.1611/ivy.el b/elpa/ivy-20210311.1638/ivy.el similarity index 99% rename from elpa/ivy-20210216.1611/ivy.el rename to elpa/ivy-20210311.1638/ivy.el index 2c670e6..48ffa66 100644 --- a/elpa/ivy-20210216.1611/ivy.el +++ b/elpa/ivy-20210311.1638/ivy.el @@ -1,10 +1,10 @@ ;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*- -;; Copyright (C) 2015-2020 Free Software Foundation, Inc. +;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/swiper -;; Version: 0.13.0 +;; Version: 0.13.4 ;; Package-Requires: ((emacs "24.5")) ;; Keywords: matching @@ -3286,10 +3286,16 @@ The function was added in Emacs 26.1.") "~" home))))) +(defvar ivy--minibuffer-metadata nil) + (defun ivy-update-candidates (cands) - (ivy--insert-minibuffer - (ivy--format - (setq ivy--all-candidates cands)))) + (let ((ivy--minibuffer-metadata + (unless (ivy-state-dynamic-collection ivy-last) + (completion-metadata "" minibuffer-completion-table + minibuffer-completion-predicate)))) + (ivy--insert-minibuffer + (ivy--format + (setq ivy--all-candidates cands))))) (defun ivy--exhibit () "Insert Ivy completions display. @@ -4032,7 +4038,8 @@ in this case." (funcall ivy--highlight-function str)) str)) (olen (length str)) - (annot (plist-get completion-extra-properties :annotation-function))) + (annot (or (completion-metadata-get ivy--minibuffer-metadata 'annotation-function) + (plist-get completion-extra-properties :annotation-function)))) (add-text-properties 0 olen '(mouse-face @@ -4425,7 +4432,8 @@ BUFFER may be a string or nil." (defun ivy--kill-current-candidate-buffer () (setf (ivy-state-preselect ivy-last) ivy--index) (setq ivy--old-re nil) - (setq ivy--all-candidates (ivy--buffer-list "" ivy-use-virtual-buffers nil)) + (setq ivy--all-candidates (ivy--buffer-list "" ivy-use-virtual-buffers + (ivy-state-predicate ivy-last))) (let ((ivy--recompute-index-inhibit t)) (ivy--exhibit))) diff --git a/elpa/ivy-20210216.1611/ivy.info b/elpa/ivy-20210311.1638/ivy.info similarity index 97% rename from elpa/ivy-20210216.1611/ivy.info rename to elpa/ivy-20210311.1638/ivy.info index c1f52aa..6a373d8 100644 --- a/elpa/ivy-20210216.1611/ivy.info +++ b/elpa/ivy-20210311.1638/ivy.info @@ -1,6 +1,6 @@ This is ivy.info, produced by makeinfo version 6.5 from ivy.texi. -Ivy manual, version 0.13.0 +Ivy manual, version 0.13.4 Ivy is an interactive interface for completion in Emacs. Emacs uses completion mechanism in a variety of contexts: code, menus, commands, @@ -11,7 +11,7 @@ available choices while previewing in the minibuffer. Selecting the final candidate is either through simple keyboard character inputs or through powerful regular expressions. - Copyright (C) 2015-2019 Free Software Foundation, Inc. + Copyright (C) 2015–2021 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, @@ -204,21 +204,22 @@ File: ivy.info, Node: Installing from Emacs Package Manager, Next: Installing ‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’ - Ivy is installed as part of the ‘counsel’ package, which is available + Ivy is installed alongside the ‘counsel’ package, which is available from two different package archives, GNU ELPA and MELPA. For the latest -stable version, use the GNU ELPA archives. For current hourly builds, -use the MELPA archives. +stable version, use the GNU ELPA archive. For the latest development +snaphshot, use the GNU-devel ELPA archive. Ivy is split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; by installing ‘counsel’, the other two are brought in as dependencies. If you are not interested in the extra functionality provided by ‘swiper’ and ‘counsel’, you can install only ‘ivy’. - See the code below for adding MELPA to the list of package archives: + See the code below for adding GNU-devel ELPA to your list of package +archives: (require 'package) (add-to-list 'package-archives - '("melpa" . "https://melpa.org/packages/")) + '("gnu-devel" . "https://elpa.gnu.org/devel/")) After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by ‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’. @@ -234,7 +235,7 @@ File: ivy.info, Node: Installing from the Git repository, Prev: Installing fro Why install from Git? ..................... - • No need to wait for MELPA’s hourly builds + • No need to wait for GNU ELPA / MELPA builds • Easy to revert to previous versions • Contribute to Ivy’s development; send patches; pull requests @@ -1916,53 +1917,53 @@ File: ivy.info, Node: Keystroke Index, Prev: Variable Index, Up: Top  Tag Table: -Node: Top1190 -Node: Introduction3101 -Node: Installation5624 -Node: Installing from Emacs Package Manager6074 -Node: Installing from the Git repository7284 -Node: Getting started8104 -Node: Basic customization8411 -Node: Key bindings9006 -Node: Global key bindings9198 -Node: Minibuffer key bindings11672 -Node: Key bindings for navigation12904 -Node: Key bindings for single selection action then exit minibuffer14111 -Node: Key bindings for multiple selections and actions keep minibuffer open16758 -Node: Key bindings that alter the minibuffer input19379 -Node: Other key bindings21324 -Node: Hydra in the minibuffer21702 -Node: Saving the current completion session to a buffer24120 -Node: Completion Styles25532 -Node: ivy--regex-plus27283 -Node: ivy--regex-ignore-order28769 -Node: ivy--regex-fuzzy29137 -Node: Customization29634 -Node: Faces29820 -Node: Defcustoms32249 -Node: Actions33608 -Node: What are actions?33934 -Node: How can different actions be called?34752 -Node: How to modify the actions list?35323 -Node: Example - add two actions to each command35983 -Node: How to undo adding the two actions36942 -Node: How to add actions to a specific command37394 -Node: Example - define a new command with several actions37810 -Node: Test the above function with ivy-occur38698 -Node: Packages39540 -Node: Commands40505 -Node: File Name Completion40690 -Node: Using TRAMP42647 -Node: Buffer Name Completion44149 -Node: Counsel commands44764 -Node: API45411 -Node: Required arguments for ivy-read46009 -Node: Optional arguments for ivy-read46528 -Node: Example - counsel-describe-function49954 -Node: Example - counsel-locate52812 -Node: Example - ivy-read-with-extra-properties56562 -Node: Variable Index57770 -Node: Keystroke Index64894 +Node: Top1192 +Node: Introduction3103 +Node: Installation5626 +Node: Installing from Emacs Package Manager6076 +Node: Installing from the Git repository7324 +Node: Getting started8144 +Node: Basic customization8451 +Node: Key bindings9046 +Node: Global key bindings9238 +Node: Minibuffer key bindings11712 +Node: Key bindings for navigation12944 +Node: Key bindings for single selection action then exit minibuffer14151 +Node: Key bindings for multiple selections and actions keep minibuffer open16798 +Node: Key bindings that alter the minibuffer input19419 +Node: Other key bindings21364 +Node: Hydra in the minibuffer21742 +Node: Saving the current completion session to a buffer24160 +Node: Completion Styles25572 +Node: ivy--regex-plus27323 +Node: ivy--regex-ignore-order28809 +Node: ivy--regex-fuzzy29177 +Node: Customization29674 +Node: Faces29860 +Node: Defcustoms32289 +Node: Actions33648 +Node: What are actions?33974 +Node: How can different actions be called?34792 +Node: How to modify the actions list?35363 +Node: Example - add two actions to each command36023 +Node: How to undo adding the two actions36982 +Node: How to add actions to a specific command37434 +Node: Example - define a new command with several actions37850 +Node: Test the above function with ivy-occur38738 +Node: Packages39580 +Node: Commands40545 +Node: File Name Completion40730 +Node: Using TRAMP42687 +Node: Buffer Name Completion44189 +Node: Counsel commands44804 +Node: API45451 +Node: Required arguments for ivy-read46049 +Node: Optional arguments for ivy-read46568 +Node: Example - counsel-describe-function49994 +Node: Example - counsel-locate52852 +Node: Example - ivy-read-with-extra-properties56602 +Node: Variable Index57810 +Node: Keystroke Index64934  End Tag Table diff --git a/elpa/ivy-hydra-0.13.0/ivy-hydra-pkg.el b/elpa/ivy-hydra-0.13.0/ivy-hydra-pkg.el deleted file mode 100755 index b10bed6..0000000 --- a/elpa/ivy-hydra-0.13.0/ivy-hydra-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;;; Generated package description from /data/data/com.termux/files/home/.emacs.d/elpa/ivy-hydra-0.13.0/ivy-hydra.el -*- no-byte-compile: t -*- -(define-package "ivy-hydra" "0.13.0" "Additional key bindings for Ivy" '((emacs "24.5") (ivy "0.13.0") (hydra "0.15.0")) :commit "cd634c6f51458f81898ecf2821ac3169cb65a1eb" :keywords '("convenience") :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/ivy-hydra-0.13.0/ivy-hydra.el b/elpa/ivy-hydra-0.13.0/ivy-hydra.el deleted file mode 100755 index 3907f5d..0000000 --- a/elpa/ivy-hydra-0.13.0/ivy-hydra.el +++ /dev/null @@ -1,135 +0,0 @@ -;;; ivy-hydra.el --- Additional key bindings for Ivy -*- lexical-binding: t -*- - -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. - -;; Author: Oleh Krehel -;; URL: https://github.com/abo-abo/swiper -;; Package-Version: 0.13.0 -;; Package-Commit: cd634c6f51458f81898ecf2821ac3169cb65a1eb -;; Version: 0.13.0 -;; Package-Requires: ((emacs "24.5") (ivy "0.13.0") (hydra "0.15.0")) -;; Keywords: convenience - -;; This file is part of GNU Emacs. - -;; This file 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, 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. - -;; For a full copy of the GNU General Public License -;; see . - -;;; Commentary: - -;; This package provides the `hydra-ivy/body' command, which is a -;; quasi-prefix map, with many useful bindings. These bindings are -;; shorter than usual, using mostly unprefixed keys. - -;;; Code: - -(require 'ivy) -(require 'hydra) - -(defun ivy--matcher-desc () - "Return description of `ivy--regex-function'." - (let ((cell (assq ivy--regex-function ivy-preferred-re-builders))) - (if cell - (cdr cell) - "other"))) - -(defhydra hydra-ivy (:hint nil - :color pink) - " -^ ^ ^ ^ ^ ^ | ^Call^ ^ ^ | ^Cancel^ | ^Options^ | Action _w_/_s_/_a_: %-14s(ivy-action-name) -^-^-^-^-^-^-+-^-^---------^-^--+-^-^------+-^-^-------+-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------- -^ ^ _k_ ^ ^ | _f_ollow occ_U_r | _i_nsert | _c_: calling %-5s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search -_h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _T_runcate: %-11`truncate-lines -^ ^ _j_ ^ ^ | _g_o ^ ^ | ^ ^ | _<_/_>_: shrink/grow^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _D_efinition of this menu -" - ;; arrows - ("h" ivy-beginning-of-buffer) - ("j" ivy-next-line) - ("k" ivy-previous-line) - ("l" ivy-end-of-buffer) - ;; mark - ("m" ivy-mark) - ("u" ivy-unmark) - ("DEL" ivy-unmark-backward) - ("t" ivy-toggle-marks) - ;; actions - ("o" keyboard-escape-quit :exit t) - ("r" ivy-dispatching-done-hydra :exit t) - ("C-g" keyboard-escape-quit :exit t) - ("i" nil) - ("C-o" nil) - ("f" ivy-alt-done :exit nil) - ("C-j" ivy-alt-done :exit nil) - ("d" ivy-done :exit t) - ("g" ivy-call) - ("C-m" ivy-done :exit t) - ("c" ivy-toggle-calling) - ("M" ivy-rotate-preferred-builders) - (">" ivy-minibuffer-grow) - ("<" ivy-minibuffer-shrink) - ("w" ivy-prev-action) - ("s" ivy-next-action) - ("a" (let ((ivy-read-action-function #'ivy-read-action-by-key)) - (ivy-read-action))) - ("T" (setq truncate-lines (not truncate-lines))) - ("C" ivy-toggle-case-fold) - ("U" ivy-occur :exit t) - ("D" (ivy-exit-with-action - (lambda (_) (find-function 'hydra-ivy/body))) - :exit t)) - -(defvar ivy-dispatching-done-columns 2 - "Number of columns to use if the hint does not fit on one line.") - -(defvar ivy-dispatching-done-idle nil - "When non-nil, the hint will be delayed by this many seconds.") - -(defvar ivy-dispatching-done-hydra-exit-keys '(("M-o" nil "back") - ("C-g" nil)) - "Keys that can be used to exit `ivy-dispatching-done-hydra'.") - -(defun ivy-dispatching-done-hydra () - "Select one of the available actions and call `ivy-done'." - (interactive) - (let* ((actions (ivy-state-action ivy-last)) - (extra-actions ivy-dispatching-done-hydra-exit-keys) - (doc (concat "action: " - (mapconcat - (lambda (x) (format "[%s] %s" (nth 0 x) (nth 2 x))) - (append (cdr actions) - extra-actions) ", "))) - (estimated-len (length doc)) - (n-columns (if (> estimated-len (window-width)) - ivy-dispatching-done-columns - nil)) - (i 0)) - (if (null (ivy--actionp actions)) - (ivy-done) - (funcall - (eval - `(defhydra ivy-read-action (:color teal :columns ,n-columns :idle ,ivy-dispatching-done-idle) - "action" - ,@(mapcar (lambda (x) - (list (nth 0 x) - `(progn - (setcar (ivy-state-action ivy-last) ,(cl-incf i)) - (ivy-done)) - (nth 2 x))) - (cdr actions)) - ,@extra-actions)))))) - -(setq ivy-read-action-function (lambda (_) (ivy-dispatching-done-hydra))) - -(provide 'ivy-hydra) - -;;; ivy-hydra.el ends here diff --git a/elpa/ivy-hydra-0.13.0/ivy-hydra-autoloads.el b/elpa/ivy-hydra-0.13.4/ivy-hydra-autoloads.el old mode 100755 new mode 100644 similarity index 100% rename from elpa/ivy-hydra-0.13.0/ivy-hydra-autoloads.el rename to elpa/ivy-hydra-0.13.4/ivy-hydra-autoloads.el diff --git a/elpa/ivy-hydra-0.13.4/ivy-hydra-pkg.el b/elpa/ivy-hydra-0.13.4/ivy-hydra-pkg.el new file mode 100644 index 0000000..3b02d21 --- /dev/null +++ b/elpa/ivy-hydra-0.13.4/ivy-hydra-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from ivy-hydra.el -*- no-byte-compile: t -*- +(define-package "ivy-hydra" "0.13.4" "Additional key bindings for Ivy" '((emacs "24.5") (ivy "0.13.4") (hydra "0.15.0")) :commit "8cf3f1821cbd1c266296bbd5e59582ae6b8b90a6" :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :keywords '("convenience") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/ivy-0.13.1/ivy-hydra.el b/elpa/ivy-hydra-0.13.4/ivy-hydra.el similarity index 68% rename from elpa/ivy-0.13.1/ivy-hydra.el rename to elpa/ivy-hydra-0.13.4/ivy-hydra.el index ce31f2b..fc6bbc7 100644 --- a/elpa/ivy-0.13.1/ivy-hydra.el +++ b/elpa/ivy-hydra-0.13.4/ivy-hydra.el @@ -1,11 +1,13 @@ ;;; ivy-hydra.el --- Additional key bindings for Ivy -*- lexical-binding: t -*- -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. +;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/swiper -;; Version: 0.13.0 -;; Package-Requires: ((emacs "24.5") (ivy "0.13.0") (hydra "0.15.0")) +;; Package-Version: 0.13.4 +;; Package-Commit: 8cf3f1821cbd1c266296bbd5e59582ae6b8b90a6 +;; Version: 0.13.4 +;; Package-Requires: ((emacs "24.5") (ivy "0.13.4") (hydra "0.15.0")) ;; Keywords: convenience ;; This file is part of GNU Emacs. @@ -41,8 +43,21 @@ (cdr cell) "other"))) -(defhydra hydra-ivy (:hint nil - :color pink) +(defun ivy-minibuffer-grow () + "Grow the minibuffer window by 1 line." + (interactive) + (setq-local max-mini-window-height + (cl-incf ivy-height))) + +(defun ivy-minibuffer-shrink () + "Shrink the minibuffer window by 1 line." + (interactive) + (when (> ivy-height 2) + (setq-local max-mini-window-height + (cl-decf ivy-height)) + (window-resize nil -1))) + +(defhydra hydra-ivy (:hint nil :color pink) " ^ ^ ^ ^ ^ ^ | ^Call^ ^ ^ | ^Cancel^ | ^Options^ | Action _w_/_s_/_a_: %-14s(ivy-action-name) ^-^-^-^-^-^-+-^-^---------^-^--+-^-^------+-^-^-------+-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------- @@ -62,7 +77,7 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc) ("t" ivy-toggle-marks) ;; actions ("o" keyboard-escape-quit :exit t) - ("r" ivy-dispatching-done-hydra :exit t) + ("r" ivy-dispatching-done :exit t) ("C-g" keyboard-escape-quit :exit t) ("i" nil) ("C-o" nil) @@ -84,7 +99,18 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc) ("U" ivy-occur :exit t) ("D" (ivy-exit-with-action (lambda (_) (find-function 'hydra-ivy/body))) - :exit t)) + :exit t)) +(dolist (sym '( + ;; these cmds have a binding here + ivy-next-action ivy-prev-action + ivy-unmark-backward ivy-toggle-case-fold + ivy-minibuffer-grow ivy-minibuffer-shrink + ivy-rotate-preferred-builders ivy-toggle-calling + ;; no binding + ivy-next-line-or-history ivy-previous-line-or-history + ivy-toggle-fuzzy ivy-yank-symbol + ivy-occur-next-error)) + (put sym 'no-counsel-M-x t)) (defvar ivy-dispatching-done-columns 2 "Number of columns to use if the hint does not fit on one line.") @@ -94,13 +120,11 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc) (defvar ivy-dispatching-done-hydra-exit-keys '(("M-o" nil "back") ("C-g" nil)) - "Keys that can be used to exit `ivy-dispatching-done-hydra'.") + "Keys that can be used to exit `ivy-hydra-read-action'.") -(defun ivy-dispatching-done-hydra () +(defun ivy-hydra-read-action (actions) "Select one of the available actions and call `ivy-done'." - (interactive) - (let* ((actions (ivy-state-action ivy-last)) - (extra-actions ivy-dispatching-done-hydra-exit-keys) + (let* ((extra-actions ivy-dispatching-done-hydra-exit-keys) (doc (concat "action: " (mapconcat (lambda (x) (format "[%s] %s" (nth 0 x) (nth 2 x))) @@ -120,13 +144,17 @@ _h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc) ,@(mapcar (lambda (x) (list (nth 0 x) `(progn - (setcar (ivy-state-action ivy-last) ,(cl-incf i)) - (ivy-done)) + (let ((prev-idx (car (ivy-state-action ivy-last)))) + (setcar (ivy-state-action ivy-last) ,(cl-incf i)) + ,@(if (eq ivy-exit 'ivy-dispatching-done) + '((ivy-done)) + '((ivy-call) + (setcar (ivy-state-action ivy-last) prev-idx))))) (nth 2 x))) (cdr actions)) - ,@extra-actions)))))) + ,@extra-actions))) + nil))) -(setq ivy-read-action-function (lambda (_) (ivy-dispatching-done-hydra))) (provide 'ivy-hydra) diff --git a/elpa/markdown-mode-20210216.852/markdown-mode-pkg.el b/elpa/markdown-mode-20210216.852/markdown-mode-pkg.el deleted file mode 100644 index 1d7be5e..0000000 --- a/elpa/markdown-mode-20210216.852/markdown-mode-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;;; Generated package description from /home/raphael/.emacs.d/elpa/markdown-mode-20210216.852/markdown-mode.el -*- no-byte-compile: t -*- -(define-package "markdown-mode" "20210216.852" "Major mode for Markdown-formatted text" '((emacs "25.1")) :commit "377ce39ffe69f058994ac4e98bde8cfb58661406" :authors '(("Jason R. Blevins" . "jblevins@xbeta.org")) :maintainer '("Jason R. Blevins" . "jblevins@xbeta.org") :keywords '("markdown" "github flavored markdown" "itex") :url "https://jblevins.org/projects/markdown-mode/") diff --git a/elpa/markdown-mode-20210216.852/markdown-mode-autoloads.el b/elpa/markdown-mode-20210220.1301/markdown-mode-autoloads.el similarity index 100% rename from elpa/markdown-mode-20210216.852/markdown-mode-autoloads.el rename to elpa/markdown-mode-20210220.1301/markdown-mode-autoloads.el diff --git a/elpa/markdown-mode-20210220.1301/markdown-mode-pkg.el b/elpa/markdown-mode-20210220.1301/markdown-mode-pkg.el new file mode 100644 index 0000000..a0a0db8 --- /dev/null +++ b/elpa/markdown-mode-20210220.1301/markdown-mode-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from markdown-mode.el -*- no-byte-compile: t -*- +(define-package "markdown-mode" "20210220.1301" "Major mode for Markdown-formatted text" '((emacs "25.1")) :commit "051734091aba17a54af96b81beebdbfc84c26459" :authors '(("Jason R. Blevins" . "jblevins@xbeta.org")) :maintainer '("Jason R. Blevins" . "jblevins@xbeta.org") :keywords '("markdown" "github flavored markdown" "itex") :url "https://jblevins.org/projects/markdown-mode/") diff --git a/elpa/markdown-mode-20210216.852/markdown-mode.el b/elpa/markdown-mode-20210220.1301/markdown-mode.el similarity index 99% rename from elpa/markdown-mode-20210216.852/markdown-mode.el rename to elpa/markdown-mode-20210220.1301/markdown-mode.el index 4073763..45c8d9a 100644 --- a/elpa/markdown-mode-20210216.852/markdown-mode.el +++ b/elpa/markdown-mode-20210220.1301/markdown-mode.el @@ -7,8 +7,8 @@ ;; Maintainer: Jason R. Blevins ;; Created: May 24, 2007 ;; Version: 2.5-dev -;; Package-Version: 20210216.852 -;; Package-Commit: 377ce39ffe69f058994ac4e98bde8cfb58661406 +;; Package-Version: 20210220.1301 +;; Package-Commit: 051734091aba17a54af96b81beebdbfc84c26459 ;; Package-Requires: ((emacs "25.1")) ;; Keywords: Markdown, GitHub Flavored Markdown, itex ;; URL: https://jblevins.org/projects/markdown-mode/ @@ -94,7 +94,7 @@ Any changes to the output buffer made by this hook will be saved.") :group 'text :link '(url-link "https://jblevins.org/projects/markdown-mode/")) -(defcustom markdown-command (let ((command (cl-loop for cmd in '("markdown" "pandoc") +(defcustom markdown-command (let ((command (cl-loop for cmd in '("markdown" "pandoc" "markdown_py") when (executable-find cmd) return (file-name-nondirectory it)))) (or command "markdown")) diff --git a/elpa/php-mode-1.23.0/php-mode-pkg.el b/elpa/php-mode-1.23.0/php-mode-pkg.el deleted file mode 100755 index 6b8a515..0000000 --- a/elpa/php-mode-1.23.0/php-mode-pkg.el +++ /dev/null @@ -1,12 +0,0 @@ -(define-package "php-mode" "1.23.0" "Major mode for editing PHP code" - '((emacs "24.3")) - :commit "08c6e0f6719fafa60cf76f741d83524fd84163d6" :keywords - ("languages" "php") - :authors - (("Eric James Michael Ritz")) - :maintainer - ("USAMI Kenta" . "tadsan@zonu.me") - :url "https://github.com/emacs-php/php-mode") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/php-mode-1.23.0/php-util-buffer.el b/elpa/php-mode-1.23.0/php-util-buffer.el deleted file mode 100755 index e287983..0000000 --- a/elpa/php-mode-1.23.0/php-util-buffer.el +++ /dev/null @@ -1,135 +0,0 @@ -;;; php-util-buffer.el --- Utility function for buffer manipulation -*- lexical-binding: t; -*- - -;; Copyright (C) 2020 Friends of Emacs-PHP development -;; Copyright 2013 The go-mode Authors. All rights reserved. - -;; Author: Dominik Honnef -;; Maintainer: USAMI Kenta -;; URL: https://github.com/emacs-php/php-mode -;; Keywords: lisp - -;; 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 . - -;;; Commentary: - -;; Functions for patching buffer. - -;;; Original License: - -;; Copyright (c) 2014 The go-mode Authors. All rights reserved. - -;; Redistribution and use in source and binary forms, with or without -;; modification, are permitted provided that the following conditions are -;; met: - -;; * Redistributions of source code must retain the above copyright -;; notice, this list of conditions and the following disclaimer. -;; * Redistributions in binary form must reproduce the above -;; copyright notice, this list of conditions and the following disclaimer -;; in the documentation and/or other materials provided with the -;; distribution. -;; * Neither the name of the copyright holder nor the names of its -;; contributors may be used to endorse or promote products derived from -;; this software without specific prior written permission. - -;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -;;; Code: - -;; gofmt apply-rcs-patch Function -;; These functions are copied by go-mode(gofmt). -(defun php-util-buffer--delete-whole-line (&optional arg) - "Delete the current line without putting it in the `kill-ring'. -Derived from function `kill-whole-line'. ARG is defined as for that -function." - (setq arg (or arg 1)) - (if (and (> arg 0) - (eobp) - (save-excursion (forward-visible-line 0) (eobp))) - (signal 'end-of-buffer nil)) - (if (and (< arg 0) - (bobp) - (save-excursion (end-of-visible-line) (bobp))) - (signal 'beginning-of-buffer nil)) - (cond ((zerop arg) - (delete-region (progn (forward-visible-line 0) (point)) - (progn (end-of-visible-line) (point)))) - ((< arg 0) - (delete-region (progn (end-of-visible-line) (point)) - (progn (forward-visible-line (1+ arg)) - (unless (bobp) - (backward-char)) - (point)))) - (t - (delete-region (progn (forward-visible-line 0) (point)) - (progn (forward-visible-line arg) (point)))))) - -(defun php-util-buffer-apply-rcs-patch (target-buffer patch-buffer) - "Apply an RCS-formatted diff from `PATCH-BUFFER' to the `TARGET-BUFFER'." - (let ( - ;; Relative offset between buffer line numbers and line numbers - ;; in patch. - ;; - ;; Line numbers in the patch are based on the source file, so - ;; we have to keep an offset when making changes to the - ;; buffer. - ;; - ;; Appending lines decrements the offset (possibly making it - ;; negative), deleting lines increments it. This order - ;; simplifies the forward-line invocations. - (line-offset 0) - (column (current-column))) - (save-excursion - (with-current-buffer patch-buffer - (goto-char (point-min)) - (while (not (eobp)) - (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)") - (error "Invalid rcs patch or internal error in php-util-buffer-apply-rcs-patch")) - (forward-line) - (let ((action (match-string 1)) - (from (string-to-number (match-string 2))) - (len (string-to-number (match-string 3)))) - (cond - ((equal action "a") - (let ((start (point))) - (forward-line len) - (let ((text (buffer-substring start (point)))) - (with-current-buffer target-buffer - (cl-decf line-offset len) - (goto-char (point-min)) - (forward-line (- from len line-offset)) - (insert text))))) - ((equal action "d") - (with-current-buffer target-buffer - (goto-char (point-min)) - (forward-line (1- (- from line-offset))) - (cl-incf line-offset len) - (php-util-buffer--delete-whole-line len))) - (t - (error "Invalid rcs patch or internal error in php-util-buffer--apply-rcs-patch"))))))) - (move-to-column column))) -;; Copy of go-mode.el ends here - -(provide 'php-util-buffer) -;;; php-util-buffer.el ends here diff --git a/elpa/php-mode-1.23.0/php-align.el b/elpa/php-mode-1.24.0/php-align.el old mode 100755 new mode 100644 similarity index 98% rename from elpa/php-mode-1.23.0/php-align.el rename to elpa/php-mode-1.24.0/php-align.el index 084f885..1e14489 --- a/elpa/php-mode-1.23.0/php-align.el +++ b/elpa/php-mode-1.24.0/php-align.el @@ -7,8 +7,7 @@ ;; Maintainer: USAMI Kenta ;; Keywords: php languages convenience align ;; Homepage: https://github.com/emacs-php/php-mode -;; Version: 1.23.0 -;; Package-Requires: ((emacs "24.3")) +;; Version: 1.24.0 ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/elpa/php-mode-1.23.0/php-face.el b/elpa/php-mode-1.24.0/php-face.el old mode 100755 new mode 100644 similarity index 99% rename from elpa/php-mode-1.23.0/php-face.el rename to elpa/php-mode-1.24.0/php-face.el index cb6a95f..1cbc800 --- a/elpa/php-mode-1.23.0/php-face.el +++ b/elpa/php-mode-1.24.0/php-face.el @@ -4,10 +4,9 @@ ;; Author: USAMI Kenta ;; Created: 5 May 2019 -;; Version: 1.23.0 +;; Version: 1.24.0 ;; Keywords: faces, php ;; Homepage: https://github.com/emacs-php/php-mode -;; Package-Requires: ((emacs "24.3")) ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/elpa/php-mode-1.24.0/php-local-manual.el b/elpa/php-mode-1.24.0/php-local-manual.el new file mode 100644 index 0000000..6601ed6 --- /dev/null +++ b/elpa/php-mode-1.24.0/php-local-manual.el @@ -0,0 +1,39 @@ +;;; php-local-manual.el --- Tools for local PHP manual -*- lexical-binding: t; -*- + +;; Copyright (C) 2020 Friends of Emacs-PHP development + +;; Author: Eric James Michael Ritz +;; Maintainer: USAMI Kenta +;; URL: https://github.com/emacs-php/php-mode +;; Keywords: docs, php +;; Version: 2.0.0 +;; License: GPL-3.0-or-later + +;; 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 . + +;;; Commentary: + +;; This package helps you search the locally installed PHP Manual. +;; If you're only developing online, this feature is probably unnecessary. + +;;; Code: +(require 'php-mode) + +(defalias 'php-local-manual-search #'php-search-local-documentation) + +;; TODO: move implementation +;; (define-obsolete-function-alias 'php-search-local-documentation #'php-local-manual-search) + +(provide 'php-local-manual) +;;; php-local-manual.el ends here diff --git a/elpa/php-mode-1.23.0/php-mode-autoloads.el b/elpa/php-mode-1.24.0/php-mode-autoloads.el old mode 100755 new mode 100644 similarity index 97% rename from elpa/php-mode-1.23.0/php-mode-autoloads.el rename to elpa/php-mode-1.24.0/php-mode-autoloads.el index f23953b..bd28717 --- a/elpa/php-mode-1.23.0/php-mode-autoloads.el +++ b/elpa/php-mode-1.24.0/php-mode-autoloads.el @@ -71,6 +71,14 @@ toggle it if ARG is `toggle'; disable the mode otherwise. (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "php-face" '("php-annotations-annotation-face"))) +;;;*** + +;;;### (autoloads nil "php-local-manual" "php-local-manual.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from php-local-manual.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "php-local-manual" '("php-local-manual-search"))) + ;;;*** ;;;### (autoloads nil "php-mode" "php-mode.el" (0 0 0 0)) @@ -211,14 +219,6 @@ Return path to current PHP project." nil nil) (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "php-project" '("php-project-"))) -;;;*** - -;;;### (autoloads nil "php-util-buffer" "php-util-buffer.el" (0 0 -;;;;;; 0 0)) -;;; Generated autoloads from php-util-buffer.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "php-util-buffer" '("php-util-buffer-"))) - ;;;*** ;;;### (autoloads nil nil ("php-mode-pkg.el") (0 0 0 0)) diff --git a/elpa/php-mode-1.23.0/php-mode-debug.el b/elpa/php-mode-1.24.0/php-mode-debug.el old mode 100755 new mode 100644 similarity index 98% rename from elpa/php-mode-1.23.0/php-mode-debug.el rename to elpa/php-mode-1.24.0/php-mode-debug.el index 1e75aa1..35dfea4 --- a/elpa/php-mode-1.23.0/php-mode-debug.el +++ b/elpa/php-mode-1.24.0/php-mode-debug.el @@ -5,8 +5,7 @@ ;; Author: USAMI Kenta ;; URL: https://github.com/emacs-php/php-mode ;; Keywords: maint -;; Version: 1.23.0 -;; Package-Requires: ((emacs "24.3")) +;; Version: 1.24.0 ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/elpa/php-mode-1.24.0/php-mode-pkg.el b/elpa/php-mode-1.24.0/php-mode-pkg.el new file mode 100644 index 0000000..7b0d0b8 --- /dev/null +++ b/elpa/php-mode-1.24.0/php-mode-pkg.el @@ -0,0 +1,12 @@ +(define-package "php-mode" "1.24.0" "Major mode for editing PHP code" + '((emacs "25.2")) + :commit "7e1b55354ce41043148ce2d3270b032c318f0f90" :authors + '(("Eric James Michael Ritz")) + :maintainer + '("USAMI Kenta" . "tadsan@zonu.me") + :keywords + '("languages" "php") + :url "https://github.com/emacs-php/php-mode") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/php-mode-1.23.0/php-mode.el b/elpa/php-mode-1.24.0/php-mode.el old mode 100755 new mode 100644 similarity index 97% rename from elpa/php-mode-1.23.0/php-mode.el rename to elpa/php-mode-1.24.0/php-mode.el index 522b017..7c4480c --- a/elpa/php-mode-1.23.0/php-mode.el +++ b/elpa/php-mode-1.24.0/php-mode.el @@ -9,11 +9,11 @@ ;; Maintainer: USAMI Kenta ;; URL: https://github.com/emacs-php/php-mode ;; Keywords: languages php -;; Version: 1.23.0 -;; Package-Requires: ((emacs "24.3")) +;; Version: 1.24.0 +;; Package-Requires: ((emacs "25.2")) ;; License: GPL-3.0-or-later -(defconst php-mode-version-number "1.23.0" +(defconst php-mode-version-number "1.24.0" "PHP Mode version number.") ;; This program is free software; you can redistribute it and/or modify @@ -68,7 +68,6 @@ (c-add-language 'php-mode 'java-mode)) (require 'font-lock) -(require 'add-log) (require 'custom) (require 'etags) (require 'speedbar) @@ -81,6 +80,8 @@ (eval-when-compile (require 'regexp-opt) + (defvar add-log-current-defun-header-regexp) + (defvar add-log-current-defun-function) (defvar c-vsemi-status-unknown-p) (defvar syntax-propertize-via-font-lock)) @@ -317,6 +318,9 @@ In that case set to `NIL'." :tag "PHP Mode Enable Project Local Variable" :type 'boolean) +(defconst php-mode-cc-vertion + (eval-when-compile c-version)) + (defun php-mode-version () "Display string describing the version of PHP Mode." (interactive) @@ -471,12 +475,12 @@ In that case set to `NIL'." (c-lang-defconst c-primitive-type-kwds php '("int" "integer" "bool" "boolean" "float" "double" "real" - "string" "object" "void")) + "string" "object" "void" "mixed")) (c-lang-defconst c-class-decl-kwds "Keywords introducing declarations where the following block (if any) contains another declaration level that should be considered a class." - php '("class" "trait" "interface")) + php '("class" "trait" "interface" "enum")) (c-lang-defconst c-brace-list-decl-kwds "Keywords introducing declarations where the following block (if @@ -489,7 +493,7 @@ PHP does not have an \"enum\"-like keyword." php (append (c-lang-const c-class-decl-kwds) '("function"))) (c-lang-defconst c-modifier-kwds - php '("abstract" "const" "final" "static")) + php '("abstract" "const" "final" "static" "case")) (c-lang-defconst c-protection-kwds "Access protection label keywords in classes." @@ -518,6 +522,9 @@ PHP does not have an \"enum\"-like keyword." (c-lang-defconst c-lambda-kwds php '("function" "use")) +(c-lang-defconst c-inexpr-block-kwds + php '("match")) + (c-lang-defconst c-other-block-decl-kwds php '("namespace")) @@ -642,6 +649,23 @@ but only if the setting is enabled" (beginning-of-line) (if (looking-at-p "\\s-*->") '+ nil)))) +(defun php-c-looking-at-or-maybe-in-bracelist (&optional containing-sexp lim) + "Replace `c-looking-at-or-maybe-in-bracelist'. + +CONTAINING-SEXP is the position of the brace/paren/bracket enclosing +POINT, or nil if there is no such position, or we do not know it. LIM is +a backward search limit." + (cond + ((looking-at-p "{") + (save-excursion + (c-backward-token-2 2 t lim) + ;; PHP 8.0 match expression + ;; echo match ($var) |{ + ;; ↑ matches ↑ initial position + (when (looking-at-p (eval-when-compile (rx symbol-start "match" symbol-end))) + (cons (point) t)))) + (t nil))) + (c-add-style "php" `((c-basic-offset . 4) @@ -946,7 +970,7 @@ this ^ lineup" (eval-and-compile (defconst php-heredoc-start-re - "<<<\\(?:\\_<.+?\\_>\\|'\\_<.+?\\_>'\\|\"\\_<.+?\\_>\"\\)$" + "<<<[ \t]*\\(?:\\_<.+?\\_>\\|'\\_<.+?\\_>'\\|\"\\_<.+?\\_>\"\\)$" "Regular expression for the start of a PHP heredoc.")) (defun php-heredoc-end-re (heredoc-start) @@ -1110,6 +1134,13 @@ After setting the stylevars run hooks according to STYLENAME :syntax-table php-mode-syntax-table ;; :after-hook (c-update-modeline) ;; (setq abbrev-mode t) + + (unless (string= php-mode-cc-vertion c-version) + (user-error "CC Mode has been updated. %s" + (if (package-installed-p 'php-mode) + "Please run `M-x package-reinstall php-mode' command." + "Please byte recompile PHP Mode files."))) + (when php-mode-disable-c-mode-hook (setq-local c-mode-hook nil) (setq-local java-mode-hook nil)) @@ -1182,8 +1213,12 @@ After setting the stylevars run hooks according to STYLENAME (setq-local open-paren-in-column-0-is-defun-start nil) (setq-local defun-prompt-regexp "^\\s-*function\\s-+&?\\s-*\\(\\(\\sw\\|\\s_\\)+\\)\\s-*") - (setq-local add-log-current-defun-header-regexp - php-beginning-of-defun-regexp) + (setq-local add-log-current-defun-function nil) + (setq-local add-log-current-defun-header-regexp php-beginning-of-defun-regexp) + + (when (fboundp 'c-looking-at-or-maybe-in-bracelist) + (advice-add #'c-looking-at-or-maybe-in-bracelist + :override 'php-c-looking-at-or-maybe-in-bracelist)) (when (>= emacs-major-version 25) (with-silent-modifications @@ -1517,7 +1552,7 @@ a completion list." ("\\<\\(const\\)\\s-+\\(\\_<.+?\\_>\\)" (1 'php-keyword) (2 'php-constant-assign)) ;; Logical operator (!) - ("\\(![^=]\\)" 1 'php-logical-op) + ("\\(!\\)[^=]" 1 'php-logical-op) ;; Highlight special variables ("\\(\\$\\)\\(this\\)\\>" (1 'php-$this-sigil) (2 'php-$this)) diff --git a/elpa/php-mode-1.23.0/php-project.el b/elpa/php-mode-1.24.0/php-project.el old mode 100755 new mode 100644 similarity index 99% rename from elpa/php-mode-1.23.0/php-project.el rename to elpa/php-mode-1.24.0/php-project.el index 6e305a7..8f45ad6 --- a/elpa/php-mode-1.23.0/php-project.el +++ b/elpa/php-mode-1.24.0/php-project.el @@ -5,8 +5,7 @@ ;; Author: USAMI Kenta ;; Keywords: tools, files ;; URL: https://github.com/emacs-php/php-mode -;; Version: 1.23.0 -;; Package-Requires: ((emacs "24.3")) +;; Version: 1.24.0 ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/elpa/php-mode-1.23.0/php.el b/elpa/php-mode-1.24.0/php.el old mode 100755 new mode 100644 similarity index 99% rename from elpa/php-mode-1.23.0/php.el rename to elpa/php-mode-1.24.0/php.el index ce532c1..c9ba5e2 --- a/elpa/php-mode-1.23.0/php.el +++ b/elpa/php-mode-1.24.0/php.el @@ -4,10 +4,9 @@ ;; Author: USAMI Kenta ;; Created: 5 Dec 2018 -;; Version: 1.23.0 +;; Version: 1.24.0 ;; Keywords: languages, php ;; Homepage: https://github.com/emacs-php/php-mode -;; Package-Requires: ((emacs "24.3")) ;; License: GPL-3.0-or-later ;; This program is free software; you can redistribute it and/or modify diff --git a/elpa/ssh-config-mode-20210217.1051/ssh-config-keywords.txt b/elpa/ssh-config-mode-20210401.243/ssh-config-keywords.txt similarity index 100% rename from elpa/ssh-config-mode-20210217.1051/ssh-config-keywords.txt rename to elpa/ssh-config-mode-20210401.243/ssh-config-keywords.txt diff --git a/elpa/ssh-config-mode-20210217.1051/ssh-config-mode-autoloads.el b/elpa/ssh-config-mode-20210401.243/ssh-config-mode-autoloads.el similarity index 100% rename from elpa/ssh-config-mode-20210217.1051/ssh-config-mode-autoloads.el rename to elpa/ssh-config-mode-20210401.243/ssh-config-mode-autoloads.el diff --git a/elpa/ssh-config-mode-20210217.1051/ssh-config-mode-pkg.el b/elpa/ssh-config-mode-20210401.243/ssh-config-mode-pkg.el similarity index 61% rename from elpa/ssh-config-mode-20210217.1051/ssh-config-mode-pkg.el rename to elpa/ssh-config-mode-20210401.243/ssh-config-mode-pkg.el index 52ae2a8..3a4ba83 100644 --- a/elpa/ssh-config-mode-20210217.1051/ssh-config-mode-pkg.el +++ b/elpa/ssh-config-mode-20210401.243/ssh-config-mode-pkg.el @@ -1,4 +1,4 @@ -(define-package "ssh-config-mode" "20210217.1051" "Mode for fontification of ~/.ssh/config" 'nil :commit "820f60af17e71898303f4f3c2576f0619528a492" :authors +(define-package "ssh-config-mode" "20210401.243" "Mode for fontification of ~/.ssh/config" 'nil :commit "6d4f8d12c6a7e7ff776271f3656be5f3ba5a784e" :authors '(("Harley Gorrell" . "harley@panix.com")) :maintainer '("Harley Gorrell" . "harley@panix.com") diff --git a/elpa/ssh-config-mode-20210217.1051/ssh-config-mode.el b/elpa/ssh-config-mode-20210401.243/ssh-config-mode.el similarity index 93% rename from elpa/ssh-config-mode-20210217.1051/ssh-config-mode.el rename to elpa/ssh-config-mode-20210401.243/ssh-config-mode.el index 7941ac0..9de34c0 100644 --- a/elpa/ssh-config-mode-20210217.1051/ssh-config-mode.el +++ b/elpa/ssh-config-mode-20210401.243/ssh-config-mode.el @@ -194,6 +194,15 @@ Comments right above a 'Host' are considered to be about that Host." "Value for `imenu-generic-expression' in `ssh-config-mode'. Only show the first hostname in the menu.") +(defun ssh-config-completion-at-point () + "Function used for `completion-at-point-functions' in `ssh-config-mode'." + (interactive) + (let* ( + (bds (bounds-of-thing-at-point 'symbol)) + (start (car bds)) + (end (cdr bds))) + (list start end ssh-config-keywords . nil ))) + ;;;###autoload (define-derived-mode ssh-config-mode fundamental-mode @@ -209,7 +218,8 @@ Only show the first hostname in the menu.") font-lock-defaults '(ssh-config-font-lock-keywords nil t)) ;; (setq-local indent-line-function 'ssh-config-indent-line) - (setq-local imenu-generic-expression ssh-config-imenu-generic-expression)) + (setq-local imenu-generic-expression ssh-config-imenu-generic-expression) + (add-hook 'completion-at-point-functions 'ssh-config-completion-at-point nil 'local)) ;;;###autoload (progn @@ -249,11 +259,20 @@ Just sets the comment syntax.") "\\(@[-a-z]+ +\\|\\)" ;; hostnames & hashes: - ;; host.example.com,1.1.1.1 - ;; |1|hash|hash| ;; Just checking for chars, not parsing it. "\\(" + ;; host.example.com,1.1.1.1 + ;; |1|hash|hash| "[-0-9A-Za-z|=.,:*/+]+" + "\\|" + ;; [136.24.83.19]:2222 + "\\[[0-9]+.[0-9]+.[0-9]+.[0-9]+\\]:[0-9]+" + "\\|" + ;; fe80::3285:a9ff:fea7:6de3%en0 + "[0-9a-f:]+\\(?:%[a-z0-9]+\\)?" + "\\|" + ;; [fe80::3285:a9ff:fea7:6de3%en0]:2222 + "\\[[0-9a-f:]+\\(?:%[a-z0-9]+\\)?\\]:[0-9]+" "\\)" "[ \t]+" diff --git a/elpa/swiper-0.13.1.signed b/elpa/swiper-0.13.1.signed deleted file mode 100644 index 8631705..0000000 --- a/elpa/swiper-0.13.1.signed +++ /dev/null @@ -1 +0,0 @@ -Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) (trust undefined) created at 2020-12-03T04:05:02-0600 using RSA \ No newline at end of file diff --git a/elpa/swiper-0.13.1/.dir-locals.el b/elpa/swiper-0.13.1/.dir-locals.el deleted file mode 100644 index 3d5e818..0000000 --- a/elpa/swiper-0.13.1/.dir-locals.el +++ /dev/null @@ -1,14 +0,0 @@ -;;; Directory Local Variables -;;; For more information see (info "(emacs) Directory Variables") - -((nil - (bug-reference-bug-regexp . "#\\(?2:[[:digit:]]+\\)") - (bug-reference-url-format . "https://github.com/abo-abo/swiper/issues/%s") - (copyright-names-regexp . "Free Software Foundation, Inc\\.") - (sentence-end-double-space . t)) - (emacs-lisp-mode - (indent-tabs-mode . nil) - (outline-regexp . ";;[;*]+[\s\t]+") - ;; extra config here: https://github.com/abo-abo/oremacs/blob/github/modes/ora-elisp-style-guide.el - ;; (lisp-indent-function . common-lisp-indent-function) - )) diff --git a/elpa/swiper-0.13.1/ChangeLog b/elpa/swiper-0.13.1/ChangeLog deleted file mode 100644 index 98f1f40..0000000 --- a/elpa/swiper-0.13.1/ChangeLog +++ /dev/null @@ -1,5518 +0,0 @@ -2020-11-29 Oleh Krehel - - Rename swiper -> ivy - -2015-12-07 Oleh Krehel - - doc/ivy.org: Add "Variable Index" node - -2015-12-07 Oleh Krehel - - doc/ivy.texi: Re-export using adjusted texinfo exporter - - * doc/ivy.org: Add defopt/endopt macros. Change `ivy-wrap' and - `ivy-height' to defopt. - -2015-12-07 Oleh Krehel - - swiper.el: Bump version to 0.7.0 - -2015-12-07 Oleh Krehel - - doc/Changelog.org: Update up to 706349f - -2015-12-07 Oleh Krehel - - ivy.el (ivy-completing-read): Use completing-read-default for tmm - - Fixes #316 - -2015-12-07 Oleh Krehel - - counsel.el (counsel-tmm): New command - - * counsel.el (counsel-tmm-prompt): New defun. - (tmm-km-list): Define this variable here, since `tmm-get-keymap' - modifies a global variable (yuck!). - - Re #316 - -2015-12-07 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Add vc-dir-mode - - Re #19 - -2015-12-04 Oleh Krehel - - Use :caller for ivy-re-builders-alist - - * counsel.el (counsel-M-x): Add :caller. - - * ivy.el (ivy--reset-state): Use :caller. - -2015-12-04 Oleh Krehel - - swiper.el (swiper--update-input-ivy): Add a work-around for "M-j" - - When `ivy-yank-word' is called, don't move to the line of the current - candidate. We're already there anyway. And not moving helps when there - are multiple occurrences of the current input on the current line. - - Fixes #314 - -2015-12-02 Oleh Krehel - - ivy.el: Structure all faces into ivy-faces custom group - -2015-11-29 Oleh Krehel - - Fix due to visual-line-mode weirdness - - * swiper.el (swiper--candidates): Under a specific random condition, - (line-move 1) from the beginning of line doesn't move to the beginning - of the next visual line. - - This change fixes it, but will result in an even slower startup when - `visual-line-mode' is active. - - Fixes #313 - -2015-11-29 Oleh Krehel - - swiper.el: Use show-all if outline-show-all isn't there - - Fixes #312 - -2015-11-29 Oleh Krehel - - Fix ivy-resume issue caused by the recursive calls change - - * ivy.el (ivy-read): recursive-ivy-last is only set if there's an active - minibuffer window. If this check isn't made, it causes the previous - `ivy-last' to be reset after the current one, so `ivy-resume' would - resume not the last command. - -2015-11-29 Oleh Krehel - - Fix the preselect for (swiper "one") again - - * ivy.el (ivy--reset-state): Take into account :preselect being integer. - This means that it's void once the candidates are filtered over - :initial-input. - - Fixes #292 - -2015-11-27 Oleh Krehel - - Fix the issue caused by recursive swiper calls - - * swiper.el (swiper--ivy): Look at the return result of `ivy-read'; - looking at `ivy-exit' no longer works. - - Fixes #311 - -2015-11-27 Oleh Krehel - - Remove 'field text property for twittering-mode - - * swiper.el (swiper--candidates): Update. - (swiper-font-lock-ensure): Add `twittering-mode'. - - Fixes #310 - -2015-11-27 Oleh Krehel - - Enable recursive swiper calls - - * ivy.el (ivy-read): Don't need to be in the minibuffer to do a - recursive store/restore. - - (ivy--reset-state): Avoid nil string while testing. - - Fixes #309 - -2015-11-27 Oleh Krehel - - doc/Changelog.org: Update up to 2bec99d - -2015-11-27 Oleh Krehel - - Fixes on the previous docstring edits - -2015-11-27 sjLambda - - Edit documentation strings in ivy.el - - Fixes #308 - -2015-11-26 Oleh Krehel - - Ease production of functions like ivy-format-function-default - - * ivy.el (ivy--format-function-generic): New defun. - (ivy-format-function-default): - (ivy-format-function-arrow): - (ivy-format-function-line): Use `ivy--format-function-generic'. - - * counsel.el (counsel--M-x-transformer): Add an extra space to simplify - the logic. - - Re #307 - -2015-11-26 Stephen Whipple - - Convert ivy formatting functions to dotted pairs. - - `ivy-format-function' now expects to operate on dotted pairs - representing (stub . extra), where `stub' is the original candidate and - `extra' is any extra information that has been added by counsel or other - libraries. - - The format function can differentiate between the original stub and - extra information and choose how to display the result to the user. - -2015-11-25 Stephen Whipple - - Update ivy format functions. - - `ivy-format-function' now accessible via Customize system. - - `ivy-format-function-default' and `ivy-format-function-arrow' - simplified. - - New format `ivy-format-function-line' added. - - `counsel-M-x' restores `ivy-format-function' before executing command. - - Fixes #306 - -2015-11-25 Oleh Krehel - - Add counsel-grep - - * ivy.el (ivy--reset-state): Don't push preselect onto collection for - :dynamic-collection. - (ivy-recompute-index-swiper-async): New defun. It's useful for - re-anchoring on collections produced async processes. The major - difference from `ivy-recompute-index-swiper' is using `equal' instead of - `eq'. - - * counsel.el (counsel--async-sentinel): Add index recomputing logic. - When `ivy--old-cands' are null, recompute the index according to - :preselect, otherwise try `ivy--recompute-index'. - (counsel-grep): New command. Very similar to `swiper', except calls an - external process for each key update. Should be much faster for very - large files, both for startup and for matching. For smaller files, it's - less convenient. - (counsel-grep-function): New defun. - (counsel-grep-action): New defun. - - Fixes #299 - -2015-11-24 Oleh Krehel - - Ivy-resume should restore the buffer for swiper - - * ivy.el (ivy-resume): Update. - - Fixes #302 - -2015-11-24 Oleh Krehel - - Fix broken candidate index in ivy-resume - - * ivy.el (ivy--reset-state): When given initial-input, call - `ivy--preselect-index' on candidates filtered by initial-input. This - is important for `ivy-resume'. - -2015-11-24 Samuel Loury - - Warn the user about the behavior of ivy--regex-ignore-order - - Fixes #296 Fixes #305 - -2015-11-24 Oleh Krehel - - Minor fixes to ivy.org and export to ivy.texi - - Fixes #304 - -2015-11-24 sjLambda - - ivy.org manual edits - -2015-11-24 kovrik - - Fix `counsel-ag` on Windows - -2015-11-22 Oleh Krehel - - swiper.el (swiper--action): push-mark only if exited the minibuffer - - "C-M-n" and "C-M-p" will no longer push mark and annoy with messages. - -2015-11-22 Oleh Krehel - - Perform string-match in the original buffer - - * ivy.el (ivy--exhibit): Wrap in `with-current-buffer' - `ivy-state-buffer'. - (ivy-recompute-index-swiper): Reset to the candidate at the current line - number, in case the previous regex resulted in 0 candidates. - - Fixes #298 - -2015-11-21 Oleh Krehel - - swiper.el (swiper--candidates): Require outline - - Fixes #297 - -2015-11-20 Oleh Krehel - - Fix the preselect for (swiper "one") - - * ivy.el (ivy--reset-state): Ignore INITIAL-INPUT on the first - step. Then all `ivy--filter' on the second step. - (ivy--preselect-index): Change arglist. No longer takes INITIAL-INPUT. - (ivy--recompute-index): Update the call to `ivy--preselect-index'. - - Fixes #292 - -2015-11-19 Oleh Krehel - - ivy.el (ivy-alt-done): Split into smaller defuns - - * ivy.el (ivy--directory-done): New defun. - (ivy-alt-done): Forward to `ivy--directory-done'. - -2015-11-19 Oleh Krehel - - ivy.el (ivy-alt-done): Refactor - - Collect all `ivy--directory' branches into a single `cond'. - -2015-11-19 Oleh Krehel - - Allow access to TRAMP from "// C-j" - - * ivy.el (ivy-alt-done): Match not only `ivy-text' but also - `ivy--current' for TRAMP regex. - - Re #285 - -2015-11-18 Stephen Whipple - - Improve ivy TRAMP support - -2015-11-18 Oleh Krehel - - ivy.el (ivy-completing-read): Fix off by one - - Re #295 - -2015-11-18 Oleh Krehel - - Switch to using ivy-exit-with-action - - * ivy.el (ivy-exit-with-action): Add a missing quote. - (ivy--cd-maybe): Use `ivy-exit-with-action'. - - * counsel.el (counsel-find-symbol): - (counsel--info-lookup-symbol): - (counsel-git-grep-query-replace): Use `ivy-exit-with-action'. - - * swiper.el (swiper-query-replace): - (swiper-mc): Use `ivy-exit-with-action'. - - The previous approach was overwriting the action list, so when - `ivy-resume' was called, only a single action was present. The new - approach doesn't have this bug. - - So now it's possible to e.g. `counsel-describe-function' -> "M-o d" -> - `ivy-resume' -> "M-o o" -> `ivy-resume' -> "M-o i". - -2015-11-18 Samuel Loury - - Make ivy-completing-read handle history as cons - - The ivy-read function assumes that history is a symbol, hence - ivy-completing-read now makes sure that a symbol is given to ivy-read. - - Moreover, it makes sure that the value of initial-input is coherent with - the value of the HISTPOS part of the history variable if it exists. - - Fixes #295 - -2015-11-17 Oleh Krehel - - swiper.el: Modify the behavior with org-mode and visual-line-mode - - * swiper.el (swiper--candidates): Set `swiper-use-visual-line' even for - `org-mode'. In that case, reveal all text to prevent `line-move' - weirdness. - (swiper--ivy): Use `swiper-use-visual-line'. - - Re #291 Re #227 - -2015-11-16 Oleh Krehel - - README.md: Add more bindings - -2015-11-16 Oleh Krehel - - Add precise preselect for swiper with visual-line-mode - - * swiper.el (swiper--ivy): Use `count-screen-lines' to calculate the - visual line number. - - Fixes #291 - -2015-11-16 Oleh Krehel - - Intermediate fix for :preselect with visual-line-mode - - * swiper.el (swiper--ivy): Use `beginning-of-visual-line' and - `end-of-visual-line'. This should fix the preselect problem for - non-duplicate buffer lines. - - For duplicate buffer lines, a `visual-line-number-at-pos' function is - necessary. I don't currently know how to implement such a function in an - efficient way. The naive implementation could be pretty inefficient, - comparable to doubling `swiper' startup time with `visual-line-mode'. - - Re #291 - -2015-11-15 Oleh Krehel - - Fix swiper preselect issue with similar or identical lines - - * ivy.el (ivy--preselect-index): Allow PRESELECT to be an integer. - - * swiper.el (swiper--anchor): - (swiper--len): Remove unused defvar. - (swiper--init): Update. - (swiper--ivy): Set PRESELECT to `line-number-at-pos'. - - Fixes #290 - -2015-11-14 Oleh Krehel - - swiper.el (swiper-all): New command to swiper all file buffers - - * swiper.el (swiper--candidates): Add NUMBERS-WIDTH arg. It could be - done better by calculating the line count of each buffer and then - getting the max of that, but this way is faster, since the collections - are traversed only once. - (swiper-multi): Update. - (swiper-all): New command. This is like `swiper-multi' where the buffer - list is pre-selected to be all file visiting buffers. - (swiper--multi-candidates): New defun. - (swiper-multi-action-1): Use `swiper--multi-candidates'. - (swiper-multi-action-2): Update - the line number is in the 'display - property of the first char. - - Re #234 - -2015-11-14 Oleh Krehel - - swiper.el (swiper--candidates): Replace "\t" with " " - - This will allow the minibuffer strings to align nicer for - `swiper-multi'. - -2015-11-14 Oleh Krehel - - ivy.el (ivy--truncate-string): New defun - - * ivy.el (ivy-format-function-default): Use `ivy--truncate-string'. - -2015-11-14 Oleh Krehel - - counsel.el (counsel-locate): Add INTIAL-INPUT arg - - Fixes #289 - -2015-11-13 Oleh Krehel - - ivy.el (ivy--sort-files-by-date): Fix due to destructive cl-sort - -2015-11-13 Oleh Krehel - - Allow to sort files by last modification time. - - * ivy.el (ivy--sort-files-by-date): New defun. - - Example of use: - - (add-to-list - 'ivy-sort-matches-functions-alist - '(read-file-name-internal . ivy--sort-files-by-date)) - - This will result in e.g. `find-file' or `counsel-find-file' sorting - files by last modification time. - - Fixes #213 - -2015-11-13 Oleh Krehel - - Allow user-specified matched candidate sorting - - * ivy.el (ivy-prefix-sort): Remove defcustom. - (ivy--filter): Forward sorting of matched candidates to `ivy--sort'. - (ivy-sort-matches-functions-alist): New defcustom. - (ivy--sort): New defun. - - Fixes #269 Fixes #265 - -2015-11-13 Oleh Krehel - - ivy.el (ivy-prefix-sort): New defcustom, off by default for now - - * ivy.el (ivy--filter): When `ivy-prefix-sort' is non-nil, additionally - sort the matching candidates with `ivy--prefix-sort'. - (ivy--prefix-sort): New defun. - - Fixes #265 - -2015-11-13 Oleh Krehel - - ivy.el (ivy-sort-functions-alist): Update doc - - Mention `ivy-sort-max-size'. - -2015-11-13 Oleh Krehel - - swiper.el: Add support for evil-jumper/backward - - * swiper.el (evil-jumper--set-jump): Declare. - (swiper--init): When `evil-jumper-mode' is on, call - `evil-jumper--set-jump'. - - * ivy.el (counsel-git-grep-cmd): Declare to silence the byte compiler. - - Fixes #268 - -2015-11-13 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Add eww-mode - -2015-11-12 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Add occur-mode - -2015-11-11 Oleh Krehel - - ivy.el (ivy-occur): Give full counsel-git-grep cands - - This means that the " | head -n 200" speed-up isn't used and full - candidates are returned. - -2015-11-11 Oleh Krehel - - ivy.el (ivy-occur-mode-map): Bind "q" to quit-window - -2015-11-11 Oleh Krehel - - Allow counsel-git-grep -> ivy-occur -> wgrep - - * ivy.el (ivy-exit-with-action): New defun. - (ivy-occur-action): Remove defvar. It's part of `ivy-occur-last' now. - (ivy-occur-last): Update doc. - (ivy-occur-map): Rename to `ivy-occur-mode-map'. - (ivy-occur-mode): New major mode. - (ivy-occur): When the caller is `counsel-git-grep', enter `grep-mode'; - otherwise enter the new `ivy-occur-mode'. For `wgrep' to work, two - things are changed: candidates need to start on the 5th line, and - candidates need to be prefixed with "./". - (ivy-occur-read-action): New command, bound to "a". - (ivy-occur-dispatch): New command, bound to "o". - (ivy-occur-press): Update to work with `grep-mode'. - (ivy-occur-grep-mode-map): New defvar. - (ivy-occur-grep-mode): New major mode. Basically, it's grep-mode with - "C-x C-q" bound to `wgrep-change-to-wgrep-mode'. - -2015-11-11 Oleh Krehel - - ivy.el (ivy-dispatching-done): Don't set action permanently - -2015-11-11 Oleh Krehel - - counsel.el (counsel--find-symbol): Silence byte compiler - -2015-11-11 Oleh Krehel - - swiper.el (swiper-toggle-face-matching): Add and bind to "C-c C-f" - - * swiper.el (swiper-map): Bind `swiper-toggle-face-matching' to - "C-c C-f". - (swiper-invocation-face): New defvar. - (swiper--ivy): Set `swiper-invocation-face'. - (swiper-toggle-face-matching): Toggle `ivy-state-matcher' between nil - (the initial value) and 'swiper--face-matcher. - (swiper--face-matcher): New defun. In addition to filtering CANDIDATES - by having them match REGEXP, also ensure that every match has - `swiper-invocation-face'. - - Example of usage: - - 1. Move point to a variable with e.g. `font-lock-keyword-face' and "C-s" - . - - 2. Use "C-c C-f" to filter the candidates further by selecting only the - ones that have `font-lock-keyword-face'. Note that "M-q" - (`swiper-query-replace') is also affected by the filtering. - - 3. Use "C-c C-f" to toggle the filtering off. - - Fixes #288 - -2015-11-10 Oleh Krehel - - ivy.el (ivy-alt-done): Ensure the trailing slash for directories - - * ivy.el (ivy-alt-done): Update. - -2015-11-06 Oleh Krehel - - counsel.el (counsel-M-x): Show current-prefix-arg in the prompt - - * counsel.el (counsel--M-x-prompt): New defun. - (counsel-M-x): Update. - - Fixes #287 - -2015-11-06 Oleh Krehel - - doc/ivy.org: Start writing a manual - -2015-11-05 Stephen Whipple - - Fix directory validity check - - Directory validity check should be based on `ivy-text` and - `ivy--directory` rather than only `ivy-text`. - - Fixes #283 Fixes #284 - -2015-11-05 Oleh Krehel - - Add a better ivy-occur pulse to swiper and counsel-git-grep - - * ivy.el (ivy-occur-press): Bind `ivy-exit' to 'done, so that - `swiper--add-overlays' called by ACTION don't do anything. - Call another `swiper--add-overlays' for swiper and counsel-git-grep, - limited to the current line. Call `swiper--cleanup' with a delay of 1 - second. - -2015-11-05 Oleh Krehel - - swiper.el (swiper--add-overlays): Take extra WND arg - -2015-11-05 Oleh Krehel - - counsel.el (counsel-git-grep-query-replace): Should exit minibuffer - -2015-11-05 Oleh Krehel - - Input "/sudo::" goes to current directory instead of root's home - - * ivy.el (ivy-alt-done): Update. - - Re #283 - -2015-11-05 Oleh Krehel - - Fix /ssh: and /sudo:: broken in 71695df - - * ivy.el (ivy-alt-done): `file-directory-p' errors when given "/ssh:" or - "/sudo::". - - Re #283 - -2015-11-05 Oleh Krehel - - Rebind ivy-occur to "C-c C-o" and "C-o u" - - * ivy.el (ivy-minibuffer-map): Update. - - * ivy-hydra.el (hydra-ivy): Update. - - Wouldn't want to violate the "C-c LETTER" convention. - -2015-11-04 Oleh Krehel - - counsel.el (counsel-M-x): Add "definition" action - -2015-11-04 Oleh Krehel - - ivy.el (ivy-occur-press): Extend with-ivy-window - - ivy-occur-action should be called in (ivy--get-window ivy-last). - - This means, for purposes of e.g. `counsel-find-symbol' or - `lispy--action-jump` that if *ivy-occur* is the only window, it will be - re-used. But if the user wants *ivy-occur* not to get buried, then - having at least 2 windows solves that problem. - -2015-11-04 Oleh Krehel - - ivy.el (ivy-minibuffer-map): Bind "C-M-a" to ivy-read-action - -2015-11-04 Oleh Krehel - - counsel.el (counsel-rhythmbox): Add :caller - - This results in more descriptive *ivy-occur* buffers. - -2015-11-04 Oleh Krehel - - ivy.el (ivy-occur-press): Work with counsel-rhythmbox - - > (cdr (assoc str coll)) - - Special behavior for `counsel-rhythmbox'. Maybe not taking `cdr' is the - right thing, but that's how Helm and `helm-rhythmbox-play-song' works. - -2015-11-04 mike - - fix 1-too-far scrolling issue - - Functions `ivy-scroll-up-command' and `ivy-scroll-down-command' would - scroll 1 unit too far. So one item in the list would be skipped and - never seen for each scroll. - -2015-11-04 Oleh Krehel - - Pulse after ivy-occur-press - - * ivy.el (ivy-state): New field TEXT. - (ivy-occur): Add `ivy-text' to the name of the buffer. Also store - `ivy-text' in `ivy-occur-last'. Might be needed in the future for a more - specific pulse. - (ivy-occur-press): Pulse the selected line. - -2015-11-03 Oleh Krehel - - Make ivy work with enable-recursive-minibuffers - - * ivy.el (ivy-read): Fix the doc of DYNAMIC-COLLECTION. Store the old - `ivy-last' in case `ivy-read' is called while inside the minibuffer. - Restore it after `ivy-call'. - -2015-11-03 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude debbugs-gnu-mode - -2015-11-03 Oleh Krehel - - ivy.el (ivy-occur): Add and bind to "C-c o" - - * ivy.el (ivy-minibuffer-map): Update. - (ivy-occur-action): - (ivy-occur-last): - (ivy-occur-map): New defvar. - (ivy-occur): New command. - (ivy-occur-click): New command bound to mouse click. - (ivy-occur-press): New command bound to "RET" press. - - `ivy-occur' allows to store the current completion session for further - use. An unlimited amount of these sessions can be used, each in its own - buffer. - -2015-11-03 Oleh Krehel - - ivy.el (with-ivy-window): Ensure window is live - - * ivy.el (ivy--get-window): New defun. - -2015-11-03 Oleh Krehel - - ivy.el (ivy-state): Add a new field BUFFER - - * ivy.el (ivy-resume): Update. - (ivy-read): Update. - - * swiper.el (swiper--action): Use `ivy-state-buffer'. - -2015-11-03 Oleh Krehel - - swiper.el (swiper-mc): Update - -2015-11-02 Oleh Krehel - - Highlight modified file buffers with 'ivy-modified-buffer face - - * ivy.el (ivy-modified-buffer): New face, blank by default. - (ivy--format): When the collection is 'internal-complete-buffer, - highlight unsaved file visiting buffers with 'ivy-modified-buffer. - - Fixes #280 - - Example custom setting for 'ivy-modified-buffer: - - (custom-set-faces - '(ivy-modified-buffer ((t (:background "#ff7777"))))) - -2015-11-01 Oleh Krehel - - ivy.el (ffap): Move require - -2015-10-31 Oleh Krehel - - counsel.el (counsel-git-grep-query-replace): Add and bind to "M-q" - - * counsel.el (counsel-git-grep-map): Bind "M-q" to - `counsel-git-grep-query-replace'. - (counsel-git-grep-query-replace): New command. Perform `query-replace' - on all matches of git-grep in all buffers. - -2015-10-31 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude eems-stream-mode - - Re #19 - -2015-10-30 Oleh Krehel - - "C-x C-f M-n" can call ffap-url-fetcher when at URL - - * ivy.el (ivy--cd-maybe): Check if the input is a valid URL. If so, exit - immediately by calling (funcall ffap-url-fetcher url). Otherwise, do the - usual `ivy--cd' thing. - -2015-10-30 Oleh Krehel - - ivy.el: "M-n" should prefer url at point to symbol at point - - * ivy.el (ivy--reset-state): Update. - -2015-10-30 Oleh Krehel - - counsel.el (counsel--find-symbol): Resolve name clash better - - * counsel.el (counsel--find-symbol): When the symbol is both bound and - fbound, prefer the fbound one, unless the :caller is - `counsel-describe-variable'. - (counsel-describe-variable): Declare :caller. - (counsel-describe-function): Declare :caller. - - One example is going to the definition of `isearch-forward' (also with - `counsel-M-x'). - -2015-10-30 Oleh Krehel - - Improve the preselect index in ivy-resume - - * ivy.el (ivy--recompute-index): Don't change the ivy--index that was - set in `ivy--reset-state' by `ivy-resume'. - - With this, it's possible to e.g. " f", enter "for", navigate to - "format" and press "C-g". Calling `ivy-resume' will point to "format" - still. - -2015-10-30 Oleh Krehel - - Use a specific blending method for dark themes - - * colir.el (colir-blend): Use 'colir-compose-soft-light for dark themes. - - Fixes #278 - -2015-10-28 Oleh Krehel - - Rename and move the minibuffer faces - - * swiper.el (swiper-minibuffer-match-face-1): - (swiper-minibuffer-match-face-2): - (swiper-minibuffer-match-face-3): - (swiper-minibuffer-match-face-4): Transform into obsolete aliases. - - * ivy.el (ivy-minibuffer-match-face-1): - (ivy-minibuffer-match-face-2): - (ivy-minibuffer-match-face-3): - (ivy-minibuffer-match-face-4): New renamed faces. - (ivy-minibuffer-faces): Rename from `swiper-minibuffer-faces'. - - Fixes #276 - -2015-10-24 Oleh Krehel - - counsel.el (counsel-git): Update default-directory - -2015-10-23 Oleh Krehel - - ivy-immediate-done should use ivy--directory - - * ivy.el (ivy-immediate-done): When completing file names, expand the - file name properly. - - Fixes #275 - -2015-10-23 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Amend exception list - - Re #19 - -2015-10-22 Oleh Krehel - - ivy.el (ivy-alt-done): Fix up last commit - -2015-10-22 Oleh Krehel - - "C-j" should not stop completion for a pasted file path - - * ivy.el (ivy-alt-done): If you paste a file path, it won't match - anything in the current directory. Previously, "C-j" would open dired - for that path. Now, "C-j" will switch to the pasted directory and - continue completion. - - This behavior conforms to `ido-find-file'. - -2015-10-22 Oleh Krehel - - Fix pasting file paths on Windows - - * ivy.el (ivy--exhibit): Update. - - Fixes #272 - -2015-10-22 Stephen Whipple - - Fix Custom menus - - Custom menus for `ivy-virtual-abbreviate' and `ivy-sort-functions-alist' - now display a better user interface. - - Fixes #274 - -2015-10-20 Oleh Krehel - - Add a test for the perfect match logic - - Re #270 - -2015-10-20 Oleh Krehel - - Bring back the lost perfect match logic - - * ivy.el (ivy--recompute-index): Don't defer the perfect match logic to - `ivy-index-functions-alist'. - (ivy-recompute-index-swiper): Simplify. - - Once again, if the minibuffer text becomes `equal' to one of the - candidates, that candidate will be selected. - - Fixes #270 - -2015-10-20 Oleh Krehel - - ivy.el (ivy-resume): Pass caller - - Fixes #245 - -2015-10-19 Oleh Krehel - - ivy.el (ivy-partial): Fix for fuzzy completion - - Postfix doesn't always work if the completion is fuzzy, so check if - `string-match' succeeds. - - Fixes #266 - -2015-10-19 Oleh Krehel - - Fix the count in user-specified counsel-git-grep - - * counsel.el (counsel--gg-count): Generate the count command from - `counsel-git-grep-cmd' by replacing "--full-name" with "-c". - - Re #244 - -2015-10-18 Oleh Krehel - - ivy.el (ivy-sort-functions-alist): Upgrade to defcustom - - Add the proper :type. - -2015-10-17 Oleh Krehel - - ivy.el (ivy-extra-directories): Improve :type - -2015-10-16 Jon Miller - - counsel.el (counsel-ag): Add initial-directory - - Support alternative initial directory which helps other packages call - this function with their unique starting directory. - -2015-10-16 Oleh Krehel - - Don't re-anchor to matching old candidate if flx is on - - * ivy.el (ivy--recompute-index): If `flx' is in position to select the - "best" candidate, don't re-anchor to the still-matching previous - candidate. - - Fixes #263 - -2015-10-15 Oleh Krehel - - Add feedback for long-running async processes - - * counsel.el (counsel--async-time): New defvar. - (counsel--async-filter): New defun. - (counsel--async-command): Use `counsel--async-filter'. - - Each time 0.5s pass after the last input, if the external process hasn't - finished yet, update minibuffer with the amount of candidates collected - so far. This is useful to see that long running commands like - `counsel-locate' or `counsel-ag' (when in a very large directory) aren't - stuck. - -2015-10-14 Oleh Krehel - - ivy-test.el (swiper--re-builder): Update - - Due to last commit - -2015-10-14 Oleh Krehel - - swiper.el (swiper--re-builder): Fix "^a" -> "^" case - - Fixes #262 - -2015-10-14 Oleh Krehel - - Adjust the swiper regexp builder for the display change - - * swiper.el (swiper--re-builder): Update. The old re-builder was for - when the line numbers were part of the candidates. Now the line - numbers are the text properties of the candidates. - - Fixes #262 - -2015-10-14 Oleh Krehel - - Try to fix the previous commit - - * ivy.el (ivy--exhibit): Update. - - Sometimes the cursor randomly moves to the start of the read-only prompt - and it's impossible to move it. - -2015-10-14 Oleh Krehel - - Fix "C-x h" selection and "C-b" bug - - * ivy.el (ivy--exhibit): Add another `constrain-to-field'. - - This ensures that the point doesn't cross into the prompt text. - Previously, there was a bug that pressing "C-b" once more when already - at the start of the input set `ivy-text' to "", i.e. ignoring the - minibuffer input. - -2015-10-14 Oleh Krehel - - Fix window selection in counsel-locate - - * counsel.el (counsel-locate): Use `with-ivy-window'. - -2015-10-14 Oleh Krehel - - swiper.el (swiper-mc): Add and bind to "C-7" - - * swiper.el (swiper-map): Update. - (swiper-mc): New command. - (swiper--ivy): Use :action. - (swiper--action): Update arglist. - -2015-10-10 Oleh Krehel - - ivy.el (ivy-case-fold-search): New defvar - - * ivy.el (ivy--reset-state): Set `ivy-case-fold-search' to 'auto. - (ivy-toggle-case-fold): New command. - (ivy--filter): Use `ivy-case-fold-search' to determine - `case-fold-search'. - - * ivy-hydra.el (hydra-ivy): Bind "C" to `ivy-toggle-case-fold'. - - Fixes #259 - -2015-10-10 Oleh Krehel - - ivy-count-format must be an empty string instead of nil - - Using an empty string is easier. No longer needed to check for nil when - using `string-match', `concat' etc. - - * doc/Changelog.org: Update. - - * ivy.el (ivy-count-format): Update doc and customize type. - (ivy--reset-state): Error if `ivy-count-format' nil is encountered. - - Fixes #257 Re #188 - -2015-10-09 Oleh Krehel - - Fix the count when git-grep for "->foo" - - * counsel.el: For some reason, "-" gets interpreted in a bad way. - Escaping it as "\-" makes it work fine. - -2015-10-09 Oleh Krehel - - ivy.el (ivy--recompute-index): Fixup - - Fixes #258 - -2015-10-09 Oleh Krehel - - Don't reset the match to first if the current one still works - - * ivy.el (ivy--recompute-index): If the old match is still located in - the current matches after the change in input, keep it selected. - - * ivy-test.el (ivy-read): Add test. - - Fixes #258 - -2015-10-09 Oleh Krehel - - ivy.el (ivy-virtual-abbreviate): New defcustom - - * ivy.el (ivy--virtual-buffers): Update. - - Fixes #255 - -2015-10-08 Oleh Krehel - - ivy-hydra.el (hydra-ivy): Make the docstring a rectangle - -2015-10-08 Oleh Krehel - - Move setq ivy--index to ivy--recompute-index - - * ivy.el (ivy--recompute-index): Move the setq statement here, so that - the customization functions have less internal variables to deal with. - (ivy-recompute-index-swiper): Update. - (ivy-recompute-index-zero): Update. - - Re #253 - -2015-10-08 Oleh Krehel - - ivy.el (ivy-index-functions-alist): New variable - - * ivy.el (ivy-state): Add `caller' field. - (ivy-read): Add `caller' keyword arg; update docstring. Use - `ivy--recompute-index'. - (ivy--recompute-index): New defun, dispatch according to `caller' and - `ivy-index-functions-alist'. - (ivy-recompute-index-swiper): New defun. - (ivy-recompute-index-zero): New defun. - - Fixes #253 - -2015-10-08 Oleh Krehel - - swiper.el: Add a lot of avy declares - -2015-10-08 Oleh Krehel - - ivy.el (ivy-dispatching-call): Add and bind to "C-M-o" - - * ivy.el (ivy-minibuffer-map): Update. - (ivy-read-action): New command. - (ivy-dispatching-done): Update. - - * ivy-hydra.el (hydra-ivy): Bind `ivy-read-action' to "a". - - Re #254 - -2015-10-07 Oleh Krehel - - Fix preselect for input "^" - - * ivy.el (ivy--filter): Update. - - Notably, e.g. `counsel-describe-variable' should properly preselect - variable at point. - -2015-10-07 Oleh Krehel - - ivy.el (ivy-last): Update docstring - -2015-10-07 Oleh Krehel - - ivy.el (ivy-use-virtual-buffers): Update docstring - -2015-10-07 Oleh Krehel - - Default ivy-display-style to 'fancy for Emacs>=24.5 - - * ivy.el (ivy-display-style): Update. - -2015-10-07 Oleh Krehel - - ivy.el (ivy-count-format): Extend customize choices - -2015-10-07 Oleh Krehel - - Fix ivy-state-preselect for file name completion - - * ivy.el (ivy--preselect-index): Add a check for null preselect. - (ivy--filter): Use `ivy--preselect-index' instead of `cl-position'. The - reason is that the collection contains e.g "foo/" while the preselect is - "foo". - -2015-10-07 Oleh Krehel - - Fix "M-o k" when switching buffers - - * ivy.el (ivy-call): Check if (active-minibuffer-window) is non-nil - before switching. - -2015-10-07 Oleh Krehel - - Adjust ivy-state-preselect for file name completion - - * ivy.el (ivy--reset-state): Since `ivy--index' is now recomputed more, - `ivy-state-preselect' needs to be in the collection properly, so that - `ivy--index' is set to preselect whenever the input is empty. - -2015-10-07 Oleh Krehel - - ivy.el (ivy--filter): Fix typo - - Re #253 - -2015-10-06 Oleh Krehel - - ivy.el (ivy--filter): Anchor only for swiper - - * ivy-test.el (ivy-read): Add tests. Except for `swiper', when the input - changes `ivy-index' should usually be 0. - - Fixes #231 - -2015-10-06 Oleh Krehel - - ivy.el (ivy--insert-prompt): Use newlines instead of truncation - - When the prompt string is longer than window-width, insert newlines - appropriately so that the whole prompt fits in the window without - scrolling. Finally, when prompt+entered text would be larger than - window-width, reformat the prompt so that entered text starts on a - newline. When completing file names, move the whole path to a new line - in that case. - - Fixes #252 - -2015-10-06 Oleh Krehel - - Support hash tables in ivy-read - - * ivy.el (ivy--reset-state): `all-completions' also works fine for hash - tables, so start using it. - - Hash tables as collections are rare. One example is "C-c C-w" in *rcirc* - (`rcirc-cmd-whois'). - -2015-10-06 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude help-mode - - Fixes #248 - -2015-10-05 Oleh Krehel - - Fix up visual-line-mode limitation logic - - * swiper.el (swiper-use-visual-line): New defvar. - (swiper--candidates): - (swiper--update-input-ivy): - (swiper--action): Update. - - Re #227 - -2015-10-04 Oleh Krehel - - swiper.el (swiper--candidates): Avoid line-move for large buffers - - Re #227 - -2015-10-04 PythonNut - - swiper-avy: show avy hints in minibuffer as well - -2015-10-03 Oleh Krehel - - Fix "End of buffer" for swiper and visual-line-mode - - Fixes #247 - -2015-10-03 Oleh Krehel - - Customize ivy-avy and fix compile warnings - - * ivy.el (ivy-avy): Require avy. Allow the user to customize `avy-keys', - `avy-background' and `avy-style' (but prefer 'pre to 'at-full, since - it doesn't obscure any letters). Don't issue an extra `ivy-call'. - - Fixes #246 - -2015-10-03 PythonNut - - Implement ivy-avy - -2015-10-02 Oleh Krehel - - counsel.el (counsel--gg-count): Fix for "'" in query - - Since "'" is used for quoting in bash, it needs to be replaced with "''" - . - -2015-10-02 Oleh Krehel - - Use forward-line instead of line-move if possible - - * swiper.el (swiper--candidates): - (swiper--update-input-ivy): - (swiper--action): `line-move' is much slower than `forward-line'. Use it - only if `visual-line-mode' is on. - -2015-10-02 Oleh Krehel - - counsel.el (counsel--gg-candidates): Use counsel-git-grep-cmd - -2015-10-02 Oleh Krehel - - Fix counsel-git-grep not updating to 0 candidates - - * counsel.el (counsel--gg-candidates): `ivy--all-candidates' should not - be nil in order for `ivy--exhibit' to update the minibuffer. - -2015-10-02 Oleh Krehel - - Make swiper compatible with visual-line-mode - - * swiper.el (swiper--candidates): Use `end-of-visual-line' and - `line-move' appropriately. - (swiper--update-input-ivy): - (swiper--action): Use `line-move' instead of `forward-line'. - (swiper--add-overlays): Update. - - Fixes #227 - -2015-10-02 Oleh Krehel - - ivy.el (ivy-resume): Don't regexp-quote preselect - - `ivy--preselect-index' uses `cl-position' before trying to match regex, - so the string needs to be as is. - - Fixes #245 - -2015-10-02 Oleh Krehel - - ivy-hydra.el: Bind "t" to toggle-truncate-lines - - * ivy.el (ivy-format-function-default): When `truncate-lines' is non-nil - don't truncate with "...". - - Use "C-o t" when you complete very long lines and want to see them - whole. - - Fixes #214 - -2015-10-02 Oleh Krehel - - ivy.el (ivy--reset-state): Less strict on :preselect - -2015-10-02 Oleh Krehel - - Specify shell command for counsel-git-grep with prefix arg - - * counsel.el (counsel-git-grep-cmd): New defvar. - (counsel-git-grep-function): Use `counsel-git-grep-cmd'. - (counsel-git-grep-cmd-history): New defvar. - (counsel-git-grep): Update signature. When called with a prefix arg, - prompt for a command reading from and recording to - `counsel-git-grep-cmd-history'. - - Remember to use "M-i" to insert the current candidate into the - minibuffer. - - Fixes #244 - -2015-09-30 Oleh Krehel - - ivy.el (ivy-yank-word): Add only one space each time - - The previous behavior got in trouble with consecutive spaces. - -2015-09-30 Oleh Krehel - - ivy.el (ivy--regex-fuzzy): Add minibuffer highlighting - - * ivy-test.el (ivy--regex-fuzzy): Update test. - - Re #207 - -2015-09-30 Oleh Krehel - - Add flx sorting - - * ivy.el (ivy--flx-cache): New defvar. - (ivy--filter): Since flx is costly, move the caching to an earlier - point. This means immediate return for when the input hasn't changed, - i.e. for "C-n" or "C-p". When flx is installed, and - (eq ivy--regex-function 'ivy--regex-fuzzy) for current function (through - `ivy-re-builders-alist'), then sort the final candidates with - `ivy--flx-sort'. - (ivy--flx-sort): New defun. In the worst case when some error pops up - return the same list. In the best case sort the `cands' that all match - `name' by closeness to `name'. - - How to use: 1. Have flx installed - (require 'flx) should succeed. 2. - Configure `ivy-re-builders-alist' appropriately to use - `ivy--regex-fuzzy', for example: - - (setq ivy-re-builders-alist - '((t . ivy--regex-fuzzy))) - - Fixes #207 - -2015-09-30 Oleh Krehel - - ivy.el (ivy-call): "C-M-n" should not leave the minibuffer - - Make sure that the minibuffer window remains selected as long as the - completion hasn't finished. For example, " f" to call - `counsel-describe-function' input - "forward" and spam "C-M-n" to read the doc for each function that starts - with "forward". The *Help* window popup would move the window focus, but - this change moves it back to the minibuffer. - -2015-09-30 Oleh Krehel - - Improve "C-g" out of a long-running async process - - * counsel.el (counsel-delete-process): New defun. - (counsel-locate): - (counsel-ag): Use `counsel-delete-process' as :unwind. - -2015-09-30 Oleh Krehel - - ivy.el (ivy--insert-prompt): Improve truncation - - Re #240 - -2015-09-29 Oleh Krehel - - counsel.el (counsel-M-x): Don't rely on package-installed-p - - * counsel.el (counsel-M-x): Use `require' instead. `package-installed-p' - may fail if package wasn't initialized. - -2015-09-29 Oleh Krehel - - counsel.el (counsel-ag-function): Improve for fancy faces - - Set `ivy--old-re' in order for fancy `ivy-display-style' to work. - -2015-09-29 Oleh Krehel - - counsel.el (counsel--find-symbol): Allow to jump back with pop-tag-mark - - Using "C-." in: - - - counsel-describe-function - - counsel-describe-variable - - counsel-load-library - - will change the current buffer. The buffer and point can be restored - with "M-*" (`pop-tag-mark'). - - I also recommend this binding: - - (global-set-key (kbd "M-,") 'pop-tag-mark) - -2015-09-29 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Add mu4e - - Re #19 - -2015-09-26 Oleh Krehel - - ivy.el (ivy--insert-prompt): Avoid negative length error - -2015-09-26 Oleh Krehel - - Truncate minibuffer prompts longer than window-width - - * ivy.el (ivy--insert-prompt): When the prompt string is longer than the - window width, truncate it to window width minus 26 chars. - - Fixes #240 - -2015-09-26 Oleh Krehel - - Make ivy-display-style more compatible with 24.3 - - * ivy.el (ivy--format-minibuffer-line): Use - `font-lock-append-text-property' instead of - `add-face-text-property'. It's not optimal, since the new face needs - to be put in front, but at least it doesn't error out. - -2015-09-26 Oleh Krehel - - ivy.el (ivy--resize-minibuffer-to-fit): Make compatible with 24.3 - - Fixes #220 - -2015-09-25 Oleh Krehel - - swiper.el (swiper--ivy): Remove obsolete version check - -2015-09-22 Julien Wietrich - - Fix minibuffer collapse in text mode emacs - - In graphic mode : resize-mini-windows is temporarily set to nil, the - only value which does not collapse the minibuffer. - - In text mode : if resize-mini-windows is nil, it is temporarily set to - 'grow-only (default emacs value). - - This prevent the minibuffer collapse in both graphic and text mode. - - In text mode it respects the user settings if it is already set to - 'grow-only or t. - - Fix #237 in text mode emacs too. - -2015-09-22 Oleh Krehel - - swiper.el (swiper--ivy): Use minibuffer-allow-text-properties - - Using `minibuffer-allow-text-properties' makes Emacs not strip the text - properties from the result of `read-from-minibuffer'. This is better - because a function call result is used instead of a global var to pass - this info. - -2015-09-19 Julien Wietrich - - Revert multiple frames workaround - - Since SHA:d8d7ed45f07b52ab63eca444f0e6fa03747fab9e workaround - SHA:435f2b6edfe3ab517c9eda56c6351f0bcfdf3845 is no longer required. - -2015-09-19 Julien Wietrich - - Fix minibuffer collapses to one line - - It happens since commit SHA:d374afea36df19b5d6b654adc6018b25d6c1d8f2 - when resize-mini-windows is set to true. - - It also happens when resize-mini-windows is set to 'grow-only (default) - and multiple frames are open. - (Although SHA:435f2b6edfe3ab517c9eda56c6351f0bcfdf3845 work around it) - - Temporarily bind `resize-mini-windows' to nil before calling - `read-from-minibuffer'. - - Fix #237 and #229 - - It might fix #77 although this need to be checked as I cannot reproduce - it. - -2015-09-18 PythonNut - - Add autoloads to some important functions - -2015-09-18 Oleh Krehel - - ivy.el (ivy-switch-buffer): Make "M-o r" rename buffer - - * ivy.el (ivy--rename-buffer-action): New defun. - - Fixes #233 - -2015-09-18 Oleh Krehel - - Make "" and "" behave as in fundamental-mode - - Fixes #232 - -2015-09-15 Oleh Krehel - - Add work-around for minibuffer not re-sizing for many frames - - * ivy.el (ivy--minibuffer-setup): When `truncate-lines' is set, it works - fine for one graphic frame, but not for two (unknown why); add a - work-around. - - Fixes #229 - -2015-09-13 Oleh Krehel - - counsel.el (counsel-yank-pop): Add autoload - -2015-09-12 Oleh Krehel - - ivy.el (ivy-format-function-default): Fix boundp bug - - Fixes #225 - -2015-09-12 Oleh Krehel - - counsel.el (counsel-yank-pop-truncate): Add group - -2015-09-12 Oleh Krehel - - swiper.el (swiper--ivy): Fix compiler warning - -2015-09-11 Oleh Krehel - - counsel.el (counsel-yank-pop): New command - - * counsel.el (counsel-yank-pop-truncate): New defcustom. Choose whether - to truncate strings over 4 lines. - (counsel-yank-pop-action): New defun. - - Fixes #218 - -2015-09-11 Oleh Krehel - - Make line numbers in swiper into display properties - - * swiper.el (swiper--candidates): Each candidate is now a single space - plus the original string. The display property of the single space - holds the line number. This means that it's no longer possible to - match line numbers in queries. Also, the preselect of the current line - is slightly worse (in case there are two identical lines in a buffer). - (swiper--ivy): Update the preselect to not include the line number. - Also, call `ivy--action' on `ivy-current' instead of `res', because - `res' doesn't have the string property that points to the line number. - (swiper--update-input-ivy): Update. - (swiper--action): Update. - - Fixes #224 - -2015-09-11 Oleh Krehel - - Set truncate-lines in the minibuffer - - * ivy.el (ivy--minibuffer-setup): Update. - (ivy-format-function-default): Check `truncate-lines'. Check if - `fringe-mode' is bound. - - Fixes #223 - -2015-09-10 Oleh Krehel - - ivy.el (ivy--resize-minibuffer-to-fit): Make compatible with 24.3 - - Re #220 - -2015-09-10 Oleh Krehel - - ivy.el (ivy-format-function-default): Handle fringe-mode 0 - - Fixes #219 - -2015-09-09 Oleh Krehel - - counsel.el (counsel-unicode-char): Add own history - - Also make "C-M-n", "C-M-p", and `ivy-resume' work properly. - -2015-09-08 Oleh Krehel - - Fix up the "foo ! bar" matching and highlighting - - * ivy.el (ivy--filter): When regex returned is a list, use only the - first string part. - - * swiper.el (swiper--update-input-ivy): When regex returned is a list, - use only the first string part. - -2015-09-08 Oleh Krehel - - Move swiper-minibuffer-faces to ivy.el - - Fixes #217 - -2015-09-07 Oleh Krehel - - Declare some SLIME functions - - * counsel.el (slime-symbol-start-pos): - (slime-symbol-end-pos): - (slime-contextual-completions): Declare. - -2015-09-07 Oleh Krehel - - counsel.el (counsel-git-grep-function): Fix up - - Set `ivy--old-re' for the benefit of fancy minibuffer faces. - -2015-09-07 Oleh Krehel - - Make the minibuffer faces look nicer - - * ivy.el (ivy-current-match): Update background and add white - foreground for light themes. Update background and add black - foreground for dark themes. - (ivy--add-face): If a face has an explicit foreground, add it ahead, - with no blending. Blend the background as usual. - - * swiper.el (swiper-minibuffer-match-face-1): - (swiper-minibuffer-match-face-2): Update the background for light - themes. - (swiper-minibuffer-match-face-4): Update the background for dark themes. - -2015-09-06 Oleh Krehel - - Add default values for minibuffer faces - - * swiper.el (swiper-minibuffer-match-face-1): - (swiper-minibuffer-match-face-2): - (swiper-minibuffer-match-face-3): - (swiper-minibuffer-match-face-4): Update. - - Re #215 - -2015-09-04 Oleh Krehel - - ivy.el (ivy--format-minibuffer-line): Fix nil regexp - -2015-09-04 Oleh Krehel - - Make ivy-current blend correctly for fancy minibuffer - - * ivy.el (ivy--format-minibuffer-line): Stop setting :height - it messes - with blending. Also, the minibuffer height issue was fixed in an - earlier pull request. - - (ivy--format): Call `ivy--add-face' on modified string, not on the - original one. - -2015-09-04 Oleh Krehel - - ivy.el (ivy--format-minibuffer-line): Use add-face-text-property - -2015-09-04 Oleh Krehel - - Add extra faces for minibuffer highlighting - - * swiper.el (swiper-minibuffer-match-face-1): - (swiper-minibuffer-match-face-2): - (swiper-minibuffer-match-face-3): - (swiper-minibuffer-match-face-4): New defface. - (swiper-minibuffer-faces): New defvar. - - * ivy.el (ivy--format-minibuffer-line): New defun. - (ivy--format): Use `ivy--format-minibuffer-line'. - -2015-09-03 Oleh Krehel - - ivy.el (ivy-display-style): New defcustom - - * ivy.el (ivy--format): Add additional highlighting for the minibuffer, - similar to `swiper', when `ivy-display-style' is set to 'fancy. - - Fixes #212 - -2015-08-31 Oleh Krehel - - counsel.el (counsel-cl): New command - - * counsel.el (counsel--el-action): Add `with-ivy-window' wrapper. - -2015-08-25 Oleh Krehel - - counsel.el (counsel--py-action): Work with "C-M-n" - - * counsel.el (counsel--py-action): Include the inserted parens in to - bounds, so that "C-M-n", "C-M-p" and `ivy-resume' work. - -2015-08-25 Oleh Krehel - - counsel.el (counsel-jedi): New command - - * counsel.el (counsel--py-action): New defun. - - Add a few declares as well. - -2015-08-21 Oleh Krehel - - Add swiper-multi command - - * swiper.el (swiper-multi-buffers): New defvar. - (swiper-multi-candidates): New defvar. - (swiper-multi-prompt): New defun. - (swiper-multi-action-1): New defun. - (swiper-multi-action-2): New defun. - - Fixes #182. - - Basic usage tips for selecting multiple buffers: - - - Use "C-M-m" (`ivy-call') to add or remove one more buffer without - exiting. - - Use "C-m" (`ivy-done') to add one last buffer. - - Or use "C-M-j" (`ivy-immediate-done') to finish without adding more - buffers. - - Hold "C-M-n" (`ivy-next-line-and-call') to add a lot of buffers at - once. - -2015-08-20 Oleh Krehel - - counsel.el (counsel-org-tag): Now works in agenda - - * counsel.el (counsel-org--set-tags): New defun. - (counsel-org-tag-action): Update. - - When on an agenda item, add/remove tags for that item. - - When any agenda items are marked with "m", add selected tags to all - items, with no duplicates. - - Fixed the bug of setting tags to "::" sometimes. Fixed "C-M-j" not - exiting. - - Fixes #200 - -2015-08-18 Felix Lange - - ivy: enlarge the minibuffer window if the candiate list doesn't fit - - Fixes #161 Fixes #198 - -2015-08-18 Oleh Krehel - - Set line-spacing to 0 in the minibuffer - - * ivy.el (ivy--minibuffer-setup): Update. - - Fixes #198 - -2015-08-14 Oleh Krehel - - ivy.el (ivy-kill-ring-save): Add and bind to "M-w" - - Fixes #197 - -2015-08-12 Oleh Krehel - - ivy.el (ivy-completing-read): Fix up last commit - - Check if string before using `string-match'. - -2015-08-12 Oleh Krehel - - When initial input contains a plus, escape it - - * ivy.el (ivy-completing-read): Escape the plus in the initial input, - for it to not be interpreted like a regex. - - Fixes #195 - -2015-08-12 Tassilo Horn - - Fix #126 again. - - After #126 has been solved, the regexp has been changed to - - "\\`[`']?\\(.*\\)'?\\'" - - where the trailing ' is optional ("'?"). However, the preceeding - "\\(.*\\)" group will already capture the trailing ' because .* is - greedy. Now I've replaced it with the non-greedy .*? which makes it - work again. - -2015-08-07 Oleh Krehel - - Fix :dynamic-collection not being sorted - - * ivy.el (ivy--sort-maybe): New defun. If the current completion has - sorting enabled, try to find the sorting function either in :sort or - `ivy-sort-functions-alist'. - (ivy--exhibit): Use `ivy--sort-maybe'. - - * counsel.el (counsel--async-sentinel): Use `ivy--sort-maybe'. - -2015-08-07 Oleh Krehel - - counsel-locate should use '' for the regex - - * counsel.el (counsel-unquote-regex-parens): New defun. - (counsel-locate-function): Update. - (counsel-ag-function): Update. - - Fixes #194 - -2015-08-07 Chunyang Xu - - (counsel-locate): Support OS X - - - OS X "open" is the equivalent to "xdg-open" - - OS X "locate" doesn't support "--regex" - -2015-08-06 Tassilo Horn - - (counsel-locate): Allow customizing locate options - -2015-08-05 Oleh Krehel - - Fix up ivy-recentf and ivy-switch-buffer window-wise - - * ivy.el (ivy--switch-buffer-action): - (ivy-recentf): Use `with-ivy-window'. - -2015-08-05 Oleh Krehel - - doc/Changelog.org: Add - -2015-08-05 Oleh Krehel - - counsel.el (counsel-find-file): Fix window focus issue - - "C-M-n" should work fine now. - -2015-08-03 Oleh Krehel - - Preselect perfect matches with a leading ^ - - * ivy.el (ivy--filter): When e.g. "filter" is in the collection, - "^filter" input should always select it, even if other candidates - match. - -2015-08-01 Chunyang Xu - - Allow ivy-count-format to be set as nil - -2015-07-30 Oleh Krehel - - Add with-ivy-window macro - - * ivy.el (with-ivy-window): New macro. - (ivy-yank-word): Update. - - * swiper.el (swiper--window): Remove defvar. - (swiper-query-replace): - (swiper-avy): - (swiper-recenter-top-bottom): - (swiper--init): - (swiper--update-input-ivy): - (swiper--add-overlays): Update. - - * counsel.el (counsel-git-grep-recenter): - (counsel-git-grep-action): - (counsel-M-x): Update. - (org-agenda-set-tags): Add a declare. - -2015-07-30 Oleh Krehel - - Bind "C-M-j" to ivy-immediate-done - - * ivy.el (ivy-minibuffer-map): Update. - - `ivy-immediate-done' will return with the current minibuffer input, even - if the input matches a candidate. - - It was possible so far to call it with "C-u C-j". - - Fixes #183 - -2015-07-28 Oleh Krehel - - counsel.el (counsel-org-tag-agenda): New command - - * counsel.el (counsel-org-tag-agenda): It's just a flet wrapper around - `org-agenda-set-tags', changing `org-set-tags' to `counsel-org-tag'. - (counsel-org-tag-action): Don't use `with-selected-window', since - `org-agenda-set-tags' will change the buffer for us. - - Re #177 - -2015-07-28 Oleh Krehel - - counsel.el (org-bound-and-true-p): Use bound-and-true-p - -2015-07-28 Oleh Krehel - - Add a few more Org declarations - - Re #179 - -2015-07-28 Oleh Krehel - - counsel.el (org-last-tags-completion-table): Declare - - Re #179 - -2015-07-28 Oleh Krehel - - counsel.el (org-setting-tags): Declare dynamic var - - Re #179 - -2015-07-28 Oleh Krehel - - swiper.el (swiper-from-isearch): New command - - Fixes #180 - -2015-07-28 Oleh Krehel - - counsel.el (org-bound-and-true-p): Update declare - -2015-07-27 Erik Hetzner - - Use recoll -t instead of recollq - -2015-07-27 Oleh Krehel - - counsel.el (counsel-org-tag): Delete dups - - The issue of duplicates arises from this setting (off by default): - - (setq org-complete-tags-always-offer-all-agenda-tags t) - - Re #177 - -2015-07-27 Oleh Krehel - - counsel.el (counsel-recoll): Simplify - -2015-07-27 Oleh Krehel - - counsel.el (counsel-org-tag): No need to be at heading - - * counsel.el (counsel-org-tag): When not at heading, move there. Save - excursion. - -2015-07-27 Oleh Krehel - - counsel.el (counsel-recoll): New command - - * counsel.el (counsel-recoll-function): New function. - -2015-07-27 Oleh Krehel - - counsel.el (counsel-ag): New command - - * counsel.el (counsel-ag-function): New defun. - (counsel-git-grep): Update prompt. - - Going from sync to async now is as simple as: - - - add :dynamic-collection t - - replace `shell-command-to-string' with `counsel--async-command' - -2015-07-27 Oleh Krehel - - Update :dynamic-collection to be a boolean - - * ivy.el (ivy--exhibit): Always use `ivy-state-collection', instead of - possibly `ivy-state-dynamic-collection'. The collection function may - return nil if it's async and doesn't want to update the minibuffer on - exit (to update it later in the sentinel). - - * counsel.el (counsel-more-chars): New defun. - (counsel-git-grep-function): Use `counsel-more-chars'; in the async - case, return nil. - (counsel-git-grep): Update :dynamic-collection to a boolean. - (counsel--gg-sentinel): - (counsel--async-sentinel): Update to set the candidates to "Error" - instead of message "Error" - a lot less distracting this way. - (counsel-locate-function): Use `counsel-more-chars'; return "Working", - since it takes a few seconds to complete a single locate query. - (counsel-locate): Update. - -2015-07-27 Oleh Krehel - - ivy.el (ivy--exhibit): Check if in post-command-hook - - * ivy.el (ivy--exhibit): A situation can occur when an async command - calls `ivy--exhibit' in the sentinel. It causes problems when the - minibuffer has already exited with "C-g". - -2015-07-27 Oleh Krehel - - Simplify counsel-git-grep logic - - * ivy.el (ivy--exhibit): Remove the condition on (eq ivy--full-length - -1). - - * counsel.el (counsel-git-grep-function): Simplify. - (counsel-gg-state): New defvar. Use this instead of - (setq ivy--full-length -1). - (counsel--gg-candidates): Set `counsel-gg-state' to -2. There are two - async processes to wait for until `ivy--exhibit' can be called: - - get the candidate count - - get the candidates Each of the async processes will increase the - number, and call - `ivy--exhibit' if the number reaches 0. - (counsel--gg-sentinel): Update. - (counsel--gg-count): Update. - -2015-07-27 Oleh Krehel - - Fix "DEL" generating a "Quit" sometimes for counsel-git-grep - - * ivy.el (ivy-backward-kill-word): It seems that `backward-kill-word' is - too elaborate; falling back to something simpler fixed the problem. - -2015-07-26 Oleh Krehel - - Allow "M-o j" to switch to virtual buffers in other window - - * ivy.el (ivy--switch-buffer-other-window-action): New defun. - (ivy-set-actions): Use `ivy--switch-buffer-other-window-action' instead - of `switch-to-buffer-other-window'. - -2015-07-24 Oleh Krehel - - counsel.el (counsel-org-change-tags): Improve removing tags - -2015-07-24 Oleh Krehel - - Fixup counsel-org-tag - - * counsel.el (counsel-org-tag-action): Add :: - (counsel-org-tag): Set `org-last-tags-completion-table', otherwise - `org-tags-completion-function' doesn't work. - -2015-07-24 Oleh Krehel - - counsel.el (counsel-org-tag): Replace org-set-tags - - * counsel.el (counsel-org-tags): New defvar. - (counsel-org-change-tags): New defun, adapted from part of - `org-set-tags'. - (counsel-org-tag-action): New defun. - (counsel-org-tag-prompt): New defun. - (counsel-org-tag): New command. - - **Using counsel-org-tag** - - - The prompt is auto-updated to the currently selected tags. - - Selecting one of the already selected tags removes it from selection. - - The best shortcut for selecting/removing multiple tags is "C-M-m" (or - "g" when the "C-o" hydra is active). - - Re #177 Re #91 - -2015-07-24 Oleh Krehel - - ivy.el (ivy-call): Remove with-selected-window - - * counsel.el (counsel-git-grep-action): Add with-selected-window. - - * ivy.el (ivy-dispatching-done): Remove trailing ": ". - (ivy-switch-buffer): Add extra action "j" calls - `switch-to-buffer-other-window'. The change `ivy-dispatching-done' had - to be done because of this. - -2015-07-24 Oleh Krehel - - Add actions for counsel-describe-function - -2015-07-24 Oleh Krehel - - Add actions for counsel-describe-variable - -2015-07-23 Oleh Krehel - - ivy.el (ivy-dispatching-done): Add a trailing newline - -2015-07-23 Oleh Krehel - - ivy.el (ivy-dispatching-done): Display the candidate - -2015-07-23 Oleh Krehel - - Allow "C-g" to interrupt ivy-dispatching-done - - * ivy.el (ivy-dispatching-done): Update. - -2015-07-23 Oleh Krehel - - ivy.el (ivy--preselect-index): Add matcher to arglist - - * ivy.el (ivy--reset-state): Call `ivy--preselect-index' with matcher. - (ivy--preselect-index): In case there's a special matcher set, it - affects the candidate list, therefore it affects the preselect index. - - Fixes #165 - -2015-07-23 Oleh Krehel - - ivy.el (ivy-dispatching-done): New command on "M-o" - - * ivy.el (ivy-minibuffer-map): Bind "M-o" to `ivy-dispatching-done'. - (ivy-action-name): Update, all actions are now in hydra's format - key - binding, command, hint. - (ivy-read): The default action is bound to "o" in the dispatch. - (ivy-switch-buffer): Update to new action format. - - * counsel.el (counsel-locate): - (counsel-rhythmbox): Update to new action format. - - The new interface allows to do whatever you want with the selected - candidate with a very short key binding. - - The old interface with "C-o w/s" still works, but: - - - it gives a lot more info than necessary for only selecting action - - doesn't scale well with the number of actions: for 10 actions you - would cycle "w/s" a lot. - - Example with `ivy-switch-buffer': - - - switch to selected buffer: "C-m" - - kill selected buffer: "M-o k"; you get a hint right after "M-o". - - When there is only one action, "M-o" will forward to "C-m". - -2015-07-22 Oleh Krehel - - ivy.el (ivy-call): Add selected-window work-around for M-x - - * ivy.el (ivy-call): For some commands that depend on the buffer, like - `counsel-git-grep' the action needs to be performed in - `ivy-state-window'. However, this results in wrong window for M-x calc. - Add a workaround until I figure out why this happens. - - Fixes #176 - -2015-07-21 Oleh Krehel - - ivy-hydra.el: Add featurep for hydra - - Fixes #174 - -2015-07-21 Oleh Krehel - - counsel.el (counsel-variable-list): Add - - * counsel.el (counsel-describe-variable): Use `counsel-variable-list'. - -2015-07-21 Oleh Krehel - - swiper.el: Update avy--goto -> avy-action-goto - -2015-07-14 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Ignore Man-mode - -2015-07-13 Oleh Krehel - - ivy.el (ivy-call): Bind to "C-M-m" or "M-RET" - - "C-M-m" is close to "C-M-n" and "C-M-p", just as "M-RET" is close to - "RET". Previously, the only binding was "C-o g". - -2015-07-13 Oleh Krehel - - ivy.el (ivy-count-format): Improve docstring - - * ivy.el (ivy-minibuffer-grow): - (ivy-toggle-calling): - (ivy-sort-functions-alist): Checkdoc. - -2015-07-11 Erik Hetzner - - Allow % in prompt string - - - quote % when passing prompt from ivy-completing-read to ivy-read - - add documentation in ivy-read that all % should be quoted - -2015-07-10 Oleh Krehel - - counsel.el (counsel-rhythmbox-history): Add - - * counsel.el (counsel-rhythmbox): Update. - -2015-07-09 Oleh Krehel - - ivy.el (ivy-read): Improve ivy-set-actions interaction - - * ivy.el (ivy-read): When the base action is already a list, merge it - with the one obtained from `ivy-set-actions'. - -2015-07-09 Oleh Krehel - - Add counsel-rhythmbox - - * counsel.el (counsel-completion-beg): - (counsel-completion-end): Move declarations before first use. - (dired-jump): Declare. - (counsel-rhythmbox-enqueue-song): New defun. - (counsel-rhythmbox): New command. Requires `helm-rhythmbox' package, and - Rhythmbox, obviously. - - * ivy.el (ivy-call): Make interactive. Add special handling for the case - when the collection is an alist. In that case, call the action not - with the collection item, but with the cdr of said item. A bit weird, - but that's the way Helm does it, and doing it in the same way means - the action functions are cross-compatible. - - * ivy-hydra.el (hydra-ivy): Bind "g" to call the current action on - current candidate without exiting. - - Now it's possible to make a query to Rhythmbox, "C-o" and navigate to a - song with "j" and "k". Try the song with "g". Or use "s" once and then - enqueue different songs with e.g. "jjgjjjgjgkkg". - -2015-07-07 Oleh Krehel - - ivy.el (ivy--regex): Improve for trailing backslash - - When there's a single trailing backslash, which would result in a bad - regex, ignore it. - -2015-07-06 Oleh Krehel - - Add a new interface to customize additional exit points - - * ivy.el (ivy--actions-list): New defvar. Store the exit points per - command. - (ivy-set-actions): New defun. Use this to set the extra exit points for - each command. - (ivy-read): Account for `ivy--actions-list'. - (ivy-switch-buffer): Set extra action to kill the buffer. Update the - call to `ivy-read'. - - * counsel.el (counsel-locate): Use the single action in the function and - customize the rest via `ivy-set-actions'. - - Re #164 - -2015-07-06 Oleh Krehel - - counsel.el (counsel-locate-history): Add - -2015-07-02 Oleh Krehel - - Update index formatting logic - - * ivy.el (ivy--reset-state): Update. - (ivy--insert-prompt): Simplify. - - If you want to see both the index and the length of the candidates, - instead of just the length, it can be done like this: - - (setq ivy-count-format "%d/%d ") - - Each "%d" is replaced appropriately due to the total length of the - candidates. For instance, this one can result in "%4d/%-4d M-x ". - - Re #167 - -2015-07-01 Oleh Krehel - - Allow to see the candidate index via ivy-count-format - - * ivy.el (ivy--insert-prompt): Update. - - To use this feature, use something like this: - - (setq ivy-count-format "(%d/%d)") - - Basically two number specifiers instead of the usual one. The problem - with this approach is that the prompt length will change as you scroll - e.g. from 9 to 10, which is uncomfortable. - - Fixes #167 - -2015-07-01 Oleh Krehel - - ivy.el (ivy--reset-state): Fixup - - Re #165 - -2015-07-01 Oleh Krehel - - ivy.el (ivy-read): Don't put empty string on history - -2015-07-01 Oleh Krehel - - Bind case-fold-search to t when the input is all lower-case - - * ivy.el (ivy--filter): Update. - - * ivy-test.el (ivy--filter): Add test. - - - input "the" matches both "the" and "The". - - input "The" matches only "The". - - Fixes #166 - -2015-07-01 Oleh Krehel - - ivy.el (ivy--reset-state): Fixup - -2015-07-01 Oleh Krehel - - Make ffap work again - - * ivy.el (ivy--reset-state): When completing files, consider the case - when the directory of PRESELECT isn't `default-directory'. - - Fixes #165 - -2015-06-30 Oleh Krehel - - ivy.el (ivy-switch-buffer): Add a multi-action interface - - While in "C-o": - - - Use "s" to make "C-m", "C-j", "C-M-n" and "C-M-p" kill - - Use "w" to switch back to normal. - - Re #164 - -2015-06-30 Oleh Krehel - - Add a multi-action interface for counsel-locate - - * ivy-hydra.el (hydra-ivy): Display the current action and allow to - scroll the action list with "w" and "s". - - * ivy.el (ivy--get-action): New defun, a getter for the action function, - since it can also be a list now. - (ivy--actionp): New defun, checks for the action list. - (ivy-next-action): New command, scrolls to the next action in the list. - (ivy-prev-action): New command, scrolls to the previous action in the - list. - (ivy-action-name): New defun. - (ivy-call): Use `ivy--get-action'. - (ivy-read): Use `ivy--get-action'. - -2015-06-30 Oleh Krehel - - Fixup the last two commits - - * counsel.el (counsel-find-file): Update. - - * ivy.el (ivy--buffer-list): Update. - - Re #164 - -2015-06-30 Oleh Krehel - - Add a custom keymap for counsel-find-file - - * counsel.el (counsel-find-file-map): New defvar. - - Re #164 - -2015-06-30 Oleh Krehel - - Add a custom keymap for ivy-switch-buffer - - * ivy.el (ivy-switch-buffer-map): New defvar. - - Re #164 - -2015-06-30 Oleh Krehel - - ivy.el (ivy-restrict-to-matches): Add and bind to "S-SPC" - -2015-06-30 Oleh Krehel - - Make counsel-locate use a process - - * counsel.el (counsel-locate-function): Update. - (counsel--async-command): New defun. - (counsel--async-sentinel): New defun. - (counsel-locate): Switch to :action, thus allowing "C-M-n" and - `ivy-resume'. - - * swiper.el: Bump version. - -2015-06-29 Oleh Krehel - - ivy-hydra.el (hydra-ivy): Bind "C-o" to be a toggle - - It makes sense for "C-o" to be a toggle, instead of just going one way. - -2015-06-29 Oleh Krehel - - Make counsel-el work with "C-M-n" and "C-M-p" - - * counsel.el (counsel-el): Use the whole obarray if no initial input is - given. Filter out only function when appropriate. - (counsel-completion-beg): New defvar. - (counsel-completion-end): New defvar. - (counsel--el-action): New defun. - - * ivy.el (ivy--reset-state): Set `ivy--full-length' to nil. - -2015-06-26 Oleh Krehel - - Fix the initial input bug introduced with "C-r" - - * ivy.el (ivy-read): Use (ivy-state-initial-input ivy-last). - (ivy--reset-state): Set (ivy-state-initial-input ivy-last). - - Fixes #162 - -2015-06-25 Oleh Krehel - - counsel.el (counsel-find-file): Use `file-name-history' - - * counsel.el (package-installed-p): Declare. - -2015-06-25 Oleh Krehel - - counsel.el (counsel-git-grep-history): New defvar - - * counsel.el (counsel-git-grep): Use `counsel-git-grep-history'. - -2015-06-25 Oleh Krehel - - swiper.el (swiper-history): New defvar - - * swiper.el (swiper--ivy): Use `swiper-history'. - - Allows to get more use of "M-p", "M-n" and "C-r". - -2015-06-25 Oleh Krehel - - Allow to recursively match history with "C-r" - - * ivy.el (ivy-minibuffer-map): Rebind "C-r" from - `ivy-previous-line-or-history' to `ivy-reverse-i-search'. "C-r" - binding was redundant, since "C-p" does almost the same. - (ivy-read): Separate the functionality that sets the global state based - on `ivy-last'. - (ivy--reset-state): New defun. Move all the global state setup here. - (ivy-reverse-i-search): New command. This is very similar to "C-r" in - bash - allows to match for history elements, instead of just scrolling - through them with "M-p" and "M-n". - -2015-06-25 Oleh Krehel - - Fixup compilation warnings related to smex - -2015-06-23 Oleh Krehel - - counsel.el (counsel-unicode-char): Use action-style call - - Fixes #160 - -2015-06-23 Oleh Krehel - - counsel.el (counsel-load-theme): New command - -2015-06-23 Oleh Krehel - - counsel.el (counsel-M-x): Avoid compilation warning - - * counsel.el (counsel-M-x): Use `command-execute' instead of - `execute-extended-command'. - -2015-06-23 Oleh Krehel - - Fix last commit being incompatible with older Emacs - - * ivy.el (ivy--format): Use `add-face-text-property' only when it's - bound. - -2015-06-23 Oleh Krehel - - Fix color blending for composite faces - - colir.el (colir-blend-face-background): Try to find the face among the - properties. - - Re #151 - -2015-06-23 Oleh Krehel - - Re-scale the text height to default in the minibuffer - - * ivy.el (ivy--format): Set the string height to default and turn off - overline, so that exactly `ivy-height' lines are visible, not less. - - Fixes #151 - -2015-06-22 Oleh Krehel - - ivy-hydra.el (hydra-ivy): Bind "C-g" - - To make sure that "C-g" really exits the hydra. - -2015-06-22 Oleh Krehel - - ivy.el (ivy-initial-inputs-alist): Add some Org commands - - * ivy.el (ivy-initial-inputs-alist): Add `org-agenda-refile' and - `org-capture-refile'. - - Fixes #156 - -2015-06-19 Kaushal Modi - - Fix the case where file name can contain ~ - - - The fix make opening files like init.el~ now possible. Earlier, - hitting that last ~ char switch the dir to ~/ - - This commit will now make that cd to ~/ only if ~ is the first char in - the search term - -2015-06-19 Greg Lucas - - Match drive letter at start of current directory - - When looking for the root of the current drive, make sure we only match - a drive letter at the beginning of the path. - -2015-06-19 Greg Lucas - - Add support for Windows drive letters - -2015-06-19 Oleh Krehel - - Improve performance for "^" initial input - - ivy.el (ivy--filter): There's no need to anchor when the previous regex - is "^" (matches everything). The result will be index 0 anyway, but - without this optimization it can be slow for ~30k candidates. - -2015-06-19 Oleh Krehel - - ivy.el (ivy-alt-done): Enable recursive minibuffers - - Re #145 - -2015-06-19 Oleh Krehel - - ivy.el (ivy-alt-done): Find file if given a full tramp path - - * ivy.el (ivy-alt-done): Add another cond branch for `ivy-text' matching - a full remote file path. - - Re #145 - -2015-06-19 Oleh Krehel - - Don't cut off "/ssh:foo" input - - * ivy.el (ivy-alt-done): With the example input, offer a completion for - known remotes with the initial input "foo". - - Re #145 - -2015-06-19 Oleh Krehel - - Add better positioning to counsel-git-grep finalizer - - counsel.el (counsel-git-grep-action): Use a regex instead of just - splitting the string on ":". Additionally, goto match, not just the line - of the match. - - Fixes #153 - -2015-06-19 Oleh Krehel - - Make counsel-M-x respect ivy-format-function - - * counsel.el (counsel--format-function-M-x): Remove defun. - (counsel--M-x-transformer): New defun. - (counsel-M-x): Temporarily bind `ivy-format-function' to apply - `counsel--M-x-transformer' beforehand. - - * ivy.el (ivy-format-function-arrow): Update style. - - Fixes #150 - -2015-06-19 Oleh Krehel - - Fix non-file completions ability to enter tramp completion - - * ivy.el (ivy-alt-done): Update. - - Re #145 - -2015-06-19 Oleh Krehel - - "M-i" should not switch directories - - ivy.el (ivy-insert-current): When the current candidate is a directory, - just insert its name without the last "/". The user can insert "/" to - switch to that directory if necessary. - - Re #141 - -2015-06-19 Oleh Krehel - - Add "^" as initial input to "C-h f" and "C-h v" - - * ivy.el (ivy-initial-inputs-alist): Add entries for - `counsel-describe-function' and `counsel-describe-variable'. - -2015-06-19 Oleh Krehel - - ivy.el (ivy-kill-line): Add and bind to "C-k" - - The only difference to `kill-line' is that it will kill the whole input - when at the end of the minibuffer. In that case, the regular `kill-line' - was extending into the second line of the minibuffer, which is - unacceptable. - -2015-06-19 Oleh Krehel - - Add a set of commands for resizing minibuffer height - - * ivy.el (ivy-minibuffer-grow): New command. - (ivy-minibuffer-shrink): New command. - - * ivy-hydra.el (hydra-ivy): Bind "<" and ">". - - Use "C-o >>>>>" to grow the minibuffer, and "C-o <<<<<" to shrink it. - - Re #151 - -2015-06-18 Oleh Krehel - - Put the file instead of partial input on history - - * ivy.el (ivy-read): When completing file names, put the whole file name - on history, not just the partial input that lead to that name. This is - important in order for `ivy--cd-maybe' to work. - - Re #152 - -2015-06-18 Oleh Krehel - - "M-n", "M-p", "M-i" should switch directories when needed - - * ivy.el (ivy-previous-history-element): - (ivy-next-history-element): - (ivy-switch-buffer): Call `ivy--cd-maybe'. - (ivy--cd-maybe): New defun. Check if the current input points to a - different directory than `ivy--directory'. If so, `ivy--cd' there. - - Fixes #152 - -2015-06-17 Oleh Krehel - - counsel.el (counsel-M-x): Fixup smex interaction - - * counsel.el (counsel-M-x): Use `smex-rank' only if smex is installed. - - Fixes #147 - -2015-06-16 Oleh Krehel - - counsel.el (counsel-M-x): Fixup - - Re #136 - -2015-06-16 Oleh Krehel - - ivy-hydra.el (defhydra): Wrap in eval-when-compile - -2015-06-16 Oleh Krehel - - Swiper should not deactivate-mark - - * swiper.el (swiper--init): Update to make it the same as `isearch'. - "C-SPC" + `swiper' should work to mark a region. - -2015-06-16 Oleh Krehel - - ivy-hydra.el: Improve for hydra not installed - - * ivy-hydra.el (hydra): No error on require. - (package-installed-p): Enable recursive minibuffers. - (hydra-ivy): Use ASCII char instead of Unicode, since the char width may - cause misalignment. - -2015-06-16 Oleh Krehel - - swiper.el (swiper-query-replace): Don't miss the first - - * swiper.el (swiper-query-replace): Since the point is always after the - matching thing in swiper, it's necessary to move it before it in order - for `perform-replace' not to skip it. - - Fixes #144 - -2015-06-16 Oleh Krehel - - Require TRAMP in time - - * ivy.el (ivy-alt-done): Require tramp before use. Store `ivy-last' - before calling `ivy-read', since each `ivy-read' overwrites - `ivy-last', and this one overwrites `counsel-find-file' action. - - Fixes #145 - -2015-06-16 Oleh Krehel - - counsel.el (counsel-M-x): Call smex-rank - - Re #136 - -2015-06-15 Oleh Krehel - - ivy-hydra.el (hydra-ivy): Add "C-j" and "C-m" exit points - - Just to make sure that the hydra exits. - -2015-06-15 Oleh Krehel - - Allow to toggle matching mode with "C-o m" - - * ivy.el (ivy-toggle-fuzzy): New command. - - * ivy-hydra.el (hydra-ivy): Bind `ivy-toggle-fuzzy' to "m". - - Fixes #142. - -2015-06-15 Oleh Krehel - - ivy.el (ivy-sort-functions-alist): Work for commands as well - - * ivy.el (ivy-sort-functions-alist): Examine `this-command' in addition - to the COLLECTION arg of `completing-read'. Add `Man-goto-section' and - `org-refile' to the list, since these commands collect the candidates - in the order in which they are in the buffer => the candidates must - not be sorted. Mention this in the doc. - -2015-06-15 Oleh Krehel - - ivy.el (ivy-initial-inputs-alist): Add man and woman - -2015-06-15 Oleh Krehel - - Fix the minibuffer being too small with enough candidates - - * ivy.el (ivy--format): Fix the bug of getting the minibuffer height - less than `ivy-height' when `ivy--index' was between `ivy--length' - and (- ivy--length (/ ivy--height 2)). - - * ivy-test.el (ivy--format): Add test. - -2015-06-15 Oleh Krehel - - ivy.el (ivy-insert-current): Add and bind to "M-i" - - Use "M-i" if you want something close to the current candidate. You can - follow up with an edit and select. - - Fixes #141 - -2015-06-15 Oleh Krehel - - Fix yank/undo bug - - * ivy.el (ivy--insert-minibuffer): Bind `buffer-undo-list' later. - Previously, "C-y C-u" would result in the first char of yanked text not - being undone. - -2015-06-15 Oleh Krehel - - Allow to customize the initial input for all commands - - * ivy.el (ivy-initial-inputs-alist): New defvar. Customize this to get - an initial input in any command. - (ivy-read): Unless INTIAL-INPUT is given, look it up in - `ivy-initial-inputs-alist' based on `this-command'. - - * counsel.el (counsel-M-x-initial-input): Remove defcustom. It's - superseded by `ivy-initial-inputs-alist'. - (counsel-M-x): Update. - - Fixes #140 - -2015-06-12 Oleh Krehel - - ivy.el (ivy--regex-fuzzy): Improve for "^" and "$" - - * ivy.el (ivy--regex-fuzzy): Don't insert .* after ^ and before $. - - * ivy-test.el (ivy--regex-fuzzy): Add test. - - Fixes #139 - -2015-06-12 Oleh Krehel - - ivy.el (hydra-ivy/body): Autoload - -2015-06-12 Oleh Krehel - - counsel.el (counsel-M-x): Call smex-initialize - - Otherwise, smex-cache isn't defined. - -2015-06-12 Oleh Krehel - - Bind "C-o" to hydra-ivy/body - - * ivy.el (ivy-minibuffer-map): Update. - - * ivy-hydra.el (hydra-ivy): New defhydra. - - Add shortcuts: - - "C-n" -> "j" - "C-p" -> "k" - "M-<" -> "h" - "M->" -> "l" - "C-j" -> "f" - "C-m" -> "d" - "C-g" -> "o" cancel "C-o" -> "i" toggle calling -> "c" - - The hydra doesn't inhibit other bindings, so "C-v" and "M-v" also work - when you toggle calling on with "c". - -2015-06-12 Oleh Krehel - - ivy-toggle-calling: Toggle calling "RET" action for current candidate - - * ivy.el (ivy-calling): New defvar. - (ivy-set-index): New defun - a setter for `ivy--index' that can call the - current action when `ivy-calling' isn't nil. - (ivy-beginning-of-buffer): - (ivy-end-of-buffer): - (ivy-scroll-up-command): - (ivy-scroll-down-command): - (ivy-next-line): - (ivy-previous-line): Use `ivy-set-index' instead of a plain `setq'. - (ivy-toggle-calling): New defun - toggle `ivy-calling'. - (ivy-call): New defun - call the current action. - (ivy-next-line-and-call): Use `ivy-call'. - (ivy-previous-line-and-call): Use `ivy-call'. - (ivy-read): Reset `ivy-calling' to nil. - - To make use of this functionality, bind `ivy-toggle-calling' in - `ivy-minibuffer-map'. After this, "C-n" will behave like "C-M-n" etc. - -2015-06-12 Oleh Krehel - - Replace "C-x 6" with "" in counsel-M-x - - counsel.el (counsel--format-function-M-x): Update. - -2015-06-12 Oleh Krehel - - counsel.el (counsel-find-file-ignore-regexp): Default to nil - - * counsel.el (counsel--find-file-matcher): Update. - - Make the default behavior more similar to `find-file'. Move the previous - value to the docstring. - -2015-06-12 Oleh Krehel - - counsel.el: Add a bunch of autoload cookies - -2015-06-12 Oleh Krehel - - counsel.el (counsel-M-x-initial-input): New defcustom - - * counsel.el (counsel-M-x): Use `counsel-M-x-initial-input'. - - Re #138 - -2015-06-12 Oleh Krehel - - Allow "TAB" to complete when input starts with "^" - - * ivy.el (ivy-partial): Strip "^" when forwarding to `try-completion'. - Afterwards, put it back. - - Fixes #138 - -2015-06-10 Oleh Krehel - - Fixup ivy-resume for file completion - - * ivy.el (ivy-resume): No longer add the preselect. - (ivy-read): Don't add initial-input "". - -2015-06-10 Oleh Krehel - - Add fuzzy matching function - - ivy.el (ivy--regex-fuzzy): New defun. - - To enable fuzzy matching, set your `ivy-re-builders-alist' accordingly: - - (setq ivy-re-builders-alist - '((t . ivy--regex-fuzzy))) - - Re #136 - -2015-06-10 Oleh Krehel - - counsel.el (counsel-M-x): Piggyback on smex for sorting - - * counsel.el (counsel-M-x): When smex is present, use it for sorting the - candidates. Also use `counsel-describe-map', so that "C-." and "C-," - work for commands. - - Re #136 - -2015-06-10 Oleh Krehel - - counsel.el (counsel-M-x): New command - - * counsel.el (counsel--format-function-M-x): New defun. - - Re #136. - -2015-06-10 Oleh Krehel - - counsel.el (counsel-symbol-at-point): Improve - - Fixes #137 - -2015-06-09 Oleh Krehel - - Add a hack for kill-buffer and invisible buffer - - * ivy.el (ivy-read): When COLLECTION is 'internal-complete-buffer, - ignore the fact that REQUIRE-MATCH was set to t. - Normally, when REQUIRE-MATCH is t, the COLLECTION should not be - extended with PRESELECT. - - Fixes #135 - -2015-06-09 Oleh Krehel - - Account for minibuffer-depth-indication-mode - - * ivy.el (ivy--insert-prompt): When `minibuffer-depth-indication-mode' - is on, and `minibuffer-depth' is more than 1, prepend it to prompt. - - Fixes #134 - -2015-06-09 Oleh Krehel - - ivy.el (ivy--switch-buffer-action): Add work-around - - If BUFFER is live, and can also be virtual, don't open the virtual one. - This work-around should be disabled once uniquify is added to buffer - list. - -2015-06-09 Oleh Krehel - - counsel-git-grep should quote strings better - - * counsel.el (counsel-git-grep-function): - (counsel--gg-candidates): Update. - - Fixes an errror when the input has a " in it. - -2015-06-08 Oleh Krehel - - ivy.el (ivy-minibuffer-map): Bind ivy-yank-word to "M-j" - - Re #133 - -2015-06-04 Oleh Krehel - - Make counsel-git-grep fully async - - * counsel.el (counsel-git-grep-count): Rename to `counsel--gg-count' and - make it async. - (counsel-git-grep-function): Set `ivy--full-length' to -1. It means that - `ivy--exhibit' should do nothing until the length is re-computed. - (counsel-git-grep): Use the sync version of `counsel-git-grep-count' for - the initial repo line count. - (counsel--gg-candidates): New defun. When called, kill the previous git - grep process and start a new one. The sentinel will insert the - candidates, bypassing the `ivy--exhibit'. - (counsel--gg-sentinel): New defun. - (counsel--gg-count): Rename from `counsel-git-grep-count'. When finished - computing, redisplay. - - * ivy.el (ivy--exhibit): Don't expect dynamic collection to return the - candidates as before. Just call it and expect it to redisplay the - minibuffer. - -2015-06-04 Oleh Krehel - - Fixup compilation warnings - -2015-06-04 Tassilo Horn - - Regexp-quote name of candidate buffer to be preselected - - Fixes #128 - -2015-06-04 Oleh Krehel - - ivy.el (ivy-virtual): New defface - - * ivy.el (ivy--virtual-buffers): Use `ivy-virtual'. No need for - `ido-use-faces' approach, the user can just customize - `ivy-virtual' to look like `default' if needed. - - Fixes #129 - -2015-06-02 Oleh Krehel - - ivy.el (ivy--done): Set ivy--current - - Fixes a bug of using :action for completing file names. - -2015-06-02 Oleh Krehel - - Handle symbol-at-point better in non-Elisp buffers - - * counsel.el (counsel-symbol-at-point): New defun. - (counsel-describe-variable): Update. - (counsel-describe-function): Update. - - Fixes #126 - -2015-06-01 Oleh Krehel - - Swiper should preserve column for empty input - - swiper.el (swiper--update-input-ivy): When there's no input yet, don't - move point. - - Re #125 - -2015-06-01 Oleh Krehel - - ivy.el (ivy-yank-word): New command - - * swiper.el (swiper--update-input-ivy): Move point to current regex, not - just current line. - - Gives a behavior similar to "C-w" of `isearch'. Possible binding: - - (define-key ivy-minibuffer-map (kbd "C-w") 'ivy-yank-word) - - Fixes #125 - -2015-06-01 Oleh Krehel - - ivy.el (ivy-recentf): New command - - Fixes #124 - -2015-05-30 Oleh Krehel - - counsel.el (counsel-find-file-at-point): New defcustom - - * counsel.el (counsel-find-file): When `counsel-find-file-at-point' is - non-nil, add the file at point to the list of candidates. - - Fixes #123 - -2015-05-30 Oleh Krehel - - counsel.el (counsel-find-file): Extend `find-file' - - * counsel.el (counsel-find-file): Forward to `find-file', with Ivy - completion. `ivy-next-line-and-call' as well as `ivy-resume' should - work. - (counsel--find-file-matcher): New defun. - (counsel-find-file-ignore-regexp): Regexp of files to ignore. - - Fixes #122 - - Recommended binding: - - (global-set-key (kbd "C-x C-f") 'counsel-find-file) - - Peek at files with "C-M-n" and "C-M-p". Input a leading dot to see all - files. - -2015-05-28 Oleh Krehel - - counsel.el (counsel-info-lookup-symbol): Add a require - - In case it's called non-interactively. - -2015-05-28 Tassilo Horn - - Add info lookup binding to counsel-describe-map - - * counsel.el (counsel-describe-map): Bind C-, to - counsel--info-lookup-symbol. - (counsel--info-lookup-symbol): New command. Just sets the ivy action to - counsel-info-lookup-symbol. - -2015-05-28 Oleh Krehel - - Change the :matcher interface - - * ivy.el (ivy--filter): The matcher is now a function that takes a - regexp and candidates and returns the filtered candidates. - - * counsel.el (counsel-git-grep-matcher): Cache matched candidates. This - is very important for "C-n" / "C-p", especially near the threshold - where a switch to :dynamic-collection is made. - -2015-05-28 Oleh Krehel - - Avoid ensuring font lock when magit-blame-mode is active - - swiper.el (swiper-font-lock-ensure): Update. - -2015-05-26 Oleh Krehel - - Allow to open an Info file on the file system - - * ivy.el (ivy-alt-done): Update. - - When in Info-mode, press "g" and select either "(./)" or "(../)" to - switch to file name completion. That file will be opened with Info. - -2015-05-25 Oleh Krehel - - swiper.el (swiper--ivy): Don't double-quote preselect - - The :preselect is already quoted in `ivy--preselect-index'. - -2015-05-25 Oleh Krehel - - swiper.el (swiper-avy): Don't start on empty input - - Fixes abo-abo/avy#50 - -2015-05-24 Ingo Lohmar - - ivy.el (ivy-next-line): Fix wraparound at end of candidates - -2015-05-23 Oleh Krehel - - swiper.el (swiper-avy): Use only the current window - - Fixes #117 - -2015-05-23 Oleh Krehel - - swiper.el: Bump version - -2015-05-23 Oleh Krehel - - README.md: Add a secion on Ivy - -2015-05-23 Oleh Krehel - - The :action parameter to ivy-read should take one arg - - * ivy.el (ivy-next-line-and-call): Update. - (ivy-previous-line-and-call): Update. - (ivy-read): Update. - (ivy--switch-buffer-action): Update. - - * swiper.el (swiper-query-replace): Update. - - * counsel.el (counsel--find-symbol): Update. - (counsel-describe-variable): Update. - (counsel-describe-function): Update. - (counsel-git): Update. - (counsel-git-grep-action): Update. - -2015-05-23 Oleh Krehel - - Fixup "C-u C-j" for `ivy-switch-buffer' - - ivy.el (ivy-immediate-done): Since action-style call is used now, - `ivy--current' must be set to `ivy-test', since it's `ivy--current' that - will count as completion result. - -2015-05-23 Oleh Krehel - - counsel.el (counsel-git): Switch to action-style call - - This allows "C-M-n" and "C-M-p" to be used. - - Re #114 - -2015-05-23 Oleh Krehel - - ivy.el (ivy-completing-read): Check for a cons initial-input - -2015-05-23 Stefan Monnier - - * swiper/ivy.el: Clean up regexps and pseudo-closures - - Don't require cl-lib twice. - (ivy-read, ivy--filter): Use closures instead of `(lambda ...). - (ivy--format, ivy--filter, ivy--exhibit, ivy--insert-prompt) - (ivy--regex-ignore-order, ivy--regex, ivy--sorted-files) - (ivy-partial-or-done, ivy-alt-done): Don't use ^/$ to match string - bounds. - -2015-05-19 Oleh Krehel - - Fixup compilation warnings - -2015-05-19 Oleh Krehel - - When building a regex, consider ^ only at start - - swiper.el (swiper--re-builder): Update. - -2015-05-19 Oleh Krehel - - counsel.el (counsel-info-lookup-symbol): Turn on sorting - -2015-05-17 Oleh Krehel - - Don't try to call permanent action if there's none - - * ivy.el (ivy-next-line-and-call): Update. - (ivy-previous-line-and-call): Update. - - Fixes #114. - -2015-05-17 Oleh Krehel - - ivy.el (ivy-forward-char): Add and bind to "C-f" - - This is to avoid problems for the ido-related "C-x C-f C-f" reflex. - -2015-05-16 Oleh Krehel - - Don't error on incomplete bad regexp in counsel-git-grep - - counsel.el (counsel-git-grep-matcher): Update. - -2015-05-16 Oleh Krehel - - counsel.el (counsel-git-grep): Warn if not in a repository - -2015-05-16 Oleh Krehel - - ivy.el (ivy-kill-word): Add and bind to "M-d" - - Fixes #94 - -2015-05-15 Oleh Krehel - - README.md: Add sample init - - Fixes #112 - -2015-05-15 __rompy - - Fixed ivy--preselect-index on windows where the drives folders ends with - a backslash (C:\, D:\) - -2015-05-14 Oleh Krehel - - Update the way spaces are quoted using ivy - - * ivy.el (ivy--split): Split only on single spaces. From all other space - groups, remove one space. - - * ivy-test.el (ivy--split): Add test. - - Fixes #109 - -2015-05-13 Oleh Krehel - - ivy.el (ivy-partial-or-done): More predictability - - * ivy.el (ivy-partial-or-done): Forward to `ivy-alt-done' only if - `ivy-partial' did nothing new, and either previous command was - `ivy-partial-or-done', or there's exactly one matching candidate. - - Fixes #107 - -2015-05-13 Oleh Krehel - - Allow to recenter with "C-l" during counsel-git-grep - - * counsel.el (counsel-git-grep-map): New defvar. - (counsel-git-grep-recenter): New command. - (counsel-git-grep-action): New defun. - (counsel-git-grep): Update. - - Fixes #103 - -2015-05-13 Oleh Krehel - - ivy.el (ivy-partial-or-done): Update doc - - Re #105 - -2015-05-13 Oleh Krehel - - ivy.el (ivy-partial-or-done): Always forward to `ivy-alt-done' - - Fixes #105 - -2015-05-12 Oleh Krehel - - ivy.el (ivy-delete-char): Add and bind to "C-d" - - `delete-char' must not be called when at end of line, since that would - bring the first candidate into the input. - - Fixes #94 - -2015-05-12 Oleh Krehel - - ivy.el (ivy-switch-buffer): Preselect other-buffer - - * ivy.el (ivy-switch-buffer): Preselect other buffer, just like - `switch-to-buffer' does it. - -2015-05-12 Oleh Krehel - - ivy.el (ivy-read): Keep the last ivy--index for :dynamic-collection - -2015-05-12 Oleh Krehel - - counsel-git-grep now works with ivy-resume - - * ivy.el (ivy-state): New field DYNAMIC-COLLECTION. - (ivy-resume): Update. - (ivy-read): New argument DYNAMIC-COLLECTION. When this is non-nil, - ignore collection and matchers etc, and just obtain the filtered - candidates by calling DYNAMIC-COLLECTION each time the input changes. - - Fixes #100 - -2015-05-12 Oleh Krehel - - Introduce :matcher for counsel-git-grep - - * ivy.el (ivy-state): Add MATCHER field. - (ivy-resume): Update. - (ivy-read): Add MATCHER argument. To make things faster, MATCHER can - reuse `ivy--old-re', but it's not required. MATCHER is a function that - takes a candidate and returns non-nil if it matches. - - * counsel.el (counsel-git-grep): Use :matcher. - (counsel-git-grep-matcher): New defun. Skip the file name and line - number, then match as usual. - - Fixes #99 - -2015-05-12 Oleh Krehel - - Forward to minibuffer-complete for filenames only if "^/" - - * ivy.el (ivy-partial-or-done): Update. - - Fixes #102 - -2015-05-12 Oleh Krehel - - Properly update virtual buffers for "^ " interaction - - * ivy.el (ivy-read): Use `ivy--buffer-list'. - (ivy--exhibit): Use `ivy--buffer-list'. - (ivy-add-virtual-buffers): Remove. - (ivy--buffer-list): New defun. - - Re #68 - -2015-05-12 Oleh Krehel - - Fix the error switching to non-existent buffers - - * ivy.el (ivy-read): Use `ivy-add-virtual-buffers'. - (ivy-buffer-list): Remove. - (ivy-add-virtual-buffers): New defun. - (ivy--switch-buffer-action): New defun, consider `ivy--current' being - zero length. - (ivy-switch-buffer): Use `ivy--switch-buffer-action'. - - Fixes #101 - -2015-05-11 Oleh Krehel - - ivy.el (ivy-partial-or-done): Fixup - - * ivy.el (ivy-partial-or-done): Switch `default-directory' so that - `minibuffer-complete' is aware of it. Select a directory only if there - is only one. - -2015-05-11 Oleh Krehel - - ivy.el (ivy-partial-or-done): Fixup - -2015-05-11 Oleh Krehel - - When completing file names, defer to `minibuffer-complete' for "TAB" - - * ivy.el (ivy-partial-or-done): Call `minibuffer-complete'. If the - resulting text is a valid directory, move there. - (ivy-read): Setup `minibuffer-completion-table' and - `minibuffer-completion-predicate'. This makes `minibuffer-complete' - work. - - Fixes #92 - -2015-05-11 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Ignore fundamental-mode - - ELP uses this. - -2015-05-11 Oleh Krehel - - Allow to customize the minibuffer formatter - - * ivy.el (ivy-format-function): New defvar. - (ivy-format-function-default): New defun. - (ivy-format-function-arrow): New defun, alternative for - `ivy-format-function'. - - Fixes #87 - -2015-05-11 Oleh Krehel - - Update test - - ivy-test.el (swiper--re-builder): Rename from `ivy--transform-re'. - -2015-05-11 Oleh Krehel - - Swiper should use the :re-builder argument - - * ivy.el (ivy--transform-re): Remove defun, :re-builder should be used - for this logic. - (ivy--filter): Update. - - * swiper.el (swiper-avy): Use `ivy--regex'. - (swiper--init): Don't set `ivy--regex-function' - it will be set by - :re-builder. - (swiper--re-builder): New defun. - (swiper--ivy): Use :re-builder in call to `ivy-read'. - (swiper--update-input-ivy): Use `ivy--regex'. - (swiper--action): Use `ivy--regex'. - - Fixes #90 - -2015-05-11 Oleh Krehel - - ivy.el (ivy-read): Add a re-builder argument - - * ivy.el (ivy-state): Add a RE-BUILDER field. - (ivy-resume): Use RE-BUILDER field. - (ivy-read): Set `ivy--regex-function' to RE-BUILDER if it's given. - -2015-05-11 Oleh Krehel - - ivy.el (ivy-backward-kill-word): Add and bind to "M-DEL" - - Fixes #94 - -2015-05-09 Oleh Krehel - - Fix the transition from a bad regex to good one - - * ivy.el (ivy--filter): Update. - - Fixes #93 - -2015-05-08 Oleh Krehel - - Declare swiper-map - - Fixes #90 - -2015-05-08 Oleh Krehel - - Rename avy-swiper to swiper-avy - - * swiper.el (swiper-avy): Rename and fix the regex. - -2015-05-08 Oleh Krehel - - ivy.el (ivy-use-virtual-buffers): New defcustom - - Re #84 - -2015-05-08 Oleh Krehel - - Add support for virtual buffers - - * ivy.el (ivy-mode-map): New defvar. Remap `switch-to-buffer' to - `ivy-switch-buffer'. - (ivy-mode): Use `ivy-mode-map'. - (ivy--virtual-buffers): New devar. - (ivy--virtual-buffers): New defun. - (ivy-buffer-list): Return a list of buffers, taking - `ido-use-virtual-buffers' into account. - (ivy-switch-buffer): New command. - - Fixes #84 - -2015-05-08 Tassilo Horn - - Simplify ivy-partial-or-done - -2015-05-08 Oleh Krehel - - Add swiper -> avy finalizer - - * ivy.el (ivy-quit-and-run): New defmacro. - (tramp-get-completion-function): Add declare. - - * swiper.el (swiper-map): Bind `avy-swiper' to "C-'". - (avy-swiper): New defun - jump to one of the currently visible swiper - candidates using avy. - -2015-05-08 Oleh Krehel - - Allow to use "^" in swiper - - * swiper.el (swiper--width): New defvar. - (swiper--candidates): Set `swiper--width'. - - * ivy.el (ivy--transform-re): New defun - transform the regex - specifically for `swiper'. - (ivy--filter): Call `ivy--transform-re'. - - * ivy-test.el (ivy--transform-re): Add test. - - Fixes #82 - -2015-05-08 Oleh Krehel - - Add ivy-partial: partial complete without exiting - - * ivy.el (ivy-partial-or-done): Forward to `ivy-partial'. - (ivy-partial): New defun. - - If you want a different style of completion for "TAB", do this in your - config: - - (define-key ivy-minibuffer-map (kbd "TAB") 'ivy-partial) - - Fixes #85 Fixes #86 - -2015-05-06 Oleh Krehel - - Try to prevent the resize of minibuffer window - - * ivy.el (ivy--insert-minibuffer): Temporarily bind - `resize-mini-windows' to nil. - - From its doc: - A value of `grow-only', the default, means let mini-windows grow - only; - they return to their normal size when the minibuffer is closed, or - the - echo area becomes empty. - - It could be that an update catches this minibuffer empty during - `ivy--insert-minibuffer'. - - Re #77 - -2015-05-06 Oleh Krehel - - Merge ivy--update-fn into ivy-last - - * ivy.el (ivy--update-fn): Remove defvar. - (ivy-read): Update. - (ivy--insert-minibuffer): Update. - -2015-05-06 Oleh Krehel - - Add parents using 'display for `counsel-load-library' - - * counsel.el (counsel--find-symbol): The argument string may have a - 'full-name property. - (counsel-string-compose): New defun. - (counsel-load-library): Make libraries unique through text properties. - - Re #79 - -2015-05-06 Oleh Krehel - - Add counsel-load-library - - * counsel.el (counsel-directory-parent): New defun. - (counsel-load-library): New command. - - Improve on `load-library': - - - don't consider .*elc or .*pkg.elc?, they're usually useless - - resolve duplicates in a similar way to uniquify (prepend parent - directory) - - allow to jump-to-library with "C-." (see `counsel-describe-map') - -2015-05-06 Oleh Krehel - - Work around grep-read-files - - * ivy.el (ivy--done): If history is `grep-files-history', the caller is - `grep-read-files'. Don't expand the file name, since it's probably a - glob, and `find' doesn't work with expanded globs. - - It should now be possible to simply "M-x" rgrep "RET" "RET" "RET". - - Fixes #72 - -2015-05-06 Oleh Krehel - - ivy.el (ivy-partial-or-done): Handle empty input - - Fixes #81 - -2015-05-05 Oleh Krehel - - Improve "TAB" interaction with `confirm-nonexistent-file-or-buffer' - - * ivy.el (ivy-partial-or-done): When - `confirm-nonexistent-file-or-buffer' is t, and there are no - candidates, modify the prompt to "(confirm)" right after the first - "TAB". - - Re #76 - -2015-05-05 Oleh Krehel - - ivy.el (ivy-done): Simplify and improve - - * ivy.el (ivy--done): New defun. - (ivy-done): Consider `confirm-nonexistent-file-or-buffer' for buffers as - well. - - Fixes #76 - -2015-05-05 Oleh Krehel - - Merge ivy--collection into ivy-last - - * ivy.el (ivy--collection): Delete defvar. - (ivy-read): Update. - (ivy--exhibit): Update. - -2015-05-05 Oleh Krehel - - Require dired when completing file names - - * ivy.el (ivy-read): Update. - - Fixes #78 - -2015-05-04 Oleh Krehel - - Make "TAB" switch directories properly - - * ivy.el (ivy-partial-or-done): Forward to `ivy-alt-done'. - - Fixes #75 - -2015-05-04 Oleh Krehel - - "TAB" shouldn't delete input when no candidate - - ivy.el (ivy-partial-or-done): Update. - - Fixes #74 - -2015-05-04 Oleh Krehel - - Ignore case for "TAB" - - * ivy.el (ivy-partial-or-done): Update. - - Now, e.g. "pub" can expand to "Public License". - -2015-05-04 Oleh Krehel - - ivy.el (ivy-tab-space): New defcustom - - * ivy.el (ivy-partial-or-done): Insert an extra space when - `ivy-tab-space' is non-nil. This is useful to complete partially and - start a new group at once. - - Fixes #73 - -2015-05-03 Oleh Krehel - - Add an option for out-of-order matching - - * ivy.el (ivy--regex-ignore-order): New defun. - - * swiper.el (swiper--init): Set `ivy--regex-function'. - (swiper--update-input-ivy): Use `ivy--regex-function'. - (swiper--action): Use `ivy--regex-function'. - - Example of use: - - (setq ivy-re-builders-alist - '((t . ivy--regex-ignore-order))) - - With this, e.g. swiper will match "bar foo" from input "foo bar". - -2015-05-03 Oleh Krehel - - swiper.el: Bump version - -2015-05-03 Oleh Krehel - - ivy.el (ivy-resume): Quote the preselect - -2015-05-02 Oleh Krehel - - Fix the candidate index for `ivy-resume' - - * ivy.el (ivy--preselect-index): The the regex, not the plain text. - -2015-05-02 Oleh Krehel - - Add unwind argument to ivy-read - - * ivy.el (ivy-state): Add `unwind' field. - (ivy-resume): Update. - (ivy-read): Call the `unwind' argument in the unwind form. - - * swiper.el (swiper--ivy): Use `unwind' for `ivy-read'. - -2015-05-01 Oleh Krehel - - Merge ivy--persistent-action into ivy-state-action - - * counsel.el (counsel-git-grep): Update. - - * ivy.el (ivy--persistent-action): Remove defvar. - (ivy-next-line-and-call): Update. - (ivy-previous-line-and-call): Update. - -2015-05-01 Oleh Krehel - - ivy-resume now works for functions that supply action - - ivy.el (ivy-resume): Use action - - Functions like `counsel-describe-funtion' and `counsel-describe-varible' - are now resume-able: after finishing with "RET" or breaking out with - "C-g" it's possible to resume the query in the same state as it was - (same collection, input, index). - - With: - - (global-set-key (kbd "C-c C-r") 'ivy-resume) - - it's possible to e.g.: - - - "F1 f" info read "RET" to describe Info-breadcrumbs - - "C-c C-r" "C-n" to describe Info-read-node-name - - "C-c C-r" "C-n" to describe Info-read-node-name-1 - ... - -2015-05-01 Oleh Krehel - - Merge ivy--action into ivy-last - - * ivy.el (ivy-state): Add action field. - (ivy-set-action): New defun. Just a shortcut to set action. - (ivy--action): Remove defvar. - (ivy-read): Add action argument. Check (ivy-state-action ivy-last) in - the end and call it, since the action can change during the completion. - (ivy--insert-prompt): Add `counsel-find-symbol' to the list. - (ivy--format): If there are no matches, set `ivy--current' to "". - -2015-05-01 Oleh Krehel - - Merge ivy-window into ivy-last - - * ivy.el (ivy-state): Add a window field. - (ivy-window): Remove defvar. - (ivy-next-line-and-call): Update. - (ivy-previous-line-and-call): Update. - (ivy-read): Update. - -2015-05-01 Oleh Krehel - - Merge ivy-def into ivy-last - - * ivy.el (ivy-def): Remove defvar. - (ivy-read): Update. - (ivy--filter): Update. - -2015-05-01 Oleh Krehel - - Allow to quote spaces while matching - - * ivy.el (ivy--split): New defun. - - Use (ivy--split str) in place of (split-string str " +" t). Allows to - "quote" N spaces by inputting N+1 spaces. - -2015-05-01 Oleh Krehel - - Add ivy-state struct - - * ivy.el (ivy-state): New defstruct. - (ivy-last): A single global to store an `ivy-state' struct. - (ivy-require-match): Move into `ivy-last'. - (ivy-done): Update. - (ivy-resume): New defun. Initial draft, kind of works for swiper. Need - to add a callback of what to do with the result as an argument. - (ivy-read): Store all arguments into `ivy-last'. - (ivy-completing-read): Update doc. - -2015-04-30 Oleh Krehel - - Allow for "/ssh:user@" as well as for "/ssh:" - - * ivy.el (ivy-alt-done): Update. - - Re #59 - -2015-04-30 Oleh Krehel - - Improve TRAMP completion for ivy-mode - - * ivy.el (ivy-build-tramp-name): New defun. - (ivy-alt-done): Use arcane TRAMP stuff to complete host names. - - Re #59 - -2015-04-30 Oleh Krehel - - ivy.el (ivy-read): Reset `ivy-text' earlier - - Related to `counsel-git-grep' "-3 chars more". - -2015-04-30 Oleh Krehel - - ivy.el (ivy--regex): Fixup - - Fixes #62 - -2015-04-30 Oleh Krehel - - Don't error on bad regex - - * ivy.el (ivy--filter): When on bad regex, just set the result to nil. - - Fixes #70 - -2015-04-29 Oleh Krehel - - Update and improve faces - - * ivy.el (ivy-subdir): Inherit from dired-directory. - - * swiper.el (swiper-match-face-1): Update doc. - (swiper-match-face-2): Update doc. - (swiper-match-face-3): Update doc. - (swiper-match-face-4): Inherit from isearch-fail. - (swiper--add-overlays): Fix the faces order swapping on the second - match. - - Now it finally works as planned: face-1 is the background (re group 0), - next it cycles: face-2, face-3, face-4, face-2, face-3, face-4. - -2015-04-29 Oleh Krehel - - Add gamma-correction to alpha-blending - - * colir.el (colir-compose-method): Make 'colir-compose-alpha default. - (colir-compose-alpha): Add gamma-correction. - -2015-04-29 Oleh Krehel - - colir.el: Add two additional blend algorithms - - * colir.el (colir-join): Remove. - (color): Require. - (colir-compose-method): New defcustom. - (colir-compose-soft-light): New defun. - (colir-compose-overlay): New defun. - (colir-compose-alpha): New defun. - (colir-blend): Update. - (colir-blend-face-background): Update. - -2015-04-29 Oleh Krehel - - ivy.el (ivy--exhibit): Fixup last commit - - * ivy.el (ivy--old-text): Should always be a string. - (ivy-read): Update. - (ivy--exhibit): Recompute candidates on flip, always set `ivy--old-re' - to nil. - -2015-04-29 Oleh Krehel - - Improve hidden buffer completion further - - * ivy.el (ivy--exhibit): Update. - - Fixes #68 Fixes #69 - -2015-04-29 Oleh Krehel - - Improve the completion of hidden buffers - - * ivy.el (ivy--collection): New defvar. - (ivy-read): Update. - (ivy--exhibit): Update. - - Re #68. - -2015-04-29 Oleh Krehel - - Bind "TAB" to do partial completion - - * ivy.el (ivy-minibuffer-map): Update. - (ivy-alt-done): New defun. - (ivy--old-text): Update. - - Re #63. - -2015-04-28 Oleh Krehel - - counsel.el (counsel-git-grep): Add optional initial-input - - * counsel.el (counsel-git-grep): Update. - - Fixes #66 - -2015-04-28 Oleh Krehel - - ivy.el (ivy-re-builders-alist): Improve doc - - Re #62 - -2015-04-28 Oleh Krehel - - ivy.el: Fixup docstrings - - * ivy.el (ivy-require-match): Update. - (ivy-def): Update. - (ivy--prompt-extra): Update. - (ivy--maybe-scroll-history): Update. - (ivy-completing-read): Update. - (ivy--insert-minibuffer): Update. - (ivy--filter): Update. - -2015-04-28 Oleh Krehel - - Add an option for multi-tier regex matching - - * ivy.el (ivy--regex-plus): New defun. This is an example for the - multi-tier interface. - (ivy--filter): Update. - - To use it, add e.g.: - - (setq ivy-re-builders-alist - '((t . ivy--regex-plus))) - - Example using boost_1_58_0 and `find-file-in-project`: - - * "utility" - 234 matches - * "utility hpp" - 139 matches - * "utility !hpp" - 95 matches - - Fixes #62 - -2015-04-28 Oleh Krehel - - Makefile: Update - -2015-04-28 Oleh Krehel - - Use alpha compositing to add ivy-current-match face - - * ivy.el (ivy--exhibit): Use `colir-blend-face-background'. In case it - fails, try `font-lock-append-text-property', which was used before. - - * colir.el (colir-join): New defun. - (colir-blend): New defun. - (colir-blend-face-background): New defun. - -2015-04-28 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude `elfeed-search-mode' - -2015-04-28 Oleh Krehel - - ivy.el (ivy--filter): Fixup - - Fixes #65 - -2015-04-28 Oleh Krehel - - ivy.el (ivy-alt-done): Treat `ivy-text' with ":" verbatim - - * ivy.el (ivy-alt-done): Should work better now for ssh: stuff. - - It should be possible to type in any directory: `/ssh:user@domain.com:` - C-j and get completion. - - Re #59 - -2015-04-28 Oleh Krehel - - Store the preselect and use it for empty ivy-text - - * ivy.el (ivy-def): New defvar. - (ivy-read): Store `ivy-def'. - (ivy-completing-read): Update. - (ivy--filter): When the input is empty, set `ivy--index' to select - `ivy-def'. - - Fixes #64 - -2015-04-25 Oleh Krehel - - Improve completion history using the propertize trick - - * ivy.el (ivy-previous-history-element): Update. - (ivy-next-history-element): Update. - (ivy--maybe-scroll-history): New defun. When the history element string - has ivy-index property, set `ivy--index' to that. - - Fixes #46 - -2015-04-24 Oleh Krehel - - Minibuffer faces should inherit minibuffer-prompt - - * ivy.el (ivy-confirm-face): Update. - (ivy-match-required-face): Update. - - Re #60 - -2015-04-24 Oleh Krehel - - Improve the match confirm while completing files - - * ivy.el (ivy-confirm-face): New face. - (ivy-match-required-face): New face. - (ivy--prompt-extra): New defvar, the prompt is concatenaded with this. - (ivy--extend-prompt): Remove. - (ivy-done): Update. - (ivy--insert-prompt): Use `ivy--prompt-extra'. Reset it unless the - `this-command' is appropriate. - (ivy--set-match-props): New defun. - - Fixes #60 - -2015-04-24 Oleh Krehel - - Reset to the first candidate when switching directories - - * ivy.el (ivy--cd): Update. - -2015-04-24 Oleh Krehel - - Propertize remote buffers with ivy-remote face - - * ivy.el (ivy-remote): New face. - (ivy-read): Update. - - Fixes #61 - -2015-04-23 Oleh Krehel - - Respect `confirm-nonexistent-file-or-buffer' - - * ivy.el (ivy--extend-prompt): New defun. - (ivy-done): Ask for a confirmation if no candidates match and - `confirm-nonexistent-file-or-buffer' is t. - - Re #60 - -2015-04-23 Oleh Krehel - - ivy.el (ivy-read): Fixup preselect addition - - It was unnecessarily inserting `preselect' when completing tags. - -2015-04-23 Oleh Krehel - - ivy.el (ivy--cd): Reset `ivy--old-re' - - * ivy.el (ivy--cd): Switching directory switches the candidates, so - `ivy--old-re' must be invalidated. - - Fixes #58 - -2015-04-23 Oleh Krehel - - ivy.el (Info-current-file): Declare - -2015-04-23 Oleh Krehel - - Use "//" to move to root instead of "/" as before - - ivy.el (ivy--exhibit): Update. - - This improves the situation with tramp and generally avoids losing the - current directory by pressing "/" by accident. - - Fixes #59 - -2015-04-23 Oleh Krehel - - Avoid sorting org refile candidates - - * ivy.el (ivy-read): Update. - -2015-04-23 Oleh Krehel - - Exclude jabber-chat-mode from font-lock - - * swiper.el (swiper-font-lock-ensure): Update. - -2015-04-23 Oleh Krehel - - Remove globbing heuristics for file name completion - - * ivy.el (ivy-done): Simplify. - (ivy-alt-done): Simplify. - - If you want to exit with the current text, ignoring candidates, use - `ivy-immediate-done' instead. Works for globs as well. - - Fixes #55 - -2015-04-23 Oleh Krehel - - counsel.el (counsel-git-grep): Fixup - -2015-04-23 Oleh Krehel - - ivy.el (ivy-backward-delete-char): Expand `ivy--directory' - - This avoids the situation of getting a nil for "~/". - - Re #57 - -2015-04-23 Oleh Krehel - - ivy.el (ivy-done): Update wrt globs - - Re #55 - -2015-04-23 Oleh Krehel - - swiper.el (swiper-query-replace): Fix - -2015-04-23 Oleh Krehel - - swiper.el (swiper--ivy): Check for stand-alone ivy - - Re #54 - -2015-04-23 Oleh Krehel - - ivy.el (ivy-done): Don't expand globs - - Re #55 - -2015-04-22 Oleh Krehel - - README.md: Update video link - -2015-04-22 Oleh Krehel - - Fixup `swiper-query-replace' - - * swiper.el (swiper-query-replace): Make sure to use `swiper--window'. - - * ivy.el (ivy--minibuffer-setup): Remove the `use-local-map' statement, - the map is already set in `read-from-minibuffer'. - -2015-04-22 Oleh Krehel - - ivy-test.el (ivy-read): Update test. - - REQUIRE-MATCH is nil by default. - -2015-04-22 Oleh Krehel - - ivy.el (ivy-read): Fix preselect logic - - * ivy.el (ivy-read): Update. - - Fixes e.g. `ert' passing "t" as the default, which isn't in collection, - but `all-completions' doesn't return nil. - -2015-04-22 Oleh Krehel - - ivy.el (ivy-done): Fixup - -2015-04-22 Oleh Krehel - - ivy.el (ivy--add-face): Don't fail for weird str - - Fixes #44 - -2015-04-22 Oleh Krehel - - swiper.el (swiper--ivy): Fix preselect being added - -2015-04-22 Oleh Krehel - - ivy.el (ivy--exhibit): Wrap in `while-no-input' - - * ivy.el (ivy--exhibit): `ivy--dynamic-function' will sometimes use - `call-process'. Adding `while-no-input' speeds up things a lot, at the - cost of a small message interrupting the minibuffer when - `call-process' takes too long or the user types too fast. - This message is not an issue for emacs-snapshot. - -2015-04-22 Oleh Krehel - - Bind "M-q" to `ivy-toggle-regexp-quote' - - * ivy.el (ivy-minibuffer-map): Update. - (ivy--regexp-quote): New defvar. - (ivy-toggle-regexp-quote): New command, toggle `ivy--regex-function' - between the value selected in `ivy-read' and `ivy--regexp-quote'. - (ivy-read): Reset `ivy--regexp-quote' to 'regexp-quote. - - Fixes #48 - -2015-04-22 Oleh Krehel - - Allow to customize the regex matching per-collection - - * ivy.el (ivy--regex-function): New defvar. - (ivy-re-builders-alist): New defvar, use this to customize. - (ivy-read): Update. - (ivy--filter): Update. - - Currently, it only works for function collections. Example: - - (setq ivy-re-builders-alist - '((read-file-name-internal . regexp-quote) - (t . ivy--regex))) - - Re #48 - -2015-04-22 Oleh Krehel - - ivy.el (ivy-done): Be more strict for `require-match' - - When `require-match' isn't in (nil confirm confirm-after-completion), - don't allow to exit if there isn't a match. Instead, amend the prompt - with "(match required)". - -2015-04-22 Oleh Krehel - - Change `ivy-read' to a cl-defun - - * ivy.el (ivy-read): All args but PROMPT and COLLECTION are now keys. - The existing basic calls to `ivy-read' should still work, the others - need to be updated. It's best to try to use `ivy-completing-read' if - possible, since it conforms to the `completing-read' arguments. New - arguments: REQUIRE-MATCH and HISTORY. If HISTORY is nil, `ivy-history' - is used. - - (ivy--sorted-files): Don't try to extend the collection. - (ivy-completing-read): Update. - - * swiper.el (swiper--ivy): Update. - - * counsel.el (counsel-describe-symbol-history): New defvar. - (counsel-describe-variable): Update the call, require match, use - `counsel-describe-symbol-history'. - (counsel-describe-function): Update the call, require match, use - `counsel-describe-symbol-history'. - - * ivy-test.el: Update tests, since zero and one length input doesn't - return immediately any more. - - Re #46 - -2015-04-22 Oleh Krehel - - ivy.el (ivy--filter): Update prefix optimization - - * ivy.el (ivy--filter): Don't use prefix optimization when the input - contains "\". - -2015-04-22 Oleh Krehel - - README.md: Add a note on outdated ivy package - - Fixes #51 - -2015-04-21 Oleh Krehel - - ivy.el (ivy--filter): Try directory expansion with "/" - - * ivy.el (ivy--filter): If candidate is "x" and completing file names, - check if "x/" is among the candidates, and if so, set `ivy--index' - accordingly. - - Re #50 - -2015-04-21 Oleh Krehel - - Fix the default-directory for `counsel-git-grep' - - * counsel.el (counsel--git-grep-dir): New defvar. - (counsel-git-grep-count): Update. - (counsel-git-grep-function): Update. - (counsel-git-grep): Update. - -2015-04-21 Oleh Krehel - - Add a way to exit ignoring the candidates - - * ivy.el (ivy-immediate-done): New commad, currently unbound. Exit the - minibuffer, ignoring the candidates. Solves the same problem as - "C-f" in `ido-mode'. - (ivy-alt-done): With a prefix arg, e.g. "C-u C-j", forward to - `ivy-immediate-done'. - - Re #50 - -2015-04-21 Oleh Krehel - - ivy.el (ivy-read): Don't add the `default-directory' - -2015-04-21 Oleh Krehel - - ivy.el (ivy-read): Use initial-input when completing files - - * ivy.el (ivy-read): Unless `require-match', add `initial-input' to the - collection. This is important e.g. for `dired-dwim-target'. - -2015-04-21 Oleh Krehel - - swiper.el (swiper--add-overlays): Make bounds optional - -2015-04-21 Oleh Krehel - - counsel.el (counsel-git-grep-count): Ignore case - -2015-04-21 Oleh Krehel - - Fix describe-function / -variable "C-." interaction - - * counsel.el (counsel-describe-variable): Don't describe variable if - jump-to-symbol action was chosen. - (counsel-describe-function): Don't describe variable if - jump-to-symbol action was chosen. - - I should handle this more gracefully if multiple actions become a - pattern. - -2015-04-21 Oleh Krehel - - counsel.el: Add awesome swiper highlighting to git grep - - * counsel.el (swiper): Require. - (counsel-git-grep-function): Use `swiper--add-overlays'. Remember to set - `swiper--window', and call `swiper--cleanup'. Use `ivy--regex' in all - cases to build the regex. - -2015-04-21 Oleh Krehel - - ivy.el (ivy--regex): Add optional greedy arg - - * ivy.el (ivy--regex): When optional greedy arg is t, be greedy. Don't - wrap a sub-expr in a group if it's already a group, for instance - "forward \(char\|list\)". - - Greedy is needed, for instance, for "git grep", which doesn't work great - with non-greedy regex. - - Re #47 - -2015-04-21 Oleh Krehel - - swiper.el (swiper--add-overlays): Update arglist - - * swiper.el (swiper--update-input-ivy): Update. - (swiper--add-overlays): Take only the regexp as the argument. Figure out - the bounds by itself. - -2015-04-21 Oleh Krehel - - ivy.el (ivy-done): Don't directory-expand glob filename - - * ivy.el (ivy-done): Don't directory-expand if there's a star in the - file name. - - This change fixes the behavior of `rgrep`. It can't handle the case of - e.g. /foo/bar/\*.el, but handles \*.el fine. - - Re #45 - -2015-04-21 Oleh Krehel - - Add an option to call the completion action without exiting - - * ivy.el (ivy--persistent-action): New defvar. This is a lambda that the - caller sets if the caller has a plan for persistent actions. - (ivy-next-line-and-call): Add and bind to "C-M-n". Identical to "C-n", - except calls `ivy--persistent-action' when it's not nil. Add and bind to - "C-M-p". Identical to "C-p", except calls `ivy--persistent-action' when - it's not nil. - (ivy-window): New defvar. - (ivy-read): Store `ivy-window'. - - * counsel.el (counsel-git-grep): Use `ivy--persistent-action'. - - For `counsel-git-grep', as an example, it's possible to move to the - matched place without exiting the completion with "C-M-n" and "C-M-p". - This is a nice advantage, since it gives a full context to each one-line - git grep match. - -2015-04-21 Oleh Krehel - - Fix double-sorting for file names - - * ivy.el (ivy--sorted-files): Update. - (ivy-read): Update. - -2015-04-21 Oleh Krehel - - ivy.el (ivy--sorted-files): Avoid returning an empty list - - Fixes #49 - -2015-04-21 Oleh Krehel - - Allow to customize the sorting methods - - * ivy.el (ivy-sort-functions-alist): New defvar, stores sorting - functions for various function collection types. - (ivy-sort-file-function): Remove, merge into `ivy-sort-functions-alist'. - (ivy-sort-max-size): Don't sort candidate lists larger than this size. - (ivy--sorted-files): Update. - (ivy-read): Add an argument SORT. When it's t, sort the candidates - according to `ivy-sort-functions-alist'. It's assumed that if - COLLECTION is a function it's OK to `cl-sort' it without making a copy. - (ivy-completing-read): Call with SORT t. - - * counsel.el (counsel-describe-variable): Call with SORT t. - (counsel-describe-function): Call with SORT t. - -2015-04-21 Oleh Krehel - - ivy.el (ivy--regex): Switch to non-greedy ".*?" joiner - - Fixes #47 - -2015-04-21 Oleh Krehel - - ivy.el (ivy-done): Expand file name for empty text - - Fixes #45 - -2015-04-20 Oleh Krehel - - `counsel-git-grep' can now handle huge git repos - - * counsel.el (counsel-git-grep-count): Return a number instead of a - string. Apply `ivy--regex' on the input. - (counsel--git-grep-count): New defvar. - (counsel-git-grep-function): If the repo has >20000 lines, use `head' - 5000 instead, but still display the true amount of matches. - (counsel-git-grep): Set `ivy--dynamic-function'. - (counsel-locate-function): Update. - - * ivy.el (ivy--dynamic-function): New defvar. When this isn't nil, it - will be called to get a new batch of candidates in case the `ivy-text' - was changed. - (ivy--full-length): The true candidates length in case of `head' - shenanigans. - (ivy--old-text): Store the old text for when `ivy--dynamic-function' was - called last. - (ivy--insert-prompt): Update. - (ivy--exhibit): Don't do filtering for non-nil `ivy--dynamic-function' - - let the caller (usually a shell tool) do the filtering. - (ivy--insert-minibuffer): New defun, created from a part of - `ivy--exhibit'. - -2015-04-20 Oleh Krehel - - Use cl-plusp instead of plusp - - * ivy.el (cl-lib): Add require. - (ivy-alt-done): Update. - - Re #43 - -2015-04-20 Oleh Krehel - - Add a dynamic counsel-locate - - * counsel.el (counsel-locate-function): New defun. - (counsel-locate): New defun. - - * ivy.el (ivy--dynamic-function): New defvar. - (ivy--exhibit): Re-compute candidates use `ivy--dynamic-function' if - it's non-nil. - -2015-04-20 Oleh Krehel - - Split `ivy-completions' into `ivy--filter' and `ivy--format' - - * ivy.el (ivy--exhibit): Update. - (ivy-completions): Remove. - (ivy--filter): New defun. - (ivy--format): New defun. - -2015-04-20 Oleh Krehel - - counsel.el (counsel-git-grep-count): Add defun - -2015-04-20 Oleh Krehel - - swiper.el: Fix compilation warnings - -2015-04-20 Oleh Krehel - - Bind arrows - - * ivy.el (ivy-minibuffer-map): Update. - - Re #40 - -2015-04-20 Oleh Krehel - - Add an optimization to speed up matching - - * ivy.el (ivy-completions): Update. - -2015-04-20 Oleh Krehel - - swiper.el: Bump version - -2015-04-20 Oleh Krehel - - ivy.el (ivy-done): Still expand "./" though - -2015-04-20 Oleh Krehel - - Don't expand the default when completing file names - - * ivy.el (ivy-done): Update. - - This affects e.g. `rgrep': "\*.el" as the default will work, but - "foo/\*.el" won't. - -2015-04-20 Oleh Krehel - - Propertize directories with ivy-subdir face - - * ivy.el (ivy-subdir): New defface. - (ivy-completions): Update. - -2015-04-20 Oleh Krehel - - Speed up the default file sorting even more - - * ivy.el (ivy--sorted-files): Use `string-match-p' instead of - `file-directory-p'. - -2015-04-20 Oleh Krehel - - Speed up the default file sorting - - * ivy.el (ivy-sort-file-function-default): Update. - (ivy--sorted-files): Update. - - Turns out that calling `file-directory-p' in `cl-sort' is too expensive. - So when `ivy-sort-file-function' is `ivy-sort-file-function-default', - propertize all strings with whether they are directories or not. - - When `ivy-sort-file-function' is something different, e.g. - `string-lessp', don't do propertizing since it also can be slow. - -2015-04-20 Oleh Krehel - - ivy.el (ivy--preselect-index): Give priority to perfect match - -2015-04-20 Oleh Krehel - - Allow "C-." to jump to current symbol definition - - * counsel.el (counsel-describe-map): New defvar. - (counsel-find-symbol): New defun. - (counsel--find-symbol): New defun - jump to definition of function or - symbol or library. - (counsel-describe-variable): Use `counsel-describe-map'. - (counsel-describe-function): Use `counsel-describe-map'. - -2015-04-20 Oleh Krehel - - Allow to customize the file sorting order - - * ivy.el (ivy-sort-file-function-default): New defun. - (ivy-sort-file-function): New defvar. Set this to your preference. - (ivy--sorted-files): Update. - - Fixes #38 - -2015-04-19 Oleh Krehel - - ivy.el (ivy-done): Update for non-matching file names - - * ivy.el (ivy-done): When `ivy--directory' is non-nil, accept input - anyway. - - Fixes #39 - -2015-04-19 Oleh Krehel - - ivy.el (ivy-completions): Fix an optimization - -2015-04-19 Oleh Krehel - - Add a matching optimization - - * ivy.el (ivy-completions): When the new regex `re' is a contains the - old regex `ivy--old-re', it must be true that all candidates that - match `re' are contained inside all candidates that match - `ivy--old-re', i.e. the pre-computed in the last step - `ivy--old-cands'. - - This should speed up completion for large (~100k) amount of candidates, - for the particular case of regex simply being extended. - -2015-04-19 Oleh Krehel - - counsel.el (counsel-git-grep): Fix the default-directory - -2015-04-19 Oleh Krehel - - Add a command to grep the current git repo - - * counsel.el (counsel-git-grep-function): New defun. - (counsel-git-grep): New command. - -2015-04-19 Oleh Krehel - - Add "C-v" and "M-v" scrolling - - * ivy.el (ivy-minibuffer-map): Update. - (ivy-scroll-up-command): New defun. - (ivy-scroll-down-command): New defun. - -2015-04-18 Oleh Krehel - - ivy.el (ivy-alt-done): Update for 0 candidates - -2015-04-18 Oleh Krehel - - swiper.el: Add a work-around for window-start not being current - - * swiper.el (swiper--update-input-ivy): Update. - - This results in double the window-height amount of lines being - heightlighted, instead of just window-height. But at least it doesn't - happen that some candidates within the current window aren't highlighted - since they're beyond the outdated window-start and window-end. - - An alternative would be to use `redisplay' to update `window-start' and - `window-end', but that causes excessive blinking. - - * ivy-test.el: Add a require. - -2015-04-18 Oleh Krehel - - ivy.el: Move all defvar before their first use - -2015-04-18 Oleh Krehel - - Add ivy key bindings to "C-h m" - - * ivy.el (ivy-mode): Update. - - Re #37 - -2015-04-18 Oleh Krehel - - Allow to customize the dotted directories - - * ivy.el (ivy-extra-directories): New defcustom. - (ivy--sorted-files): Update. - - Re #38 - -2015-04-18 Oleh Krehel - - Add a work-around for completing topics in the info dir - - * ivy.el (ivy-read): Weirdly, the topic names need to be wrapped in - "(...)". Also, `all-completions' returns nothing for "", but returns - stuff for "(". Also, `all-completions' for "(" returns plenty of - duplicates. - -2015-04-18 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude dired-mode - -2015-04-18 Oleh Krehel - - counsel.el: Switch from `with-no-warnings' to `declare-function' - -2015-04-17 Oleh Krehel - - Allow to complete dir with "/" if it's a perfect match - - * ivy.el (ivy--exhibit): Update. - -2015-04-17 Oleh Krehel - - Add sorting for file completion - - * ivy.el (ivy-alt-done): Exit with current directory when on first - element, which is always "./", thanks to sorting. - (ivy--cd): Update. - (ivy--sorted-files): New defun for sorting file names. "./" and "../" - are always the first, then come the directories, then the files. - (ivy-read): Update. - -2015-04-17 Oleh Krehel - - Add "/" and "~" shortcuts while finding files - - * ivy.el (ivy--cd): New defun. - (ivy-backward-delete-char): Use `ivy--cd'. - (ivy--exhibit): When the file completion text ends in "/" or "~", move - to those dirs. - -2015-04-17 Oleh Krehel - - Add work-around for DEF not being in COLLECTION for `completing-read' - - * ivy.el (ivy-read): Update. - -2015-04-17 Oleh Krehel - - swiper.el: Remove dependency on ivy - - ivy.el now comes together with swiper. - - Re #36. - -2015-04-16 Oleh Krehel - - Ivy-mode now works better with `find-file' - - * ivy.el (ivy-minibuffer-map): Bind "C-j" to visit a directory without - exiting the minibuffer. - (ivy--directory): New defvar. - (ivy-done): Expand file names. - (ivy-alt-done): New defun. - (ivy-backward-delete-char): When completing file names, visit the parent - dir. - (ivy-read): Add the predicate argument, similar to `completing-read'. - All code that uses `ivy-read' needs to be updated. Move the - collection/predicate stuff here. - (ivy-completing-read): Update. - (ivy--insert-prompt): Display the current directory when completing file - names. - -2015-04-16 Oleh Krehel - - ivy.el (ivy-completing-read): Rely more on `all-completions' - -2015-04-16 Oleh Krehel - - Add require-match functionality - - * ivy.el (ivy-require-match): New defvar. - (ivy-done): When nothing matches, and `ivy-require-match' isn't t, use - the current text anyway. - (ivy-completing-read): Update. - -2015-04-16 Oleh Krehel - - Add function as collection support for ivy-mode - - * ivy.el (ivy-completing-read): Update. Ignore initial input for - function collection type. - -2015-04-16 Oleh Krehel - - Don't try to fontify huge buffers - - * swiper.el (swiper-font-lock-ensure): Update. - -2015-04-16 Oleh Krehel - - Remove ido-mode shenanigans - - Combining `ido-mode' and `ivy-read' seemed to cause a problem at some - stage. Can't reproduce now, so I'll just remove this for a while. - -2015-04-16 Oleh Krehel - - swiper.el: Bump version - -2015-04-13 Oleh Krehel - - Fix thing-at-point in describe-function and -variable - - * counsel.el (counsel-describe-variable): Update. - (counsel-describe-function): Update. - -2015-04-10 Oleh Krehel - - Update sorting order, make sure that perfect match is selected - - ivy.el (ivy-completions): Update. - - When the regex matches perfectly, select it. - -2015-04-09 Oleh Krehel - - Add ivy-mode - - * ivy.el (ivy-completing-read): New defun. - (ivy-mode): New global minor mode. - -2015-04-09 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude org-agenda-mode - - Re #19 - -2015-04-09 Oleh Krehel - - Add four more commands - - * counsel.el (counsel-describe-variable): New defun. - (counsel-describe-function): New defun. - (counsel-info-lookup-symbol): New defun. - (counsel-unicode-char): New defun. - - * Makefile: Compile counsel.el as well. - -2015-04-03 Steve Purcell - - Fix invalid package header line - -2015-04-03 Oleh Krehel - - counsel.el: Fixup prefixes - -2015-04-03 Oleh Krehel - - counsel.el (couns-clj): Add with-no-warnings - -2015-04-02 Oleh Krehel - - counsel.el: Update comments - -2015-03-31 Oleh Krehel - - Fix `ivy-backward-delete-char-function' - - * ivy.el (ivy-on-del-error-function): Rename from - `ivy-backward-delete-char-function'. - (ivy-backward-delete-char): Don't use eval. - -2015-03-30 Kevin - - Add defcustom for ivy-backward-delete-char - -2015-03-30 Oleh Krehel - - Allow duplicate candidates in `ivy-read' - - * ivy.el (ivy-completions): Use `eq' instead of `equal' in - `cl-position'. - -2015-03-27 Oleh Krehel - - swiper.el (swiper-map): Bind "C-l" to recenter - - * swiper.el (swiper-map): Update. - (swiper-recenter-top-bottom): New defun. - (swiper--update-input-ivy): Use `<=' in order for `recenter-top-bottom' - to work. - -2015-03-26 Oleh Krehel - - swiper.el (swiper-query-replace): Enable recursive minibuffers - - * swiper.el (swiper-query-replace): Update. - - Fixes #31. - -2015-03-26 Oleh Krehel - - Default ARG to 1 for arrows - - * ivy.el (ivy-next-line): Update. - (ivy-previous-line): Update. - -2015-03-26 Oleh Krehel - - Add numeric arguments to arrows - - * ivy.el (ivy-next-line): Update. - (ivy-next-line-or-history): Update. - (ivy-previous-line): Update. - (ivy-previous-line-or-history): Update. - (ivy-read): Update doc. - -2015-03-26 Oleh Krehel - - "C-s" should forward to "C-n" etc - - * ivy.el (ivy-next-line-or-history): Update. - (ivy-previous-line-or-history): Update. - -2015-03-25 Oleh Krehel - - Allow to cancel "M-q" with "C-g" - - swiper.el (swiper-query-replace): If the TO argument to - `perform-replace' isn't read, don't exit minibuffer. - - If the user called `swiper-query-replace' and isn't happy with the - current input being the FROM arg of `perform-replace', it's possible to - cancel with "C-g", and edit the input once again. - -2015-03-25 Oleh Krehel - - swiper.el (swiper-query-replace): Call only in minibuffer - -2015-03-25 Oleh Krehel - - Add swiper-query-replace - - * ivy.el (ivy-read): Update signature - a keymap is also accepted and - the argument order has changed. - The keymap is composed with `ivy-minibuffer-map'. - Update for `ivy--action'. - (ivy--action): New defvar. If a function sets it, `ivy-read' will call - it. - - * swiper.el (swiper-map): New defvar. - (swiper-query-replace): New defun. - (swiper--ivy): Use swiper-map in the call to `ivy-read'. - - * counsel.el (couns-git): Fix one empty candidate. - -2015-03-25 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Ignore gnus modes - -2015-03-23 Oleh Krehel - - Ensure that inserted candidates don't have read-only property - - * ivy.el (ivy-completions): Update. - - Fixes #28. - - The issue was that the whole text of erc buffer has (read-only t) - property. That means if I copy some of those strings and insert them - into the minibuffer, I can't delete them unless I set - `inhibit-read-only' to t. Instead, I set the read-only to nil for the - string that I insert. It doesn't affect the original buffer string. - -2015-03-23 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Omit erc-mode - - Re #28 - -2015-03-22 Oleh Krehel - - Update Copyright - -2015-03-22 Oleh Krehel - - Move swiper-helm to another repo - -2015-03-22 John Mastro - - ivy.el (ivy-wrap): New defcustom - - (ivy-next-line): Wrap around if `ivy-wrap' is non-nil - (ivy-next-line-or-history): Wrap around if `ivy-wrap' is non-nil - (ivy-previous-line): Wrap around if `ivy-wrap' is non-nil - (ivy-previous-line-or-history): Wrap around if `ivy-wrap' is non-nil - -2015-03-22 John Mastro - - swiper.el (swiper-min-highlight): New defcustom - - (swiper--add-overlays): Use `swiper-min-highlight' - -2015-03-22 John Mastro - - swiper.el (swiper--init): Set `swiper--opoint' - - (swiper): Don't set `swiper--opoint' - -2015-03-21 Oleh Krehel - - Update "C-n" and "C-p" bindings - - * ivy.el (ivy-next-line): Don't touch history. - (ivy-next-line-or-history): Select previous history element if there's - no input. - (ivy-previous-line): Don't touch history. - (ivy-previous-line-or-history): Select previous history element if - there's no input. - - Re #23 - -2015-03-21 Oleh Krehel - - Use `font-lock-append-text-property' to non-destructively modify a - string - - * ivy.el (ivy--add-face): Improve. - `font-lock-append-text-property' non-destructively changes properties in - a string, which means if a string was copied from another and modified, - the original will not be changed. In this way, it's better than - `add-face-text-property'; and still better than `propertize' that simply - erases all properties before applying. - - Fixes #22 - -2015-03-21 Steve Purcell - - Fix invalid package header line - -2015-03-21 Oleh Krehel - - Add a custom `ivy-count-format' - - * ivy.el (ivy-count-format): New defcustom. - (ivy-read): Use `ivy-count-format', unless PROMPT already has a %d spec. - - Set `ivy-count-format' to nil or "" if you don't want to see an - auto-updating match count in the minibuffer. - - Re #23. - -2015-03-21 Oleh Krehel - - swiper-helm.el: Fix typo - -2015-03-21 Oleh Krehel - - swiper.el: Remove the helm bits - - They are now in swiper-helm.el. Available for install separately from - MELPA. - -2015-03-20 Oleh Krehel - - swiper-helm.el: Copy all helm stuff here - -2015-03-20 Oleh Krehel - - ivy.el (ivy-completions): Simplify - -2015-03-19 Oleh Krehel - - ivy.el: Remove while-no-input - - This will speed up the updates. But it might slow down somewhere else. - The issue was that "M-DEL" did not cause an update. - -2015-03-19 Oleh Krehel - - README.md: Add build status - -2015-03-19 Oleh Krehel - - ivy.el (ivy-read): Allow for format-style PROMPT - - * ivy.el (ivy-read): When given a prompt of e.g. "%d pattern: ", update - the number of candidates in the prompt. - (ivy--prompt): New defvar. - (ivy--insert-prompt): New defun. - (ivy--exhibit): Call `ivy--insert-prompt'. - (ivy-completions): Fix a bug of `ivy--index' becoming -1 when the number - of matches becomes zero. - - * swiper.el (swiper--format-spec): New defvar. - (swiper--candidates): Update. - (swiper--ivy): Use `swiper--format-spec' to make the prompt. - -2015-03-19 Oleh Krehel - - ivy.el (ivy-read): Change index to preselect - - * ivy.el (ivy-read): Update signature. Instead of giving the integer - index of what to preselect, give a string to preselect. - (ivy--preselect-index): New defun. - - * swiper.el (swiper--index-at-point): Rename to `ivy--preselect-index'. - (swiper--ivy): Simplify. - -2015-03-19 Oleh Krehel - - ivy-test.el: Add testing - - * Makefile: Add a test and compile target. - -2015-03-19 Oleh Krehel - - ivy.el: Return nil when there is no match - - * ivy.el (ivy-done): Update. - (ivy-read): Update. - -2015-03-19 Oleh Krehel - - swiper.el: Silence a few compilation warnings - -2015-03-18 Oleh Krehel - - swiper.el: Fix non-matching lines issue with initial-input - - * swiper.el (swiper--index-at-point): New defun. - (swiper--ivy): Update. - - Fixes #20. - -2015-03-18 Oleh Krehel - - Add isearch-like history behavior - - * ivy.el (ivy-next-line): Select previous history element for empty - input. - (ivy-previous-line): Select previous history element for empty input. - (ivy-previous-history-element): New defun. - (ivy-next-history-element): New defun. - - Re #21 - -2015-03-18 Oleh Krehel - - ivy.el (ivy-read): Bring last history candidate to front - -2015-03-18 Oleh Krehel - - counsel.el: Add git file completion - - * counsel.el (couns-git): Add. - -2015-03-18 Oleh Krehel - - swiper.el (swiper--helm): Require helm-match-plugin - - This seems to be necessary after a recent helm update. - -2015-03-18 Oleh Krehel - - ivy.el: Fix ivy-history recording the full text instead of input - - * ivy.el (ivy-read): Update. - - Fixes #21 - -2015-03-18 Oleh Krehel - - swiper.el (swiper-font-lock-ensure): Exclude a few modes - - Re #19 - -2015-03-17 Oleh Krehel - - Work around magit highlighting problem - - * swiper.el (swiper-font-lock-ensure): Update. - - Re #19 - -2015-03-17 Oleh Krehel - - swiper.el (swiper--opoint): Fix bad defvar - -2015-03-17 Oleh Krehel - - counsel.el: Add Clojure completion at point - -2015-03-17 Oleh Krehel - - swiper.el: Fix error for empty buffer - - * swiper.el (swiper--candidates): Update. - (swiper--action): Update. - - Fixes #17. - -2015-03-16 killdash9 - - Need to check value of variable - -2015-03-16 Oleh Krehel - - swiper.el: Clean up overlays better on "C-g" - - * swiper.el (swiper--cleanup): Improve. - - Fixes #11. - -2015-03-16 Oleh Krehel - - Open invisible overlays using isearch - - * swiper.el (swiper--update-input-ivy): Improve. - - Fixes #11. - -2015-03-16 Oleh Krehel - - ivy.el (ivy-read): Return immediately for less than 2 candidates - -2015-03-16 Oleh Krehel - - counsel.el: Add - -2015-03-15 Oleh Krehel - - Truncate candidates to window width in the minibuffer - - * ivy.el (ivy-completions): Update. - -2015-03-15 Oleh Krehel - - Add some rudimentary history handling - - * ivy.el (ivy-minibuffer-map): Bind "M-n", "M-p", and "C-g". - (ivy-history): New defvar. - (ivy-read): Update. - (ivy--minibuffer-setup): Offer thing-at-point for "M-n". - (ivy--default): New defvar. - - Re #16. - -2015-03-15 Oleh Krehel - - ivy.el (ivy-previous-line): Change to `cl-decf' - - Re #15 - -2015-03-15 Oleh Krehel - - swiper.el: Make ivy the default back end - -2015-03-15 Oleh Krehel - - Don't recenter unless necessary - - * swiper.el (swiper--update-input-ivy): Update. - -2015-03-15 Oleh Krehel - - Add anchoring - - * ivy.el (ivy-read): Add optional argument INDEX. It's the index of - initally selected entry. - (ivy-completions): Update. - - * swiper.el (swiper--ivy): Call `ivy-read' with `line-number-at-pos'. - - Fixes #16 - -2015-03-15 Xavier Garrido - - Fix use of cl-incf - - * ivy.el (ivy-next-line): Update. - - Fixes #15 - -2015-03-14 Oleh Krehel - - Require delsel for `minibuffer-keyboard-quit' - - * ivy.el (ivy-backward-delete-char): Update. - - Fixes #14. - -2015-03-14 Oleh Krehel - - swiper.el: Save position before last search - - * swiper.el (swiper--ivy): Forward to `swiper--action'. - (swiper--helm): Use `swiper--action-helm'. - (swiper--action-helm): New defun. - (swiper--action): Generalize, use push-mark, similarly to `isearch'. - - Fixes #12. - -2015-03-14 Oleh Krehel - - Reveal invisible overlays - - * swiper.el (swiper--ivy): Update. - (swiper--ensure-visible): New defun. - (swiper--action): Update. - - Fixes #11. - -2015-03-14 Steve Purcell - - Inherit standard faces by default - - Every time a new custom face definition is created, it breaks every - existing theme. Better, then, to inherit standard faces by default. - - This commit has the side benefit of making the faces defined here - legible in themes with dark backgrounds. - -2015-03-14 Oleh Krehel - - swiper.el: Restore original point on canceling - - * swiper.el (swiper--opoint): New defvar. - (swiper): Update. - (swiper--ivy): Update. - - Fixes #9. - -2015-03-14 Oleh Krehel - - ivy.el: Add `ivy-exit' - - * ivy.el (ivy-done): Update. - (ivy-read): Update. - (ivy-exit): New defvar. - -2015-03-14 Oleh Krehel - - Add initial-input optional argument - - * swiper.el (swiper): Update. - (swiper--ivy): Update. - (swiper--helm): Update. - - * ivy.el (ivy-read): Update. - - Fixes #8. - -2015-03-13 Oleh Krehel - - Account for zero-length regex matches - - * swiper.el (swiper--add-overlays): Update. - - Fixes #6. - -2015-03-13 Oleh Krehel - - swiper.el: Use `with-selected-window' instead of `with-current-buffer' - - * swiper.el (swiper--buffer): Remove. - (swiper--init): Update. - (swiper--update-input-helm): Update. - (swiper--update-input-ivy): Update. - (swiper--update-sel): Update. - -2015-03-13 Oleh Krehel - - ivy.el: Improve the highlighting in the minibuffer - - * ivy.el (ivy--add-face): Use `add-face-text-property' if it's - available. You need to upgrade to Emacs 24.4 to get this feature. - (ivy-completions): Use `ivy--add-face'. - -2015-03-13 Oleh Krehel - - README.md: Update - -2015-03-13 Oleh Krehel - - Update dependencies. - - * ivy.el: Depend on emacs "24.1". - - * swiper.el: Depend on ivy "0.1.0". - -2015-03-13 Oleh Krehel - - Add `ivy' back end - - * ivy.el: New completion back end. - - * swiper.el: Package doesn't depend on `helm'. - (ivy): Depend on `ivy'. - (swiper-completion-method): New defcustom. - (swiper--window): New var. - (swiper--helm-keymap): Rename from `swiper--keymap'. - (swiper): Change to a dispatch. - (swiper--init): New defun. - (swiper--ivy): New command. - (swiper--helm): New command. - (swiper--cleanup): New defun. - (swiper--update-input-helm): Rename from `swiper--update-input'. - (swiper--update-input-ivy): New defun. - (swiper--add-overlays): New defun. - (swiper--update-sel): Update. - (swiper--subexps): - (swiper--regex-hash): - (swiper--regex): Move to ivy. - (swiper--action): Update. - -2015-03-11 killdash9 - - familiar isearch key bindings while helm is active - -2015-03-11 Oleh Krehel - - swiper.el (swiper--regex): Update signature - -2015-03-11 Syohei YOSHIDA - - Use cl-lib macros instead of cl.el - -2015-03-11 Syohei YOSHIDA - - add autoload cookie for lazy loading - -2015-03-11 Oleh Krehel - - Add dependency on emacs 24.1 - -2015-03-10 Oleh Krehel - - Add compatibility alias for `font-lock-ensure' - - * swiper.el (swiper-font-lock-ensure): Add. - - Fixes #1. - -2015-03-10 Oleh Krehel - - README.md: Add - -2015-03-10 Oleh Krehel - - swiper.el (swiper--regex): Zero groups without space - - * swiper.el (swiper--update-input): Update the face order accordingly. - -2015-03-10 Oleh Krehel - - Update call to `font-lock-ensure' - - * swiper.el (swiper--candidates): `font-lock-ensure' takes no arguments - in 24.4.1. - -2015-03-09 Oleh Krehel - - Initial import - diff --git a/elpa/swiper-0.13.1/swiper-pkg.el b/elpa/swiper-0.13.1/swiper-pkg.el deleted file mode 100644 index 9dfc592..0000000 --- a/elpa/swiper-0.13.1/swiper-pkg.el +++ /dev/null @@ -1,2 +0,0 @@ -;; Generated package description from swiper.el -*- no-byte-compile: t -*- -(define-package "swiper" "0.13.1" "Isearch with an overview. Oh, man!" '((emacs "24.5") (ivy "0.13.1")) :keywords '("matching") :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/swiper-0.13.1/swiper-autoloads.el b/elpa/swiper-0.13.4/swiper-autoloads.el similarity index 95% rename from elpa/swiper-0.13.1/swiper-autoloads.el rename to elpa/swiper-0.13.4/swiper-autoloads.el index bd4b480..8ae878c 100644 --- a/elpa/swiper-0.13.1/swiper-autoloads.el +++ b/elpa/swiper-0.13.4/swiper-autoloads.el @@ -47,10 +47,6 @@ Like `swiper-isearch' but the first result is before the point. (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "swiper" '("swiper-"))) -;;;*** - -;;;### (autoloads nil nil ("swiper-pkg.el") (0 0 0 0)) - ;;;*** ;; Local Variables: diff --git a/elpa/swiper-0.13.4/swiper-pkg.el b/elpa/swiper-0.13.4/swiper-pkg.el new file mode 100644 index 0000000..68ce20c --- /dev/null +++ b/elpa/swiper-0.13.4/swiper-pkg.el @@ -0,0 +1,2 @@ +;;; Generated package description from swiper.el -*- no-byte-compile: t -*- +(define-package "swiper" "0.13.4" "Isearch with an overview. Oh, man!" '((emacs "24.5") (ivy "0.13.4")) :commit "8cf3f1821cbd1c266296bbd5e59582ae6b8b90a6" :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :keywords '("matching") :url "https://github.com/abo-abo/swiper") diff --git a/elpa/swiper-0.13.1/swiper.el b/elpa/swiper-0.13.4/swiper.el similarity index 85% rename from elpa/swiper-0.13.1/swiper.el rename to elpa/swiper-0.13.4/swiper.el index 10813a4..bc4c589 100644 --- a/elpa/swiper-0.13.1/swiper.el +++ b/elpa/swiper-0.13.4/swiper.el @@ -1,11 +1,13 @@ ;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*- -;; Copyright (C) 2015-2019 Free Software Foundation, Inc. +;; Copyright (C) 2015-2021 Free Software Foundation, Inc. ;; Author: Oleh Krehel ;; URL: https://github.com/abo-abo/swiper -;; Version: 0.13.1 -;; Package-Requires: ((emacs "24.5") (ivy "0.13.1")) +;; Package-Version: 0.13.4 +;; Package-Commit: 8cf3f1821cbd1c266296bbd5e59582ae6b8b90a6 +;; Version: 0.13.4 +;; Package-Requires: ((emacs "24.5") (ivy "0.13.4")) ;; Keywords: matching ;; This file is part of GNU Emacs. @@ -42,47 +44,47 @@ :prefix "swiper-") (defface swiper-match-face-1 - '((t (:inherit lazy-highlight))) + '((t :inherit lazy-highlight)) "The background face for `swiper' matches." :group 'ivy-faces) (defface swiper-match-face-2 - '((t (:inherit isearch))) + '((t :inherit isearch)) "Face for `swiper' matches modulo 1." :group 'ivy-faces) (defface swiper-match-face-3 - '((t (:inherit match))) + '((t :inherit match)) "Face for `swiper' matches modulo 2." :group 'ivy-faces) (defface swiper-match-face-4 - '((t (:inherit isearch-fail))) + '((t :inherit isearch-fail)) "Face for `swiper' matches modulo 3." :group 'ivy-faces) (defface swiper-background-match-face-1 - '((t (:inherit swiper-match-face-1))) + '((t :inherit swiper-match-face-1)) "The background face for non-current `swiper' matches." :group 'ivy-faces) (defface swiper-background-match-face-2 - '((t (:inherit swiper-match-face-2))) + '((t :inherit swiper-match-face-2)) "Face for non-current `swiper' matches modulo 1." :group 'ivy-faces) (defface swiper-background-match-face-3 - '((t (:inherit swiper-match-face-3))) + '((t :inherit swiper-match-face-3)) "Face for non-current `swiper' matches modulo 2." :group 'ivy-faces) (defface swiper-background-match-face-4 - '((t (:inherit swiper-match-face-4))) + '((t :inherit swiper-match-face-4)) "Face for non-current `swiper' matches modulo 3." :group 'ivy-faces) (defface swiper-line-face - '((t (:inherit highlight))) + '((t :inherit highlight)) "Face for current `swiper' line." :group 'ivy-faces) @@ -108,13 +110,12 @@ swiper-background-match-face-4)) (colir-compose-method #'colir-compose-soft-light)) (cl-mapc (lambda (f1 f2) - (let ((bg (face-background f1))) + (let* ((bg (face-background f1)) + ;; FIXME: (colir-color-parse "color-22") is nil. + (bg (and bg (colir-color-parse bg)))) (when bg - (set-face-background - f2 - (colir-blend - (colir-color-parse bg) - (colir-color-parse "#ffffff")))))) + (setq bg (colir-blend bg (colir-color-parse "#ffffff"))) + (set-face-background f2 bg)))) swiper-faces faces))) (swiper--recompute-background-faces) @@ -134,8 +135,17 @@ Treated as non-nil when searching backwards." :type 'boolean :group 'swiper) +(defun swiper-C-s (&optional arg) + "Move cursor vertically down ARG candidates. +If the input is empty, select the previous history element instead." + (interactive "p") + (if (string= ivy-text "") + (ivy-previous-history-element 1) + (ivy-next-line arg))) + (defvar swiper-map (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-s") 'swiper-C-s) (define-key map (kbd "M-q") 'swiper-query-replace) (define-key map (kbd "C-l") 'swiper-recenter-top-bottom) (define-key map (kbd "C-'") 'swiper-avy) @@ -149,16 +159,16 @@ Treated as non-nil when searching backwards." (defun swiper--query-replace-updatefn () (let ((lisp (ignore-errors (nth 2 (query-replace-compile-replacement ivy-text t))))) (dolist (ov swiper--query-replace-overlays) - (when lisp - (dolist (x (overlay-get ov 'matches)) - (setq lisp (cl-subst (cadr x) (car x) lisp :test #'equal))) - (setq lisp (ignore-errors (eval lisp)))) (overlay-put ov 'after-string (propertize - (if (stringp lisp) - lisp - ivy-text) + (condition-case nil + (with-current-buffer (overlay-buffer ov) + (set-match-data (overlay-get ov 'md)) + (if (consp lisp) + (eval lisp) + (match-substitute-replacement ivy-text))) + (error ivy-text)) 'face 'error))))) (defun swiper--query-replace-cleanup () @@ -168,19 +178,19 @@ Treated as non-nil when searching backwards." (defun swiper--query-replace-setup () (with-ivy-window (let ((end (window-end (selected-window) t)) - (re (ivy--regex ivy-text))) + (re (ivy-re-to-str ivy-regex))) (save-excursion (beginning-of-line) - (while (and (re-search-forward re end t) - (not (eobp))) + (while (re-search-forward re end t) (let ((ov (make-overlay (1- (match-end 0)) (match-end 0))) - (md (match-data))) + (md (match-data t))) (overlay-put ov 'matches (mapcar (lambda (x) (list `(match-string ,x) (match-string x))) (number-sequence 0 (1- (/ (length md) 2))))) + (overlay-put ov 'md md) (push ov swiper--query-replace-overlays)) (unless (> (match-end 0) (match-beginning 0)) (forward-char))))))) @@ -196,14 +206,18 @@ Treated as non-nil when searching backwards." (swiper--query-replace-setup) (unwind-protect (let* ((enable-recursive-minibuffers t) - (from (ivy--regex ivy-text)) + (from (ivy-re-to-str ivy-regex)) + (groups (number-sequence 1 ivy--subexps)) (default - (format "\\,(concat %s)" - (if (<= ivy--subexps 1) - "\\&" - (mapconcat (lambda (i) (format "\\%d" i)) - (number-sequence 1 ivy--subexps) - " \" \" ")))) + (list + (mapconcat (lambda (i) (format "\\%d" i)) groups " ") + (format "\\,(concat %s)" + (if (<= ivy--subexps 1) + "\\&" + (mapconcat + (lambda (i) (format "\\%d" i)) + groups + " \" \" "))))) (to (query-replace-compile-replacement (ivy-read @@ -223,6 +237,7 @@ Treated as non-nil when searching backwards." (ivy-configure 'swiper-query-replace :update-fn #'swiper--query-replace-updatefn) +(put 'swiper-query-replace 'no-counsel-M-x t) (defvar inhibit-message) @@ -247,6 +262,7 @@ Treated as non-nil when searching backwards." (goto-char (point-min)) (perform-replace from to t t nil))) (set-window-configuration wnd-conf)))))))) +(put 'swiper-all-query-replace 'no-counsel-M-x t) (defvar avy-all-windows) (defvar avy-style) @@ -432,6 +448,7 @@ such as `scroll-conservatively' are set to a high value.") package-menu-mode rcirc-mode sauron-mode + sieve-mode treemacs-mode twittering-mode vc-dir-mode @@ -452,6 +469,7 @@ such as `scroll-conservatively' are set to a high value.") (unless (swiper-font-lock-ensure-p) (unless (or (> (buffer-size) 100000) (null font-lock-mode)) (if (fboundp 'font-lock-ensure) + ;; Added in Emacs 25.1. (font-lock-ensure) (with-no-warnings (font-lock-fontify-buffer)))))) @@ -488,8 +506,6 @@ such as `scroll-conservatively' are set to a high value.") " " (buffer-substring beg end)))) -(declare-function outline-show-all "outline") - (defvar swiper-use-visual-line-p (lambda (n-lines) (and visual-line-mode @@ -511,6 +527,7 @@ numbers; replaces calculating the width from buffer line count." (when (eq major-mode 'org-mode) (require 'outline) (if (fboundp 'outline-show-all) + ;; Added in Emacs 25.1. (outline-show-all) (with-no-warnings (show-all)))) @@ -565,7 +582,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (let ((thing (ivy-thing-at-point))) (when (use-region-p) (deactivate-mark)) - (swiper thing))) + (swiper (regexp-quote thing)))) ;;;###autoload (defun swiper-all-thing-at-point () @@ -574,7 +591,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (let ((thing (ivy-thing-at-point))) (when (use-region-p) (deactivate-mark)) - (swiper-all thing))) + (swiper-all (regexp-quote thing)))) (defun swiper--extract-matches (regex cands) "Extract captured REGEX groups from CANDS." @@ -604,7 +621,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (if (eq (ivy-state-caller ivy-last) 'swiper-isearch) (swiper--isearch-occur-cands cands) (mapcar (lambda (s) - (let ((n (get-text-property 0 'swiper-line-number s))) + (let ((n (swiper--line-number s))) (setq s (substring s 1)) (add-text-properties 0 1 (list 'swiper-line-number n) s) (cons n s))) @@ -655,6 +672,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (defun swiper-occur (&optional cands) "Generate a custom occur buffer for `swiper'. When capture groups are present in the input, print them instead of lines." + (setq cands (or ivy-marked-candidates cands)) (let* ((buffer (swiper--occur-buffer)) (fname (propertize (with-ivy-window @@ -664,18 +682,20 @@ When capture groups are present in the input, print them instead of lines." (buffer-name buffer))) 'face 'ivy-grep-info)) - (ivy-text (progn (string-match "\"\\(.*\\)\"" (buffer-name)) - (match-string 1 (buffer-name)))) - (re (mapconcat #'identity (ivy--split ivy-text) ".*?")) + (re + (progn + (string-match "\"\\(.*\\)\"" (buffer-name)) + (ivy-set-text (match-string 1 (buffer-name))) + (mapconcat #'identity (ivy--split ivy-text) ".*?"))) (cands (swiper--occur-cands fname (or cands (save-window-excursion - (setq ivy--old-re nil) (switch-to-buffer buffer) (if (eq (ivy-state-caller ivy-last) 'swiper) (let ((ivy--regex-function 'swiper--re-builder)) + (setq ivy--old-re nil) (ivy--filter re (swiper--candidates))) (swiper-isearch-function ivy-text))))))) (if (string-match-p "\\\\(" re) @@ -715,50 +735,37 @@ When capture groups are present in the input, print them instead of lines." (when (bound-and-true-p evil-mode) (evil-set-jump))) -(declare-function char-fold-to-regexp "char-fold") +(defun swiper--normalize-regex (re) + "Normalize the swiper regex RE. +Add a space after a leading `^' if needed and apply +`search-default-mode' if bound." + (replace-regexp-in-string + "^\\(?:\\\\(\\)?\\^" + (concat "\\&" (if (eq 'swiper (ivy-state-caller ivy-last)) " " "")) + (if (functionp (bound-and-true-p search-default-mode)) + (mapconcat + (lambda (x) + (if (string-match-p "\\`[^$\\^]+\\'" x) + (funcall search-default-mode x) + x)) + (split-string re "\\b") "") + re) + t)) (defun swiper--re-builder (str) "Transform STR into a swiper regex. This is the regex used in the minibuffer where candidates have line numbers. For the buffer, use `ivy--regex' instead." (let* ((re-builder (ivy-alist-setting ivy-re-builders-alist)) - (re (cond - ((equal str "") - "") - ((equal str "^") - (setq ivy--subexps 0) - ".") - ((= (aref str 0) ?^) - (let* ((re (funcall re-builder (substring str 1))) - (re (if (listp re) - (mapconcat (lambda (x) - (format "\\(%s\\)" (car x))) - (cl-remove-if-not #'cdr re) - ".*?") - re))) - (cond - ((string= re "$") - "^$") - ((zerop ivy--subexps) - (prog1 (format "^ ?\\(%s\\)" re) - (setq ivy--subexps 1))) - (t - (format "^ %s" re))))) - ((eq (bound-and-true-p search-default-mode) 'char-fold-to-regexp) - (if (string-match "\\`\\\\_<\\(.+\\)\\\\_>\\'" str) - (concat - "\\_<" - (char-fold-to-regexp (match-string 1 str)) - "\\_>") - (let ((subs (ivy--split str))) - (setq ivy--subexps (length subs)) - (mapconcat - (lambda (s) (format "\\(%s\\)" (char-fold-to-regexp s))) - subs - ".*?")))) - (t - (funcall re-builder str))))) - re)) + (str (replace-regexp-in-string "\\\\n" "\n" str)) + (re (funcall re-builder str))) + (if (consp re) + (mapcar + (lambda (x) + (cons (swiper--normalize-regex (car x)) + (cdr x))) + re) + (swiper--normalize-regex re)))) (defvar swiper-history nil "History for `swiper'.") @@ -799,7 +806,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (if initial-input (cl-position-if (lambda (x) - (= (1+ preselect) (get-text-property 0 'swiper-line-number x))) + (= (1+ preselect) (swiper--line-number x))) (progn (setq ivy--old-re nil) (ivy--filter initial-input candidates))) @@ -813,6 +820,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern." (point)) (unless (or res swiper-stay-on-quit) (goto-char swiper--opoint)) + (isearch-clean-overlays) (unless (or res (string= ivy-text "")) (cl-pushnew ivy-text swiper-history)) (setq swiper--current-window-start nil) @@ -916,19 +924,17 @@ the face, window and priority of the overlay." (or (display-graphic-p) (not recenter-redisplay))) -(defun swiper--positive-regexps (str) - (let ((regexp-or-regexps - (funcall ivy--regex-function str))) - (if (listp regexp-or-regexps) - (mapcar #'car (cl-remove-if-not #'cdr regexp-or-regexps)) - (list regexp-or-regexps)))) +(defun swiper--positive-regexps () + (if (listp ivy-regex) + (mapcar #'car (cl-remove-if-not #'cdr ivy-regex)) + (list ivy-regex))) (defun swiper--update-input-ivy () "Called when `ivy' input is updated." (with-ivy-window (swiper--cleanup) (when (> (length (ivy-state-current ivy-last)) 0) - (let ((regexps (swiper--positive-regexps ivy-text)) + (let ((regexps (swiper--positive-regexps)) (re-idx -1) (case-fold-search (ivy--case-fold-p ivy-text))) (dolist (re regexps) @@ -936,7 +942,7 @@ the face, window and priority of the overlay." (let* ((re (replace-regexp-in-string " " "\t" re)) - (num (get-text-property 0 'swiper-line-number (ivy-state-current ivy-last)))) + (num (swiper--line-number (ivy-state-current ivy-last)))) (unless (memq this-command '(ivy-yank-word ivy-yank-symbol ivy-yank-char @@ -959,8 +965,9 @@ the face, window and priority of the overlay." (setq swiper--current-line num)) (when (re-search-forward re (line-end-position) t) (setq swiper--current-match-start (match-beginning 0)))) - (isearch-range-invisible (line-beginning-position) - (line-end-position)) + (funcall isearch-filter-predicate + (line-beginning-position) + (line-end-position)) (swiper--maybe-recenter))) (swiper--add-overlays re @@ -996,8 +1003,12 @@ WND, when specified is the window." (save-excursion (goto-char beg) ;; RE can become an invalid regexp - (while (and (ignore-errors (re-search-forward re end t)) - (> (- (match-end 0) (match-beginning 0)) 0)) + (while (progn + (when (eolp) + (unless (eobp) + (forward-char))) + (and (ignore-errors (re-search-forward re end t)) + (> (- (match-end 0) (match-beginning 0)) 0))) ;; Don't highlight a match if it spans multiple ;; lines. `count-lines' returns 1 if the match is within a ;; single line, even if it includes the newline, and 2 or @@ -1026,7 +1037,7 @@ WND, when specified is the window." (unless (> (- me mb) 2017) (funcall adder-fn mb me - (if (zerop ivy--subexps) + (if (and ivy-use-group-face-if-no-groups (zerop ivy--subexps)) (nth (1+ (mod (or re-idx 0) (1- (length faces)))) faces) (car faces)) 0))) @@ -1037,10 +1048,11 @@ WND, when specified is the window." (em (match-end j))) (when (and (integerp em) (integerp bm)) - (while (and (< j ivy--subexps) - (integerp (match-beginning (+ j 1))) - (= em (match-beginning (+ j 1)))) - (setq em (match-end (cl-incf j)))) + (when (eq (ivy-alist-setting ivy-re-builders-alist t) #'ivy--regex-fuzzy) + (while (and (< j ivy--subexps) + (integerp (match-beginning (+ j 1))) + (= em (match-beginning (+ j 1)))) + (setq em (match-end (cl-incf j))))) (funcall adder-fn bm em (nth (1+ (mod (+ i 2) (1- (length faces)))) @@ -1069,9 +1081,25 @@ WND, when specified is the window." (recenter)))) (setq swiper--current-window-start (window-start))) +(defun swiper--line-number (x) + (or (get-text-property 0 'swiper-line-number x) + (get-text-property 1 'swiper-line-number x))) + +(defcustom swiper-verbose t + "When non-nil, print more informational messages." + :type 'boolean) + +(defun swiper--push-mark () + (when (/= (point) swiper--opoint) + (unless (and transient-mark-mode mark-active) + (when (eq ivy-exit 'done) + (push-mark swiper--opoint t) + (when swiper-verbose + (message "Mark saved where search started")))))) + (defun swiper--action (x) "Goto line X." - (let ((ln (1- (get-text-property 0 'swiper-line-number x))) + (let ((ln (1- (swiper--line-number x))) (re (ivy--regex ivy-text)) (case-fold-search (ivy--case-fold-p ivy-text))) (if (null x) @@ -1092,34 +1120,34 @@ WND, when specified is the window." (goto-char (match-beginning 0))) (swiper--ensure-visible) (swiper--maybe-recenter) - (when (/= (point) swiper--opoint) - (unless (and transient-mark-mode mark-active) - (when (eq ivy-exit 'done) - (push-mark swiper--opoint t) - (message "Mark saved where search started")))) - (add-to-history - 'regexp-search-ring - re - regexp-search-ring-max) - ;; integration with evil-mode's search - (when (bound-and-true-p evil-mode) - (when (eq evil-search-module 'isearch) - (setq isearch-string ivy-text)) - (when (eq evil-search-module 'evil-search) - (add-to-history 'evil-ex-search-history re) - (setq evil-ex-search-pattern (list re t t)) - (setq evil-ex-search-direction 'forward) - (when evil-ex-search-persistent-highlight - (evil-ex-search-activate-highlight evil-ex-search-pattern)))))))) + (swiper--push-mark) + (swiper--remember-search-history re))))) + +(defun swiper--remember-search-history (re) + "Add the search pattern RE to the search history ring." + (add-to-history + 'regexp-search-ring + re + regexp-search-ring-max) + ;; integration with evil-mode's search + (when (bound-and-true-p evil-mode) + (when (eq evil-search-module 'isearch) + (setq isearch-string ivy-text)) + (when (eq evil-search-module 'evil-search) + (add-to-history 'evil-ex-search-history re) + (setq evil-ex-search-pattern (list re t t)) + (setq evil-ex-search-direction 'forward) + (when evil-ex-search-persistent-highlight + (evil-ex-search-activate-highlight evil-ex-search-pattern))))) (defun swiper-from-isearch () "Invoke `swiper' from isearch." (interactive) - (let ((query (if isearch-regexp - isearch-string - (regexp-quote isearch-string)))) - (isearch-exit) - (swiper query))) + (swiper (prog1 (if isearch-regexp + isearch-string + (regexp-quote isearch-string)) + (let ((search-nonincremental-instead nil)) + (isearch-exit))))) (defvar swiper-multi-buffers nil "Store the current list of buffers.") @@ -1184,12 +1212,13 @@ otherwise continue prompting for buffers." (with-ivy-window (switch-to-buffer buffer-name) (goto-char (point-min)) - (forward-line (1- (get-text-property 0 'swiper-line-number x))) + (forward-line (1- (swiper--line-number x))) (re-search-forward (ivy--regex ivy-text) (line-end-position) t) - (isearch-range-invisible (line-beginning-position) - (line-end-position)) + (funcall isearch-filter-predicate + (line-beginning-position) + (line-end-position)) (unless (eq ivy-exit 'done) (swiper--cleanup) (swiper--add-overlays (ivy--regex ivy-text)))))))) @@ -1218,7 +1247,7 @@ otherwise continue prompting for buffers." (or (ivy-more-chars) (let* ((buffers (cl-remove-if-not #'swiper-all-buffer-p (buffer-list))) - (re-full (funcall ivy--regex-function str)) + (re-full ivy-regex) re re-tail cands match (case-fold-search (ivy--case-fold-p str))) @@ -1312,8 +1341,9 @@ See `ivy-format-functions-alist' for further information." (with-ivy-window (switch-to-buffer buffer-name) (goto-char (get-text-property 0 'point x)) - (isearch-range-invisible (line-beginning-position) - (line-end-position)) + (funcall isearch-filter-predicate + (line-beginning-position) + (line-end-position)) (unless (eq ivy-exit 'done) (swiper--cleanup) (swiper--add-overlays (ivy--regex ivy-text)))))))) @@ -1353,7 +1383,9 @@ See `ivy-format-functions-alist' for further information." (save-excursion (goto-char (if backward (point-max) (point-min))) (while (and (funcall (if backward #'re-search-backward #'re-search-forward) re nil t) - (not (if backward (bobp) (eobp)))) + (not (and + (= (match-beginning 0) (match-end 0)) + (if backward (bobp) (eobp))))) (when (swiper-match-usable-p) (let ((pos (if (or backward swiper-goto-start-of-match) (match-beginning 0) @@ -1402,7 +1434,7 @@ See `ivy-format-functions-alist' for further information." (setq filtered-cands nil)))) (defun swiper--isearch-function (str) - (let ((re-full (funcall ivy--regex-function str))) + (let ((re-full ivy-regex)) (unless (equal re-full "") (let* ((case-fold-search (ivy--case-fold-p str)) (re @@ -1440,7 +1472,7 @@ that we search only for one character." (lambda () (with-ivy-window (swiper--add-overlays (ivy--regex ivy-text)))))) - (dolist (re (swiper--positive-regexps ivy-text)) + (dolist (re (swiper--positive-regexps)) (swiper--add-overlays re)))) (defun swiper-isearch-action (x) @@ -1453,11 +1485,14 @@ that we search only for one character." (when (and (or (eq this-command 'ivy-previous-line-or-history) (and (eq this-command 'ivy-done) (eq last-command 'ivy-previous-line-or-history))) - (looking-back ivy--old-re (line-beginning-position))) + (looking-back ivy-regex (line-beginning-position))) (goto-char (match-beginning 0))) - (isearch-range-invisible (point) (1+ (point))) + (funcall isearch-filter-predicate (point) (1+ (point))) (swiper--maybe-recenter) - (unless (eq ivy-exit 'done) + (if (eq ivy-exit 'done) + (progn + (swiper--push-mark) + (swiper--remember-search-history (ivy--regex ivy-text))) (swiper--cleanup) (swiper--delayed-add-overlays) (swiper--add-cursor-overlay @@ -1520,14 +1555,20 @@ When not running `swiper-isearch' already, start it." (defun swiper-isearch-format-function (cands) (if (numberp (car-safe cands)) - (if (string= ivy--old-re "^$") - "" - (swiper--isearch-format - ivy--index ivy--length ivy--old-cands - ivy--old-re - (ivy-state-current ivy-last) - (ivy-state-buffer ivy-last))) - (ivy-format-function-default cands))) + (let ((re (ivy-re-to-str ivy-regex))) + (if (string= re "^$") + "" + (mapconcat + #'identity + (swiper--isearch-format + ivy--index ivy--length (or ivy--old-cands ivy--all-candidates) + re + (ivy-state-current ivy-last) + (ivy-state-buffer ivy-last)) + "\n"))) + (funcall + (ivy-alist-setting ivy-format-functions-alist t) + cands))) (defun swiper--line-at-point (pt) (save-excursion @@ -1535,22 +1576,27 @@ When not running `swiper-isearch' already, start it." (let ((s (buffer-substring (line-beginning-position) (line-end-position)))) - (put-text-property 0 1 'point pt s) - (ivy-cleanup-string s)))) + (if (string= s "") + s + (put-text-property 0 1 'point pt s) + (ivy-cleanup-string s))))) (defun swiper--isearch-highlight (str &optional current) (let ((start 0) - (i 0)) - (while (string-match ivy--old-re str start) - (setq start (match-end 0)) - (swiper--add-properties - (if (eq current i) - swiper-faces - swiper-background-faces) - (lambda (beg end face _priority) - (ivy-add-face-text-property - beg end face str))) - (cl-incf i)) + (i 0) + (re (ivy-re-to-str ivy-regex))) + (catch 'done + (while (string-match re str start) + (if (= (match-beginning 0) (match-end 0)) + (throw 'done t) + (setq start (match-end 0))) + (swiper--add-properties + (if (eq current i) + swiper-faces + swiper-background-faces) + (lambda (beg end face _priority) + (add-face-text-property beg end face nil str))) + (cl-incf i))) str)) (defun swiper--isearch-format (index length cands regex current buffer) @@ -1580,10 +1626,10 @@ When not running `swiper-isearch' already, start it." (dotimes (_ (1+ j)) (string-match regex current-str start) (setq start (match-end 0))) - (swiper--isearch-highlight current-str j) - (font-lock-append-text-property + (font-lock-prepend-text-property 0 (length current-str) 'face 'swiper-line-face current-str) + (swiper--isearch-highlight current-str j) (push current-str res)) (cl-incf len) (setq i (1+ index)) @@ -1599,46 +1645,48 @@ When not running `swiper-isearch' already, start it." (push (swiper--isearch-highlight s) res) (cl-incf len)) (cl-incf i)) - (mapconcat #'identity (nreverse res) "\n")))) + (nreverse res)))) + +(defun swiper--isearch-init () + "Initialize `swiper-isearch'." + (swiper--init) + (setq swiper--isearch-start-point (point)) + (swiper-font-lock-ensure)) + +(defun swiper--isearch-unwind () + (swiper--cleanup) + (unless (or (eq ivy-exit 'done) swiper-stay-on-quit) + (goto-char swiper--opoint)) + (isearch-clean-overlays) + (swiper--ensure-visible) + (unless (or (eq ivy-exit 'done) (string= ivy-text "")) + (cl-pushnew ivy-text swiper-history))) ;;;###autoload (defun swiper-isearch (&optional initial-input) "A `swiper' that's not line-based." (interactive) - (swiper--init) - (setq swiper--isearch-start-point (point)) - (swiper-font-lock-ensure) (let ((ivy-fixed-height-minibuffer t) (cursor-in-non-selected-windows nil) - (swiper-min-highlight 1) - res) - (unwind-protect - (and - (setq res - (ivy-read - "Swiper: " - #'swiper-isearch-function - :initial-input initial-input - :keymap swiper-isearch-map - :dynamic-collection t - :require-match t - :action #'swiper-isearch-action - :re-builder #'swiper--re-builder - :history 'swiper-history - :extra-props (list :fname (buffer-file-name)) - :caller 'swiper-isearch)) - (point)) - (unless (or res swiper-stay-on-quit) - (goto-char swiper--opoint)) - (isearch-clean-overlays) - (swiper--ensure-visible) - (unless (or res (string= ivy-text "")) - (cl-pushnew ivy-text swiper-history))))) + (swiper-min-highlight 1)) + (ivy-read + "Swiper: " + #'swiper-isearch-function + :initial-input initial-input + :keymap swiper-isearch-map + :dynamic-collection t + :require-match t + :action #'swiper-isearch-action + :re-builder #'swiper--re-builder + :history 'swiper-history + :extra-props (list :fname (buffer-file-name)) + :caller 'swiper-isearch))) (ivy-configure 'swiper-isearch :occur #'swiper-occur + :init-fn #'swiper--isearch-init :update-fn 'auto - :unwind-fn #'swiper--cleanup + :unwind-fn #'swiper--isearch-unwind :format-fn #'swiper-isearch-format-function) ;;;###autoload @@ -1662,7 +1710,7 @@ Intended to be bound in `isearch-mode-map' and `swiper-map'." (swiper-isearch query)) (ivy-exit-with-action (lambda (_) - (when (looking-back ivy--old-re (line-beginning-position)) + (when (looking-back (ivy-re-to-str ivy-regex) (line-beginning-position)) (goto-char (match-beginning 0))) (isearch-mode t) (unless (string= ivy-text "") diff --git a/elpa/transient-0.2.0/transient-autoloads.el b/elpa/transient-0.2.0/transient-autoloads.el deleted file mode 100755 index 301f3c7..0000000 --- a/elpa/transient-0.2.0/transient-autoloads.el +++ /dev/null @@ -1,26 +0,0 @@ -;;; transient-autoloads.el --- automatically extracted autoloads -;; -;;; Code: - -(add-to-list 'load-path (directory-file-name - (or (file-name-directory #$) (car load-path)))) - - -;;;### (autoloads nil "transient" "transient.el" (0 0 0 0)) -;;; Generated autoloads from transient.el - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "transient" '("current-transient-" "define-" "post-transient-hook" "transient-"))) - -;;;*** - -;;;### (autoloads nil nil ("transient-pkg.el") (0 0 0 0)) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; transient-autoloads.el ends here diff --git a/elpa/transient-0.2.0/transient-pkg.el b/elpa/transient-0.2.0/transient-pkg.el deleted file mode 100755 index c9a9152..0000000 --- a/elpa/transient-0.2.0/transient-pkg.el +++ /dev/null @@ -1,12 +0,0 @@ -(define-package "transient" "0.2.0" "Transient commands" - '((emacs "25.1")) - :commit "a269614c69ad8b2703e6e5093d0017d6afad6cca" :keywords - ("bindings") - :authors - (("Jonas Bernoulli" . "jonas@bernoul.li")) - :maintainer - ("Jonas Bernoulli" . "jonas@bernoul.li") - :url "https://github.com/magit/transient") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/transient-0.2.0/dir b/elpa/transient-0.3.0/dir old mode 100755 new mode 100644 similarity index 100% rename from elpa/transient-0.2.0/dir rename to elpa/transient-0.3.0/dir diff --git a/elpa/transient-0.3.0/transient-autoloads.el b/elpa/transient-0.3.0/transient-autoloads.el new file mode 100644 index 0000000..e20a77f --- /dev/null +++ b/elpa/transient-0.3.0/transient-autoloads.el @@ -0,0 +1,80 @@ +;;; transient-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "transient" "transient.el" (0 0 0 0)) +;;; Generated autoloads from transient.el + +(autoload 'transient-insert-suffix "transient" "\ +Insert a SUFFIX into PREFIX before LOC. +PREFIX is a prefix command, a symbol. +SUFFIX is a suffix command or a group specification (of + the same forms as expected by `transient-define-prefix'). +LOC is a command, a key vector, a key description (a string + as returned by `key-description'), or a coordination list + (whose last element may also be a command or key). +See info node `(transient)Modifying Existing Transients'. + +\(fn PREFIX LOC SUFFIX)" nil nil) + +(function-put 'transient-insert-suffix 'lisp-indent-function 'defun) + +(autoload 'transient-append-suffix "transient" "\ +Insert a SUFFIX into PREFIX after LOC. +PREFIX is a prefix command, a symbol. +SUFFIX is a suffix command or a group specification (of + the same forms as expected by `transient-define-prefix'). +LOC is a command, a key vector, a key description (a string + as returned by `key-description'), or a coordination list + (whose last element may also be a command or key). +See info node `(transient)Modifying Existing Transients'. + +\(fn PREFIX LOC SUFFIX)" nil nil) + +(function-put 'transient-append-suffix 'lisp-indent-function 'defun) + +(autoload 'transient-replace-suffix "transient" "\ +Replace the suffix at LOC in PREFIX with SUFFIX. +PREFIX is a prefix command, a symbol. +SUFFIX is a suffix command or a group specification (of + the same forms as expected by `transient-define-prefix'). +LOC is a command, a key vector, a key description (a string + as returned by `key-description'), or a coordination list + (whose last element may also be a command or key). +See info node `(transient)Modifying Existing Transients'. + +\(fn PREFIX LOC SUFFIX)" nil nil) + +(function-put 'transient-replace-suffix 'lisp-indent-function 'defun) + +(autoload 'transient-remove-suffix "transient" "\ +Remove the suffix or group at LOC in PREFIX. +PREFIX is a prefix command, a symbol. +LOC is a command, a key vector, a key description (a string + as returned by `key-description'), or a coordination list + (whose last element may also be a command or key). +See info node `(transient)Modifying Existing Transients'. + +\(fn PREFIX LOC)" nil nil) + +(function-put 'transient-remove-suffix 'lisp-indent-function 'defun) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "transient" '("transient-"))) + +;;;*** + +;;;### (autoloads nil nil ("transient-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; transient-autoloads.el ends here diff --git a/elpa/transient-0.3.0/transient-pkg.el b/elpa/transient-0.3.0/transient-pkg.el new file mode 100644 index 0000000..ef8942d --- /dev/null +++ b/elpa/transient-0.3.0/transient-pkg.el @@ -0,0 +1,12 @@ +(define-package "transient" "0.3.0" "Transient commands" + '((emacs "25.1")) + :commit "9ca983bab26d1a8e189a8c44471d9575284b268d" :authors + '(("Jonas Bernoulli" . "jonas@bernoul.li")) + :maintainer + '("Jonas Bernoulli" . "jonas@bernoul.li") + :keywords + '("bindings") + :url "https://github.com/magit/transient") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/transient-0.2.0/transient.el b/elpa/transient-0.3.0/transient.el old mode 100755 new mode 100644 similarity index 80% rename from elpa/transient-0.2.0/transient.el rename to elpa/transient-0.3.0/transient.el index 4c7367d..6ac494c --- a/elpa/transient-0.2.0/transient.el +++ b/elpa/transient-0.3.0/transient.el @@ -1,25 +1,27 @@ ;;; transient.el --- Transient commands -*- lexical-binding: t; -*- -;; Copyright (C) 2018-2020 Jonas Bernoulli +;; Copyright (C) 2018-2021 Free Software Foundation, Inc. ;; Author: Jonas Bernoulli ;; Homepage: https://github.com/magit/transient ;; Package-Requires: ((emacs "25.1")) +;; Package-Version: 0.3.0 ;; Keywords: bindings -;; This file is not part of GNU Emacs. +;; This file is part of GNU Emacs. -;; This file is free software; you can redistribute it and/or modify +;; 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, +;; by the Free Software Foundation, either version 3 of the License, ;; or (at your option) any later version. -;; This file is distributed in the hope that it will be useful, +;; 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. -;; For a full copy of the GNU GPL see http://www.gnu.org/licenses. +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . ;;; Commentary: @@ -62,6 +64,37 @@ (defvar Man-notify-method) +(define-obsolete-function-alias 'define-transient-command + 'transient-define-prefix "Transient 0.3.0") +(define-obsolete-function-alias 'define-suffix-command + 'transient-define-suffix "Transient 0.3.0") +(define-obsolete-function-alias 'define-infix-command + 'transient-define-infix "Transient 0.3.0") +(define-obsolete-function-alias 'define-infix-argument + 'transient-define-argument "Transient 0.3.0") + +(define-obsolete-variable-alias 'current-transient-prefix + 'transient-current-prefix "Transient 0.3.0") +(define-obsolete-variable-alias 'current-transient-command + 'transient-current-command "Transient 0.3.0") +(define-obsolete-variable-alias 'current-transient-suffixes + 'transient-current-suffixes "Transient 0.3.0") +(define-obsolete-variable-alias 'post-transient-hook + 'transient-exit-hook "Transient 0.3.0") + +(defmacro transient--with-emergency-exit (&rest body) + (declare (indent defun)) + `(condition-case err + (let ((debugger #'transient--exit-and-debug)) + ,(macroexp-progn body)) + ((debug error) + (transient--emergency-exit) + (signal (car err) (cdr err))))) + +(defun transient--exit-and-debug (&rest args) + (transient--emergency-exit) + (apply #'debug args)) + ;;; Options (defgroup transient nil @@ -110,7 +143,9 @@ features are available: :type 'boolean) (defcustom transient-display-buffer-action - '(display-buffer-in-side-window (side . bottom)) + '(display-buffer-in-side-window + (side . bottom) + (inhibit-same-window . t)) "The action used to display the transient popup buffer. The transient popup buffer is displayed in a window using @@ -136,7 +171,7 @@ then it doesn't work. If you change the value of this option, then you might also want to change the value of `transient-mode-line-format'." - :package-version '(transient . "0.2.0") + :package-version '(transient . "0.3.0") :group 'transient :type '(cons (choice function (repeat :tag "Functions" function)) alist)) @@ -221,6 +256,22 @@ using a layout optimized for lisp. :group 'transient :type '(choice (const :tag "Transform no keys (nil)" nil) function)) +(defcustom transient-semantic-coloring nil + "Whether to color prefixes and suffixes in Hydra-like fashion. +This feature is experimental. + +If non-nil, then the key binding of each suffix is colorized to +indicate whether it exits the transient state or not. The color +of the prefix is indicated using the line that is drawn when the +value of `transient-mode-line-format' is `line'. + +For more information about how Hydra uses colors see +https://github.com/abo-abo/hydra#color and +https://oremacs.com/2015/02/19/hydra-colors-reloaded." + :package-version '(transient . "0.3.0") + :group 'transient + :type 'boolean) + (defcustom transient-detect-key-conflicts nil "Whether to detect key binding conflicts. @@ -232,7 +283,7 @@ used." :type 'boolean) (defcustom transient-force-fixed-pitch nil - "Whether to force used of monospaced font in popup buffer. + "Whether to force use of monospaced font in the popup buffer. Even if you use a proportional font for the `default' face, you might still want to use a monospaced font in transient's @@ -360,6 +411,10 @@ Also see option `transient-highlight-mismatched-keys'." Also see option `transient-highlight-mismatched-keys'." :group 'transient-faces) +(defface transient-inapt-suffix '((t :inherit shadow :italic t)) + "Face used for suffixes that are inapt at this time." + :group 'transient-faces) + (defface transient-enabled-suffix '((t :background "green" :foreground "black" :weight bold)) "Face used for enabled levels while editing suffix levels. @@ -384,6 +439,38 @@ This is only used if `transient-mode-line-format' is `line'. Only the background color is significant." :group 'transient-faces) +(defgroup transient-color-faces + '((transient-semantic-coloring custom-variable)) + "Faces used by Transient for Hydra-like command coloring. +These faces are only used if `transient-semantic-coloring' +\(which see) is non-nil." + :group 'transient-faces) + +(defface transient-red + '((t :inherit transient-key :foreground "red")) + "Face used for red prefixes and suffixes." + :group 'transient-color-faces) + +(defface transient-blue + '((t :inherit transient-key :foreground "blue")) + "Face used for blue prefixes and suffixes." + :group 'transient-color-faces) + +(defface transient-amaranth + '((t :inherit transient-key :foreground "#E52B50")) + "Face used for amaranth prefixes." + :group 'transient-color-faces) + +(defface transient-pink + '((t :inherit transient-key :foreground "#FF6EB4")) + "Face used for pink prefixes." + :group 'transient-color-faces) + +(defface transient-teal + '((t :inherit transient-key :foreground "#367588")) + "Face used for teal prefixes." + :group 'transient-color-faces) + ;;; Persistence (defun transient--read-file-contents (file) @@ -393,13 +480,13 @@ Only the background color is significant." (insert-file-contents file) (read (current-buffer)))))) -(defun transient--pp-to-file (object file) +(defun transient--pp-to-file (list file) (make-directory (file-name-directory file) t) - (setq object (cl-sort object #'string< :key #'car)) + (setq list (cl-sort (copy-sequence list) #'string< :key #'car)) (with-temp-file file (let ((print-level nil) (print-length nil)) - (pp object (current-buffer))))) + (pp list (current-buffer))))) (defvar transient-values (transient--read-file-contents transient-values-file) @@ -452,6 +539,7 @@ If `transient-save-history' is nil, then do nothing." (command :initarg :command) (level :initarg :level) (variable :initarg :variable :initform nil) + (init-value :initarg :init-value) (value) (default-value :initarg :value) (scope :initarg :scope :initform nil) (history :initarg :history :initform nil) @@ -461,7 +549,8 @@ If `transient-save-history' is nil, then do nothing." (info-manual :initarg :info-manual :initform nil) (transient-suffix :initarg :transient-suffix :initform nil) (transient-non-suffix :initarg :transient-non-suffix :initform nil) - (incompatible :initarg :incompatible :initform nil)) + (incompatible :initarg :incompatible :initform nil) + (suffix-description :initarg :suffix-description :initform nil)) "Transient prefix command. Each transient prefix command consists of a command, which is @@ -522,7 +611,40 @@ slot is non-nil." (command :initarg :command) (transient :initarg :transient) (format :initarg :format :initform " %k %d") - (description :initarg :description :initform nil)) + (description :initarg :description :initform nil) + (inapt :initform nil) + (inapt-if + :initarg :inapt-if + :initform nil + :documentation "Inapt if predicate returns non-nil.") + (inapt-if-not + :initarg :inapt-if-not + :initform nil + :documentation "Inapt if predicate returns nil.") + (inapt-if-non-nil + :initarg :inapt-if-non-nil + :initform nil + :documentation "Inapt if variable's value is non-nil.") + (inapt-if-nil + :initarg :inapt-if-nil + :initform nil + :documentation "Inapt if variable's value is nil.") + (inapt-if-mode + :initarg :inapt-if-mode + :initform nil + :documentation "Inapt if major-mode matches value.") + (inapt-if-not-mode + :initarg :inapt-if-not-mode + :initform nil + :documentation "Inapt if major-mode does not match value.") + (inapt-if-derived + :initarg :inapt-if-derived + :initform nil + :documentation "Inapt if major-mode derives from value.") + (inapt-if-not-derived + :initarg :inapt-if-not-derived + :initform nil + :documentation "Inapt if major-mode does not derive from value.")) "Superclass for suffix command.") (defclass transient-infix (transient-suffix) @@ -530,7 +652,10 @@ slot is non-nil." (argument :initarg :argument) (shortarg :initarg :shortarg) (value :initform nil) + (init-value :initarg :init-value) + (unsavable :initarg :unsavable :initform nil) (multi-value :initarg :multi-value :initform nil) + (always-read :initarg :always-read :initform nil) (allow-empty :initarg :allow-empty :initform nil) (history-key :initarg :history-key :initform nil) (reader :initarg :reader :initform nil) @@ -569,9 +694,11 @@ They become the value of this this argument.") ;;;; Group (defclass transient-group (transient-child) - ((suffixes :initarg :suffixes :initform nil) - (hide :initarg :hide :initform nil) - (description :initarg :description :initform nil)) + ((suffixes :initarg :suffixes :initform nil) + (hide :initarg :hide :initform nil) + (description :initarg :description :initform nil) + (setup-children :initarg :setup-children) + (pad-keys :initarg :pad-keys)) "Abstract superclass of all group classes." :abstract t) @@ -597,7 +724,7 @@ elements themselves.") ;;; Define -(defmacro define-transient-command (name arglist &rest args) +(defmacro transient-define-prefix (name arglist &rest args) "Define NAME as a transient prefix command. ARGLIST are the arguments that command takes. @@ -642,6 +769,7 @@ to the setup function: [&rest keywordp sexp] [&rest vectorp] [&optional ("interactive" interactive) def-body])) + (indent defun) (doc-string 3)) (pcase-let ((`(,class ,slots ,suffixes ,docstr ,body) (transient--expand-define-args args))) @@ -660,7 +788,7 @@ to the setup function: ',(cl-mapcan (lambda (s) (transient--parse-child name s)) suffixes))))) -(defmacro define-suffix-command (name arglist &rest args) +(defmacro transient-define-suffix (name arglist &rest args) "Define NAME as a transient suffix command. ARGLIST are the arguments that the command takes. @@ -682,6 +810,7 @@ ARGLIST. The infix arguments are usually accessed by using [&rest keywordp sexp] ("interactive" interactive) def-body)) + (indent defun) (doc-string 3)) (pcase-let ((`(,class ,slots ,_ ,docstr ,body) (transient--expand-define-args args))) @@ -692,7 +821,7 @@ ARGLIST. The infix arguments are usually accessed by using (put ',name 'transient--suffix (,(or class 'transient-suffix) :command ',name ,@slots))))) -(defmacro define-infix-command (name _arglist &rest args) +(defmacro transient-define-infix (name _arglist &rest args) "Define NAME as a transient infix command. ARGLIST is always ignored and reserved for future use. @@ -730,6 +859,7 @@ keyword. (declare (debug (&define name lambda-list [&optional lambda-doc] [&rest keywordp sexp])) + (indent defun) (doc-string 3)) (pcase-let ((`(,class ,slots ,_ ,docstr ,_) (transient--expand-define-args args))) @@ -740,12 +870,12 @@ keyword. (put ',name 'transient--suffix (,(or class 'transient-switch) :command ',name ,@slots))))) -(defalias 'define-infix-argument 'define-infix-command +(defalias 'transient-define-argument 'define-infix-command "Define NAME as a transient infix command. Only use this alias to define an infix command that actually sets an infix argument. To define a infix command that, for -example, sets a variable use `define-infix-command' instead. +example, sets a variable use `transient-define-infix' instead. \(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)") @@ -760,7 +890,9 @@ example, sets a variable use `define-infix-command' instead. (setq class v) (push k keys) (push v keys)))) - (while (vectorp (car args)) + (while (let ((arg (car args))) + (or (vectorp arg) + (and arg (symbolp arg)))) (push (pop args) suffixes)) (list (if (eq (car-safe class) 'quote) (cadr class) @@ -772,6 +904,12 @@ example, sets a variable use `define-infix-command' instead. (defun transient--parse-child (prefix spec) (cl-etypecase spec + (symbol (let ((value (symbol-value spec))) + (if (and (listp value) + (or (listp (car value)) + (vectorp (car value)))) + (cl-mapcan (lambda (s) (transient--parse-child prefix s)) value) + (transient--parse-child prefix value)))) (vector (when-let ((c (transient--parse-group prefix spec))) (list c))) (list (when-let ((c (transient--parse-suffix prefix spec))) (list c))) (string (list spec)))) @@ -820,6 +958,15 @@ example, sets a variable use `define-infix-command' instead. (error "Need command, got %S" car)) ((symbolp car) (setq args (plist-put args :command pop))) + ((and (commandp car) + (not (stringp car))) + (let ((cmd pop) + (sym (intern (format "transient:%s:%s" + prefix + (or (plist-get args :description) + (plist-get args :key)))))) + (defalias sym cmd) + (setq args (plist-put args :command sym)))) ((or (stringp car) (and car (listp car))) (let ((arg pop)) @@ -841,8 +988,7 @@ example, sets a variable use `define-infix-command' instead. ((not (string-suffix-p "=" arg)) (setq class 'transient-switch)) (t - (setq class 'transient-option) - (setq args (plist-put args :reader 'read-string)))))) + (setq class 'transient-option))))) (t (error "Needed command or argument, got %S" car))) (while (keywordp car) @@ -904,10 +1050,22 @@ example, sets a variable use `define-infix-command' instead. (t (when (and (listp suffix) (listp elt)) + ;; Both suffixes are key bindings; not heading strings. (let ((key (transient--spec-key suf))) (if (equal (transient--kbd key) (transient--kbd (transient--spec-key elt))) - (setq action 'replace) + ;; We must keep `mem' until after we have inserted + ;; behind it, which `transient-remove-suffix' does + ;; not allow us to do. + (let ((spred (transient--suffix-predicate suf)) + (epred (transient--suffix-predicate elt))) + ;; If both suffixes have a predicate and they + ;; are not identical, then there is a high + ;; probability that we want to keep both. + (when (or (not spred) + (not epred) + (equal spred epred)) + (setq action 'replace))) (transient-remove-suffix prefix key)))) (cl-ecase action (insert (setcdr mem (cons elt (cdr mem))) @@ -915,11 +1073,12 @@ example, sets a variable use `define-infix-command' instead. (append (setcdr mem (cons suf (cdr mem)))) (replace (setcar mem suf))))))) +;;;###autoload (defun transient-insert-suffix (prefix loc suffix) "Insert a SUFFIX into PREFIX before LOC. PREFIX is a prefix command, a symbol. SUFFIX is a suffix command or a group specification (of - the same forms as expected by `define-transient-command'). + the same forms as expected by `transient-define-prefix'). LOC is a command, a key vector, a key description (a string as returned by `key-description'), or a coordination list (whose last element may also be a command or key). @@ -927,11 +1086,12 @@ See info node `(transient)Modifying Existing Transients'." (declare (indent defun)) (transient--insert-suffix prefix loc suffix 'insert)) +;;;###autoload (defun transient-append-suffix (prefix loc suffix) "Insert a SUFFIX into PREFIX after LOC. PREFIX is a prefix command, a symbol. SUFFIX is a suffix command or a group specification (of - the same forms as expected by `define-transient-command'). + the same forms as expected by `transient-define-prefix'). LOC is a command, a key vector, a key description (a string as returned by `key-description'), or a coordination list (whose last element may also be a command or key). @@ -939,11 +1099,12 @@ See info node `(transient)Modifying Existing Transients'." (declare (indent defun)) (transient--insert-suffix prefix loc suffix 'append)) +;;;###autoload (defun transient-replace-suffix (prefix loc suffix) "Replace the suffix at LOC in PREFIX with SUFFIX. PREFIX is a prefix command, a symbol. SUFFIX is a suffix command or a group specification (of - the same forms as expected by `define-transient-command'). + the same forms as expected by `transient-define-prefix'). LOC is a command, a key vector, a key description (a string as returned by `key-description'), or a coordination list (whose last element may also be a command or key). @@ -951,6 +1112,7 @@ See info node `(transient)Modifying Existing Transients'." (declare (indent defun)) (transient--insert-suffix prefix loc suffix 'replace)) +;;;###autoload (defun transient-remove-suffix (prefix loc) "Remove the suffix or group at LOC in PREFIX. PREFIX is a prefix command, a symbol. @@ -976,7 +1138,7 @@ See info node `(transient)Modifying Existing Transients'." "Edit the suffix at LOC in PREFIX, setting PROP to VALUE. PREFIX is a prefix command, a symbol. SUFFIX is a suffix command or a group specification (of - the same forms as expected by `define-transient-command'). + the same forms as expected by `transient-define-prefix'). LOC is a command, a key vector, a key description (a string as returned by `key-description'), or a coordination list (whose last element may also be a command or key). @@ -1058,24 +1220,24 @@ See info node `(transient)Modifying Existing Transients'." ;;; Variables -(defvar current-transient-prefix nil +(defvar transient-current-prefix nil "The transient from which this suffix command was invoked. This is an object representing that transient, use -`current-transient-command' to get the respective command.") +`transient-current-command' to get the respective command.") -(defvar current-transient-command nil +(defvar transient-current-command nil "The transient from which this suffix command was invoked. This is a symbol representing that transient, use `current-transient-object' to get the respective object.") -(defvar current-transient-suffixes nil +(defvar transient-current-suffixes nil "The suffixes of the transient from which this suffix command was invoked. This is a list of objects. Usually it is sufficient to instead use the function `transient-args', which returns a list of values. In complex cases it might be necessary to use this variable instead.") -(defvar post-transient-hook nil +(defvar transient-exit-hook nil "Hook run after exiting a transient.") (defvar transient--prefix nil) @@ -1117,6 +1279,12 @@ Usually it remains current while the transient is active.") (defvar transient--history nil) +(defvar transient--scroll-commands + '(transient-scroll-up + transient-scroll-down + mwheel-scroll + scroll-bar-toolkit-scroll)) + ;;; Identities (defun transient-suffix-object (&optional command) @@ -1128,7 +1296,7 @@ the case of an infix command, which is a kind of suffix command). This function is intended to be called by infix commands, whose command definition usually (at least when defined using -`define-infix-command') is this: +`transient-define-infix') is this: (lambda () (interactive) @@ -1156,73 +1324,52 @@ you are contemplating using it in your own code, then you should probably use this instead: (get COMMAND 'transient--suffix)" - (if transient--prefix + (when command + (cl-check-type command command)) + (if (or transient--prefix + transient-current-prefix) (cl-find-if (lambda (obj) (eq (transient--suffix-command obj) (or command this-original-command))) - transient--suffixes) + (or transient--suffixes + transient-current-suffixes)) (when-let ((obj (get (or command this-command) 'transient--suffix)) (obj (clone obj))) (transient-init-scope obj) (transient-init-value obj) obj))) -(defun transient--suffix-command (arg) - "Return the command specified by ARG. - -Given a suffix specified by ARG, this function returns the -respective command or a symbol that represents it. It could -therefore be considered the inverse of `transient-suffix-object'. - -Unlike that function it is only intended for internal use though, -and it is more complicated to describe because of some internal -tricks it has to account for. You do not actually have to know -any of this. - -ARG can be a `transient-suffix' object, a symbol representing a -command, or a command (which can be either a fbound symbol or a -lambda expression). - -If it is an object, then the value of its `command' slot is used -as follows. If ARG satisfies `commandp', then that is returned. -Otherwise it is assumed to be a symbol that merely represents the -command. In that case the lambda expression that is stored in -the symbols `transient--infix-command' property is returned. - -Therefore, if ARG is an object, then this function always returns -something that is callable as a command. - -ARG can also be something that is callable as a function. If it -is a symbol, then that is returned. Otherwise it is a lambda -expression and a symbol that merely representing that command is -returned. - -Therefore, if ARG is something that is callable as a command, -then this function always returns a symbol that is, or merely -represents that command. - -The reason that there are \"symbols that merely represent a -command\" is that by avoiding binding a symbol as a command we -can prevent it from being offered as a completion candidate for -`execute-extended-command'. That is useful for infix arguments, -which usually do not work correctly unless called from a -transient. Unfortunately this only works for infix arguments -that are defined inline in the definition of a transient prefix -command; explicitly defined infix arguments continue to pollute -the command namespace. It would be better if all this were made -unnecessary by a `execute-extended-command-ignore' symbol property -but unfortunately that does not exist (yet?)." - (if (transient-suffix--eieio-childp arg) - (let ((sym (oref arg command))) - (if (commandp sym) - sym - (get sym 'transient--infix-command))) - (if (symbolp arg) - arg - ;; ARG is an interactive lambda. The symbol returned by this - ;; is not actually a command, just a symbol representing it - ;; for purposes other than invoking it as a command. - (oref (transient-suffix-object) command)))) +(defun transient--suffix-command (object) + "Return the command represented by OBJECT. + +If the value of OBJECT's `command' slot is a command, then return +that. Otherwise it is a symbol whose `transient--infix-command' +property holds an anonymous command, which is returned instead." + (cl-check-type object transient-suffix) + (let ((sym (oref object command))) + (if (commandp sym) + sym + (get sym 'transient--infix-command)))) + +(defun transient--suffix-symbol (arg) + "Return a symbol representing ARG. + +ARG must be a command and/or a symbol. If it is a symbol, +then just return it. Otherwise return the symbol whose +`transient--infix-command' property's value is ARG." + (or (cl-typep arg 'command) + (cl-typep arg 'symbol) + (signal 'wrong-type-argument `((command symbol) ,arg))) + (if (symbolp arg) + arg + (let* ((obj (transient-suffix-object)) + (sym (oref obj command))) + (if (eq (get sym 'transient--infix-command) arg) + sym + (catch 'found + (mapatoms (lambda (sym) + (when (eq (get sym 'transient--infix-command) arg) + (throw 'found sym))))))))) ;;; Keymaps @@ -1233,7 +1380,7 @@ but unfortunately that does not exist (yet?)." (define-key map (kbd "C-q") 'transient-quit-all) (define-key map (kbd "C-z") 'transient-suspend) (define-key map (kbd "C-v") 'transient-scroll-up) - (define-key map (kbd "M-v") 'transient-scroll-down) + (define-key map (kbd "C-M-v") 'transient-scroll-down) (define-key map [next] 'transient-scroll-up) (define-key map [prior] 'transient-scroll-down) map) @@ -1257,8 +1404,9 @@ edited using the same functions as used for transients.") (define-key map (kbd "C-t") 'transient-show) (define-key map (kbd "?") 'transient-help) (define-key map (kbd "C-h") 'transient-help) - (define-key map (kbd "M-p") 'transient-history-prev) - (define-key map (kbd "M-n") 'transient-history-next) + ;; Also bound to "C-x p" and "C-x n" in transient-common-commands. + (define-key map (kbd "C-M-p") 'transient-history-prev) + (define-key map (kbd "C-M-n") 'transient-history-next) map) "Top-level keymap used by all transients.") @@ -1291,8 +1439,8 @@ edited using the same functions as used for transients.") ["Value commands" ("C-x s " "Set" transient-set) ("C-x C-s" "Save" transient-save) - ("M-p " "Previous value" transient-history-prev) - ("M-n " "Next value" transient-history-next)] + ("C-x p " "Previous value" transient-history-prev) + ("C-x n " "Next value" transient-history-next)] ["Sticky commands" ;; Like `transient-sticky-map' except that ;; "C-g" has to be bound to a different command. @@ -1331,6 +1479,7 @@ edited using the same functions as used for transients.") (define-key map [transient-scroll-up] 'transient--do-stay) (define-key map [transient-scroll-down] 'transient--do-stay) (define-key map [mwheel-scroll] 'transient--do-stay) + (define-key map [scroll-bar-toolkit-scroll] 'transient--do-stay) (define-key map [transient-noop] 'transient--do-noop) (define-key map [transient-mouse-push-button] 'transient--do-move) (define-key map [transient-push-button] 'transient--do-move) @@ -1393,7 +1542,6 @@ of the corresponding object.") (when-let ((conflict (and transient-detect-key-conflicts (transient--lookup-key map kbd)))) (unless (eq cmd conflict) - (transient--emergency-exit) (error "Cannot bind %S to %s and also %s" (string-trim key) cmd conflict))) @@ -1407,23 +1555,27 @@ of the corresponding object.") (let ((map (make-sparse-keymap))) (set-keymap-parent map transient-predicate-map) (dolist (obj transient--suffixes) - (let* ((cmd (transient--suffix-command obj)) - (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix)))) - (if (slot-boundp obj 'transient) - (define-key map (vector cmd) - (let ((do (oref obj transient))) - (pcase do - (`t (if sub-prefix - 'transient--do-replace - 'transient--do-stay)) - (`nil 'transient--do-exit) - (_ do)))) - (unless (lookup-key transient-predicate-map (vector cmd)) - (define-key map (vector cmd) - (if sub-prefix - 'transient--do-replace - (or (oref transient--prefix transient-suffix) - 'transient--do-exit))))))) + (let* ((cmd (oref obj command)) + (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix))) + (sym (transient--suffix-symbol cmd))) + (cond + ((oref obj inapt) + (define-key map (vector sym) 'transient--do-warn-inapt)) + ((slot-boundp obj 'transient) + (define-key map (vector sym) + (let ((do (oref obj transient))) + (pcase do + (`t (if sub-prefix + 'transient--do-replace + 'transient--do-stay)) + (`nil 'transient--do-exit) + (_ do))))) + ((not (lookup-key transient-predicate-map (vector sym))) + (define-key map (vector sym) + (if sub-prefix + 'transient--do-replace + (or (oref transient--prefix transient-suffix) + 'transient--do-exit))))))) map)) (defun transient--make-redisplay-map () @@ -1470,58 +1622,81 @@ be nil and PARAMS may be (but usually is not) used to set e.g. the This function is also called internally in which case LAYOUT and EDIT may be non-nil." (transient--debug 'setup) - (cond - ((not name) - ;; Switching between regular and edit mode. - (transient--pop-keymap 'transient--transient-map) - (transient--pop-keymap 'transient--redisplay-map) - (setq name (oref transient--prefix command)) - (setq params (list :scope (oref transient--prefix scope)))) - ((not (or layout ; resuming parent/suspended prefix - current-transient-command)) ; entering child prefix - (transient--stack-zap)) ; replace suspended prefix, if any - (edit - ;; Returning from help to edit. - (setq transient--editp t))) - (transient--init-objects name layout params) - (transient--history-init transient--prefix) - (setq transient--predicate-map (transient--make-predicate-map)) - (setq transient--transient-map (transient--make-transient-map)) - (setq transient--redisplay-map (transient--make-redisplay-map)) - (setq transient--original-window (selected-window)) - (setq transient--original-buffer (current-buffer)) - (transient--redisplay) - (transient--init-transient) - (transient--suspend-which-key-mode)) + (when (> (minibuffer-depth) 0) + (user-error "Cannot invoke transient %s while minibuffer is active")) + (transient--with-emergency-exit + (cond + ((not name) + ;; Switching between regular and edit mode. + (transient--pop-keymap 'transient--transient-map) + (transient--pop-keymap 'transient--redisplay-map) + (setq name (oref transient--prefix command)) + (setq params (list :scope (oref transient--prefix scope)))) + (transient--transient-map + ;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}" + ;; of an outer prefix. Unlike the usual `transient--do-replace', + ;; these predicates fail to clean up after the outer prefix. + (transient--pop-keymap 'transient--transient-map) + (transient--pop-keymap 'transient--redisplay-map)) + ((not (or layout ; resuming parent/suspended prefix + transient-current-command)) ; entering child prefix + (transient--stack-zap)) ; replace suspended prefix, if any + (edit + ;; Returning from help to edit. + (setq transient--editp t))) + (transient--init-objects name layout params) + (transient--history-init transient--prefix) + (setq transient--predicate-map (transient--make-predicate-map)) + (setq transient--transient-map (transient--make-transient-map)) + (setq transient--redisplay-map (transient--make-redisplay-map)) + (setq transient--original-window (selected-window)) + (setq transient--original-buffer (current-buffer)) + (transient--redisplay) + (transient--init-transient) + (transient--suspend-which-key-mode))) + +(cl-defgeneric transient-setup-children (group children) + "Setup the CHILDREN of GROUP. +If the value of the `setup-children' slot is non-nil, then call +that function with CHILDREN as the only argument and return the +value. Otherwise return CHILDREN as is." + (if (slot-boundp group 'setup-children) + (funcall (oref group setup-children) children) + children)) (defun transient--init-objects (name layout params) - (setq transient--prefix - (let ((proto (get name 'transient--prefix))) - (apply #'clone proto - :prototype proto - :level (or (alist-get - t (alist-get name transient-levels)) - transient-default-level) - params))) - (transient-init-value transient--prefix) - (setq transient--layout - (or layout - (let ((levels (alist-get name transient-levels))) - (cl-mapcan (lambda (c) (transient--init-child levels c)) - (append (get name 'transient--layout) - (and (not transient--editp) - (get 'transient-common-commands - 'transient--layout))))))) - (setq transient--suffixes - (cl-labels ((s (def) - (cond - ((stringp def) nil) - ((listp def) (cl-mapcan #'s def)) - ((transient-group--eieio-childp def) - (cl-mapcan #'s (oref def suffixes))) - ((transient-suffix--eieio-childp def) - (list def))))) - (cl-mapcan #'s transient--layout)))) + (setq transient--prefix (transient--init-prefix name params)) + (setq transient--layout (or layout (transient--init-suffixes name))) + (setq transient--suffixes (transient--flatten-suffixes transient--layout))) + +(defun transient--init-prefix (name &optional params) + (let ((obj (let ((proto (get name 'transient--prefix))) + (apply #'clone proto + :prototype proto + :level (or (alist-get t (alist-get name transient-levels)) + transient-default-level) + params)))) + (transient-init-value obj) + obj)) + +(defun transient--init-suffixes (name) + (let ((levels (alist-get name transient-levels))) + (cl-mapcan (lambda (c) (transient--init-child levels c)) + (append (get name 'transient--layout) + (and (not transient--editp) + (get 'transient-common-commands + 'transient--layout)))))) + +(defun transient--flatten-suffixes (layout) + (cl-labels ((s (def) + (cond + ((stringp def) nil) + ((listp def) (cl-mapcan #'s def)) + ((transient-group--eieio-childp def) + (cl-mapcan #'s (oref def suffixes))) + ((transient-suffix--eieio-childp def) + (list def))))) + (cl-mapcan #'s layout))) (defun transient--init-child (levels spec) (cl-etypecase spec @@ -1536,14 +1711,14 @@ EDIT may be non-nil." (when (transient--use-suffix-p obj) (when-let ((suffixes (cl-mapcan (lambda (c) (transient--init-child levels c)) - children))) + (transient-setup-children obj children)))) (oset obj suffixes suffixes) (list obj))))))) (defun transient--init-suffix (levels spec) (pcase-let* ((`(,level ,class ,args) spec) (cmd (plist-get args :command)) - (level (or (alist-get (transient--suffix-command cmd) levels) + (level (or (alist-get (transient--suffix-symbol cmd) levels) level))) (let ((fn (and (symbolp cmd) (symbol-function cmd)))) @@ -1559,8 +1734,10 @@ EDIT may be non-nil." (transient--init-suffix-key obj) (transient--ensure-infix-command obj) (when (transient--use-suffix-p obj) - (transient-init-scope obj) - (transient-init-value obj) + (if (transient--inapt-suffix-p obj) + (oset obj inapt t) + (transient-init-scope obj) + (transient-init-value obj)) (list obj)))))) (cl-defmethod transient--init-suffix-key ((obj transient-suffix)) @@ -1584,27 +1761,64 @@ EDIT may be non-nil." (<= level (oref transient--prefix level))))) (defun transient--use-suffix-p (obj) - (with-slots - (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived) - obj - (cond - (if (funcall if)) - (if-not (not (funcall if-not))) - (if-non-nil (symbol-value if-non-nil)) - (if-nil (not (symbol-value if-nil))) - (if-mode (if (atom if-mode) - (eq major-mode if-mode) - (memq major-mode if-mode))) - (if-not-mode (not (if (atom if-not-mode) - (eq major-mode if-not-mode) - (memq major-mode if-not-mode)))) - (if-derived (if (atom if-derived) - (derived-mode-p if-derived) - (apply #'derived-mode-p if-derived))) - (if-not-derived (not (if (atom if-not-derived) - (derived-mode-p if-not-derived) - (apply #'derived-mode-p if-not-derived)))) - (t)))) + (transient--do-suffix-p + (oref obj if) + (oref obj if-not) + (oref obj if-nil) + (oref obj if-non-nil) + (oref obj if-mode) + (oref obj if-not-mode) + (oref obj if-derived) + (oref obj if-not-derived) + t)) + +(defun transient--inapt-suffix-p (obj) + (transient--do-suffix-p + (oref obj inapt-if) + (oref obj inapt-if-not) + (oref obj inapt-if-nil) + (oref obj inapt-if-non-nil) + (oref obj inapt-if-mode) + (oref obj inapt-if-not-mode) + (oref obj inapt-if-derived) + (oref obj inapt-if-not-derived) + nil)) + +(defun transient--do-suffix-p + (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived + default) + (cond + (if (funcall if)) + (if-not (not (funcall if-not))) + (if-non-nil (symbol-value if-non-nil)) + (if-nil (not (symbol-value if-nil))) + (if-mode (if (atom if-mode) + (eq major-mode if-mode) + (memq major-mode if-mode))) + (if-not-mode (not (if (atom if-not-mode) + (eq major-mode if-not-mode) + (memq major-mode if-not-mode)))) + (if-derived (if (atom if-derived) + (derived-mode-p if-derived) + (apply #'derived-mode-p if-derived))) + (if-not-derived (not (if (atom if-not-derived) + (derived-mode-p if-not-derived) + (apply #'derived-mode-p if-not-derived)))) + (t default))) + +(defun transient--suffix-predicate (spec) + (let ((plist (nth 2 spec))) + (seq-some (lambda (prop) + (when-let ((pred (plist-get plist prop))) + (list prop pred))) + '( :if :if-not + :if-nil :if-non-nil + :if-mode :if-not-mode + :if-derived :if-not-derived + :inapt-if :inapt-if-not + :inapt-if-nil :inapt-if-non-nil + :inapt-if-mode :inapt-if-not-mode + :inapt-if-derived :inapt-if-not-derived)))) ;;; Flow-Control @@ -1646,9 +1860,8 @@ EDIT may be non-nil." (setq this-command 'transient-set-level)) (t (setq transient--exitp nil) - (when (eq (if-let ((fn (or (lookup-key transient--predicate-map - (vector this-original-command)) - (oref transient--prefix transient-non-suffix)))) + (when (eq (if-let ((fn (transient--get-predicate-for + this-original-command))) (let ((action (funcall fn))) (when (eq action transient--exit) (setq transient--exitp (or transient--exitp t))) @@ -1662,6 +1875,11 @@ EDIT may be non-nil." transient--exit) (transient--pre-exit))))) +(defun transient--get-predicate-for (cmd) + (or (lookup-key transient--predicate-map + (vector (transient--suffix-symbol cmd))) + (oref transient--prefix transient-non-suffix))) + (defun transient--pre-exit () (transient--debug 'pre-exit) (transient--delete-window) @@ -1670,7 +1888,8 @@ EDIT may be non-nil." (transient--pop-keymap 'transient--redisplay-map) (remove-hook 'pre-command-hook #'transient--pre-command) (unless transient--showp - (message "")) + (let ((message-log-max nil)) + (message ""))) (setq transient--transient-map nil) (setq transient--predicate-map nil) (setq transient--redisplay-map nil) @@ -1693,9 +1912,9 @@ EDIT may be non-nil." (kill-buffer buf)))) (defun transient--export () - (setq current-transient-prefix transient--prefix) - (setq current-transient-command (oref transient--prefix command)) - (setq current-transient-suffixes transient--suffixes) + (setq transient-current-prefix transient--prefix) + (setq transient-current-command (oref transient--prefix command)) + (setq transient-current-suffixes transient--suffixes) (transient--history-push transient--prefix)) (defun transient--minibuffer-setup () @@ -1751,15 +1970,15 @@ EDIT may be non-nil." (remove-hook 'minibuffer-exit-hook #'transient--minibuffer-exit) (advice-remove 'abort-recursive-edit #'transient--minibuffer-exit) (remove-hook 'post-command-hook #'transient--post-command)) - (setq current-transient-prefix nil) - (setq current-transient-command nil) - (setq current-transient-suffixes nil) + (setq transient-current-prefix nil) + (setq transient-current-command nil) + (setq transient-current-suffixes nil) (let ((resume (and transient--stack (not (memq transient--exitp '(replace suspend)))))) (setq transient--exitp nil) (setq transient--helpp nil) (setq transient--editp nil) - (run-hooks 'post-transient-hook) + (run-hooks 'transient-exit-hook) (when resume (transient--stack-pop)))) (transient--pop-keymap 'transient--redisplay-map) @@ -1788,9 +2007,7 @@ EDIT may be non-nil." (defun transient--redisplay () (if (or (eq transient-show-popup t) transient--showp) - (unless (memq this-command '(transient-scroll-up - transient-scroll-down - mwheel-scroll)) + (unless (memq this-command transient--scroll-commands) (transient--show)) (when (and (numberp transient-show-popup) (not (zerop transient-show-popup)) @@ -1815,35 +2032,24 @@ EDIT may be non-nil." (defun transient--debug (arg &rest args) (when transient--debug (if (symbolp arg) - (message "-- %-16s (cmd: %s, exit: %s)" - arg this-command transient--exitp) + (message "-- %-16s (cmd: %s, event: %S, exit: %s)" + arg + (transient--suffix-symbol this-command) + (key-description (this-command-keys-vector)) + transient--exitp) (apply #'message arg args)))) (defun transient--emergency-exit () "Exit the current transient command after an error occurred. - -Beside being used with `condition-case', this function also has -to be a member of `debugger-mode-hook', else the debugger would -be unusable and exiting it by pressing \"q\" would fail because -the transient command would still be active and that key would -either be unbound or do something else. - When no transient is active (i.e. when `transient--prefix') is nil, then do nothing." + (transient--debug 'emergency-exit) (when transient--prefix (setq transient--stack nil) (setq transient--exitp t) (transient--pre-exit) (transient--post-command))) -(add-hook 'debugger-mode-hook 'transient--emergency-exit) - -(defmacro transient--with-emergency-exit (&rest body) - (declare (indent defun)) - `(condition-case nil - ,(macroexp-progn body) - (error (transient--emergency-exit)))) - ;;; Pre-Commands (defun transient--do-stay () @@ -1860,6 +2066,11 @@ nil, then do nothing." (setq this-command 'transient-undefined) transient--stay) +(defun transient--do-warn-inapt () + "Call `transient-inapt' and stay transient." + (setq this-command 'transient-inapt) + transient--stay) + (defun transient--do-call () "Call the command after exporting variables and stay transient." (transient--export) @@ -1908,6 +2119,18 @@ to `transient--do-warn'." (setq this-command 'transient-popup-navigation-help)) transient--stay) +(put 'transient--do-stay 'transient-color 'transient-blue) +(put 'transient--do-noop 'transient-color 'transient-blue) +(put 'transient--do-warn 'transient-color 'transient-blue) +(put 'transient--do-warn-inapt 'transient-color 'transient-blue) +(put 'transient--do-call 'transient-color 'transient-blue) +(put 'transient--do-exit 'transient-color 'transient-red) +(put 'transient--do-replace 'transient-color 'transient-red) +(put 'transient--do-suspend 'transient-color 'transient-red) +(put 'transient--do-quit-one 'transient-color 'transient-red) +(put 'transient--do-quit-all 'transient-color 'transient-red) +(put 'transient--do-move 'transient-color 'transient-blue) + ;;; Commands (defun transient-noop () @@ -1917,13 +2140,24 @@ to `transient--do-warn'." (defun transient-undefined () "Warn the user that the pressed key is not bound to any suffix." (interactive) + (transient--invalid "Unbound suffix")) + +(defun transient-inapt () + "Warn the user that the invoked command is inapt." + (interactive) + (transient--invalid "Inapt command")) + +(defun transient--invalid (msg) (ding) - (message "Unbound suffix: `%s' (Use `%s' to abort, `%s' for help) [%s]" + (message "%s: `%s' (Use `%s' to abort, `%s' for help) [%s]" + msg (propertize (key-description (this-single-command-keys)) 'face 'font-lock-warning-face) (propertize "C-g" 'face 'transient-key) (propertize "?" 'face 'transient-key) - this-original-command)) + (propertize (symbol-name (transient--suffix-symbol + this-original-command)) + 'face 'font-lock-warning-face))) (defun transient-toggle-common () "Toggle whether common commands are always shown." @@ -1995,11 +2229,11 @@ transient is active." (and (lookup-key transient--transient-map keys) (string-to-number (let ((transient--active-infix - (transient-suffix-object))) + (transient-suffix-object command))) (transient--show) (transient--read-number-N (format "Set level for `%s': " - (transient--suffix-command command)) + (transient--suffix-symbol command)) nil nil (not (eq command prefix))))))))))) (cond ((not command) @@ -2008,12 +2242,12 @@ transient is active." (level (let* ((prefix (oref transient--prefix command)) (alist (alist-get prefix transient-levels)) - (key (transient--suffix-command command))) + (sym (transient--suffix-symbol command))) (if (eq command prefix) (progn (oset transient--prefix level level) - (setq key t)) + (setq sym t)) (oset (transient-suffix-object command) level level)) - (setf (alist-get key alist) level) + (setf (alist-get sym alist) level) (setf (alist-get prefix transient-levels) alist)) (transient-save-levels)) (t @@ -2022,12 +2256,12 @@ transient is active." (defun transient-set () "Save the value of the active transient for this Emacs session." (interactive) - (transient-set-value (or transient--prefix current-transient-prefix))) + (transient-set-value (or transient--prefix transient-current-prefix))) (defun transient-save () "Save the value of the active transient persistenly across Emacs sessions." (interactive) - (transient-save-value (or transient--prefix current-transient-prefix))) + (transient-save-value (or transient--prefix transient-current-prefix))) (defun transient-history-next () "Switch to the next value used for the active transient." @@ -2119,6 +2353,20 @@ abstract `transient-infix' class must implement this function. Non-infix suffix commands usually don't have a value." nil) +(cl-defmethod transient-init-value :around ((obj transient-prefix)) + "If bound, then call OBJ's `init-value' function. +Otherwise call the primary method according to objects class." + (if (slot-boundp obj 'init-value) + (funcall (oref obj init-value) obj) + (cl-call-next-method obj))) + +(cl-defmethod transient-init-value :around ((obj transient-infix)) + "If bound, then call OBJ's `init-value' function. +Otherwise call the primary method according to objects class." + (if (slot-boundp obj 'init-value) + (funcall (oref obj init-value) obj) + (cl-call-next-method obj))) + (cl-defmethod transient-init-value ((obj transient-prefix)) (if (slot-boundp obj 'value) (oref obj value) @@ -2188,7 +2436,7 @@ which might make it necessary to kill it from the outside." "Read a value while taking care of history. This method is suitable for a wide variety of infix commands, -including but not limitted to inline arguments and variables. +including but not limited to inline arguments and variables. If you do not use this method for your own infix class, then you should likely replicate a lot of the behavior of this @@ -2200,9 +2448,10 @@ limited number of possible values should you replace this with a simple method that does not handle history. (E.g. for a command line switch the only possible values are \"use it\" and \"don't use it\", in which case it is pointless to preserve history.)" - (with-slots (value multi-value allow-empty choices) obj + (with-slots (value multi-value always-read allow-empty choices) obj (if (and value (not multi-value) + (not always-read) transient--prefix) (oset obj value nil) (let* ((overriding-terminal-local-map nil) @@ -2235,7 +2484,8 @@ it\", in which case it is pointless to preserve history.)" ((and (equal value "\"\"") allow-empty) (setq value ""))) (when value - (when (bound-and-true-p ivy-mode) + (when (and (bound-and-true-p ivy-mode) + (stringp (car transient--history))) (set-text-properties 0 (length (car transient--history)) nil (car transient--history))) (setf (alist-get history-key transient-history) @@ -2255,15 +2505,22 @@ The last value is \"don't use any of these switches\"." (cadr (member value choices)) (car choices)))) +(cl-defmethod transient-infix-read ((command symbol)) + "Elsewhere use the reader of the infix command COMMAND. +Use this if you want to share an infix's history with a regular +stand-alone command." + (cl-letf (((symbol-function #'transient--show) #'ignore)) + (transient-infix-read (get command 'transient--suffix)))) + ;;;; Readers (defun transient-read-directory (prompt _initial-input _history) "Read a directory." - (expand-file-name (read-directory-name prompt))) + (file-local-name (expand-file-name (read-directory-name prompt)))) (defun transient-read-existing-directory (prompt _initial-input _history) "Read an existing directory." - (expand-file-name (read-directory-name prompt nil nil t))) + (file-local-name (expand-file-name (read-directory-name prompt nil nil t)))) (defun transient-read-number-N0 (prompt initial-input history) "Read a natural number (including zero) and return it as a string." @@ -2343,10 +2600,7 @@ prompt." "Set the value of infix object OBJ to value.") (cl-defmethod transient-infix-set ((obj transient-infix) value) - "Set the value of infix object OBJ to value. - -This implementation should be suitable for almost all infix -commands." + "Set the value of infix object OBJ to value." (oset obj value value)) (cl-defmethod transient-infix-set :around ((obj transient-argument) value) @@ -2389,16 +2643,22 @@ If the current command was invoked from the transient prefix command PREFIX, then return the active infix arguments. If the current command was not invoked from PREFIX, then return the set, saved or default value for PREFIX." - (if (eq current-transient-command prefix) - (delq nil (mapcar 'transient-infix-value current-transient-suffixes)) - (let ((transient--prefix nil) - (transient--layout nil) - (transient--suffixes nil)) - (transient--init-objects prefix nil nil) - (delq nil (mapcar 'transient-infix-value transient--suffixes))))) + (delq nil (mapcar 'transient-infix-value (transient-suffixes prefix)))) + +(defun transient-suffixes (prefix) + "Return the suffix objects of the transient prefix command PREFIX." + (if (eq transient-current-command prefix) + transient-current-suffixes + (let ((transient--prefix (transient--init-prefix prefix))) + (transient--flatten-suffixes + (transient--init-suffixes prefix))))) (defun transient-get-value () - (delq nil (mapcar 'transient-infix-value current-transient-suffixes))) + (delq nil (mapcar (lambda (obj) + (and (or (not (slot-exists-p obj 'unsavable)) + (not (oref obj unsavable))) + (transient-infix-value obj))) + transient-current-suffixes))) (cl-defgeneric transient-infix-value (obj) "Return the value of the suffix object OBJ. @@ -2447,7 +2707,7 @@ contribute to the value of the transient." nil) (cl-defmethod transient-infix-value ((obj transient-files)) - "Return (concat ARGUMENT VALUE) or nil. + "Return (cons ARGUMENT VALUE) or nil. ARGUMENT and VALUE are the values of the respective slots of OBJ. If VALUE is nil, then return nil. VALUE may be the empty string, @@ -2455,6 +2715,25 @@ which is not the same as nil." (when-let ((value (oref obj value))) (cons (oref obj argument) value))) +;;;; Utilities + +(defun transient-arg-value (arg args) + "Return the value of ARG as it appears in ARGS. + +For a switch return a boolean. For an option return the value as +a string, using the empty string for the empty value, or nil if +the option does not appear in ARGS." + (if (string-match-p "=\\'" arg) + (save-match-data + (when-let ((match (let ((re (format "\\`%s\\(?:=\\(.+\\)\\)?\\'" + (substring arg 0 -1)))) + (cl-find-if (lambda (a) + (and (stringp a) + (string-match re a))) + args)))) + (or (match-string 1 match) ""))) + (and (member arg args) t))) + ;;; History (cl-defgeneric transient--history-key (obj) @@ -2549,9 +2828,14 @@ have a history of their own.") (transient--insert-help)) (when (and (eq transient-mode-line-format 'line) window-system) - (insert (propertize "__" 'face 'transient-separator - 'display '(space :height (1)))) - (insert (propertize "\n" 'face 'transient-separator 'line-height t))) + (let ((face + (if-let ((f (and (transient--semantic-coloring-p) + (transient--prefix-color transient--prefix)))) + `(,@(and (>= emacs-major-version 27) '(:extend t)) + :background ,(face-foreground f)) + 'transient-separator))) + (insert (propertize "__" 'face face 'display '(space :height (1)))) + (insert (propertize "\n" 'face face 'line-height t)))) (let ((window-resize-pixelwise t) (window-size-fixed nil)) (fit-window-to-buffer nil nil 1)) @@ -2583,12 +2867,14 @@ have a history of their own.") (insert desc ?\n))) (cl-defmethod transient--insert-group ((group transient-row)) + (transient--maybe-pad-keys group) (dolist (suffix (oref group suffixes)) (insert (transient-format suffix)) (insert " ")) (insert ?\n)) (cl-defmethod transient--insert-group ((group transient-column)) + (transient--maybe-pad-keys group) (dolist (suffix (oref group suffixes)) (let ((str (transient-format suffix))) (insert str) @@ -2599,6 +2885,7 @@ have a history of their own.") (let* ((columns (mapcar (lambda (column) + (transient--maybe-pad-keys column group) (let ((rows (mapcar 'transient-format (oref column suffixes)))) (when-let ((desc (transient-format-description column))) (push desc rows)) @@ -2621,9 +2908,11 @@ have a history of their own.") (let* ((subgroups (oref group suffixes)) (n (length subgroups))) (dotimes (s n) - (transient--insert-group (nth s subgroups)) - (when (< s (1- n)) - (insert ?\n))))) + (let ((subgroup (nth s subgroups))) + (transient--maybe-pad-keys subgroup group) + (transient--insert-group subgroup) + (when (< s (1- n)) + (insert ?\n)))))) (cl-defgeneric transient-format (obj) "Format and return OBJ for display. @@ -2667,6 +2956,10 @@ Optional support for popup buttons is also implemented here." 'transient-enabled-suffix 'transient-disabled-suffix)))) (cl-call-next-method obj)))) + (when (oref obj inapt) + (set-text-properties 0 (length str) + (list 'face 'transient-inapt-suffix) + str)) (if transient-enable-popup-navigation (make-text-button str nil 'type 'transient-button @@ -2677,7 +2970,7 @@ Optional support for popup buttons is also implemented here." "Return a string generated using OBJ's `format'. %k is formatted using `transient-format-key'. %d is formatted using `transient-format-description'. -%f is formatted using `transient-format-value'." +%v is formatted using `transient-format-value'." (format-spec (oref obj format) `((?k . ,(transient-format-key obj)) (?d . ,(transient-format-description obj)) @@ -2696,7 +2989,8 @@ Optional support for popup buttons is also implemented here." (cl-defmethod transient-format-key ((obj transient-suffix)) "Format OBJ's `key' for display and return the result." - (let ((key (oref obj key))) + (let ((key (oref obj key)) + (cmd (oref obj command))) (if transient--redisplay-key (let ((len (length transient--redisplay-key)) (seq (cl-coerce (edmacro-parse-keys key t) 'list))) @@ -2718,15 +3012,21 @@ Optional support for popup buttons is also implemented here." (setq suf (replace-regexp-in-string " " "" suf))) (concat (propertize pre 'face 'default) (and (string-prefix-p (concat pre " ") key) " ") - (propertize suf 'face 'transient-key) + (transient--colorize-key suf cmd) (save-excursion (when (string-match " +\\'" key) (match-string 0 key)))))) ((transient--lookup-key transient-sticky-map (kbd key)) - (propertize key 'face 'transient-key)) + (transient--colorize-key key cmd)) (t (propertize key 'face 'transient-unreachable-key)))) - (propertize key 'face 'transient-key)))) + (transient--colorize-key key cmd)))) + +(defun transient--colorize-key (key command) + (propertize key 'face + (or (and (transient--semantic-coloring-p) + (transient--suffix-color command)) + 'transient-key))) (cl-defmethod transient-format-key :around ((obj transient-argument)) (let ((key (cl-call-next-method obj))) @@ -2767,6 +3067,9 @@ is nil, then use \"(BUG: no description)\" as the description. If the OBJ's `key' is currently unreachable, then apply the face `transient-unreachable' to the complete string." (let ((desc (or (cl-call-next-method obj) + (and (slot-boundp transient--prefix 'suffix-description) + (funcall (oref transient--prefix suffix-description) + obj)) (propertize "(BUG: no description)" 'face 'error)))) (if (transient--key-unreachable-p obj) (propertize desc 'face 'transient-unreachable) @@ -2830,6 +3133,34 @@ If the OBJ's `key' is currently unreachable, then apply the face (let ((val (lookup-key keymap key))) (and val (not (integerp val)) val))) +(defun transient--maybe-pad-keys (group &optional parent) + (when-let ((pad (if (slot-boundp group 'pad-keys) + (oref group pad-keys) + (and parent + (slot-boundp parent 'pad-keys) + (oref parent pad-keys))))) + (let ((width (apply #'max + (cons (if (integerp pad) pad 0) + (mapcar (lambda (suffix) + (length (oref suffix key))) + (oref group suffixes)))))) + (dolist (suffix (oref group suffixes)) + (oset suffix key + (truncate-string-to-width (oref suffix key) width nil ?\s)))))) + +(defun transient-command-summary-or-name (obj) + "Return the summary or name of the command represented by OBJ. + +If the command has a doc-string, then return the first line of +that, else its name. + +Intended to be temporarily used as the `:suffix-description' of +a prefix command, while porting a regular keymap to a transient." + (let ((command (transient--suffix-symbol (oref obj command)))) + (if-let ((doc (documentation command))) + (propertize (car (split-string doc "\n")) 'face 'font-lock-doc-face) + (propertize (symbol-name command) 'face 'font-lock-function-name-face)))) + ;;; Help (cl-defgeneric transient-show-help (obj) @@ -3092,6 +3423,35 @@ search instead." (select-window transient--original-window) (transient--resume-override)) +;;;; Hydra Color Emulation + +(defun transient--semantic-coloring-p () + (and transient-semantic-coloring + (not transient--helpp) + (not transient--editp))) + +(defun transient--suffix-color (command) + (or (get command 'transient-color) + (get (transient--get-predicate-for command) 'transient-color))) + +(defun transient--prefix-color (command) + (let* ((nonsuf (or (oref command transient-non-suffix) + 'transient--do-warn)) + (nonsuf (if (memq nonsuf '(transient--do-noop transient--do-warn)) + 'disallow + (get nonsuf 'transient-color))) + (suffix (if-let ((pred (oref command transient-suffix))) + (get pred 'transient-color) + (if (eq nonsuf 'transient-red) + 'transient-red + 'transient-blue)))) + (pcase (list suffix nonsuf) + (`(transient-red disallow) 'transient-amaranth) + (`(transient-blue disallow) 'transient-teal) + (`(transient-red transient-red) 'transient-pink) + (`(transient-red transient-blue) 'transient-red) + (`(transient-blue transient-blue) 'transient-blue)))) + ;;;; Edebug (defun transient--edebug--recursive-edit (fn arg-mode) @@ -3123,12 +3483,12 @@ search instead." (defun transient--suspend-which-key-mode () (when (bound-and-true-p which-key-mode) (which-key-mode -1) - (add-hook 'post-transient-hook 'transient--resume-which-key-mode))) + (add-hook 'transient-exit-hook 'transient--resume-which-key-mode))) (defun transient--resume-which-key-mode () (unless transient--prefix (which-key-mode 1) - (remove-hook 'post-transient-hook 'transient--resume-which-key-mode))) + (remove-hook 'transient-exit-hook 'transient--resume-which-key-mode))) (defun transient-bind-q-to-quit () "Modify some keymaps to bind \"q\" to the appropriate quit command. @@ -3173,15 +3533,27 @@ we stop there." (push (funcall function (car acc) elt) acc)) (nreverse acc))) +(defun transient-plist-to-alist (plist) + (let (alist) + (while plist + (push (cons (let* ((symbol (pop plist)) + (name (symbol-name symbol))) + (if (eq (aref name 0) ?:) + (intern (substring name 1)) + symbol)) + (pop plist)) + alist)) + (nreverse alist))) + ;;; Font-Lock (defconst transient-font-lock-keywords (eval-when-compile `((,(concat "(" - (regexp-opt (list "define-transient-command" - "define-infix-command" - "define-infix-argument" - "define-suffix-command") + (regexp-opt (list "transient-define-prefix" + "transient-define-infix" + "transient-define-argument" + "transient-define-suffix") t) "\\_>[ \t'\(]*" "\\(\\(?:\\sw\\|\\s_\\)+\\)?") @@ -3190,6 +3562,37 @@ we stop there." (font-lock-add-keywords 'emacs-lisp-mode transient-font-lock-keywords) +;;; Auxiliary Classes +;;;; `transient-lisp-variable' + +(defclass transient-lisp-variable (transient-variable) + ((reader :initform transient-lisp-variable--reader) + (always-read :initform t) + (set-value :initarg :set-value :initform set)) + "[Experimental] Class used for Lisp variables.") + +(cl-defmethod transient-init-value ((obj transient-lisp-variable)) + (oset obj value (symbol-value (oref obj variable)))) + +(cl-defmethod transient-infix-set ((obj transient-lisp-variable) value) + (funcall (oref obj set-value) + (oref obj variable) + (oset obj value value))) + +(cl-defmethod transient-format-description ((obj transient-lisp-variable)) + (or (oref obj description) + (symbol-name (oref obj variable)))) + +(cl-defmethod transient-format-value ((obj transient-lisp-variable)) + (propertize (prin1-to-string (oref obj value)) + 'face 'transient-value)) + +(cl-defmethod transient-prompt ((obj transient-lisp-variable)) + (format "Set %s: " (oref obj variable))) + +(defun transient-lisp-variable--reader (prompt initial-input _history) + (read--expression prompt initial-input)) + ;;; _ (provide 'transient) ;; Local Variables: diff --git a/elpa/transient-0.2.0/transient.info b/elpa/transient-0.3.0/transient.info old mode 100755 new mode 100644 similarity index 90% rename from elpa/transient-0.2.0/transient.info rename to elpa/transient-0.3.0/transient.info index ce28386..82cc0a5 --- a/elpa/transient-0.2.0/transient.info +++ b/elpa/transient-0.3.0/transient.info @@ -1,7 +1,7 @@ This is transient.info, produced by makeinfo version 6.5 from transient.texi. - Copyright (C) 2018-2020 Jonas Bernoulli + Copyright (C) 2018-2021 Jonas Bernoulli You can redistribute this document and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -44,9 +44,9 @@ reading a new value in the minibuffer. Calling a suffix command usually causes the transient to be exited but suffix commands can also be configured to not exit the transient. -This manual is for Transient version 0.2.0. +This manual is for Transient version 0.3.0. - Copyright (C) 2018-2020 Jonas Bernoulli + Copyright (C) 2018-2021 Jonas Bernoulli You can redistribute this document and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -62,7 +62,6 @@ This manual is for Transient version 0.2.0. * Introduction:: * Usage:: -* Other Options:: * Modifying Existing Transients:: * Defining New Commands:: * Classes and Methods:: @@ -85,6 +84,7 @@ Usage * Getting Help for Suffix Commands:: * Enabling and Disabling Suffixes:: * Other Commands:: +* Other Options:: Defining New Commands @@ -167,9 +167,9 @@ global variables are unset, and finally the command is actually called. Suffix commands can also be configured to not exit the transient. A suffix command can, but does not have to, use the infix arguments -in much the same way it can choose to use or ignore the prefix +in much the same way any command can choose to use or ignore the prefix arguments. For a suffix command that was invoked from a transient the -variable ‘current-transient-suffixes’ and the function ‘transient-args’ +variable ‘transient-current-suffixes’ and the function ‘transient-args’ serve about the same purpose as the variables ‘prefix-arg’ and ‘current-prefix-arg’ do for any command that was called after the prefix arguments have been set using a command such as ‘universal-argument’. @@ -197,8 +197,8 @@ looks a bit like this: main benefit then is that the user can see all the available commands in a popup buffer. That is useful by itself because it frees the user from having to remember all the keys that are valid after a certain prefix -key or command. Magit’s ‘magit-dispatch’ command is an example of using -Transient to merely implement a command dispatcher. +key or command. Magit’s ‘magit-dispatch’ (on ‘C-x M-g’) command is an +example of using Transient to merely implement a command dispatcher. In addition to that, Transient also allows users to interactively pass arguments to commands. These arguments can be much more complex @@ -238,7 +238,7 @@ which the author of Transient did not anticipate (or didn’t get around to implementing yet).  -File: transient.info, Node: Usage, Next: Other Options, Prev: Introduction, Up: Top +File: transient.info, Node: Usage, Next: Modifying Existing Transients, Prev: Introduction, Up: Top 2 Usage ******* @@ -253,6 +253,7 @@ File: transient.info, Node: Usage, Next: Other Options, Prev: Introduction, * Getting Help for Suffix Commands:: * Enabling and Disabling Suffixes:: * Other Commands:: +* Other Options::  File: transient.info, Node: Invoking Transients, Next: Aborting and Resuming Transients, Up: Usage @@ -275,7 +276,8 @@ and they may use the values set by the infix commands, i.e. the infix *arguments*. Instead of setting arguments to be used by a suffix command, infix -commands may also set some value by side-effect. +commands may also set some value by side-effect, e.g. by setting the +value of some variable.  File: transient.info, Node: Aborting and Resuming Transients, Next: Common Suffix Commands, Prev: Invoking Transients, Up: Usage @@ -346,12 +348,13 @@ File: transient.info, Node: Common Suffix Commands, Next: Saving Values, Prev A few shared suffix commands are available in all transients. These suffix commands are not shown in the popup buffer by default. - Most of these commands are bound to ‘C-x ’ and after pressing -‘C-x’ a section featuring all common commands is temporarily shown in -the popup buffer. After invoking one of these commands, that section -disappears again. Note however that one of these commands is described -as "Show common permanently"; invoke that if you want the common -commands to always be shown for all transients. + This includes the aborting commands mentioned in the previous node as +well as some other commands that are all bound to ‘C-x ’. After +‘C-x’ is pressed, a section featuring all these common commands is +temporarily shown in the popup buffer. After invoking one of them, the +section disappears again. Note however that one of these commands is +described as "Show common permanently"; invoke that if you want the +common commands to always be shown for all transients. ‘C-x t’ (‘transient-toggle-common’) @@ -416,8 +419,7 @@ but it is easily accessible (see *note Using History::). (1) ‘magit-diff’ and ‘magit-log’ are two prominent examples, and their handling of buffer-local values is actually a bit more complicated -than outlined above and even customizable. This is something I am -rethinking, but I don’t want to rush any changes.) +than outlined above and even customizable.  File: transient.info, Node: Using History, Next: Getting Help for Suffix Commands, Prev: Saving Values, Up: Usage @@ -430,12 +432,14 @@ value is saved to its history. These values can be cycled through the same way one can cycle through the history of commands that read user-input in the minibuffer. -‘M-p’ (‘transient-history-prev’) +‘C-M-p’ (‘transient-history-prev’) +‘C-x p’ (‘transient-history-prev’) This command switches to the previous value used for the active transient. -‘M-n’ (‘transient-history-next’) +‘C-M-n’ (‘transient-history-next’) +‘C-x n’ (‘transient-history-next’) This command switches to the next value used for the active transient. @@ -524,11 +528,6 @@ expect that it won’t be of use to most users, and they should place very important suffixes on a lower level, so that they remain available even if the user lowers the transient level. - (Magit currently places nearly all suffixes on level 4 and lower -levels are not used at all yet. So for the time being you should not -set a lower default level and using a higher level might not give you as -many additional suffixes as you hoped.) - -- User Option: transient-default-level This option controls which suffix levels are made available by @@ -567,7 +566,7 @@ many additional suffixes as you hoped.) state, you have to make sure that that state is currently active.  -File: transient.info, Node: Other Commands, Prev: Enabling and Disabling Suffixes, Up: Usage +File: transient.info, Node: Other Commands, Next: Other Options, Prev: Enabling and Disabling Suffixes, Up: Usage 2.8 Other Commands ================== @@ -591,10 +590,10 @@ window, and the key bindings are the same as for ‘scroll-up-command’ and wrapper around ‘scroll-down-command’ (which see).  -File: transient.info, Node: Other Options, Next: Modifying Existing Transients, Prev: Usage, Up: Top +File: transient.info, Node: Other Options, Prev: Other Commands, Up: Usage -3 Other Options -*************** +2.9 Other Options +================= -- User Option: transient-show-popup @@ -621,7 +620,7 @@ File: transient.info, Node: Other Options, Next: Modifying Existing Transients -- User Option: transient-enable-popup-navigation This option controls whether navigation commands are enabled in the - transient popup. + transient popup buffer. While a transient is active the transient popup buffer is not the current buffer, making it necessary to use dedicated commands to @@ -640,7 +639,7 @@ File: transient.info, Node: Other Options, Next: Modifying Existing Transients This option specifies the action used to display the transient popup buffer. The transient popup buffer is displayed in a window - using ‘(display-buffer buf transient-display-buffer-action)’. + using ‘(display-buffer BUFFER transient-display-buffer-action)’. The value of this option has the form ‘(FUNCTION . ALIST)’, where FUNCTION is a function or a list of functions. Each such function @@ -750,9 +749,9 @@ File: transient.info, Node: Other Options, Next: Modifying Existing Transients ‘default’ to be remapped to ‘fixed-pitch’ in that buffer.  -File: transient.info, Node: Modifying Existing Transients, Next: Defining New Commands, Prev: Other Options, Up: Top +File: transient.info, Node: Modifying Existing Transients, Next: Defining New Commands, Prev: Usage, Up: Top -4 Modifying Existing Transients +3 Modifying Existing Transients ******************************* To an extent transients can be customized interactively, see *note @@ -764,13 +763,13 @@ transients can be further modified non-interactively. • PREFIX is a transient prefix command, a symbol. • SUFFIX is a transient infix or suffix specification in the same - form as expected by ‘define-transient-command’. Note that an infix + form as expected by ‘transient-define-prefix’. Note that an infix is a special kind of suffix. Depending on context "suffixes" means "suffixes (including infixes)" or "non-infix suffixes". Here it means the former. See *note Suffix Specifications::. SUFFIX may also be a group in the same form as expected by - ‘define-transient-command’. See *note Group Specifications::. + ‘transient-define-prefix’. See *note Group Specifications::. • LOC is a command, a key vector, a key description (a string as returned by ‘key-description’), or a list specifying coordinates @@ -831,7 +830,7 @@ signal an error.  File: transient.info, Node: Defining New Commands, Next: Classes and Methods, Prev: Modifying Existing Transients, Up: Top -5 Defining New Commands +4 Defining New Commands *********************** * Menu: @@ -845,7 +844,7 @@ File: transient.info, Node: Defining New Commands, Next: Classes and Methods,  File: transient.info, Node: Defining Transients, Next: Binding Suffix and Infix Commands, Up: Defining New Commands -5.1 Defining Transients +4.1 Defining Transients ======================= A transient consists of a prefix command and at least one suffix @@ -855,7 +854,7 @@ binds the transient’s infix and suffix commands. In other words, it defines the complete transient, not just the transient prefix command that is used to invoke that transient. - -- Macro: define-transient-command name arglist [docstring] [keyword + -- Macro: transient-define-prefix name arglist [docstring] [keyword value]... group... [body...] This macro defines NAME as a transient prefix command and binds the @@ -901,11 +900,11 @@ that is used to invoke that transient.  File: transient.info, Node: Binding Suffix and Infix Commands, Next: Defining Suffix and Infix Commands, Prev: Defining Transients, Up: Defining New Commands -5.2 Binding Suffix and Infix Commands +4.2 Binding Suffix and Infix Commands ===================================== -The macro ‘define-transient-command’ is used to define a transient. -This defines the actual transient prefix command (see *note Defining +The macro ‘transient-define-prefix’ is used to define a transient. This +defines the actual transient prefix command (see *note Defining Transients::) and adds the transient’s infix and suffix bindings, as described below. @@ -913,7 +912,7 @@ described below. functions such as ‘transient-insert-suffix’ (See *note Modifying Existing Transients::). These functions take a "suffix specification" as one of their arguments, which has the same form as the specifications -used in ‘define-transient-command’. +used in ‘transient-define-prefix’. * Menu: @@ -923,7 +922,7 @@ used in ‘define-transient-command’.  File: transient.info, Node: Group Specifications, Next: Suffix Specifications, Up: Binding Suffix and Infix Commands -5.2.1 Group Specifications +4.2.1 Group Specifications -------------------------- The suffix and infix commands of a transient are organized in groups. @@ -935,7 +934,7 @@ of suffixes. subgroups. In most cases the class does not have to be specified explicitly, but see *note Group Classes::. - Groups are specified in the call to ‘define-transient-command’, using + Groups are specified in the call to ‘transient-define-prefix’, using vectors. Because groups are represented using vectors, we cannot use square brackets to indicate an optional element and instead use curly brackets to do the latter. @@ -975,9 +974,9 @@ constructor of that class. These predicates can also be used on individual suffixes and are only documented once, see *note Predicate Slots::. - • Finally the value of ‘:hide’, if non-nil, is a predicate that - controls whether the group is hidden by default. The key bindings - for suffixes of a hidden group should all use the same prefix key. + • The value of ‘:hide’, if non-nil, is a predicate that controls + whether the group is hidden by default. The key bindings for + suffixes of a hidden group should all use the same prefix key. Pressing that prefix key should temporarily show the group and its suffixes, which assumes that a predicate like this is used: @@ -985,6 +984,17 @@ constructor of that class. (eq (car transient--redisplay-key) ?\C-c)) ; the prefix key shared by all bindings + • The value of ‘:setup-children’, if non-nil, is a function that + takes two arguments the group object itself and a list of children. + The children are given as a, potentially empty, list consisting of + either group or suffix specifications. It can make arbitrary + changes to the children including constructing new children from + scratch. Also see ‘transient-setup-children’. + + • The boolean ‘:pad-keys’ argument controls whether keys of all + suffixes contained in a group are right padded, effectively + aligning the descriptions. + The ELEMENTs are either all subgroups (vectors), or all suffixes (lists) and strings. (At least currently no group type exists that would allow mixing subgroups with commands at the same level, though in @@ -995,16 +1005,23 @@ lists that specify commands and strings. Strings are inserted verbatim. The empty string can be used to insert gaps between suffixes, which is particularly useful if the suffixes are outlined as a table. + Variables are supported inside group specifications. For example in +place of a direct subgroup specification, a variable can be used whose +value is a vector that qualifies as a group specification. Likewise a +variable can be used where a suffix specification is expected. Lists of +group or suffix specifications are also supported. Indirect +specifications are resolved when the transient prefix is being defined. + The form of suffix specifications is documented in the next node.  File: transient.info, Node: Suffix Specifications, Prev: Group Specifications, Up: Binding Suffix and Infix Commands -5.2.2 Suffix Specifications +4.2.2 Suffix Specifications --------------------------- A transient’s suffix and infix commands are bound when the transient -prefix command is defined using ‘define-transient-command’, see *note +prefix command is defined using ‘transient-define-prefix’, see *note Defining Transients::. The commands are organized into groups, see *note Group Specifications::. Here we describe the form used to bind an individual suffix command. @@ -1042,10 +1059,18 @@ transient. The next element is either a command or an argument. This is the only argument that is mandatory in all cases. - • COMMAND is a symbol that is bound as a function, which has to be a - command. Any command will do; it does not need to have an object - associated with it (as would be the case if ‘define-suffix-command’ - or ‘define-infix-command’ were used to define it). + • Usually COMMAND is a symbol that is bound as a function, which has + to be defined or at least autoloaded as a command by the time the + containing prefix command is invoked. + + Any command will do; it does not need to have an object associated + with it (as would be the case if ‘transient-define-suffix’ or + ‘transient-define-infix’ were used to define it). + + The command can also be a closure or lambda expression, but that + should only be used for dynamic transients whose suffixes are + defined when the prefix command is invoked. See information about + the ‘:setup-children’ function in *note Group Specifications::. As mentioned above, the object that is associated with a command can be used to set the default for certain values that otherwise @@ -1078,13 +1103,13 @@ Slots::.  File: transient.info, Node: Defining Suffix and Infix Commands, Next: Using Infix Arguments, Prev: Binding Suffix and Infix Commands, Up: Defining New Commands -5.3 Defining Suffix and Infix Commands +4.3 Defining Suffix and Infix Commands ====================================== Note that an infix is a special kind of suffix. Depending on context "suffixes" means "suffixes (including infixes)" or "non-infix suffixes". - -- Macro: define-suffix-command name arglist [docstring] [keyword + -- Macro: transient-define-suffix name arglist [docstring] [keyword value]... body... This macro defines NAME as a transient suffix command. @@ -1102,7 +1127,7 @@ Note that an infix is a special kind of suffix. Depending on context ARGLIST. The infix arguments are usually accessed by using ‘transient-args’ inside ‘interactive’. - -- Macro: define-infix-command name arglist [docstring] [keyword + -- Macro: transient-define-infix name arglist [docstring] [keyword value]... This macro defines NAME as a transient infix command. @@ -1138,20 +1163,20 @@ Note that an infix is a special kind of suffix. Depending on context have to use ‘transient-suffix-command’ to define the infix command and use ‘t’ as the value of the ‘:transient’ keyword. - -- Macro: define-infix-argument name arglist [docstring] [keyword + -- Macro: transient-define-argument name arglist [docstring] [keyword value]... This macro defines NAME as a transient infix command. - It is an alias for ‘define-infix-command’. Only use this alias to - define an infix command that actually sets an infix argument. To - define an infix command that, for example, sets a variable, use - ‘define-infix-command’ instead. + This is an alias for ‘transient-define-infix’. Only use this alias + to define an infix command that actually sets an infix argument. + To define an infix command that, for example, sets a variable, use + ‘transient-define-infix’ instead.  File: transient.info, Node: Using Infix Arguments, Next: Transient State, Prev: Defining Suffix and Infix Commands, Up: Defining New Commands -5.4 Using Infix Arguments +4.4 Using Infix Arguments ========================= The function and the variables described below allow suffix commands to @@ -1170,7 +1195,7 @@ The preferred way of doing that is to call the ‘transient-args’ function, which for infix arguments serves about the same purpose as ‘prefix-arg’ serves for prefix arguments. - -- Function: transient-args &optional prefix + -- Function: transient-args prefix This function returns the value of the transient prefix command PREFIX. @@ -1180,7 +1205,22 @@ function, which for infix arguments serves about the same purpose as current command was not invoked from PREFIX, then it returns the set, saved or default value for PREFIX. - -- Variable: current-transient-suffixes + -- Function: transient-arg-value arg args + + This function return the value of ARG as it appears in ARGS. + + For a switch a boolean is returned. For an option the value is + returned as a string, using the empty string for the empty value, + or nil if the option does not appear in ARGS. + + -- Function: transient-suffixes prefix + + This function returns the suffixes of the transient prefix command + PREFIX. This is a list of objects. This function should only be + used if you need the objects (as opposed to just their values) and + if the current command is not being invoked from PREFIX. + + -- Variable: transient-current-suffixes The suffixes of the transient from which this suffix command was invoked. This is a list of objects. Usually it is sufficient to @@ -1189,13 +1229,13 @@ function, which for infix arguments serves about the same purpose as variable instead, i.e. if you need access to information beside the value. - -- Variable: current-transient-prefix + -- Variable: transient-current-prefix The transient from which this suffix command was invoked. The returned value is a ‘transient-prefix’ object, which holds information associated with the transient prefix command. - -- Variable: current-transient-command + -- Variable: transient-current-command The transient from which this suffix command was invoked. The returned value is a symbol, the transient prefix command. @@ -1203,7 +1243,7 @@ function, which for infix arguments serves about the same purpose as  File: transient.info, Node: Transient State, Prev: Using Infix Arguments, Up: Defining New Commands -5.5 Transient State +4.5 Transient State =================== Invoking a transient prefix command "activates" the respective @@ -1279,7 +1319,7 @@ call ‘transient-export’, ‘transient--stack-zap’ or ‘transient--stack-push’; and set the values of ‘transient--exitp’, ‘transient--helpp’ or ‘transient--editp’. -5.5.1 Pre-commands for Infixes +4.5.1 Pre-commands for Infixes ------------------------------ The default for infixes is ‘transient--do-stay’. This is also the only @@ -1289,7 +1329,7 @@ function that makes sense for infixes. Call the command without exporting variables and stay transient. -5.5.2 Pre-commands for Suffixes +4.5.2 Pre-commands for Suffixes ------------------------------- The default for suffixes is ‘transient--do-exit’. @@ -1309,7 +1349,7 @@ The default for suffixes is ‘transient--do-exit’. This is used for suffixes that are prefixes themselves, i.e. for sub-prefixes. -5.5.3 Pre-commands for Non-Suffixes +4.5.3 Pre-commands for Non-Suffixes ----------------------------------- The default for non-suffixes, i.e commands that are bound in other @@ -1329,7 +1369,7 @@ slot. Call ‘transient-noop’ and stay transient. -5.5.4 Special Pre-Commands +4.5.4 Special Pre-Commands -------------------------- -- Function: transient--do-quit-one @@ -1353,7 +1393,7 @@ slot.  File: transient.info, Node: Classes and Methods, Next: Related Abstractions and Packages, Prev: Defining New Commands, Up: Top -6 Classes and Methods +5 Classes and Methods ********************* Transient uses classes and generic functions to make it possible to @@ -1407,12 +1447,12 @@ This happens in two ways.  File: transient.info, Node: Group Classes, Next: Group Methods, Up: Classes and Methods -6.1 Group Classes +5.1 Group Classes ================= The type of a group can be specified using the ‘:class’ property at the beginning of the class specification, e.g. ‘[:class transient-columns -...]’ in a call to ‘define-transient-command’. +...]’ in a call to ‘transient-define-prefix’. • The abstract ‘transient-child’ class is the base class of both ‘transient-group’ (and therefore all groups) as well as of @@ -1455,9 +1495,23 @@ beginning of the class specification, e.g. ‘[:class transient-columns  File: transient.info, Node: Group Methods, Next: Prefix Classes, Prev: Group Classes, Up: Classes and Methods -6.2 Group Methods +5.2 Group Methods ================= + -- Function: transient-setup-children group children + + This generic function can be used to setup the children or a group. + + The default implementation usually just returns the children + unchanged, but if the ‘setup-children’ slot of GROUP is non-nil, + then it calls that function with CHILDREN as the only argument and + returns the value. + + The children are given as a, potentially empty, list consisting of + either group or suffix specifications. These functions can make + arbitrary changes to the children including constructing new + children from scratch. + -- Function: transient--insert-group group This generic function formats the group and its elements and @@ -1467,12 +1521,12 @@ File: transient.info, Node: Group Methods, Next: Prefix Classes, Prev: Group Functions that are called by this function may need to operate in the buffer from which the transient was called. To do so they can - temporally make the ‘transient--source-buffer’ the current buffer. + temporarily make the ‘transient--source-buffer’ the current buffer.  File: transient.info, Node: Prefix Classes, Next: Suffix Classes, Prev: Group Methods, Up: Classes and Methods -6.3 Prefix Classes +5.3 Prefix Classes ================== Currently the ‘transient-prefix’ class is being used for all prefix @@ -1498,7 +1552,7 @@ to the active transient’s object should not affect later invocations.  File: transient.info, Node: Suffix Classes, Next: Suffix Methods, Prev: Prefix Classes, Up: Classes and Methods -6.4 Suffix Classes +5.4 Suffix Classes ================== • All suffix and infix classes derive from ‘transient-suffix’, which @@ -1547,7 +1601,7 @@ they are very much subject to change and not documented.  File: transient.info, Node: Suffix Methods, Next: Prefix Slots, Prev: Suffix Classes, Up: Classes and Methods -6.5 Suffix Methods +5.5 Suffix Methods ================== To get information about the methods implementing these generic @@ -1561,7 +1615,7 @@ functions use ‘describe-function’.  File: transient.info, Node: Suffix Value Methods, Next: Suffix Format Methods, Up: Suffix Methods -6.5.1 Suffix Value Methods +5.5.1 Suffix Value Methods -------------------------- -- Function: transient-init-value obj @@ -1632,7 +1686,7 @@ File: transient.info, Node: Suffix Value Methods, Next: Suffix Format Methods,  File: transient.info, Node: Suffix Format Methods, Prev: Suffix Value Methods, Up: Suffix Methods -6.5.2 Suffix Format Methods +5.5.2 Suffix Format Methods --------------------------- -- Function: transient-format obj @@ -1677,7 +1731,7 @@ File: transient.info, Node: Suffix Format Methods, Prev: Suffix Value Methods,  File: transient.info, Node: Prefix Slots, Next: Suffix Slots, Prev: Suffix Methods, Up: Classes and Methods -6.6 Prefix Slots +5.6 Prefix Slots ================ • ‘man-page’ or ‘info-manual’ can be used to specify the @@ -1699,13 +1753,13 @@ File: transient.info, Node: Prefix Slots, Next: Suffix Slots, Prev: Suffix Me causes the others to be disabled. • ‘scope’ For some transients it might be necessary to have a sort of - secondary value, called a "scope". See ‘define-transient-command’. + secondary value, called a "scope". See ‘transient-define-prefix’. -6.6.1 Internal Prefix Slots +5.6.1 Internal Prefix Slots --------------------------- These slots are mostly intended for internal use. They should not be -set in calls to ‘define-transient-command’. +set in calls to ‘transient-define-prefix’. • ‘prototype’ When a transient prefix command is invoked, then a clone of that object is stored in the global variable @@ -1733,7 +1787,7 @@ set in calls to ‘define-transient-command’.  File: transient.info, Node: Suffix Slots, Next: Predicate Slots, Prev: Prefix Slots, Up: Classes and Methods -6.7 Suffix Slots +5.7 Suffix Slots ================ Here we document most of the slots that are only available for suffix @@ -1742,7 +1796,7 @@ documented in *note Predicate Slots::. Also see *note Suffix Classes::. -6.7.1 Slots of ‘transient-suffix’ +5.7.1 Slots of ‘transient-suffix’ --------------------------------- • ‘key’ The key, a key vector or a key description string. @@ -1765,7 +1819,7 @@ documented in *note Predicate Slots::. • ‘description’ The description, either a string or a function that is called with no argument and returns a string. -6.7.2 Slots of ‘transient-infix’ +5.7.2 Slots of ‘transient-infix’ -------------------------------- Some of these slots are only meaningful for some of the subclasses. @@ -1775,10 +1829,25 @@ They are defined here anyway to allow sharing certain methods. • ‘shortarg’ The short argument, e.g. ‘-v’. + • ‘value’ The value. Should not be accessed directly. + + • ‘init-value’ Function that is responsable for setting the object’s + value. If bound, then this is called with the object as the only + argument. Usually this is not bound, in which case the object’s + primary ‘transient-init-value’ method is called instead. + + • ‘unsavable’ Whether the value of the suffix is not saved as part of + the prefixes. + • ‘multi-value’ For options, whether the option can have multiple values. If non-nil, then default to use ‘completing-read-multiple’. + • ‘always-read’ For options, whether to read a value on every + invocation. If this is nil, then options that have a value are + simply unset and have to be invoked a second time to set a new + value. + • ‘allow-empty’ For options, whether the empty string is a valid value. @@ -1797,12 +1866,12 @@ They are defined here anyway to allow sharing certain methods. • ‘choices’ A list of valid values. How exactly that is used depends on the class of the object. -6.7.3 Slots of ‘transient-variable’ +5.7.3 Slots of ‘transient-variable’ ----------------------------------- • ‘variable’ The variable. -6.7.4 Slots of ‘transient-switches’ +5.7.4 Slots of ‘transient-switches’ ----------------------------------- • ‘argument-format’ The display format. Must contain ‘%s’, one of @@ -1814,7 +1883,7 @@ They are defined here anyway to allow sharing certain methods.  File: transient.info, Node: Predicate Slots, Prev: Suffix Slots, Up: Classes and Methods -6.8 Predicate Slots +5.8 Predicate Slots =================== Suffix and group objects share some predicate slots that control whether @@ -1848,7 +1917,7 @@ Suffixes::.  File: transient.info, Node: Related Abstractions and Packages, Next: FAQ, Prev: Classes and Methods, Up: Top -7 Related Abstractions and Packages +6 Related Abstractions and Packages *********************************** * Menu: @@ -1859,7 +1928,7 @@ File: transient.info, Node: Related Abstractions and Packages, Next: FAQ, Pre  File: transient.info, Node: Comparison With Prefix Keys and Prefix Arguments, Next: Comparison With Other Packages, Up: Related Abstractions and Packages -7.1 Comparison With Prefix Keys and Prefix Arguments +6.1 Comparison With Prefix Keys and Prefix Arguments ==================================================== While transient commands were inspired by regular prefix keys and prefix @@ -1875,7 +1944,7 @@ arguments, they are also quite different and much more complex. • ‘{NUMBER}’ is a footnote. -7.1.1 Regular Prefix Commands +6.1.1 Regular Prefix Commands ----------------------------- See *note (elisp)Prefix Keys::. @@ -1886,7 +1955,7 @@ See *note (elisp)Prefix Keys::. | `--> command3 --> (c) -7.1.2 Regular Prefix Arguments +6.1.2 Regular Prefix Arguments ------------------------------ See *note (elisp)Prefix Command Arguments::. @@ -1905,7 +1974,7 @@ See *note (elisp)Prefix Command Arguments::. | | `-------- discards --------' -7.1.3 Transients +6.1.3 Transients ---------------- (∩`-´)⊃━☆゚.*・。゚ @@ -2058,10 +2127,10 @@ elsewhere.  File: transient.info, Node: Comparison With Other Packages, Prev: Comparison With Prefix Keys and Prefix Arguments, Up: Related Abstractions and Packages -7.2 Comparison With Other Packages +6.2 Comparison With Other Packages ================================== -7.2.1 Magit-Popup +6.2.1 Magit-Popup ----------------- Transient is the successor to Magit-Popup (see *note @@ -2082,7 +2151,7 @@ was added, which was not already part of Magit-Popup’s initial release. that the key bindings for switches must begin with "-" and those for options must begin with "=". -7.2.2 Hydra +6.2.2 Hydra ----------- Hydra (see ) is another package that @@ -2116,7 +2185,7 @@ command dispatchers: focus and the interface is a bit more complicated. A very basic example using the current interface: - (define-transient-command outline-navigate () + (transient-define-prefix outline-navigate () :transient-suffix 'transient--do-stay :transient-non-suffix 'transient--do-warn [("p" "previous visible heading" outline-previous-visible-heading) @@ -2241,18 +2310,20 @@ Appendix B Keystroke Index (line 26) * C-h: Getting Help for Suffix Commands. (line 10) +* C-M-n: Using History. (line 17) +* C-M-p: Using History. (line 11) * C-q: Aborting and Resuming Transients. (line 36) * C-x C-s: Saving Values. (line 25) * C-x l: Enabling and Disabling Suffixes. - (line 49) + (line 44) +* C-x n: Using History. (line 18) +* C-x p: Using History. (line 12) * C-x s: Saving Values. (line 20) * C-x t: Common Suffix Commands. - (line 16) + (line 17) * C-z: Aborting and Resuming Transients. (line 42) -* M-n: Using History. (line 16) -* M-p: Using History. (line 11) * M-x transient-resume: Aborting and Resuming Transients. (line 55) @@ -2267,8 +2338,10 @@ Appendix C Command Index * transient-help: Getting Help for Suffix Commands. (line 10) -* transient-history-next: Using History. (line 16) +* transient-history-next: Using History. (line 17) +* transient-history-next <1>: Using History. (line 18) * transient-history-prev: Using History. (line 11) +* transient-history-prev <1>: Using History. (line 12) * transient-quit-all: Aborting and Resuming Transients. (line 36) * transient-quit-one: Aborting and Resuming Transients. @@ -2282,11 +2355,11 @@ Appendix C Command Index * transient-scroll-up arg: Other Commands. (line 12) * transient-set: Saving Values. (line 20) * transient-set-level: Enabling and Disabling Suffixes. - (line 49) + (line 44) * transient-suspend: Aborting and Resuming Transients. (line 42) * transient-toggle-common: Common Suffix Commands. - (line 16) + (line 17)  File: transient.info, Node: Function Index, Next: Variable Index, Prev: Command Index, Up: Top @@ -2297,13 +2370,6 @@ Appendix D Function Index [index] * Menu: -* define-infix-argument: Defining Suffix and Infix Commands. - (line 63) -* define-infix-command: Defining Suffix and Infix Commands. - (line 27) -* define-suffix-command: Defining Suffix and Infix Commands. - (line 9) -* define-transient-command: Defining Transients. (line 13) * transient--do-call: Transient State. (line 98) * transient--do-exit: Transient State. (line 94) * transient--do-noop: Transient State. (line 125) @@ -2314,11 +2380,20 @@ Appendix D Function Index * transient--do-suspend: Transient State. (line 144) * transient--do-warn: Transient State. (line 121) * transient--history-init: Prefix Classes. (line 10) -* transient--insert-group: Group Methods. (line 6) +* transient--insert-group: Group Methods. (line 20) * transient-append-suffix: Modifying Existing Transients. (line 47) +* transient-arg-value: Using Infix Arguments. + (line 32) * transient-args: Using Infix Arguments. (line 22) +* transient-define-argument: Defining Suffix and Infix Commands. + (line 63) +* transient-define-infix: Defining Suffix and Infix Commands. + (line 27) +* transient-define-prefix: Defining Transients. (line 13) +* transient-define-suffix: Defining Suffix and Infix Commands. + (line 9) * transient-format: Suffix Format Methods. (line 6) * transient-format-description: Suffix Format Methods. @@ -2349,10 +2424,13 @@ Appendix D Function Index (line 51) * transient-scroll-down: Other Commands. (line 18) * transient-scroll-up: Other Commands. (line 12) +* transient-setup-children: Group Methods. (line 6) * transient-show-help: Suffix Format Methods. (line 30) * transient-suffix-put: Modifying Existing Transients. (line 65) +* transient-suffixes: Using Infix Arguments. + (line 40)  File: transient.info, Node: Variable Index, Prev: Function Index, Up: Top @@ -2363,27 +2441,27 @@ Appendix E Variable Index [index] * Menu: -* current-transient-command: Using Infix Arguments. +* transient-current-command: Using Infix Arguments. + (line 62) +* transient-current-prefix: Using Infix Arguments. + (line 56) +* transient-current-suffixes: Using Infix Arguments. (line 47) -* current-transient-prefix: Using Infix Arguments. - (line 41) -* current-transient-suffixes: Using Infix Arguments. - (line 32) * transient-default-level: Enabling and Disabling Suffixes. - (line 38) + (line 33) * transient-detect-key-conflicts: Other Options. (line 137) * transient-display-buffer-action: Other Options. (line 46) * transient-enable-popup-navigation: Other Options. (line 28) * transient-force-fixed-pitch: Other Options. (line 151) * transient-highlight-mismatched-keys: Other Options. (line 96) -* transient-history-file: Using History. (line 33) -* transient-history-limit: Using History. (line 38) +* transient-history-file: Using History. (line 35) +* transient-history-limit: Using History. (line 40) * transient-levels-file: Enabling and Disabling Suffixes. - (line 44) + (line 39) * transient-mode-line-format: Other Options. (line 71) * transient-read-with-initial-input: Other Options. (line 88) * transient-show-common-commands: Common Suffix Commands. - (line 23) + (line 24) * transient-show-popup: Other Options. (line 6) * transient-substitute-key-function: Other Options. (line 115) * transient-values-file: Saving Values. (line 30) @@ -2393,45 +2471,45 @@ Appendix E Variable Index Tag Table: Node: Top751 Node: Introduction3651 -Node: Usage9438 -Node: Invoking Transients9772 -Node: Aborting and Resuming Transients10804 -Node: Common Suffix Commands13463 -Node: Saving Values15217 -Ref: Saving Values-Footnote-116475 -Node: Using History16745 -Node: Getting Help for Suffix Commands18286 -Node: Enabling and Disabling Suffixes19679 -Node: Other Commands22969 -Node: Other Options23925 -Node: Modifying Existing Transients31049 -Node: Defining New Commands34453 -Node: Defining Transients34789 -Node: Binding Suffix and Infix Commands37221 -Node: Group Specifications38076 -Node: Suffix Specifications41409 -Node: Defining Suffix and Infix Commands44976 -Node: Using Infix Arguments48161 -Node: Transient State50381 -Node: Classes and Methods56254 -Node: Group Classes58468 -Node: Group Methods60385 -Node: Prefix Classes61030 -Node: Suffix Classes62122 -Node: Suffix Methods64366 -Node: Suffix Value Methods64687 -Node: Suffix Format Methods67447 -Node: Prefix Slots68899 -Node: Suffix Slots71376 -Node: Predicate Slots74227 -Node: Related Abstractions and Packages75475 -Node: Comparison With Prefix Keys and Prefix Arguments75762 -Node: Comparison With Other Packages86074 -Node: FAQ90265 -Node: Keystroke Index93999 -Node: Command Index95633 -Node: Function Index97420 -Node: Variable Index101577 +Node: Usage9466 +Node: Invoking Transients9834 +Node: Aborting and Resuming Transients10911 +Node: Common Suffix Commands13570 +Node: Saving Values15404 +Ref: Saving Values-Footnote-116662 +Node: Using History16855 +Node: Getting Help for Suffix Commands18494 +Node: Enabling and Disabling Suffixes19887 +Node: Other Commands22925 +Node: Other Options23903 +Node: Modifying Existing Transients31014 +Node: Defining New Commands34408 +Node: Defining Transients34744 +Node: Binding Suffix and Infix Commands37175 +Node: Group Specifications38029 +Node: Suffix Specifications42358 +Node: Defining Suffix and Infix Commands46316 +Node: Using Infix Arguments49514 +Node: Transient State52346 +Node: Classes and Methods58219 +Node: Group Classes60433 +Node: Group Methods62349 +Node: Prefix Classes63598 +Node: Suffix Classes64690 +Node: Suffix Methods66934 +Node: Suffix Value Methods67255 +Node: Suffix Format Methods70015 +Node: Prefix Slots71467 +Node: Suffix Slots73942 +Node: Predicate Slots77468 +Node: Related Abstractions and Packages78716 +Node: Comparison With Prefix Keys and Prefix Arguments79003 +Node: Comparison With Other Packages89315 +Node: FAQ93505 +Node: Keystroke Index97239 +Node: Command Index99019 +Node: Function Index100952 +Node: Variable Index105456  End Tag Table