Commit c72f7c4fe06e
Changed files (39)
.emacs.d
elpa
counsel-20170911.1121
hydra-20170903.218
ivy-20170911.1034
ivy-hydra-20170703.2350
s-20170906.1304
swiper-20170911.1036
.emacs.d/elpa/counsel-20170911.1121/counsel-autoloads.el
@@ -0,0 +1,372 @@
+;;; counsel-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "counsel" "counsel.el" (22977 29294 369907
+;;;;;; 188000))
+;;; Generated autoloads from counsel.el
+
+(autoload 'counsel-el "counsel" "\
+Elisp completion at point.
+
+\(fn)" t nil)
+
+(autoload 'counsel-cl "counsel" "\
+Common Lisp completion at point.
+
+\(fn)" t nil)
+
+(autoload 'counsel-clj "counsel" "\
+Clojure completion at point.
+
+\(fn)" t nil)
+
+(autoload 'counsel-unicode-char "counsel" "\
+Insert COUNT copies of a Unicode character at point.
+COUNT defaults to 1.
+
+\(fn &optional COUNT)" t nil)
+
+(autoload 'counsel-describe-variable "counsel" "\
+Forward to `describe-variable'.
+
+Variables declared using `defcustom' are highlighted according to
+`ivy-highlight-face'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-describe-function "counsel" "\
+Forward to `describe-function'.
+
+Interactive functions (i.e., commands) are highlighted according
+to `ivy-highlight-face'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-set-variable "counsel" "\
+Set a variable, with completion.
+
+When the selected variable is a `defcustom' with the type boolean
+or radio, offer completion of all possible values.
+
+Otherwise, offer a variant of `eval-expression', with the initial
+input corresponding to the chosen variable.
+
+\(fn)" t nil)
+
+(autoload 'counsel-info-lookup-symbol "counsel" "\
+Forward to (`info-lookup-symbol' SYMBOL MODE) with ivy completion.
+
+\(fn SYMBOL &optional MODE)" t nil)
+
+(autoload 'counsel-file-register "counsel" "\
+Search file in register.
+
+You cannot use Emacs' normal register commands to create file
+registers. Instead you must use the `set-register' function like
+so: `(set-register ?i \"/home/eric/.emacs.d/init.el\")'. Now you
+can use `C-x r j i' to open that file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-bookmark "counsel" "\
+Forward to `bookmark-jump' or `bookmark-set' if bookmark doesn't exist.
+
+\(fn)" t nil)
+
+(autoload 'counsel-M-x "counsel" "\
+Ivy version of `execute-extended-command'.
+Optional INITIAL-INPUT is the initial input in the minibuffer.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-load-library "counsel" "\
+Load a selected the Emacs Lisp library.
+The libraries are offered from `load-path'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-find-library "counsel" "\
+Visit a selected the Emacs Lisp library.
+The libraries are offered from `load-path'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-load-theme "counsel" "\
+Forward to `load-theme'.
+Usable with `ivy-resume', `ivy-next-line-and-call' and
+`ivy-previous-line-and-call'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-descbinds "counsel" "\
+Show a list of all defined keys and their definitions.
+If non-nil, show only bindings that start with PREFIX.
+BUFFER defaults to the current one.
+
+\(fn &optional PREFIX BUFFER)" t nil)
+
+(autoload 'counsel-git "counsel" "\
+Find file in the current Git repository.
+INITIAL-INPUT can be given as the initial minibuffer input.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-git-grep "counsel" "\
+Grep for a string in the current git repository.
+When CMD is a string, use it as a \"git grep\" command.
+When CMD is non-nil, prompt for a specific \"git grep\" command.
+INITIAL-INPUT can be given as the initial minibuffer input.
+
+\(fn &optional CMD INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-git-stash "counsel" "\
+Search through all available git stashes.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git-change-worktree "counsel" "\
+Find the file corresponding to the current buffer on a different worktree.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git-checkout "counsel" "\
+Call the \"git checkout\" command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git-log "counsel" "\
+Call the \"git log --grep\" shell command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-find-file "counsel" "\
+Forward to `find-file'.
+When INITIAL-INPUT is non-nil, use it in the minibuffer during completion.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-recentf "counsel" "\
+Find a file on `recentf-list'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-locate "counsel" "\
+Call the \"locate\" shell command.
+INITIAL-INPUT can be given as the initial minibuffer input.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-dpkg "counsel" "\
+Call the \"dpkg\" shell command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-rpm "counsel" "\
+Call the \"rpm\" shell command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-file-jump "counsel" "\
+Jump to a file below the current directory.
+List all files within the current directory or any of its subdirectories.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY)" t nil)
+
+(autoload 'counsel-dired-jump "counsel" "\
+Jump to a directory (in dired) below the current directory.
+List all subdirectories within the current directory.
+INITIAL-INPUT can be given as the initial minibuffer input.
+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.
+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'.
+AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY EXTRA-AG-ARGS AG-PROMPT)" t nil)
+
+(autoload 'counsel-pt "counsel" "\
+Grep for a string in the current directory using pt.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-pt-base-command' instead of
+`counsel-ag-base-command'.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-ack "counsel" "\
+Grep for a string in the current directory using ack.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-ack-base-command' replacing
+`counsel-ag-base-command'.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-rg "counsel" "\
+Grep for a string in the current directory using rg.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+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.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY EXTRA-RG-ARGS RG-PROMPT)" t nil)
+
+(autoload 'counsel-grep "counsel" "\
+Grep for a string in the current file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-grep-or-swiper "counsel" "\
+Call `swiper' for small buffers and `counsel-grep' for large ones.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-tag "counsel" "\
+Add or remove tags in `org-mode'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-tag-agenda "counsel" "\
+Set tags for the current agenda item.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-goto "counsel" "\
+Go to a different location in the current file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-goto-all "counsel" "\
+Go to a different location in any org file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-tmm "counsel" "\
+Text-mode emulation of looking and choosing from a menubar.
+
+\(fn)" t nil)
+
+(autoload 'counsel-yank-pop "counsel" "\
+Ivy replacement for `yank-pop'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-imenu "counsel" "\
+Jump to a buffer position indexed by imenu.
+
+\(fn)" t nil)
+
+(autoload 'counsel-list-processes "counsel" "\
+Offer completion for `process-list'.
+The default action deletes the selected process.
+An extra action allows to switch to the process buffer.
+
+\(fn)" t nil)
+
+(autoload 'counsel-expression-history "counsel" "\
+Select an element of `read-expression-history'.
+And insert it into the minibuffer. Useful during `eval-expression'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-shell-command-history "counsel" "\
+Browse shell command history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-esh-history "counsel" "\
+Browse Eshell history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-shell-history "counsel" "\
+Browse shell history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-rhythmbox "counsel" "\
+Choose a song from the Rhythmbox library to play or enqueue.
+
+\(fn)" t nil)
+
+(autoload 'counsel-linux-app "counsel" "\
+Launch a Linux desktop application, similar to Alt-<F2>.
+
+\(fn)" t nil)
+
+(autoload 'counsel-company "counsel" "\
+Complete using `company-candidates'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-colors-emacs "counsel" "\
+Show a list of all supported colors for a particular frame.
+
+You can insert or kill the name or the hexadecimal rgb value of the
+selected candidate.
+
+\(fn)" t nil)
+
+(autoload 'counsel-colors-web "counsel" "\
+Show a list of all W3C web colors for use in CSS.
+
+You can insert or kill the name or the hexadecimal rgb value of the
+selected candidate.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-agenda-headlines "counsel" "\
+Choose from headers of `org-mode' files in the agenda.
+
+\(fn)" t nil)
+
+(autoload 'counsel-irony "counsel" "\
+Inline C/C++ completion using Irony.
+
+\(fn)" t nil)
+
+(autoload 'counsel-apropos "counsel" "\
+Show all matching symbols.
+See `apropos' for further information about what is considered
+a symbol and how to search for them.
+
+\(fn)" t nil)
+
+(autoload 'counsel-switch-to-shell-buffer "counsel" "\
+Switch to a shell buffer, or create one.
+
+\(fn)" t nil)
+
+(defvar counsel-mode nil "\
+Non-nil if Counsel mode is enabled.
+See the `counsel-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 `counsel-mode'.")
+
+(custom-autoload 'counsel-mode "counsel" nil)
+
+(autoload 'counsel-mode "counsel" "\
+Toggle Counsel mode on or off.
+Turn Counsel mode on if ARG is positive, off otherwise. Counsel
+mode remaps built-in emacs functions that have counsel
+replacements.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; counsel-autoloads.el ends here
.emacs.d/elpa/counsel-20170911.1121/counsel-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "counsel" "20170911.1121" "Various completion functions using Ivy" '((emacs "24.3") (swiper "0.9.0")) :commit "0a1d361b926291874124f8c63a653d83ead64a36" :url "https://github.com/abo-abo/swiper" :keywords '("completion" "matching"))
.emacs.d/elpa/counsel-20170911.1121/counsel.el
@@ -0,0 +1,4018 @@
+;;; counsel.el --- Various completion functions using Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Package-Version: 20170911.1121
+;; Version: 0.9.1
+;; Package-Requires: ((emacs "24.3") (swiper "0.9.0"))
+;; Keywords: completion, 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Just call one of the interactive functions in this file to complete
+;; the corresponding thing using `ivy'.
+;;
+;; Currently available:
+;; - Symbol completion for Elisp, Common Lisp, Python and Clojure.
+;; - Describe fuctions for Elisp: function, variable, library, command,
+;; bindings, theme.
+;; - Navigation functions: imenu, ace-line, semantic, outline
+;; - Git utilities: git-files, git-grep, git-log, git-stash.
+;; - Grep utitilies: grep, ag, pt, recoll.
+;; - System utilities: process list, rhythmbox, linux-app.
+;; - Many more.
+
+;;; Code:
+
+(require 'swiper)
+(require 'etags)
+(require 'esh-util)
+
+;;* Utility
+(defun counsel-more-chars (n)
+ "Return two fake candidates prompting for at least N input."
+ (list ""
+ (format "%d chars more" (- n (length ivy-text)))))
+
+(defun counsel-unquote-regex-parens (str)
+ "Unquote regex parenthesis in STR."
+ (let ((start 0)
+ ms)
+ (while (setq start (string-match "\\\\)\\|\\\\(\\|[()]" str start))
+ (setq ms (match-string-no-properties 0 str))
+ (cond ((equal ms "\\(")
+ (setq str (replace-match "(" nil t str))
+ (setq start (+ start 1)))
+ ((equal ms "\\)")
+ (setq str (replace-match ")" nil t str))
+ (setq start (+ start 1)))
+ ((equal ms "(")
+ (setq str (replace-match "\\(" nil t str))
+ (setq start (+ start 2)))
+ ((equal ms ")")
+ (setq str (replace-match "\\)" nil t str))
+ (setq start (+ start 2)))
+ (t
+ (error "Unexpected"))))
+ str))
+
+(defun counsel-directory-parent (dir)
+ "Return the directory parent of directory DIR."
+ (concat (file-name-nondirectory
+ (directory-file-name dir)) "/"))
+
+(defun counsel-string-compose (prefix str)
+ "Make PREFIX the display prefix of STR through text properties."
+ (let ((str (copy-sequence str)))
+ (put-text-property
+ 0 1 'display
+ (concat prefix (substring str 0 1))
+ str)
+ str))
+
+(defun counsel-require-program (program)
+ "Check system for PROGRAM, printing error if unfound."
+ (when (and (stringp program)
+ (not (string= program ""))
+ (not (executable-find program)))
+ (user-error "Required program \"%s\" not found in your path" program)))
+
+;;* 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.")
+
+(defvar counsel--async-duration nil
+ "Store the time a process takes to gather all its candidates.
+The time is measured in seconds.")
+
+(defvar counsel--async-exit-code-plist nil
+ "Associates exit codes with reasons.")
+
+(defun counsel-set-async-exit-code (cmd number str)
+ "For CMD, associate NUMBER exit code with STR."
+ (let ((plist (plist-get counsel--async-exit-code-plist cmd)))
+ (setq counsel--async-exit-code-plist
+ (plist-put
+ counsel--async-exit-code-plist
+ cmd
+ (plist-put plist number str)))))
+
+(defvar counsel-async-split-string-re "\n"
+ "Store the regexp for splitting shell command output.")
+
+(defvar counsel-async-ignore-re nil
+ "Candidates matched the regexp will be ignored by `counsel--async-command'.")
+
+(defun counsel--async-command (cmd &optional process-sentinel process-filter)
+ "Start new counsel process by calling CMD.
+If a counsel process is already running, kill it and its associated buffer
+before starting a new one. If non-nil, use PROCESS-SENTINEL as the sentinel
+function instead of `counsel--async-sentinel'. If non-nil, use PROCESS-FILTER
+for handling the output of the process instead of `counsel--async-filter'."
+ (let* ((counsel--process " *counsel*")
+ (proc (get-process counsel--process))
+ (buff (get-buffer counsel--process)))
+ (when proc
+ (delete-process proc))
+ (when buff
+ (kill-buffer buff))
+ (setq proc (start-process-shell-command
+ counsel--process
+ counsel--process
+ cmd))
+ (setq counsel--async-start
+ (setq counsel--async-time (current-time)))
+ (set-process-sentinel proc (or process-sentinel #'counsel--async-sentinel))
+ (set-process-filter proc (or process-filter #'counsel--async-filter))))
+
+(defvar counsel-grep-last-line nil)
+
+(defun counsel--async-sentinel (process event)
+ "Sentinel function for an asynchronous counsel PROCESS.
+EVENT is a string describing the change."
+ (let ((cands
+ (cond ((string= event "finished\n")
+ (with-current-buffer (process-buffer process)
+ (split-string
+ (buffer-string)
+ counsel-async-split-string-re
+ t)))
+ ((string-match "exited abnormally with code \\([0-9]+\\)\n" event)
+ (let* ((exit-code-plist (plist-get counsel--async-exit-code-plist
+ (ivy-state-caller ivy-last)))
+ (exit-num (read (match-string 1 event)))
+ (exit-code (plist-get exit-code-plist exit-num)))
+ (list
+ (or exit-code
+ (format "error code %d" exit-num))))))))
+ (cond ((string= event "finished\n")
+ (ivy--set-candidates
+ (ivy--sort-maybe
+ cands))
+ (setq counsel-grep-last-line nil)
+ (when counsel--async-start
+ (setq counsel--async-duration
+ (time-to-seconds (time-since counsel--async-start))))
+ (let ((re (funcall ivy--regex-function ivy-text)))
+ (unless (stringp re)
+ (setq re (caar re)))
+ (if (null ivy--old-cands)
+ (unless (ivy-set-index
+ (ivy--preselect-index
+ (ivy-state-preselect ivy-last)
+ ivy--all-candidates))
+ (ivy--recompute-index
+ ivy-text re ivy--all-candidates))
+ (ivy--recompute-index
+ ivy-text re ivy--all-candidates)))
+ (setq ivy--old-cands ivy--all-candidates)
+ (if (null ivy--all-candidates)
+ (ivy--insert-minibuffer "")
+ (ivy--exhibit)))
+ ((string-match "exited abnormally with code \\([0-9]+\\)\n" event)
+ (setq ivy--all-candidates cands)
+ (setq ivy--old-cands ivy--all-candidates)
+ (ivy--exhibit)))))
+
+(defcustom counsel-async-filter-update-time 500000
+ "The amount of time in microseconds to wait until updating
+`counsel--async-filter'."
+ :type 'integer
+ :group 'ivy)
+
+(defun counsel--async-filter (process str)
+ "Receive from PROCESS the output STR.
+Update the minibuffer with the amount of lines collected every
+`counsel-async-filter-update-time' microseconds since the last update."
+ (with-current-buffer (process-buffer process)
+ (insert str))
+ (let (size)
+ (when (time-less-p
+ `(0 0 ,counsel-async-filter-update-time 0)
+ (time-since counsel--async-time))
+ (with-current-buffer (process-buffer process)
+ (goto-char (point-min))
+ (setq size (- (buffer-size) (forward-line (buffer-size))))
+ (ivy--set-candidates
+ (let ((strings (split-string (buffer-string)
+ counsel-async-split-string-re
+ t)))
+ (if (and counsel-async-ignore-re
+ (stringp counsel-async-ignore-re))
+ (cl-remove-if
+ (lambda (str)
+ (string-match-p counsel-async-ignore-re str))
+ strings)
+ strings))))
+ (let ((ivy--prompt (format
+ (concat "%d++ " (ivy-state-prompt ivy-last))
+ size)))
+ (ivy--insert-minibuffer
+ (ivy--format ivy--all-candidates)))
+ (setq counsel--async-time (current-time)))))
+
+(defcustom counsel-prompt-function 'counsel-prompt-function-default
+ "A function to return a full prompt string from a basic prompt string."
+ :type
+ '(choice
+ (const :tag "Plain" counsel-prompt-function-default)
+ (const :tag "Directory" counsel-prompt-function-dir)
+ (function :tag "Custom"))
+ :group 'ivy)
+
+(make-obsolete-variable
+ 'counsel-prompt-function
+ "Use `ivy-set-prompt' instead"
+ "0.8.0 <2016-06-20 Mon>")
+
+(defun counsel-prompt-function-default ()
+ "Return prompt appended with a semicolon."
+ (ivy-add-prompt-count
+ (format "%s: " (ivy-state-prompt ivy-last))))
+
+(defun counsel-delete-process ()
+ "Delete current counsel process."
+ (let ((process (get-process " *counsel*")))
+ (when process
+ (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))
+ ""))
+ (ivy-height 7)
+ (funp (eq (char-before (car bnd)) ?\())
+ symbol-names)
+ (if bnd
+ (progn
+ (setq ivy-completion-beg
+ (move-marker (make-marker) (car bnd)))
+ (setq ivy-completion-end
+ (move-marker (make-marker) (cdr bnd))))
+ (setq ivy-completion-beg nil)
+ (setq ivy-completion-end nil))
+ (if (string= str "")
+ (mapatoms
+ (lambda (x)
+ (when (symbolp x)
+ (push (symbol-name x) symbol-names))))
+ (setq symbol-names
+ (all-completions str obarray
+ (and funp
+ (lambda (x)
+ (or (functionp x)
+ (macrop x)
+ (special-form-p x)))))))
+ (ivy-read "Symbol name: " symbol-names
+ :predicate (and funp #'functionp)
+ :initial-input str
+ :action #'ivy-completion-in-region-action)))
+
+;;** `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")
+
+(defun counsel-jedi ()
+ "Python completion at point."
+ (interactive)
+ (let ((bnd (bounds-of-thing-at-point 'symbol)))
+ (if bnd
+ (progn
+ (setq ivy-completion-beg (car bnd))
+ (setq ivy-completion-end (cdr bnd)))
+ (setq ivy-completion-beg nil)
+ (setq ivy-completion-end nil)))
+ (deferred:sync!
+ (jedi:complete-request))
+ (ivy-read "Symbol name: " (jedi:ac-direct-matches)
+ :action #'counsel--py-action))
+
+(defun counsel--py-action (symbol)
+ "Insert SYMBOL, erasing the previous one."
+ (when (stringp symbol)
+ (with-ivy-window
+ (when ivy-completion-beg
+ (delete-region
+ ivy-completion-beg
+ ivy-completion-end))
+ (setq ivy-completion-beg
+ (move-marker (make-marker) (point)))
+ (insert symbol)
+ (setq ivy-completion-end
+ (move-marker (make-marker) (point)))
+ (when (equal (get-text-property 0 'symbol symbol) "f")
+ (insert "()")
+ (setq ivy-completion-end
+ (move-marker (make-marker) (point)))
+ (backward-char 1)))))
+
+;;** `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))
+ (ivy-height 7)
+ (res (ivy-read (format "pattern (%s): " str)
+ candidates)))
+ (when (stringp res)
+ (when bnd
+ (delete-region (car bnd) (cdr bnd)))
+ (insert res))))
+
+;;;###autoload
+(defun counsel-clj ()
+ "Clojure completion at point."
+ (interactive)
+ (counsel--generic
+ (lambda (str)
+ (mapcar
+ #'cl-caddr
+ (cider-sync-request:complete str ":same")))))
+
+;;** `counsel-unicode-char'
+(defvar counsel-unicode-char-history nil
+ "History for `counsel-unicode-char'.")
+
+;;;###autoload
+(defun counsel-unicode-char (&optional count)
+ "Insert COUNT copies of a Unicode character at point.
+COUNT defaults to 1."
+ (interactive "p")
+ (let ((minibuffer-allow-text-properties t)
+ (ivy-sort-max-size (expt 256 6)))
+ (setq ivy-completion-beg (point))
+ (setq ivy-completion-end (point))
+ (ivy-read "Unicode name: "
+ (nreverse
+ (mapcar (lambda (x)
+ (propertize
+ (format "%06X % -60s%c" (cdr x) (car x) (cdr x))
+ 'result (cdr x)))
+ (ucs-names)))
+ :action (lambda (char)
+ (with-ivy-window
+ (delete-region ivy-completion-beg ivy-completion-end)
+ (setq ivy-completion-beg (point))
+ (insert-char (get-text-property 0 'result char) count)
+ (setq ivy-completion-end (point))))
+ :history 'counsel-unicode-char-history
+ :sort t)))
+
+;;* Elisp symbols
+;;** `counsel-describe-variable'
+(defvar counsel-describe-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-.") #'counsel-find-symbol)
+ (define-key map (kbd "C-,") #'counsel--info-lookup-symbol)
+ map))
+
+(ivy-set-actions
+ 'counsel-describe-variable
+ '(("I" counsel-info-lookup-symbol "info")
+ ("d" counsel--find-symbol "definition")))
+
+(defvar counsel-describe-symbol-history nil
+ "History for `counsel-describe-variable' and `counsel-describe-function'.")
+
+(defun counsel-find-symbol ()
+ "Jump to the definition of the current symbol."
+ (interactive)
+ (ivy-exit-with-action #'counsel--find-symbol))
+
+(defun counsel--info-lookup-symbol ()
+ "Lookup the current symbol in the info docs."
+ (interactive)
+ (ivy-exit-with-action #'counsel-info-lookup-symbol))
+
+(defun counsel--find-symbol (x)
+ "Find symbol definition that corresponds to string X."
+ (with-ivy-window
+ (with-no-warnings
+ (ring-insert find-tag-marker-ring (point-marker)))
+ (let ((full-name (get-text-property 0 'full-name x)))
+ (if full-name
+ (find-library full-name)
+ (let ((sym (read x)))
+ (cond ((and (eq (ivy-state-caller ivy-last)
+ 'counsel-describe-variable)
+ (boundp sym))
+ (find-variable sym))
+ ((fboundp sym)
+ (find-function sym))
+ ((boundp sym)
+ (find-variable sym))
+ ((or (featurep sym)
+ (locate-library
+ (prin1-to-string sym)))
+ (find-library
+ (prin1-to-string sym)))
+ (t
+ (error "Couldn't find definition of %s"
+ sym))))))))
+
+(define-obsolete-function-alias 'counsel-symbol-at-point
+ 'ivy-thing-at-point "0.7.0")
+
+(defun counsel-variable-list ()
+ "Return the list of all currently bound variables."
+ (let (cands)
+ (mapatoms
+ (lambda (vv)
+ (when (or (get vv 'variable-documentation)
+ (and (boundp vv) (not (keywordp vv))))
+ (push (symbol-name vv) cands))))
+ (delete "" cands)))
+
+(defun counsel-describe-variable-transformer (var)
+ "Propertize VAR if it's a custom variable."
+ (if (custom-variable-p (intern var))
+ (ivy-append-face var 'ivy-highlight-face)
+ var))
+
+(ivy-set-display-transformer
+ 'counsel-describe-variable 'counsel-describe-variable-transformer)
+
+;;;###autoload
+(defun counsel-describe-variable ()
+ "Forward to `describe-variable'.
+
+Variables declared using `defcustom' are highlighted according to
+`ivy-highlight-face'."
+ (interactive)
+ (let ((enable-recursive-minibuffers t))
+ (ivy-read
+ "Describe variable: "
+ (counsel-variable-list)
+ :keymap counsel-describe-map
+ :preselect (ivy-thing-at-point)
+ :history 'counsel-describe-symbol-history
+ :require-match t
+ :sort t
+ :action (lambda (x)
+ (describe-variable
+ (intern x)))
+ :caller 'counsel-describe-variable)))
+
+;;** `counsel-describe-function'
+(ivy-set-actions
+ 'counsel-describe-function
+ '(("I" counsel-info-lookup-symbol "info")
+ ("d" counsel--find-symbol "definition")))
+
+(defun counsel-describe-function-transformer (function-name)
+ "Propertize FUNCTION-NAME if it's an interactive function."
+ (if (commandp (intern function-name))
+ (ivy-append-face function-name 'ivy-highlight-face)
+ function-name))
+
+(ivy-set-display-transformer
+ 'counsel-describe-function 'counsel-describe-function-transformer)
+
+;;;###autoload
+(defun counsel-describe-function ()
+ "Forward to `describe-function'.
+
+Interactive functions \(i.e., commands) are highlighted according
+to `ivy-highlight-face'."
+ (interactive)
+ (let ((enable-recursive-minibuffers t))
+ (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
+ :sort t
+ :action (lambda (x)
+ (describe-function
+ (intern x)))
+ :caller 'counsel-describe-function)))
+
+;;** `counsel-set-variable'
+(defvar counsel-set-variable-history nil
+ "Store history for `counsel-set-variable'.")
+
+(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)))
+
+(defun counsel--setq-doconst (x)
+ "Return a cons of description and value for X.
+X is an item of a radio- or choice-type defcustom."
+ (let (y)
+ (when (and (listp x)
+ (consp (setq y (last x))))
+ (unless (equal y '(function))
+ (setq x (car y))
+ (cons (prin1-to-string x)
+ (if (symbolp x)
+ (list 'quote x)
+ x))))))
+
+;;;###autoload
+(defun counsel-set-variable ()
+ "Set a variable, with completion.
+
+When the selected variable is a `defcustom' with the type boolean
+or radio, offer completion of all possible values.
+
+Otherwise, offer a variant of `eval-expression', with the initial
+input corresponding to the chosen variable."
+ (interactive)
+ (let ((sym (intern
+ (ivy-read "Variable: "
+ (counsel-variable-list)
+ :preselect (ivy-thing-at-point)
+ :history 'counsel-set-variable-history)))
+ sym-type
+ cands)
+ (if (and (boundp sym)
+ (setq sym-type (get sym 'custom-type))
+ (cond
+ ((and (consp sym-type)
+ (memq (car sym-type) '(choice radio)))
+ (setq cands (delq nil (mapcar #'counsel--setq-doconst (cdr sym-type)))))
+ ((eq sym-type 'boolean)
+ (setq cands '(("nil" . nil) ("t" . t))))
+ (t nil)))
+ (let* ((sym-val (symbol-value sym))
+ ;; Escape '%' chars if present
+ (sym-val-str (replace-regexp-in-string "%" "%%" (format "%s" sym-val)))
+ (res (ivy-read (format "Set (%S <%s>): " sym sym-val-str)
+ cands
+ :preselect (prin1-to-string sym-val))))
+ (when res
+ (setq res
+ (if (assoc res cands)
+ (cdr (assoc res cands))
+ (read 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))))
+
+;;** `counsel-info-lookup-symbol'
+(defvar info-lookup-mode)
+(declare-function info-lookup->completions "info-look")
+(declare-function info-lookup->mode-value "info-look")
+(declare-function info-lookup-select-mode "info-look")
+(declare-function info-lookup-change-mode "info-look")
+(declare-function info-lookup "info-look")
+
+;;;###autoload
+(defun counsel-info-lookup-symbol (symbol &optional mode)
+ "Forward to (`info-lookup-symbol' SYMBOL MODE) with ivy completion."
+ (interactive
+ (progn
+ (require 'info-look)
+ (let* ((topic 'symbol)
+ (mode (cond (current-prefix-arg
+ (info-lookup-change-mode topic))
+ ((info-lookup->mode-value
+ topic (info-lookup-select-mode))
+ info-lookup-mode)
+ ((info-lookup-change-mode topic))))
+ (completions (info-lookup->completions topic mode))
+ (enable-recursive-minibuffers t)
+ (value (ivy-read
+ "Describe symbol: "
+ (mapcar #'car completions)
+ :preselect (ivy-thing-at-point)
+ :sort t)))
+ (list value info-lookup-mode))))
+ (require 'info-look)
+ (info-lookup 'symbol symbol mode))
+
+;;** `counsel-M-x'
+(ivy-set-actions
+ 'counsel-M-x
+ '(("d" counsel--find-symbol "definition")
+ ("h" (lambda (x) (describe-function (intern x))) "help")))
+
+(ivy-set-display-transformer
+ 'counsel-M-x
+ 'counsel-M-x-transformer)
+
+;;;###autoload
+(defun counsel-file-register ()
+ "Search file in register.
+
+You cannot use Emacs' normal register commands to create file
+registers. Instead you must use the `set-register' function like
+so: `(set-register ?i \"/home/eric/.emacs.d/init.el\")'. Now you
+can use `C-x r j i' to open that file."
+ (interactive)
+ (ivy-read "File Register: "
+ ;; Use the `register-alist' variable to filter out file
+ ;; registers. Each entry for a file registar will have the
+ ;; following layout:
+ ;;
+ ;; (NUMBER 'file . "string/path/to/file")
+ ;;
+ ;; So we go through each entry and see if the `cadr' is
+ ;; `eq' to the symbol `file'. If so then add the filename
+ ;; (`cddr') which `ivy-read' will use for its choices.
+ (mapcar (lambda (register-alist-entry)
+ (if (eq 'file (cadr register-alist-entry))
+ (cddr register-alist-entry)))
+ register-alist)
+ :sort t
+ :require-match t
+ :history 'counsel-file-register
+ :caller 'counsel-file-register
+ :action (lambda (register-file)
+ (with-ivy-window (find-file register-file)))))
+
+(ivy-set-actions
+ 'counsel-file-register
+ '(("j" find-file-other-window "other window")))
+
+(declare-function bookmark-all-names "bookmark")
+(declare-function bookmark-location "bookmark")
+
+(defcustom counsel-bookmark-avoid-dired nil
+ "If non-nil, open directory bookmarks with `counsel-find-file'.
+By default `counsel-bookmark' opens a dired buffer for directories."
+ :type 'boolean
+ :group 'ivy)
+
+;;;###autoload
+(defun counsel-bookmark ()
+ "Forward to `bookmark-jump' or `bookmark-set' if bookmark doesn't exist."
+ (interactive)
+ (require 'bookmark)
+ (ivy-read "Create or jump to bookmark: "
+ (bookmark-all-names)
+ :action (lambda (x)
+ (cond ((and counsel-bookmark-avoid-dired
+ (member x (bookmark-all-names))
+ (file-directory-p (bookmark-location x)))
+ (with-ivy-window
+ (let ((default-directory (bookmark-location x)))
+ (counsel-find-file))))
+ ((member x (bookmark-all-names))
+ (with-ivy-window
+ (bookmark-jump x)))
+ (t
+ (bookmark-set x))))
+ :caller 'counsel-bookmark))
+
+(ivy-set-actions
+ 'counsel-bookmark
+ '(("d" bookmark-delete "delete")
+ ("e" bookmark-rename "edit")))
+
+(defun counsel-M-x-transformer (cmd)
+ "Return CMD appended with the corresponding binding in the current window."
+ (let ((binding (substitute-command-keys (format "\\[%s]" cmd))))
+ (setq binding (replace-regexp-in-string "C-x 6" "<f2>" binding))
+ (if (string-match "^M-x" binding)
+ cmd
+ (format "%s (%s)"
+ cmd (propertize binding 'face 'font-lock-keyword-face)))))
+
+(defvar smex-initialized-p)
+(defvar smex-ido-cache)
+(declare-function smex-initialize "ext:smex")
+(declare-function smex-detect-new-commands "ext:smex")
+(declare-function smex-update "ext:smex")
+(declare-function smex-rank "ext:smex")
+
+(defun counsel--M-x-prompt ()
+ "String for `M-x' plus the string representation of `current-prefix-arg'."
+ (if (not current-prefix-arg)
+ "M-x "
+ (concat
+ (if (eq current-prefix-arg '-)
+ "- "
+ (if (integerp current-prefix-arg)
+ (format "%d " current-prefix-arg)
+ (if (= (car current-prefix-arg) 4)
+ "C-u "
+ (format "%d " (car current-prefix-arg)))))
+ "M-x ")))
+
+(defvar counsel-M-x-history nil
+ "History for `counsel-M-x'.")
+
+;;;###autoload
+(defun counsel-M-x (&optional initial-input)
+ "Ivy version of `execute-extended-command'.
+Optional INITIAL-INPUT is the initial input in the minibuffer."
+ (interactive)
+ (let* ((cands obarray)
+ (pred 'commandp)
+ (sort t))
+ (when (require 'smex nil 'noerror)
+ (unless smex-initialized-p
+ (smex-initialize))
+ (when (smex-detect-new-commands)
+ (smex-update))
+ (setq cands smex-ido-cache)
+ (setq pred nil)
+ (setq sort nil))
+ ;; When `counsel-M-x' returns, `last-command' would be set to
+ ;; `counsel-M-x' because :action hasn't been invoked yet.
+ ;; Instead, preserve the old value of `this-command'.
+ (setq this-command last-command)
+ (setq real-this-command real-last-command)
+ (ivy-read (counsel--M-x-prompt) cands
+ :predicate pred
+ :require-match t
+ :history 'counsel-M-x-history
+ :action
+ (lambda (cmd)
+ (when (featurep 'smex)
+ (smex-rank (intern cmd)))
+ (let ((prefix-arg current-prefix-arg))
+ (setq real-this-command
+ (setq this-command (intern cmd)))
+ (command-execute (intern cmd) 'record)))
+ :sort sort
+ :keymap counsel-describe-map
+ :initial-input initial-input
+ :caller 'counsel-M-x)))
+
+;;** `counsel-load-library'
+(defun counsel-library-candidates ()
+ "Return a list of completion candidates for `counsel-load-library'."
+ (interactive)
+ (let ((dirs load-path)
+ (suffix (concat (regexp-opt '(".el" ".el.gz") t) "\\'"))
+ (cands (make-hash-table :test #'equal))
+ short-name
+ old-val
+ dir-parent
+ res)
+ (dolist (dir dirs)
+ (when (file-directory-p dir)
+ (dolist (file (file-name-all-completions "" dir))
+ (when (string-match suffix file)
+ (unless (string-match "pkg.elc?$" file)
+ (setq short-name (substring file 0 (match-beginning 0)))
+ (if (setq old-val (gethash short-name cands))
+ (progn
+ ;; assume going up directory once will resolve name clash
+ (setq dir-parent (counsel-directory-parent (cdr old-val)))
+ (puthash short-name
+ (cons
+ (counsel-string-compose dir-parent (car old-val))
+ (cdr old-val))
+ cands)
+ (setq dir-parent (counsel-directory-parent dir))
+ (puthash (concat dir-parent short-name)
+ (cons
+ (propertize
+ (counsel-string-compose
+ dir-parent short-name)
+ 'full-name (expand-file-name file dir))
+ dir)
+ cands))
+ (puthash short-name
+ (cons (propertize
+ short-name
+ 'full-name (expand-file-name file dir))
+ dir) cands)))))))
+ (maphash (lambda (_k v) (push (car v) res)) cands)
+ (nreverse res)))
+
+;;;###autoload
+(defun counsel-load-library ()
+ "Load a selected the Emacs Lisp library.
+The libraries are offered from `load-path'."
+ (interactive)
+ (let ((cands (counsel-library-candidates)))
+ (ivy-read "Load library: " cands
+ :action (lambda (x)
+ (load-library
+ (get-text-property 0 'full-name x)))
+ :keymap counsel-describe-map)))
+
+(ivy-set-actions
+ 'counsel-load-library
+ '(("d" counsel--find-symbol "definition")))
+
+;;** `counsel-find-library'
+;;;###autoload
+(defun counsel-find-library ()
+ "Visit a selected the Emacs Lisp library.
+The libraries are offered from `load-path'."
+ (interactive)
+ (let ((cands (counsel-library-candidates)))
+ (ivy-read "Find library: " cands
+ :action #'counsel--find-symbol
+ :keymap counsel-describe-map)))
+
+;;** `counsel-load-theme'
+(declare-function powerline-reset "ext:powerline")
+
+(defun counsel-load-theme-action (x)
+ "Disable current themes and load theme X."
+ (condition-case nil
+ (progn
+ (mapc #'disable-theme custom-enabled-themes)
+ (load-theme (intern x) t)
+ (when (fboundp 'powerline-reset)
+ (powerline-reset)))
+ (error "Problem loading theme %s" x)))
+
+;;;###autoload
+(defun counsel-load-theme ()
+ "Forward to `load-theme'.
+Usable with `ivy-resume', `ivy-next-line-and-call' and
+`ivy-previous-line-and-call'."
+ (interactive)
+ (ivy-read "Load custom theme: "
+ (mapcar 'symbol-name
+ (custom-available-themes))
+ :action #'counsel-load-theme-action
+ :caller 'counsel-load-theme))
+
+;;** `counsel-descbinds'
+(ivy-set-actions
+ 'counsel-descbinds
+ '(("d" counsel-descbinds-action-find "definition")
+ ("I" counsel-descbinds-action-info "info")))
+
+(defvar counsel-descbinds-history nil
+ "History for `counsel-descbinds'.")
+
+(defun counsel--descbinds-cands (&optional prefix buffer)
+ "Get key bindings starting with PREFIX in BUFFER.
+See `describe-buffer-bindings' for further information."
+ (let ((buffer (or buffer (current-buffer)))
+ (re-exclude (regexp-opt
+ '("<vertical-line>" "<bottom-divider>" "<right-divider>"
+ "<mode-line>" "<C-down-mouse-2>" "<left-fringe>"
+ "<right-fringe>" "<header-line>"
+ "<vertical-scroll-bar>" "<horizontal-scroll-bar>")))
+ res)
+ (with-temp-buffer
+ (let ((indent-tabs-mode t))
+ (describe-buffer-bindings buffer prefix))
+ (goto-char (point-min))
+ ;; Skip the "Key translations" section
+ (re-search-forward "")
+ (forward-char 1)
+ (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)
+ (not (or (commandp (setq cmd (intern-soft fun)))
+ (member fun '("Prefix Command")))))
+ (push
+ (cons (format
+ "%-15s %s"
+ (propertize key 'face 'font-lock-builtin-face)
+ fun)
+ (cons key cmd))
+ res))))
+ (forward-line 1)))
+ (nreverse res)))
+
+(defun counsel-descbinds-action-describe (x)
+ "Describe function of candidate X.
+See `describe-function' for further information."
+ (let ((cmd (cddr x)))
+ (describe-function cmd)))
+
+(defun counsel-descbinds-action-find (x)
+ "Find symbol definition of candidate X.
+See `counsel--find-symbol' for further information."
+ (let ((cmd (cddr x)))
+ (counsel--find-symbol (symbol-name cmd))))
+
+(defun counsel-descbinds-action-info (x)
+ "Display symbol definition of candidate X, as found in the relevant manual.
+See `info-lookup-symbol' for further information."
+ (let ((cmd (cddr x)))
+ (counsel-info-lookup-symbol (symbol-name cmd))))
+
+;;;###autoload
+(defun counsel-descbinds (&optional prefix buffer)
+ "Show a list of all defined keys and their definitions.
+If non-nil, show only bindings that start with PREFIX.
+BUFFER defaults to the current one."
+ (interactive)
+ (ivy-read "Bindings: " (counsel--descbinds-cands prefix buffer)
+ :action #'counsel-descbinds-action-describe
+ :history 'counsel-descbinds-history
+ :caller 'counsel-descbinds))
+;;** `counsel-describe-face'
+(defun counsel-describe-face ()
+ "Completion for `describe-face'."
+ (interactive)
+ (let (cands)
+ (mapatoms
+ (lambda (s)
+ (if (facep s)
+ (push (symbol-name s) cands))))
+ (ivy-read "Face: " cands
+ :preselect (symbol-name (face-at-point t))
+ :action #'describe-face)))
+;;* Git
+;;** `counsel-git'
+(defvar counsel-git-cmd "git ls-files --full-name --"
+ "Command for `counsel-git'.")
+
+(defvar counsel--git-dir nil
+ "Store the base git directory.")
+
+(ivy-set-actions
+ 'counsel-git
+ '(("j" find-file-other-window "other window")
+ ("x" counsel-find-file-extern "open externally")))
+
+(defun counsel-locate-git-root ()
+ "Locate the root of the git repository containing the current buffer."
+ (or (locate-dominating-file default-directory ".git")
+ (error "Not in a git repository")))
+
+;;;###autoload
+(defun counsel-git (&optional initial-input)
+ "Find file in the current Git repository.
+INITIAL-INPUT can be given as the initial minibuffer input."
+ (interactive)
+ (counsel-require-program (car (split-string counsel-git-cmd)))
+ (ivy-set-prompt 'counsel-git counsel-prompt-function)
+ (setq counsel--git-dir (expand-file-name
+ (counsel-locate-git-root)))
+ (let* ((default-directory counsel--git-dir)
+ (cands (split-string
+ (shell-command-to-string counsel-git-cmd)
+ "\n"
+ t)))
+ (ivy-read "Find file" cands
+ :initial-input initial-input
+ :action #'counsel-git-action
+ :caller 'counsel-git)))
+
+(defun counsel-git-action (x)
+ "Find file X in current Git repository."
+ (with-ivy-window
+ (let ((default-directory counsel--git-dir))
+ (find-file x))))
+
+;;** `counsel-git-grep'
+(defvar counsel-git-grep-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-l") 'ivy-call-and-recenter)
+ (define-key map (kbd "M-q") 'counsel-git-grep-query-replace)
+ (define-key map (kbd "C-c C-m") 'counsel-git-grep-switch-cmd)
+ map))
+
+(ivy-set-occur 'counsel-git-grep 'counsel-git-grep-occur)
+(ivy-set-display-transformer 'counsel-git-grep 'counsel-git-grep-transformer)
+
+(defvar counsel-git-grep-cmd-default "git --no-pager grep --full-name -n --no-color -i -e \"%s\""
+ "Initial command for `counsel-git-grep'.")
+
+(defvar counsel-git-grep-cmd nil
+ "Store the command for `counsel-git-grep'.")
+
+(defvar counsel--git-grep-count nil
+ "Store the line count in current repository.")
+
+(defvar counsel-git-grep-history nil
+ "History for `counsel-git-grep'.")
+
+(defvar counsel-git-grep-cmd-history
+ (list counsel-git-grep-cmd-default)
+ "History for `counsel-git-grep' shell commands.")
+
+(defcustom counsel-grep-post-action-hook nil
+ "Hook that runs after the point moves to the next candidate.
+Typical value: '(recenter)."
+ :type 'hook
+ :group 'ivy)
+
+(defun counsel-prompt-function-dir ()
+ "Return prompt appended with the parent directory."
+ (ivy-add-prompt-count
+ (let ((directory counsel--git-dir))
+ (format "%s [%s]: "
+ (ivy-state-prompt ivy-last)
+ (let ((dir-list (eshell-split-path directory)))
+ (if (> (length dir-list) 3)
+ (apply #'concat
+ (append '("...")
+ (cl-subseq dir-list (- (length dir-list) 3))))
+ directory))))))
+
+(defcustom counsel-git-grep-skip-counting-lines nil
+ "If non-nil, don't count lines before grepping ina git repository."
+ :type 'boolean
+ :group 'ivy)
+
+(defun counsel-git-grep-function (string &optional _pred &rest _unused)
+ "Grep in the current git repository for STRING."
+ (if (and (or counsel-git-grep-skip-counting-lines (> counsel--git-grep-count 20000))
+ (< (length string) 3))
+ (counsel-more-chars 3)
+ (let* ((default-directory counsel--git-dir)
+ (cmd (format counsel-git-grep-cmd
+ (setq ivy--old-re (ivy--regex string t)))))
+ (if (and (not counsel-git-grep-skip-counting-lines) (<= counsel--git-grep-count 20000))
+ (split-string (shell-command-to-string cmd) "\n" t)
+ (counsel--gg-candidates (ivy--regex string))
+ nil))))
+
+(defun counsel-git-grep-action (x)
+ "Go to occurrence X in current Git repository."
+ (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" x)
+ (with-ivy-window
+ (let ((file-name (match-string-no-properties 1 x))
+ (line-number (match-string-no-properties 2 x)))
+ (find-file (expand-file-name file-name counsel--git-dir))
+ (goto-char (point-min))
+ (forward-line (1- (string-to-number line-number)))
+ (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
+ (swiper--ensure-visible)
+ (run-hooks 'counsel-grep-post-action-hook)
+ (unless (eq ivy-exit 'done)
+ (swiper--cleanup)
+ (swiper--add-overlays (ivy--regex ivy-text)))))))
+
+(defun counsel-git-grep-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES for `counsel-git-grep'."
+ (or (and (equal regexp ivy--old-re)
+ ivy--old-cands)
+ (prog1
+ (setq ivy--old-cands
+ (cl-remove-if-not
+ (lambda (x)
+ (ignore-errors
+ (when (string-match "^[^:]+:[^:]+:" x)
+ (setq x (substring x (match-end 0)))
+ (if (stringp regexp)
+ (string-match regexp x)
+ (let ((res t))
+ (dolist (re regexp)
+ (setq res
+ (and res
+ (ignore-errors
+ (if (cdr re)
+ (string-match (car re) x)
+ (not (string-match (car re) x)))))))
+ res)))))
+ candidates))
+ (setq ivy--old-re regexp))))
+
+(defun counsel-git-grep-transformer (str)
+ "Higlight file and line number in STR."
+ (when (string-match "\\`\\([^:]+\\):\\([^:]+\\):" str)
+ (set-text-properties (match-beginning 1)
+ (match-end 1)
+ '(face compilation-info)
+ str)
+ (set-text-properties (match-beginning 2)
+ (match-end 2)
+ '(face compilation-line-number)
+ str))
+ str)
+
+(defvar counsel-git-grep-projects-alist nil
+ "An alist of project directory to \"git-grep\" command.
+Allows to automatically use a custom \"git-grep\" command for all
+files in a project.")
+
+(defun counsel--git-grep-cmd-and-proj (cmd)
+ (let ((dd (expand-file-name default-directory))
+ proj)
+ (cond
+ ((stringp cmd))
+ (cmd
+ (if (setq proj
+ (cl-find-if
+ (lambda (x)
+ (string-match (car x) dd))
+ counsel-git-grep-projects-alist))
+ (setq cmd (cdr proj))
+ (setq cmd
+ (ivy-read "cmd: " counsel-git-grep-cmd-history
+ :history 'counsel-git-grep-cmd-history
+ :re-builder #'ivy--regex))
+ (setq counsel-git-grep-cmd-history
+ (delete-dups counsel-git-grep-cmd-history))))
+ (t
+ (setq cmd counsel-git-grep-cmd-default)))
+ (cons proj cmd)))
+
+;;;###autoload
+(defun counsel-git-grep (&optional cmd initial-input)
+ "Grep for a string in the current git repository.
+When CMD is a string, use it as a \"git grep\" command.
+When CMD is non-nil, prompt for a specific \"git grep\" command.
+INITIAL-INPUT can be given as the initial minibuffer input."
+ (interactive "P")
+ (ivy-set-prompt 'counsel-git-grep counsel-prompt-function)
+ (let ((proj-and-cmd (counsel--git-grep-cmd-and-proj cmd))
+ proj)
+ (setq proj (car proj-and-cmd))
+ (setq counsel-git-grep-cmd (cdr proj-and-cmd))
+ (counsel-require-program (car (split-string counsel-git-grep-cmd)))
+ (setq counsel--git-dir (if proj
+ (car proj)
+ (counsel-locate-git-root)))
+ (unless (or proj counsel-git-grep-skip-counting-lines)
+ (setq counsel--git-grep-count
+ (if (eq system-type 'windows-nt)
+ 0
+ (counsel--gg-count "" t))))
+ (let ((collection-function
+ (if proj
+ #'counsel-git-grep-proj-function
+ #'counsel-git-grep-function))
+ (unwind-function
+ (if proj
+ (lambda ()
+ (counsel-delete-process)
+ (swiper--cleanup))
+ (lambda ()
+ (swiper--cleanup)))))
+ (ivy-read "git grep" collection-function
+ :initial-input initial-input
+ :matcher #'counsel-git-grep-matcher
+ :dynamic-collection (or proj counsel-git-grep-skip-counting-lines (> counsel--git-grep-count 20000))
+ :keymap counsel-git-grep-map
+ :action #'counsel-git-grep-action
+ :unwind unwind-function
+ :history 'counsel-git-grep-history
+ :caller 'counsel-git-grep))))
+
+(defun counsel-git-grep-proj-function (str)
+ "Grep for STR in the current git repository."
+ (if (< (length str) 3)
+ (counsel-more-chars 3)
+ (let ((regex (setq ivy--old-re
+ (ivy--regex str t))))
+ (counsel--async-command (format counsel-git-grep-cmd regex))
+ nil)))
+
+(defun counsel-git-grep-switch-cmd ()
+ "Set `counsel-git-grep-cmd' to a different value."
+ (interactive)
+ (setq counsel-git-grep-cmd
+ (ivy-read "cmd: " counsel-git-grep-cmd-history
+ :history 'counsel-git-grep-cmd-history))
+ (setq counsel-git-grep-cmd-history
+ (delete-dups counsel-git-grep-cmd-history))
+ (unless (ivy-state-dynamic-collection ivy-last)
+ (setq ivy--all-candidates
+ (all-completions "" 'counsel-git-grep-function))))
+
+(defvar counsel-gg-state nil
+ "The current state of candidates / count sync.")
+
+(defun counsel--gg-candidates (regex)
+ "Return git grep candidates for REGEX."
+ (setq counsel-gg-state -2)
+ (counsel--gg-count regex)
+ (let* ((default-directory counsel--git-dir)
+ (counsel-gg-process " *counsel-gg*")
+ (proc (get-process counsel-gg-process))
+ (buff (get-buffer counsel-gg-process)))
+ (when proc
+ (delete-process proc))
+ (when buff
+ (kill-buffer buff))
+ (setq proc (start-process-shell-command
+ counsel-gg-process
+ counsel-gg-process
+ (concat
+ (format counsel-git-grep-cmd regex)
+ " | head -n 200")))
+ (set-process-sentinel
+ proc
+ #'counsel--gg-sentinel)))
+
+(defun counsel--gg-sentinel (process event)
+ "Sentinel function for a `counsel-git-grep' PROCESS.
+EVENT is a string describing the change."
+ (if (member event '("finished\n"
+ "exited abnormally with code 141\n"))
+ (progn
+ (with-current-buffer (process-buffer process)
+ (setq ivy--all-candidates
+ (or (split-string (buffer-string) "\n" t)
+ '("")))
+ (setq ivy--old-cands ivy--all-candidates))
+ (when (= 0 (cl-incf counsel-gg-state))
+ (ivy--exhibit)))
+ (if (string= event "exited abnormally with code 1\n")
+ (progn
+ (setq ivy--all-candidates '("Error"))
+ (setq ivy--old-cands ivy--all-candidates)
+ (ivy--exhibit)))))
+
+(defun counsel--gg-count (regex &optional no-async)
+ "Count the number of results matching REGEX in `counsel-git-grep'.
+The command to count the matches is called asynchronously.
+If NO-ASYNC is non-nil, do it synchronously instead."
+ (let ((default-directory counsel--git-dir)
+ (cmd
+ (concat
+ (format
+ (replace-regexp-in-string
+ "--full-name" "-c"
+ counsel-git-grep-cmd)
+ ;; "git grep -i -c '%s'"
+ (replace-regexp-in-string
+ "-" "\\\\-"
+ (replace-regexp-in-string "'" "''" regex)))
+ " | sed 's/.*:\\(.*\\)/\\1/g' | awk '{s+=$1} END {print s}'"))
+ (counsel-ggc-process " *counsel-gg-count*"))
+ (if no-async
+ (string-to-number (shell-command-to-string cmd))
+ (let ((proc (get-process counsel-ggc-process))
+ (buff (get-buffer counsel-ggc-process)))
+ (when proc
+ (delete-process proc))
+ (when buff
+ (kill-buffer buff))
+ (setq proc (start-process-shell-command
+ counsel-ggc-process
+ counsel-ggc-process
+ cmd))
+ (set-process-sentinel
+ proc
+ #'(lambda (process event)
+ (when (string= event "finished\n")
+ (with-current-buffer (process-buffer process)
+ (setq ivy--full-length (string-to-number (buffer-string))))
+ (when (= 0 (cl-incf counsel-gg-state))
+ (ivy--exhibit)))))))))
+
+(defun counsel-git-grep-occur ()
+ "Generate a custom occur buffer for `counsel-git-grep'.
+When REVERT is non-nil, regenerate the current *ivy-occur* buffer."
+ (unless (eq major-mode 'ivy-occur-grep-mode)
+ (ivy-occur-grep-mode)
+ (setq default-directory counsel--git-dir))
+ (setq ivy-text
+ (and (string-match "\"\\(.*\\)\"" (buffer-name))
+ (match-string 1 (buffer-name))))
+ (let* ((regex (funcall ivy--regex-function ivy-text))
+ (positive-pattern (replace-regexp-in-string
+ ;; git-grep can't handle .*?
+ "\\.\\*\\?" ".*"
+ (if (stringp regex) regex (caar regex))))
+ (negative-patterns
+ (mapconcat (lambda (x)
+ (and (null (cdr x))
+ (format "| grep -v %s" (car x))))
+ regex
+ " "))
+ (cmd (concat (format counsel-git-grep-cmd positive-pattern) negative-patterns))
+ cands)
+ (setq cands (split-string
+ (shell-command-to-string cmd)
+ "\n"
+ t))
+ ;; 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 cands)))
+ (ivy--occur-insert-lines
+ (mapcar
+ (lambda (cand) (concat "./" cand))
+ cands))))
+
+(defun counsel-git-grep-query-replace ()
+ "Start `query-replace' with string to replace from last search string."
+ (interactive)
+ (if (null (window-minibuffer-p))
+ (user-error
+ "Should only be called in the minibuffer through `counsel-git-grep-map'")
+ (let* ((enable-recursive-minibuffers t)
+ (from (ivy--regex ivy-text))
+ (to (query-replace-read-to from "Query replace" t)))
+ (ivy-exit-with-action
+ (lambda (_)
+ (let (done-buffers)
+ (dolist (cand ivy--old-cands)
+ (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" cand)
+ (with-ivy-window
+ (let ((file-name (match-string-no-properties 1 cand)))
+ (setq file-name (expand-file-name file-name counsel--git-dir))
+ (unless (member file-name done-buffers)
+ (push file-name done-buffers)
+ (find-file file-name)
+ (goto-char (point-min)))
+ (perform-replace from to t t nil)))))))))))
+
+;;** `counsel-git-stash'
+(defun counsel-git-stash-kill-action (x)
+ "Add git stash command to kill ring.
+The git command applies the stash entry where candidate X was found in."
+ (when (string-match "\\([^:]+\\):" x)
+ (kill-new (message (format "git stash apply %s" (match-string 1 x))))))
+
+;;;###autoload
+(defun counsel-git-stash ()
+ "Search through all available git stashes."
+ (interactive)
+ (setq counsel--git-dir (counsel-locate-git-root))
+ (let ((cands (split-string (shell-command-to-string
+ "IFS=$'\n'
+for i in `git stash list --format=\"%gd\"`; do
+ git stash show -p $i | grep -H --label=\"$i\" \"$1\"
+done") "\n" t)))
+ (ivy-read "git stash: " cands
+ :action 'counsel-git-stash-kill-action
+ :caller 'counsel-git-stash)))
+
+;;** `counsel-git-log'
+(defvar counsel-git-log-cmd "GIT_PAGER=cat git log --grep '%s'"
+ "Command used for \"git log\".")
+
+(defvar counsel-git-log-split-string-re "\ncommit "
+ "The `split-string' separates when split output of `counsel-git-log-cmd'.")
+
+(defun counsel-git-log-function (input)
+ "Search for INPUT in git log."
+ (if (< (length input) 3)
+ (counsel-more-chars 3)
+ ;; `counsel--yank-pop-format-function' uses this
+ (setq ivy--old-re (funcall ivy--regex-function input))
+ (counsel--async-command
+ ;; "git log --grep" likes to have groups quoted e.g. \(foo\).
+ ;; But it doesn't like the non-greedy ".*?".
+ (format counsel-git-log-cmd
+ (replace-regexp-in-string "\\.\\*\\?" ".*"
+ (ivy-re-to-str ivy--old-re))))
+ nil))
+
+(defun counsel-git-log-action (x)
+ "Add candidate X to kill ring."
+ (message "%S" (kill-new x)))
+
+(defcustom counsel-yank-pop-truncate-radius 2
+ "When non-nil, truncate the display of long strings."
+ :type 'integer
+ :group 'ivy)
+
+;;** `counsel-git-change-worktree'
+(autoload 'string-trim-right "subr-x")
+(defun counsel-git-change-worktree-action (git-root-dir tree)
+ "Find the corresponding file in the worktree located at tree.
+The current buffer is assumed to be in a subdirectory of GIT-ROOT-DIR.
+TREE is the selected candidate."
+ (let* ((new-root-dir (counsel-git-worktree-parse-root tree))
+ (tree-filename (file-relative-name (buffer-file-name) git-root-dir))
+ (file-name (expand-file-name tree-filename new-root-dir)))
+ (find-file file-name)))
+
+(defun counsel-git-worktree-list ()
+ "List worktrees in the git repository containing the current buffer."
+ (setq counsel--git-dir (counsel-locate-git-root))
+ (let ((cmd-output (shell-command-to-string "git worktree list")))
+ (delete "" (split-string (string-trim-right cmd-output) "\n"))))
+
+(defun counsel-git-worktree-parse-root (tree)
+ "Return worktree from candidate TREE."
+ (substring tree 0 (string-match " " tree)))
+
+(defun counsel-git-close-worktree-files-action (root-dir)
+ "Close all buffers from the worktree located at ROOT-DIR."
+ (setq root-dir (counsel-git-worktree-parse-root root-dir))
+ (save-excursion
+ (dolist (buf (buffer-list))
+ (set-buffer buf)
+ (and buffer-file-name
+ (string= "." (file-relative-name root-dir (counsel-locate-git-root)))
+ (kill-buffer buf)))))
+
+(ivy-set-actions
+ 'counsel-git-change-worktree
+ '(("k" counsel-git-close-worktree-files-action "kill all")))
+
+;;;###autoload
+(defun counsel-git-change-worktree ()
+ "Find the file corresponding to the current buffer on a different worktree."
+ (interactive)
+ (setq counsel--git-dir (counsel-locate-git-root))
+ (ivy-read "Select worktree: "
+ (or (cl-delete counsel--git-dir (counsel-git-worktree-list)
+ :key #'counsel-git-worktree-parse-root :test #'string=)
+ (error "No other worktrees!"))
+ :action (lambda (tree) (counsel-git-change-worktree-action counsel--git-dir tree))
+ :require-match t
+ :caller 'counsel-git-change-worktree))
+
+;;** `counsel-git-checkout'
+(defun counsel-git-checkout-action (branch)
+ "Call the \"git checkout BRANCH\" command.
+
+BRANCH is a string whose first word designates the command argument."
+ (shell-command
+ (format "git checkout %s" (substring branch 0 (string-match " " branch)))))
+
+(defun counsel-git-branch-list ()
+ "List branches in the git repository containing the current buffer.
+
+Does not list the currently checked out one."
+ (setq counsel--git-dir (counsel-locate-git-root))
+ (let ((cmd-output (shell-command-to-string "git branch -vv --all")))
+ (cl-mapcan
+ (lambda (str)
+ (when (string-prefix-p " " str)
+ (list (substring str (string-match "[^[:blank:]]" str)))))
+ (split-string (string-trim-right cmd-output) "\n"))))
+
+;;;###autoload
+(defun counsel-git-checkout ()
+ "Call the \"git checkout\" command."
+ (interactive)
+ (ivy-read "Checkout branch: " (counsel-git-branch-list)
+ :action #'counsel-git-checkout-action
+ :caller 'counsel-git-checkout))
+
+;;;###autoload
+(defun counsel-git-log ()
+ "Call the \"git log --grep\" shell command."
+ (interactive)
+ (let ((counsel-async-split-string-re counsel-git-log-split-string-re)
+ (counsel-async-ignore-re "^[ \n]*$")
+ (counsel-yank-pop-truncate-radius 5)
+ (ivy-format-function #'counsel--yank-pop-format-function)
+ (ivy-height 4))
+ (ivy-read "Grep log: " #'counsel-git-log-function
+ :dynamic-collection t
+ :action #'counsel-git-log-action
+ :unwind #'counsel-delete-process
+ :caller 'counsel-git-log)))
+
+;;* File
+;;** `counsel-find-file'
+(defvar counsel-find-file-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-DEL") 'counsel-up-directory)
+ (define-key map (kbd "C-<backspace>") 'counsel-up-directory)
+ map))
+
+(add-to-list 'ivy-ffap-url-functions 'counsel-github-url-p)
+(add-to-list 'ivy-ffap-url-functions 'counsel-emacs-url-p)
+(add-to-list 'ivy-ffap-url-functions 'counsel-url-expand)
+(defun counsel-find-file-cd-bookmark-action (_)
+ "Reset `counsel-find-file' from selected directory."
+ (ivy-read "cd: "
+ (progn
+ (ivy--virtual-buffers)
+ (delete-dups
+ (mapcar (lambda (x) (file-name-directory (cdr x)))
+ ivy--virtual-buffers)))
+ :action (lambda (x)
+ (let ((default-directory (file-name-directory x)))
+ (counsel-find-file)))))
+
+(defcustom counsel-root-command "sudo"
+ "Command to gain root privileges."
+ :type 'string
+ :group 'ivy)
+
+(defun counsel-find-file-as-root (x)
+ "Find file X with root privileges."
+ (counsel-require-program counsel-root-command)
+ (let* ((host (file-remote-p x 'host))
+ (file-name (format "/%s:%s:%s"
+ counsel-root-command
+ (or host "")
+ (expand-file-name
+ (if host
+ (file-remote-p x 'localname)
+ x)))))
+ ;; If the current buffer visits the same file we are about to open,
+ ;; replace the current buffer with the new one.
+ (if (eq (current-buffer) (get-file-buffer x))
+ (find-alternate-file file-name)
+ (find-file file-name))))
+
+(ivy-set-actions
+ 'counsel-find-file
+ '(("j" find-file-other-window "other window")
+ ("b" counsel-find-file-cd-bookmark-action "cd bookmark")
+ ("x" counsel-find-file-extern "open externally")
+ ("r" counsel-find-file-as-root "open as root")))
+
+(defcustom counsel-find-file-at-point nil
+ "When non-nil, add file-at-point to the list of candidates."
+ :type 'boolean
+ :group 'ivy)
+
+(defcustom counsel-find-file-ignore-regexp nil
+ "A regexp of files to ignore while in `counsel-find-file'.
+These files are un-ignored if `ivy-text' matches them. The
+common way to show all files is to start `ivy-text' with a dot.
+
+Example value: \"\\(?:\\`[#.]\\)\\|\\(?:[#~]\\'\\)\". This will hide
+temporary and lock files.
+\\<ivy-minibuffer-map>
+Choosing the dotfiles option, \"\\`\\.\", might be convenient,
+since you can still access the dotfiles if your input starts with
+a dot. The generic way to toggle ignored files is \\[ivy-toggle-ignore],
+but the leading dot is a lot faster."
+ :group 'ivy
+ :type `(choice
+ (const :tag "None" nil)
+ (const :tag "Dotfiles" "\\`\\.")
+ (const :tag "Ignored Extensions"
+ ,(regexp-opt completion-ignored-extensions))
+ (regexp :tag "Regex")))
+
+(defun counsel--find-file-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES.
+Skip some dotfiles unless `ivy-text' requires them."
+ (let ((res (ivy--re-filter regexp candidates)))
+ (if (or (null ivy-use-ignore)
+ (null counsel-find-file-ignore-regexp)
+ (string-match "\\`\\." ivy-text))
+ res
+ (or (cl-remove-if
+ (lambda (x)
+ (and
+ (string-match counsel-find-file-ignore-regexp x)
+ (not (member x ivy-extra-directories))))
+ res)
+ res))))
+
+(declare-function ffap-guesser "ffap")
+
+(defvar counsel-find-file-speedup-remote t
+ "Speed up opening remote files by disabling `find-file-hook' for them.")
+
+;;;###autoload
+(defun counsel-find-file (&optional initial-input)
+ "Forward to `find-file'.
+When INITIAL-INPUT is non-nil, use it in the minibuffer during completion."
+ (interactive)
+ (ivy-read "Find file: " 'read-file-name-internal
+ :matcher #'counsel--find-file-matcher
+ :initial-input initial-input
+ :action
+ (lambda (x)
+ (with-ivy-window
+ (if (and counsel-find-file-speedup-remote
+ (file-remote-p ivy--directory))
+ (let ((find-file-hook nil))
+ (find-file (expand-file-name x ivy--directory)))
+ (find-file (expand-file-name x ivy--directory)))))
+ :preselect (when counsel-find-file-at-point
+ (require 'ffap)
+ (let ((f (ffap-guesser)))
+ (when f (expand-file-name f))))
+ :require-match 'confirm-after-completion
+ :history 'file-name-history
+ :keymap counsel-find-file-map
+ :caller 'counsel-find-file))
+
+(defun counsel-up-directory ()
+ "Go to the parent directory preselecting the current one."
+ (interactive)
+ (let ((dir-file-name
+ (directory-file-name (expand-file-name ivy--directory))))
+ (ivy--cd (file-name-directory dir-file-name))
+ (setf (ivy-state-preselect ivy-last)
+ (file-name-as-directory (file-name-nondirectory dir-file-name)))))
+
+(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]+")
+ (or
+ (eq (vc-backend (buffer-file-name)) 'Git)
+ (or
+ (memq major-mode '(magit-commit-mode))
+ (bound-and-true-p magit-commit-mode)))
+ (match-string-no-properties 0)))
+
+(defun counsel-github-url-p ()
+ "Return a Github issue URL at point."
+ (counsel-require-program "git")
+ (let ((url (counsel-at-git-issue-p)))
+ (when url
+ (let ((origin (shell-command-to-string
+ "git remote get-url origin"))
+ user repo)
+ (cond ((string-match "\\`git@github.com:\\([^/]+\\)/\\(.*\\)\\.git$"
+ origin)
+ (setq user (match-string 1 origin))
+ (setq repo (match-string 2 origin)))
+ ((string-match "\\`https://github.com/\\([^/]+\\)/\\(.*\\)$"
+ origin)
+ (setq user (match-string 1 origin))
+ (setq repo (match-string 2 origin))))
+ (when user
+ (setq url (format "https://github.com/%s/%s/issues/%s"
+ user repo (substring url 1))))))))
+
+(defun counsel-emacs-url-p ()
+ "Return a Debbugs issue URL at point."
+ (counsel-require-program "git")
+ (let ((url (counsel-at-git-issue-p)))
+ (when url
+ (let ((origin (shell-command-to-string
+ "git remote get-url origin")))
+ (when (string-match "git.sv.gnu.org:/srv/git/emacs.git" origin)
+ (format "http://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s"
+ (substring url 1)))))))
+
+(defvar counsel-url-expansions-alist nil
+ "Map of regular expressions to expansions.
+
+This variable should take the form of a list of (REGEXP . FORMAT)
+pairs.
+
+`counsel-url-expand' will expand the word at point according to
+FORMAT for the first matching REGEXP. FORMAT can be either a
+string or a function. If it is a string, it will be used as the
+format string for the `format' function, with the word at point
+as the next argument. If it is a function, it will be called
+with the word at point as the sole argument.
+
+For example, a pair of the form:
+ '(\"\\`BSERV-[[:digit:]]+\\'\" . \"https://jira.atlassian.com/browse/%s\")
+will expand to URL `https://jira.atlassian.com/browse/BSERV-100'
+when the word at point is BSERV-100.
+
+If the format element is a function, more powerful
+transformations are possible. As an example,
+ '(\"\\`issue\\([[:digit:]]+\\)\\'\" .
+ (lambda (word)
+ (concat \"http://debbugs.gnu.org/cgi/bugreport.cgi?bug=\"
+ (match-string 1 word))))
+trims the \"issue\" prefix from the word at point before creating the URL.")
+
+(defun counsel-url-expand ()
+ "Expand word at point using `counsel-url-expansions-alist'.
+The first pair in the list whose regexp matches the word at point
+will be expanded according to its format. This function is
+intended to be used in `ivy-ffap-url-functions' to browse the
+result as a URL."
+ (let ((word-at-point (current-word)))
+ (cl-some
+ (lambda (pair)
+ (let ((regexp (car pair))
+ (formatter (cdr pair)))
+ (when (string-match regexp word-at-point)
+ (if (functionp formatter)
+ (funcall formatter word-at-point)
+ (format formatter word-at-point)))))
+ counsel-url-expansions-alist)))
+
+;;** `counsel-recentf'
+(defvar recentf-list)
+(declare-function recentf-mode "recentf")
+
+;;;###autoload
+(defun counsel-recentf ()
+ "Find a file on `recentf-list'."
+ (interactive)
+ (require 'recentf)
+ (recentf-mode)
+ (ivy-read "Recentf: " (mapcar #'substring-no-properties recentf-list)
+ :action (lambda (f)
+ (with-ivy-window
+ (find-file f)))
+ :caller 'counsel-recentf))
+(ivy-set-actions
+ 'counsel-recentf
+ '(("j" find-file-other-window "other window")
+ ("x" counsel-find-file-extern "open externally")))
+
+;;** `counsel-locate'
+(defcustom counsel-locate-cmd (cond ((eq system-type 'darwin)
+ 'counsel-locate-cmd-noregex)
+ ((and (eq system-type 'windows-nt)
+ (executable-find "es.exe"))
+ 'counsel-locate-cmd-es)
+ (t
+ '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."
+ :group 'ivy
+ :type '(choice
+ (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)))
+
+(ivy-set-actions
+ 'counsel-locate
+ '(("x" counsel-locate-action-extern "xdg-open")
+ ("d" counsel-locate-action-dired "dired")))
+
+(counsel-set-async-exit-code 'counsel-locate 1 "Nothing found")
+
+(defvar counsel-locate-history nil
+ "History for `counsel-locate'.")
+
+(defun counsel-locate-action-extern (x)
+ "Use xdg-open shell command, or corresponding system command, on X."
+ (interactive (list (read-file-name "File: ")))
+ (if (and (eq system-type 'windows-nt)
+ (fboundp 'w32-shell-execute))
+ (w32-shell-execute "open" x)
+ (call-process shell-file-name nil
+ nil nil
+ shell-command-switch
+ (format "%s %s"
+ (cl-case system-type
+ (darwin "open")
+ (t "xdg-open"))
+ (shell-quote-argument x)))))
+
+(defalias 'counsel-find-file-extern 'counsel-locate-action-extern)
+
+(declare-function dired-jump "dired-x")
+
+(defun counsel-locate-action-dired (x)
+ "Use `dired-jump' on X."
+ (dired-jump nil x))
+
+(defun counsel-locate-cmd-default (input)
+ "Return a shell command based on INPUT."
+ (counsel-require-program "locate")
+ (format "locate -i --regex '%s'"
+ (counsel-unquote-regex-parens
+ (ivy--regex input))))
+
+(defun counsel-locate-cmd-noregex (input)
+ "Return a shell command based on INPUT."
+ (counsel-require-program "locate")
+ (format "locate -i '%s'" input))
+
+(defun counsel-locate-cmd-mdfind (input)
+ "Return a shell command based on INPUT."
+ (counsel-require-program "mdfind")
+ (format "mdfind -name '%s'" input))
+
+(defun counsel-locate-cmd-es (input)
+ "Return a shell command based on INPUT."
+ (counsel-require-program "es.exe")
+ (format "es.exe -i -r %s"
+ (counsel-unquote-regex-parens
+ (ivy--regex input t))))
+
+(defun counsel-locate-function (input)
+ "Call the \"locate\" shell command with INPUT."
+ (if (< (length input) 3)
+ (counsel-more-chars 3)
+ (counsel--async-command
+ (funcall counsel-locate-cmd input))
+ '("" "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))
+
+;;** `counsel-dpkg'
+;;;###autoload
+(defun counsel-dpkg ()
+ "Call the \"dpkg\" shell command."
+ (interactive)
+ (counsel-require-program "dpkg")
+ (let ((cands (mapcar
+ (lambda (x)
+ (let ((y (split-string x " +")))
+ (cons (format "%-40s %s"
+ (ivy--truncate-string
+ (nth 1 y) 40)
+ (nth 4 y))
+ (mapconcat #'identity y " "))))
+ (split-string
+ (shell-command-to-string "dpkg -l | tail -n+6") "\n" t))))
+ (ivy-read "dpkg: " cands
+ :action (lambda (x)
+ (message (cdr x)))
+ :caller 'counsel-dpkg)))
+
+;;** `counsel-rpm'
+;;;###autoload
+(defun counsel-rpm ()
+ "Call the \"rpm\" shell command."
+ (interactive)
+ (counsel-require-program "rpm")
+ (let ((cands (mapcar
+ (lambda (x)
+ (let ((y (split-string x "|")))
+ (cons (format "%-40s %s"
+ (ivy--truncate-string
+ (nth 0 y) 40)
+ (nth 1 y))
+ (mapconcat #'identity y " "))))
+ (split-string
+ (shell-command-to-string "rpm -qa --qf \"%{NAME}|%{SUMMARY}\\n\"") "\n" t))))
+ (ivy-read "rpm: " cands
+ :action (lambda (x)
+ (message (cdr x)))
+ :caller 'counsel-rpm)))
+
+;;** File Jump and Dired Jump
+
+;;;###autoload
+(defun counsel-file-jump (&optional initial-input initial-directory)
+ "Jump to a file below the current directory.
+List all files within the current directory or any of its subdirectories.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search."
+ (interactive
+ (list nil
+ (when current-prefix-arg
+ (read-directory-name "From directory: "))))
+ (counsel-require-program "find")
+ (let* ((default-directory (or initial-directory default-directory)))
+ (ivy-read "Find file: "
+ (split-string
+ (shell-command-to-string
+ (concat find-program " * -type f -not -path '*\/.git*'"))
+ "\n" t)
+ :matcher #'counsel--find-file-matcher
+ :initial-input initial-input
+ :action (lambda (x)
+ (with-ivy-window
+ (find-file (expand-file-name x ivy--directory))))
+ :preselect (when counsel-find-file-at-point
+ (require 'ffap)
+ (let ((f (ffap-guesser)))
+ (when f (expand-file-name f))))
+ :require-match 'confirm-after-completion
+ :history 'file-name-history
+ :keymap counsel-find-file-map
+ :caller 'counsel-file-jump)))
+
+;;;###autoload
+(defun counsel-dired-jump (&optional initial-input initial-directory)
+ "Jump to a directory (in dired) below the current directory.
+List all subdirectories within the current directory.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search."
+ (interactive
+ (list nil
+ (when current-prefix-arg
+ (read-directory-name "From directory: "))))
+ (counsel-require-program "find")
+ (let* ((default-directory (or initial-directory default-directory)))
+ (ivy-read "Directory: "
+ (split-string
+ (shell-command-to-string
+ (concat find-program " * -type d -not -path '*\/.git*'"))
+ "\n" t)
+ :initial-input initial-input
+ :action (lambda (d) (dired-jump nil (expand-file-name d)))
+ :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 `counsel--git-dir' 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 counsel--git-dir)
+ counsel--git-dir))
+ (prepend
+ (if git-grep-dir-is-file
+ (concat (file-name-nondirectory counsel--git-dir) ":")
+ "")))
+ (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 (lambda (cand) (concat "./" prepend cand)) ivy--all-candidates))))
+
+;;** `counsel-ag'
+(defvar counsel-ag-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-l") 'ivy-call-and-recenter)
+ (define-key map (kbd "M-q") 'counsel-git-grep-query-replace)
+ map))
+
+(defcustom counsel-ag-base-command "ag --nocolor --nogroup %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. The default is \"ag --nocolor --nogroup %s\"."
+ :type 'string
+ :group 'ivy)
+
+(counsel-set-async-exit-code 'counsel-ag 1 "No matches found")
+(ivy-set-occur 'counsel-ag 'counsel-ag-occur)
+(ivy-set-display-transformer 'counsel-ag 'counsel-git-grep-transformer)
+
+(defun counsel-ag-function (string base-cmd extra-ag-args)
+ "Grep in the current directory for STRING using BASE-CMD.
+If non-nil, append EXTRA-AG-ARGS to BASE-CMD."
+ (when (null extra-ag-args)
+ (setq extra-ag-args ""))
+ (if (< (length string) 3)
+ (counsel-more-chars 3)
+ (let ((default-directory counsel--git-dir)
+ (regex (counsel-unquote-regex-parens
+ (setq ivy--old-re
+ (ivy--regex string)))))
+ (let* ((args-end (string-match " -- " extra-ag-args))
+ (file (if args-end
+ (substring-no-properties extra-ag-args (+ args-end 3))
+ ""))
+ (extra-ag-args (if args-end
+ (substring-no-properties extra-ag-args 0 args-end)
+ extra-ag-args))
+ (ag-cmd (format base-cmd
+ (concat extra-ag-args
+ " -- "
+ (shell-quote-argument regex)
+ file))))
+ (if (file-remote-p default-directory)
+ (split-string (shell-command-to-string ag-cmd) "\n" t)
+ (counsel--async-command ag-cmd)
+ nil)))))
+
+;;;###autoload
+(defun counsel-ag (&optional initial-input initial-directory extra-ag-args ag-prompt)
+ "Grep for a string in the current directory using ag.
+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'.
+AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument."
+ (interactive)
+ (counsel-require-program (car (split-string counsel-ag-base-command)))
+ (when current-prefix-arg
+ (setq initial-directory
+ (or initial-directory
+ (read-directory-name (concat
+ (car (split-string counsel-ag-base-command))
+ " in directory: "))))
+ (setq extra-ag-args
+ (or extra-ag-args
+ (let* ((pos (cl-position ? counsel-ag-base-command))
+ (command (substring-no-properties counsel-ag-base-command 0 pos))
+ (ag-args (replace-regexp-in-string
+ "%s" "" (substring-no-properties counsel-ag-base-command pos))))
+ (read-string (format "(%s) args:" command) ag-args)))))
+ (ivy-set-prompt 'counsel-ag counsel-prompt-function)
+ (setq counsel--git-dir (or initial-directory default-directory))
+ (ivy-read (or ag-prompt (car (split-string counsel-ag-base-command)))
+ (lambda (string)
+ (counsel-ag-function string counsel-ag-base-command extra-ag-args))
+ :initial-input initial-input
+ :dynamic-collection t
+ :keymap counsel-ag-map
+ :history 'counsel-git-grep-history
+ :action #'counsel-git-grep-action
+ :unwind (lambda ()
+ (counsel-delete-process)
+ (swiper--cleanup))
+ :caller 'counsel-ag))
+
+(defun counsel-ag-occur ()
+ "Generate a custom occur buffer for `counsel-ag'."
+ (counsel--grep-mode-occur nil))
+
+;;** `counsel-pt'
+(defcustom counsel-pt-base-command "pt --nocolor --nogroup -e %s"
+ "Alternative to `counsel-ag-base-command' using pt."
+ :type 'string
+ :group 'ivy)
+
+;;;###autoload
+(defun counsel-pt (&optional initial-input)
+ "Grep for a string in the current directory using pt.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-pt-base-command' instead of
+`counsel-ag-base-command'."
+ (interactive)
+ (let ((counsel-ag-base-command counsel-pt-base-command))
+ (counsel-ag initial-input)))
+
+;;** `counsel-ack'
+(defcustom counsel-ack-base-command
+ (concat
+ (file-name-nondirectory
+ (or (executable-find "ack-grep") "ack"))
+ " --nocolor --nogroup %s")
+ "Alternative to `counsel-ag-base-command' using ack."
+ :type 'string
+ :group 'ivy)
+
+;;;###autoload
+(defun counsel-ack (&optional initial-input)
+ "Grep for a string in the current directory using ack.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-ack-base-command' replacing
+`counsel-ag-base-command'."
+ (interactive)
+ (let ((counsel-ag-base-command counsel-ack-base-command))
+ (counsel-ag initial-input)))
+
+
+;;** `counsel-rg'
+(defcustom counsel-rg-base-command "rg -i --no-heading --line-number --color never %s ."
+ "Alternative to `counsel-ag-base-command' using ripgrep."
+ :type 'string
+ :group 'ivy)
+
+(counsel-set-async-exit-code 'counsel-rg 1 "No matches found")
+(ivy-set-occur 'counsel-rg 'counsel-rg-occur)
+(ivy-set-display-transformer 'counsel-rg 'counsel-git-grep-transformer)
+
+;;;###autoload
+(defun counsel-rg (&optional initial-input initial-directory extra-rg-args rg-prompt)
+ "Grep for a string in the current directory using rg.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+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."
+ (interactive
+ (list nil
+ (when current-prefix-arg
+ (read-directory-name (concat
+ (car (split-string counsel-rg-base-command))
+ " in directory: ")))))
+ (counsel-require-program (car (split-string counsel-rg-base-command)))
+ (ivy-set-prompt 'counsel-rg counsel-prompt-function)
+ (setq counsel--git-dir (or initial-directory
+ (locate-dominating-file default-directory ".git")
+ default-directory))
+ (ivy-read (or rg-prompt (car (split-string counsel-rg-base-command)))
+ (lambda (string)
+ (counsel-ag-function string counsel-rg-base-command extra-rg-args))
+ :initial-input initial-input
+ :dynamic-collection t
+ :keymap counsel-ag-map
+ :history 'counsel-git-grep-history
+ :action #'counsel-git-grep-action
+ :unwind (lambda ()
+ (counsel-delete-process)
+ (swiper--cleanup))
+ :caller 'counsel-rg))
+
+(defun counsel-rg-occur ()
+ "Generate a custom occur buffer for `counsel-rg'."
+ (counsel--grep-mode-occur nil))
+
+;;** `counsel-grep'
+(defcustom counsel-grep-base-command "grep -nE '%s' %s"
+ "Format string to use in `cousel-grep-function' to construct the command."
+ :type 'string
+ :group 'ivy)
+
+(defun counsel-grep-function (string)
+ "Grep in the current directory for STRING."
+ (if (< (length string) 2)
+ (counsel-more-chars 2)
+ (let ((regex (counsel-unquote-regex-parens
+ (setq ivy--old-re
+ (ivy--regex string)))))
+ (counsel--async-command
+ (format counsel-grep-base-command regex
+ (shell-quote-argument counsel--git-dir)))
+ nil)))
+
+(defun counsel-grep-action (x)
+ "Go to candidate X."
+ (with-ivy-window
+ (swiper--cleanup)
+ (let ((default-directory (file-name-directory counsel--git-dir))
+ file-name line-number)
+ (when (cond ((string-match "\\`\\([0-9]+\\):\\(.*\\)\\'" x)
+ (setq file-name counsel--git-dir)
+ (setq line-number (match-string-no-properties 1 x)))
+ ((string-match "\\`\\([^:]+\\):\\([0-9]+\\):\\(.*\\)\\'" x)
+ (setq file-name (match-string-no-properties 1 x))
+ (setq line-number (match-string-no-properties 2 x)))
+ (t nil))
+ ;; If the file buffer is already open, just get it. Prevent doing
+ ;; `find-file', as that file could have already been opened using
+ ;; `find-file-literally'.
+ (let ((buf (get-file-buffer file-name)))
+ (unless buf
+ (setq buf (find-file file-name)))
+ (with-current-buffer buf
+ (setq line-number (string-to-number line-number))
+ (if (null counsel-grep-last-line)
+ (progn
+ (goto-char (point-min))
+ (forward-line (1- (setq counsel-grep-last-line line-number))))
+ (forward-line (- line-number counsel-grep-last-line))
+ (setq counsel-grep-last-line line-number))
+ (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
+ (run-hooks 'counsel-grep-post-action-hook)
+ (if (eq ivy-exit 'done)
+ (swiper--ensure-visible)
+ (isearch-range-invisible (line-beginning-position)
+ (line-end-position))
+ (swiper--add-overlays (ivy--regex ivy-text)))))))))
+
+(defun counsel-grep-occur ()
+ "Generate a custom occur buffer for `counsel-grep'."
+ (counsel--grep-mode-occur t))
+
+(ivy-set-occur 'counsel-grep 'counsel-grep-occur)
+(counsel-set-async-exit-code 'counsel-grep 1 "")
+
+;;;###autoload
+(defun counsel-grep ()
+ "Grep for a string in the current file."
+ (interactive)
+ (counsel-require-program (car (split-string counsel-grep-base-command)))
+ (setq counsel-grep-last-line nil)
+ (setq counsel--git-dir (buffer-file-name))
+ (let ((init-point (point))
+ res)
+ (unwind-protect
+ (setq res (ivy-read "grep: " 'counsel-grep-function
+ :dynamic-collection t
+ :preselect (format "%d:%s"
+ (line-number-at-pos)
+ (regexp-quote
+ (buffer-substring-no-properties
+ (line-beginning-position)
+ (line-end-position))))
+ :history 'counsel-git-grep-history
+ :update-fn (lambda ()
+ (counsel-grep-action (ivy-state-current ivy-last)))
+ :re-builder #'ivy--regex
+ :action #'counsel-grep-action
+ :unwind (lambda ()
+ (counsel-delete-process)
+ (swiper--cleanup))
+ :caller 'counsel-grep))
+ (unless res
+ (goto-char init-point)))))
+
+;;** `counsel-grep-or-swiper'
+(defcustom counsel-grep-swiper-limit 300000
+ "When the buffer is larger than this, use `counsel-grep' instead of `swiper'."
+ :type 'integer
+ :group 'ivy)
+
+(defvar counsel-compressed-file-regex
+ (progn
+ (require 'jka-compr nil t)
+ (jka-compr-build-file-regexp))
+ "Store the regex for compressed file names.")
+
+;;;###autoload
+(defun counsel-grep-or-swiper ()
+ "Call `swiper' for small buffers and `counsel-grep' for large ones."
+ (interactive)
+ (let ((fname (buffer-file-name)))
+ (if (and fname
+ (not (buffer-narrowed-p))
+ (not (ignore-errors
+ (file-remote-p fname)))
+ (not (string-match
+ counsel-compressed-file-regex
+ fname))
+ (> (buffer-size)
+ (if (eq major-mode 'org-mode)
+ (/ counsel-grep-swiper-limit 4)
+ counsel-grep-swiper-limit)))
+ (progn
+ (when (file-writable-p fname)
+ (save-buffer))
+ (counsel-grep))
+ (swiper--ivy (swiper--candidates)))))
+
+;;** `counsel-recoll'
+(defun counsel-recoll-function (string)
+ "Run recoll for STRING."
+ (if (< (length string) 3)
+ (counsel-more-chars 3)
+ (counsel--async-command
+ (format "recoll -t -b %s"
+ (shell-quote-argument string)))
+ nil))
+
+;; This command uses the recollq command line tool that comes together
+;; with the recoll (the document indexing database) source:
+;; http://www.lesbonscomptes.com/recoll/download.html
+;; You need to build it yourself (together with recoll):
+;; cd ./query && make && sudo cp recollq /usr/local/bin
+;; You can try the GUI version of recoll with:
+;; sudo apt-get install recoll
+;; Unfortunately, that does not install recollq.
+(defun counsel-recoll (&optional initial-input)
+ "Search for a string in the recoll database.
+You'll be given a list of files that match.
+Selecting a file will launch `swiper' for that file.
+INITIAL-INPUT can be given as the initial minibuffer input."
+ (interactive)
+ (counsel-require-program "recoll")
+ (ivy-read "recoll: " 'counsel-recoll-function
+ :initial-input initial-input
+ :dynamic-collection t
+ :history 'counsel-git-grep-history
+ :action (lambda (x)
+ (when (string-match "file://\\(.*\\)\\'" x)
+ (let ((file-name (match-string 1 x)))
+ (find-file file-name)
+ (unless (string-match "pdf$" x)
+ (swiper ivy-text)))))
+ :unwind #'counsel-delete-process
+ :caller 'counsel-recoll))
+;;* Misc Emacs
+;;** `counsel-org-tag'
+(defvar counsel-org-tags nil
+ "Store the current list of tags.")
+
+(defvar org-outline-regexp)
+(defvar org-indent-mode)
+(defvar org-indent-indentation-per-level)
+(defvar org-tags-column)
+(declare-function org-get-tags-string "org")
+(declare-function org-move-to-column "org-compat")
+
+(defun counsel-org-change-tags (tags)
+ "Change tags of current org headline to TAGS."
+ (let ((current (org-get-tags-string))
+ (col (current-column))
+ level)
+ ;; Insert new tags at the correct column
+ (beginning-of-line 1)
+ (setq level (or (and (looking-at org-outline-regexp)
+ (- (match-end 0) (point) 1))
+ 1))
+ (cond
+ ((and (equal current "") (equal tags "")))
+ ((re-search-forward
+ (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$")
+ (point-at-eol) t)
+ (if (equal tags "")
+ (delete-region
+ (match-beginning 0)
+ (match-end 0))
+ (goto-char (match-beginning 0))
+ (let* ((c0 (current-column))
+ ;; compute offset for the case of org-indent-mode active
+ (di (if (bound-and-true-p org-indent-mode)
+ (* (1- org-indent-indentation-per-level) (1- level))
+ 0))
+ (p0 (if (equal (char-before) ?*) (1+ (point)) (point)))
+ (tc (+ org-tags-column (if (> org-tags-column 0) (- di) di)))
+ (c1 (max (1+ c0) (if (> tc 0) tc (- (- tc) (string-width tags)))))
+ (rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags)))
+ (replace-match rpl t t)
+ (and c0 indent-tabs-mode (tabify p0 (point)))
+ tags)))
+ (t (error "Tags alignment failed")))
+ (org-move-to-column col)))
+
+(defun counsel-org--set-tags ()
+ "Set tags of current org headline to `counsel-org-tags'."
+ (counsel-org-change-tags
+ (if counsel-org-tags
+ (format ":%s:"
+ (mapconcat #'identity counsel-org-tags ":"))
+ "")))
+
+(defvar org-agenda-bulk-marked-entries)
+
+(declare-function org-get-at-bol "org")
+(declare-function org-agenda-error "org-agenda")
+
+(defun counsel-org-tag-action (x)
+ "Add tag X to `counsel-org-tags'.
+If X is already part of the list, remove it instead. Quit the selection if
+X is selected by either `ivy-done', `ivy-alt-done' or `ivy-immediate-done',
+otherwise continue prompting for tags."
+ (if (member x counsel-org-tags)
+ (progn
+ (setq counsel-org-tags (delete x counsel-org-tags)))
+ (unless (equal x "")
+ (setq counsel-org-tags (append counsel-org-tags (list x)))
+ (unless (member x ivy--all-candidates)
+ (setq ivy--all-candidates (append ivy--all-candidates (list x))))))
+ (let ((prompt (counsel-org-tag-prompt)))
+ (setf (ivy-state-prompt ivy-last) prompt)
+ (setq ivy--prompt (concat "%-4d " prompt)))
+ (cond ((memq this-command '(ivy-done
+ ivy-alt-done
+ ivy-immediate-done))
+ (if (eq major-mode 'org-agenda-mode)
+ (if (null org-agenda-bulk-marked-entries)
+ (let ((hdmarker (or (org-get-at-bol 'org-hd-marker)
+ (org-agenda-error))))
+ (with-current-buffer (marker-buffer hdmarker)
+ (goto-char hdmarker)
+ (counsel-org--set-tags)))
+ (let ((add-tags (copy-sequence counsel-org-tags)))
+ (dolist (m org-agenda-bulk-marked-entries)
+ (with-current-buffer (marker-buffer m)
+ (save-excursion
+ (goto-char m)
+ (setq counsel-org-tags
+ (delete-dups
+ (append (split-string (org-get-tags-string) ":" t)
+ add-tags)))
+ (counsel-org--set-tags))))))
+ (counsel-org--set-tags)))
+ ((eq this-command 'ivy-call)
+ (with-selected-window (active-minibuffer-window)
+ (delete-minibuffer-contents)))))
+
+(defun counsel-org-tag-prompt ()
+ "Return prompt for `counsel-org-tag'."
+ (format "Tags (%s): "
+ (mapconcat #'identity counsel-org-tags ", ")))
+
+(defvar org-setting-tags)
+(defvar org-last-tags-completion-table)
+(defvar org-tag-persistent-alist)
+(defvar org-tag-alist)
+(defvar org-complete-tags-always-offer-all-agenda-tags)
+
+(declare-function org-at-heading-p "org")
+(declare-function org-back-to-heading "org")
+(declare-function org-get-buffer-tags "org")
+(declare-function org-global-tags-completion-table "org")
+(declare-function org-agenda-files "org")
+(declare-function org-agenda-set-tags "org-agenda")
+
+;;;###autoload
+(defun counsel-org-tag ()
+ "Add or remove tags in `org-mode'."
+ (interactive)
+ (save-excursion
+ (if (eq major-mode 'org-agenda-mode)
+ (if org-agenda-bulk-marked-entries
+ (setq counsel-org-tags nil)
+ (let ((hdmarker (or (org-get-at-bol 'org-hd-marker)
+ (org-agenda-error))))
+ (with-current-buffer (marker-buffer hdmarker)
+ (goto-char hdmarker)
+ (setq counsel-org-tags
+ (split-string (org-get-tags-string) ":" t)))))
+ (unless (org-at-heading-p)
+ (org-back-to-heading t))
+ (setq counsel-org-tags (split-string (org-get-tags-string) ":" t)))
+ (let ((org-setting-tags t)
+ (org-last-tags-completion-table
+ (append org-tag-persistent-alist
+ (or org-tag-alist (org-get-buffer-tags))
+ (and
+ (or org-complete-tags-always-offer-all-agenda-tags
+ (eq major-mode 'org-agenda-mode))
+ (org-global-tags-completion-table
+ (org-agenda-files))))))
+ (ivy-read (counsel-org-tag-prompt)
+ (lambda (str &rest _unused)
+ (delete-dups
+ (all-completions str 'org-tags-completion-function)))
+ :history 'org-tags-history
+ :action 'counsel-org-tag-action
+ :caller 'counsel-org-tag))))
+
+;;;###autoload
+(defun counsel-org-tag-agenda ()
+ "Set tags for the current agenda item."
+ (interactive)
+ (let ((store (symbol-function 'org-set-tags)))
+ (unwind-protect
+ (progn
+ (fset 'org-set-tags
+ (symbol-function 'counsel-org-tag))
+ (org-agenda-set-tags nil nil))
+ (fset 'org-set-tags store))))
+
+(defcustom counsel-org-goto-display-style 'path
+ "The style for displaying headlines in `counsel-org-goto' functions.
+
+If headline, the title and the leading stars are displayed.
+
+If path, the path hierarchy is displayed. For each entry the title is shown.
+`counsel-org-goto-separator' is used as separator between entries.
+
+If title or any other value, only the title of the headline is displayed.
+
+Use `counsel-org-goto-display-tags' and `counsel-org-goto-display-todo' to
+display tags and todo keywords respectively."
+ :type '(choice
+ (const :tag "Title only" title)
+ (const :tag "Headline" headline)
+ (const :tag "Path" path))
+ :group 'ivy)
+
+(defcustom counsel-org-goto-separator "/"
+ "Character(s) to separate path entries in `counsel-org-goto' functions.
+This variable has no effect unless `counsel-org-goto-display-style' is
+set to path."
+ :type 'string
+ :group 'ivy)
+
+(defcustom counsel-org-goto-display-tags nil
+ "If non-nil, display tags in `counsel-org-goto' functions."
+ :type 'boolean
+ :group 'ivy)
+
+(defcustom counsel-org-goto-display-todo nil
+ "If non-nil, display todo keywords in `counsel-org-goto' functions."
+ :type 'boolean
+ :group 'ivy)
+
+(defcustom counsel-org-goto-face-style nil
+ "The face used for displaying headlines in `counsel-org-goto' functions.
+
+If org, the default faces from `org-mode' are applied, i.e. org-level-1
+through org-level-8. Note that no cycling is in effect, therefore headlines
+on levels 9 and higher will not be styled.
+
+If verbatim, the face used in the buffer is applied. For simple headlines
+this is usually the same as org except that it depends on how much of the
+buffer has been completely loaded. If your buffer exceeds a certain size,
+headlines are styled lazily depending on which parts of the tree are visible.
+Headlines which are not styled yet in the buffer will appear unstyled in the
+minibuffer as well. If your headlines contain parts which are fontified
+differently than the headline itself (eg. todo keywords, tags, links) and you
+want these parts to be styled properly, verbatim is the way to go, otherwise
+you are probably better off using org instead.
+
+If custom, the faces defined in `counsel-org-goto-custom-faces' are applied.
+Note that no cycling is in effect, therefore if there is no face defined
+for a certain level, headlines on that level will not be styled.
+
+If nil or any other value, no face is applied to the headline.
+
+See `counsel-org-goto-display-tags' and `counsel-org-goto-display-todo' if
+you want to display tags and todo keywords in your headlines."
+ :type '(choice
+ (const :tag "Same as org-mode" org)
+ (const :tag "Verbatim" verbatim)
+ (const :tag "Custom" custom))
+ :group 'ivy)
+
+(defcustom counsel-org-goto-custom-faces nil
+ "Custom faces for displaying headlines in `counsel-org-goto' functions.
+
+The n-th entry is used for headlines on level n, starting with n = 1. If
+a headline is an a level for which there is no entry in the list, it will
+not be styled.
+
+This variable has no effect unless `counsel-org-goto-face-style' is set
+to custom."
+ :type '(repeat face)
+ :group 'ivy)
+
+(declare-function org-get-heading "org")
+(declare-function org-goto-marker-or-bmk "org")
+(declare-function outline-next-heading "outline")
+
+;;;###autoload
+(defun counsel-org-goto ()
+ "Go to a different location in the current file."
+ (interactive)
+ (let ((entries (counsel-org-goto--get-headlines)))
+ (ivy-read "Goto: "
+ entries
+ :history 'counsel-org-goto-history
+ :action 'counsel-org-goto-action
+ :caller 'counsel-org-goto)))
+
+;;;###autoload
+(defun counsel-org-goto-all ()
+ "Go to a different location in any org file."
+ (interactive)
+ (let (entries)
+ (dolist (b (buffer-list))
+ (with-current-buffer b
+ (when (derived-mode-p 'org-mode)
+ (if entries
+ (nconc entries (counsel-org-goto--get-headlines))
+ (setq entries (counsel-org-goto--get-headlines))))))
+ (ivy-read "Goto: "
+ entries
+ :history 'counsel-org-goto-history
+ :action 'counsel-org-goto-action
+ :caller 'counsel-org-goto-all)))
+
+(defun counsel-org-goto-action (x)
+ "Go to headline in candidate X."
+ (org-goto-marker-or-bmk (cdr x)))
+
+(defun counsel-org-goto--get-headlines ()
+ "Get all headlines from the current org buffer."
+ (save-excursion
+ (let (entries
+ start-pos
+ stack
+ (stack-level 0))
+ (goto-char (point-min))
+ (setq start-pos (or (and (org-at-heading-p)
+ (point))
+ (outline-next-heading)))
+ (while start-pos
+ (let ((name (org-get-heading
+ (not counsel-org-goto-display-tags)
+ (not counsel-org-goto-display-todo)))
+ level)
+ (search-forward " ")
+ (setq level
+ (- (length (buffer-substring-no-properties start-pos (point)))
+ 1))
+ (cond ((eq counsel-org-goto-display-style 'path)
+ ;; Update stack. The empty entry guards against incorrect
+ ;; headline hierarchies e.g. a level 3 headline immediately
+ ;; following a level 1 entry.
+ (while (<= level stack-level)
+ (pop stack)
+ (cl-decf stack-level))
+ (while (> level stack-level)
+ (push "" stack)
+ (cl-incf stack-level))
+ (setf (car stack) (counsel-org-goto--add-face name level))
+ (setq name (mapconcat
+ #'identity
+ (reverse stack)
+ counsel-org-goto-separator)))
+ (t
+ (when (eq counsel-org-goto-display-style 'headline)
+ (setq name (concat (make-string level ?*) " " name)))
+ (setq name (counsel-org-goto--add-face name level))))
+ (push (cons name (point-marker)) entries))
+ (setq start-pos (outline-next-heading)))
+ (nreverse entries))))
+
+(defun counsel-org-goto--add-face (name level)
+ "Add face to headline NAME on LEVEL.
+The face can be customized through `counsel-org-goto-face-style'."
+ (or (and (eq counsel-org-goto-face-style 'org)
+ (propertize
+ name
+ 'face
+ (concat "org-level-" (number-to-string level))))
+ (and (eq counsel-org-goto-face-style 'verbatim)
+ name)
+ (and (eq counsel-org-goto-face-style 'custom)
+ (propertize
+ name
+ 'face
+ (nth (1- level) counsel-org-goto-custom-faces)))
+ (propertize name 'face 'minibuffer-prompt)))
+
+;;** `counsel-mark-ring'
+(defun counsel--pad (string length)
+ "Pad STRING to LENGTH with spaces."
+ (let ((padding (max 0 (- length (length string)))))
+ (concat string (make-string padding ?\s))))
+
+(defun counsel-mark-ring ()
+ "Browse `mark-ring' interactively."
+ (interactive)
+ (let ((candidates
+ (with-current-buffer (current-buffer)
+ (let ((padding (length (format "%s: " (line-number-at-pos (eobp))))))
+ (save-mark-and-excursion
+ (goto-char (point-min))
+ (sort (mapcar (lambda (mark)
+ (let* ((position (marker-position mark))
+ (line-number (line-number-at-pos position))
+ (line-marker (counsel--pad (format "%s:" line-number) padding))
+ (bol (point-at-bol line-number))
+ (eol (point-at-eol line-number))
+ (line (buffer-substring bol eol)))
+ (cons (format "%s%s" line-marker line) position)))
+ (cl-remove-duplicates mark-ring :test #'equal))
+ (lambda (m1 m2)
+ (< (cdr m1) (cdr m2)))))))))
+ (ivy-read "Marks: " candidates
+ :action (lambda (elem)
+ (goto-char (cdr elem))))))
+
+;;** `counsel-package'
+(defvar package--initialized)
+(defvar package-alist)
+(defvar package-archive-contents)
+(declare-function package-installed-p "package")
+(declare-function package-delete "package")
+
+(defun counsel-package ()
+ "Install or delete packages.
+
+Packages not currently installed have a \"+\" prepended. Selecting one
+of these will try to install it. Currently installed packages have a
+\"-\" prepended, and selecting one of these will delete the package.
+
+Additional Actions:
+
+ \\<ivy-minibuffer-map>\\[ivy-dispatching-done] d: describe package"
+ (interactive)
+ (unless package--initialized
+ (package-initialize t))
+ (unless package-archive-contents
+ (package-refresh-contents))
+ (let ((cands (mapcar #'counsel-package-make-package-cell
+ package-archive-contents)))
+ (ivy-read "Packages (install +pkg or delete -pkg): "
+ (cl-sort cands #'counsel--package-sort)
+ :action #'counsel-package-action
+ :initial-input "^+ "
+ :require-match t
+ :caller 'counsel-package)))
+
+(defun counsel-package-make-package-cell (pkg)
+ "Make candidate for package PKG."
+ (let* ((pkg-sym (car pkg))
+ (pkg-name (symbol-name pkg-sym)))
+ (cons (format "%s%s"
+ (if (package-installed-p pkg-sym) "-" "+")
+ pkg-name)
+ pkg)))
+
+(defun counsel-package-action (pkg-cons)
+ "Delete or install package in PKG-CONS."
+ (let ((pkg (cadr pkg-cons)))
+ (if (package-installed-p pkg)
+ (package-delete
+ (cadr (assoc pkg package-alist)))
+ (package-install pkg))))
+
+(defun counsel-package-action-describe (pkg-cons)
+ "Call `describe-package' for package in PKG-CONS."
+ (describe-package (cadr pkg-cons)))
+
+(declare-function package-desc-extras "package")
+
+(defun counsel-package-action-homepage (pkg-cons)
+ "Open homepage for package in PKG-CONS."
+ (let* ((desc-list (cddr pkg-cons))
+ (desc (if (listp desc-list) (car desc-list) desc-list))
+ (url (cdr (assoc :url (package-desc-extras desc)))))
+ (when url
+ (require 'browse-url)
+ (browse-url url))))
+
+(defun counsel--package-sort (a b)
+ "Sort function for `counsel-package'.
+A is the left hand side, B the right hand side."
+ (let* ((a (car a))
+ (b (car b))
+ (a-inst (equal (substring a 0 1) "+"))
+ (b-inst (equal (substring b 0 1) "+")))
+ (or (and a-inst (not b-inst))
+ (and (eq a-inst b-inst) (string-lessp a b)))))
+
+(ivy-set-actions 'counsel-package
+ '(("d" counsel-package-action-describe "describe package")
+ ("h" counsel-package-action-homepage "open package homepage")))
+
+;;** `counsel-tmm'
+(defvar tmm-km-list nil)
+(declare-function tmm-get-keymap "tmm")
+(declare-function tmm--completion-table "tmm")
+(declare-function tmm-get-keybind "tmm")
+
+(defun counsel-tmm-prompt (menu)
+ "Select and call an item from the MENU keymap."
+ (let (out
+ choice
+ chosen-string)
+ (setq tmm-km-list nil)
+ (map-keymap (lambda (k v) (tmm-get-keymap (cons k v))) menu)
+ (setq tmm-km-list (nreverse tmm-km-list))
+ (setq out (ivy-read "Menu bar: " (tmm--completion-table tmm-km-list)
+ :require-match t
+ :sort nil))
+ (setq choice (cdr (assoc out tmm-km-list)))
+ (setq chosen-string (car choice))
+ (setq choice (cdr choice))
+ (cond ((keymapp choice)
+ (counsel-tmm-prompt choice))
+ ((and choice chosen-string)
+ (setq last-command-event chosen-string)
+ (call-interactively choice)))))
+
+(defvar tmm-table-undef)
+
+;;;###autoload
+(defun counsel-tmm ()
+ "Text-mode emulation of looking and choosing from a menubar."
+ (interactive)
+ (require 'tmm)
+ (run-hooks 'menu-bar-update-hook)
+ (setq tmm-table-undef nil)
+ (counsel-tmm-prompt (tmm-get-keybind [menu-bar])))
+
+;;** `counsel-yank-pop'
+(defun counsel--yank-pop-truncate (str)
+ "Truncate STR for use in `counsel-yank-pop'."
+ (condition-case nil
+ (let* ((lines (split-string str "\n" t))
+ (n (length lines))
+ (re (ivy-re-to-str ivy--old-re))
+ (first-match (cl-position-if
+ (lambda (s) (string-match re s))
+ lines))
+ (beg (max 0 (- first-match
+ counsel-yank-pop-truncate-radius)))
+ (end (min n (+ first-match
+ counsel-yank-pop-truncate-radius
+ 1)))
+ (seq (cl-subseq lines beg end)))
+ (if (null first-match)
+ (error "Could not match %s" str)
+ (when (> beg 0)
+ (setcar seq (concat "[...] " (car seq))))
+ (when (< end n)
+ (setcar (last seq)
+ (concat (car (last seq)) " [...]")))
+ (mapconcat #'identity seq "\n")))
+ (error str)))
+
+(defcustom counsel-yank-pop-separator "\n"
+ "Separator for the kill ring strings in `counsel-yank-pop'."
+ :group 'ivy
+ :type 'string)
+
+(defun counsel--yank-pop-format-function (cand-pairs)
+ "Transform CAND-PAIRS into a string for `counsel-yank-pop'."
+ (ivy--format-function-generic
+ (lambda (str)
+ (mapconcat
+ (lambda (s)
+ (ivy--add-face s 'ivy-current-match))
+ (split-string
+ (counsel--yank-pop-truncate str) "\n" t)
+ "\n"))
+ (lambda (str)
+ (counsel--yank-pop-truncate str))
+ cand-pairs
+ counsel-yank-pop-separator))
+
+(defun counsel-yank-pop-action (s)
+ "Insert S into the buffer, overwriting the previous yank."
+ (with-ivy-window
+ (delete-region ivy-completion-beg
+ ivy-completion-end)
+ (insert (substring-no-properties s))
+ (setq ivy-completion-end (point))))
+
+(defun counsel-yank-pop-action-remove (s)
+ "Remove S from the kill ring."
+ (setq kill-ring (delete s kill-ring)))
+
+;;;###autoload
+(defun counsel-yank-pop ()
+ "Ivy replacement for `yank-pop'."
+ (interactive)
+ (if (eq last-command 'yank)
+ (progn
+ (setq ivy-completion-end (point))
+ (setq ivy-completion-beg
+ (save-excursion
+ (search-backward (car kill-ring))
+ (point))))
+ (setq ivy-completion-beg (point))
+ (setq ivy-completion-end (point)))
+ (let ((candidates
+ (mapcar #'ivy-cleanup-string
+ (cl-remove-if
+ (lambda (s)
+ (string-match "\\`[\n[:blank:]]*\\'" s))
+ (delete-dups kill-ring)))))
+ (let ((ivy-format-function #'counsel--yank-pop-format-function)
+ (ivy-height 5))
+ (ivy-read "kill-ring: " candidates
+ :action 'counsel-yank-pop-action
+ :caller 'counsel-yank-pop))))
+
+(ivy-set-actions
+ 'counsel-yank-pop
+ '(("d" counsel-yank-pop-action-remove "delete")))
+
+;;** `counsel-imenu'
+(defvar imenu-auto-rescan)
+(defvar imenu-auto-rescan-maxout)
+(declare-function imenu--subalist-p "imenu")
+(declare-function imenu--make-index-alist "imenu")
+
+(defun counsel-imenu-get-candidates-from (alist &optional prefix)
+ "Create a list of (key . value) from ALIST.
+PREFIX is used to create the key."
+ (cl-mapcan (lambda (elm)
+ (if (imenu--subalist-p elm)
+ (counsel-imenu-get-candidates-from
+ (cl-loop for (e . v) in (cdr elm) collect
+ (cons e (if (integerp v) (copy-marker v) v)))
+ ;; pass the prefix to next recursive call
+ (concat prefix (if prefix ".") (car elm)))
+ (let ((key (concat
+ (when prefix
+ (concat
+ (propertize prefix 'face 'compilation-info)
+ ": "))
+ (car elm))))
+ (list (cons key
+ ;; create a imenu candidate here
+ (cons key (if (overlayp (cdr elm))
+ (overlay-start (cdr elm))
+ (cdr elm))))))))
+ alist))
+
+(defvar counsel-imenu-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-l") 'ivy-call-and-recenter)
+ map))
+
+;;;###autoload
+(defun counsel-imenu ()
+ "Jump to a buffer position indexed by imenu."
+ (interactive)
+ (unless (featurep 'imenu)
+ (require 'imenu nil t))
+ (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)))
+ (ivy-read "imenu items:" (counsel-imenu-get-candidates-from items)
+ :preselect (thing-at-point 'symbol)
+ :require-match t
+ :action (lambda (candidate)
+ (with-ivy-window
+ ;; In org-mode, (imenu candidate) will expand child node
+ ;; after jump to the candidate position
+ (imenu (cdr candidate))))
+ :keymap counsel-imenu-map
+ :caller 'counsel-imenu)))
+
+;;** `counsel-list-processes'
+(defun counsel-list-processes-action-delete (x)
+ "Delete process X."
+ (delete-process x)
+ (setf (ivy-state-collection ivy-last)
+ (setq ivy--all-candidates
+ (delete x ivy--all-candidates))))
+
+(defun counsel-list-processes-action-switch (x)
+ "Switch to buffer of process X."
+ (let* ((proc (get-process x))
+ (buf (and proc (process-buffer proc))))
+ (if buf
+ (switch-to-buffer buf)
+ (message "Process %s doesn't have a buffer" x))))
+
+;;;###autoload
+(defun counsel-list-processes ()
+ "Offer completion for `process-list'.
+The default action deletes the selected process.
+An extra action allows to switch to the process buffer."
+ (interactive)
+ (list-processes--refresh)
+ (ivy-read "Process: " (mapcar #'process-name (process-list))
+ :require-match t
+ :action
+ '(1
+ ("o" counsel-list-processes-action-delete "kill")
+ ("s" counsel-list-processes-action-switch "switch"))
+ :caller 'counsel-list-processes))
+
+;;** `counsel-ace-link'
+(defun counsel-ace-link ()
+ "Use Ivy completion for `ace-link'."
+ (interactive)
+ (let (collection action)
+ (cond ((eq major-mode 'Info-mode)
+ (setq collection 'ace-link--info-collect)
+ (setq action 'ace-link--info-action))
+ ((eq major-mode 'help-mode)
+ (setq collection 'ace-link--help-collect)
+ (setq action 'ace-link--help-action))
+ ((eq major-mode 'woman-mode)
+ (setq collection 'ace-link--woman-collect)
+ (setq action 'ace-link--woman-action))
+ ((eq major-mode 'eww-mode)
+ (setq collection 'ace-link--eww-collect)
+ (setq action 'ace-link--eww-action))
+ ((eq major-mode 'compilation-mode)
+ (setq collection 'ace-link--eww-collect)
+ (setq action 'ace-link--compilation-action))
+ ((eq major-mode 'org-mode)
+ (setq collection 'ace-link--org-collect)
+ (setq action 'ace-link--org-action)))
+ (if (null collection)
+ (error "%S is not supported" major-mode)
+ (ivy-read "Ace-Link: " (funcall collection)
+ :action (lambda (x) (funcall action (cdr x)))
+ :require-match t
+ :caller 'counsel-ace-link))))
+;;** `counsel-expression-history'
+;;;###autoload
+(defun counsel-expression-history ()
+ "Select an element of `read-expression-history'.
+And insert it into the minibuffer. Useful during `eval-expression'."
+ (interactive)
+ (let ((enable-recursive-minibuffers t))
+ (ivy-read "Expr: " (delete-dups read-expression-history)
+ :action #'insert)))
+
+;;** `counsel-shell-command-history'
+;;;###autoload
+(defun counsel-shell-command-history ()
+ "Browse shell command history."
+ (interactive)
+ (ivy-read "cmd: " shell-command-history
+ :action #'insert
+ :caller 'counsel-shell-command-history))
+
+;;** `counsel-esh-history'
+(defun counsel--browse-history (elements)
+ "Use Ivy to navigate through ELEMENTS."
+ (setq ivy-completion-beg (point))
+ (setq ivy-completion-end (point))
+ (ivy-read "Symbol name: "
+ (delete-dups
+ (when (> (ring-size elements) 0)
+ (ring-elements elements)))
+ :action #'ivy-completion-in-region-action))
+
+(defvar eshell-history-ring)
+
+;;;###autoload
+(defun counsel-esh-history ()
+ "Browse Eshell history."
+ (interactive)
+ (require 'em-hist)
+ (counsel--browse-history eshell-history-ring))
+
+(defvar comint-input-ring)
+
+;;;###autoload
+(defun counsel-shell-history ()
+ "Browse shell history."
+ (interactive)
+ (require 'comint)
+ (counsel--browse-history comint-input-ring))
+
+;;** `counsel-hydra-heads'
+(defvar hydra-curr-body-fn)
+(declare-function hydra-keyboard-quit "ext:hydra")
+
+(defun counsel-hydra-heads ()
+ "Call a head of the current/last hydra."
+ (interactive)
+ (let* ((base (substring
+ (prin1-to-string hydra-curr-body-fn)
+ 0 -4))
+ (heads (eval (intern (concat base "heads"))))
+ (keymap (eval (intern (concat base "keymap"))))
+ (head-names
+ (mapcar (lambda (x)
+ (cons
+ (if (nth 2 x)
+ (format "[%s] %S (%s)" (nth 0 x) (nth 1 x) (nth 2 x))
+ (format "[%s] %S" (nth 0 x) (nth 1 x)))
+ (lookup-key keymap (kbd (nth 0 x)))))
+ heads)))
+ (ivy-read "head: " head-names
+ :action (lambda (x) (call-interactively (cdr x))))
+ (hydra-keyboard-quit)))
+;;** `counsel-semantic'
+(declare-function semantic-tag-start "tag")
+(declare-function semantic-tag-of-class-p "tag")
+(declare-function semantic-fetch-tags "semantic")
+
+(defun counsel-semantic-action (tag)
+ "Got to semantic TAG."
+ (with-ivy-window
+ (goto-char (semantic-tag-start tag))))
+
+(defun counsel-semantic ()
+ "Jump to a semantic tag in the current buffer."
+ (interactive)
+ (let ((tags
+ (mapcar
+ (lambda (tag)
+ (if (semantic-tag-of-class-p tag 'function)
+ (cons
+ (propertize
+ (car tag)
+ 'face 'font-lock-function-name-face)
+ (cdr tag))
+ tag))
+ (semantic-fetch-tags))))
+ (ivy-read "tag: " tags
+ :action 'counsel-semantic-action)))
+
+;;** `counsel-outline'
+(defun counsel-outline-candidates ()
+ "Return outline candidates."
+ (let (cands)
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward outline-regexp nil t)
+ (skip-chars-forward " ")
+ (push (cons (buffer-substring-no-properties
+ (point) (line-end-position))
+ (line-beginning-position))
+ cands))
+ (nreverse cands))))
+
+(defun counsel-outline-action (x)
+ "Go to outline X."
+ (with-ivy-window
+ (goto-char (cdr x))))
+
+(defun counsel-outline ()
+ "Jump to outline with completion."
+ (interactive)
+ (ivy-read "outline: " (counsel-outline-candidates)
+ :action #'counsel-outline-action))
+
+;;* Misc OS
+;;** `counsel-rhythmbox'
+(declare-function dbus-call-method "dbus")
+(declare-function dbus-get-property "dbus")
+
+(defun counsel-rhythmbox-play-song (song)
+ "Let Rhythmbox play SONG."
+ (let ((service "org.gnome.Rhythmbox3")
+ (path "/org/mpris/MediaPlayer2")
+ (interface "org.mpris.MediaPlayer2.Player"))
+ (dbus-call-method :session service path interface
+ "OpenUri" (cdr song))))
+
+(defun counsel-rhythmbox-enqueue-song (song)
+ "Let Rhythmbox enqueue SONG."
+ (let ((service "org.gnome.Rhythmbox3")
+ (path "/org/gnome/Rhythmbox3/PlayQueue")
+ (interface "org.gnome.Rhythmbox3.PlayQueue"))
+ (dbus-call-method :session service path interface
+ "AddToQueue" (cdr song))))
+
+(defvar counsel-rhythmbox-history nil
+ "History for `counsel-rhythmbox'.")
+
+(defvar counsel-rhythmbox-songs nil)
+
+(defun counsel-rhythmbox-current-song ()
+ "Return the currently playing song title."
+ (ignore-errors
+ (let* ((entry (dbus-get-property
+ :session
+ "org.mpris.MediaPlayer2.rhythmbox"
+ "/org/mpris/MediaPlayer2"
+ "org.mpris.MediaPlayer2.Player"
+ "Metadata"))
+ (artist (caar (cadr (assoc "xesam:artist" entry))))
+ (album (cl-caadr (assoc "xesam:album" entry)))
+ (title (cl-caadr (assoc "xesam:title" entry))))
+ (format "%s - %s - %s" artist album title))))
+
+;;;###autoload
+(defun counsel-rhythmbox ()
+ "Choose a song from the Rhythmbox library to play or enqueue."
+ (interactive)
+ (require 'dbus)
+ (unless counsel-rhythmbox-songs
+ (let* ((service "org.gnome.Rhythmbox3")
+ (path "/org/gnome/UPnP/MediaServer2/Library/all")
+ (interface "org.gnome.UPnP.MediaContainer2")
+ (nb-songs (dbus-get-property
+ :session service path interface "ChildCount")))
+ (if (not nb-songs)
+ (error "Couldn't connect to Rhythmbox")
+ (setq counsel-rhythmbox-songs
+ (mapcar (lambda (x)
+ (cons
+ (format
+ "%s - %s - %s"
+ (cl-caadr (assoc "Artist" x))
+ (cl-caadr (assoc "Album" x))
+ (cl-caadr (assoc "DisplayName" x)))
+ (cl-caaadr (assoc "URLs" x))))
+ (dbus-call-method
+ :session service path interface "ListChildren"
+ 0 nb-songs '("*")))))))
+ (ivy-read "Rhythmbox: " counsel-rhythmbox-songs
+ :history 'counsel-rhythmbox-history
+ :preselect (counsel-rhythmbox-current-song)
+ :action
+ '(1
+ ("p" counsel-rhythmbox-play-song "Play song")
+ ("e" counsel-rhythmbox-enqueue-song "Enqueue song"))
+ :caller 'counsel-rhythmbox))
+
+;;** `counsel-linux-app'
+(defcustom counsel-linux-apps-directories
+ '("/usr/local/share/applications/" "/usr/share/applications/")
+ "Directories in which to search for applications (.desktop files)."
+ :group 'counsel
+ :type '(list directory))
+
+(defcustom counsel-linux-app-format-function 'counsel-linux-app-format-function-default
+ "Function to format Linux application names the `counsel-linux-app' menu.
+The format function will be passed the application's name, comment, and command
+as arguments."
+ :group 'counsel
+ :type '(choice
+ (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 "Command" counsel-linux-app-format-function-command-only)
+ (function :tag "Custom")))
+
+(defvar counsel-linux-apps-faulty nil
+ "List of faulty desktop files.")
+
+(defvar counsel--linux-apps-cache nil
+ "Cache of desktop files data.")
+
+(defvar counsel--linux-apps-cached-files nil
+ "List of cached desktop files.")
+
+(defvar counsel--linux-apps-cache-timestamp nil
+ "Time when we last updated the cached application list.")
+
+(defvar counsel--linux-apps-cache-format-function nil
+ "The function used to format the cached Linux application menu.")
+
+(defun counsel-linux-app-format-function-default (name comment exec)
+ "Default Linux application name formatter.
+NAME is the name of the application, COMMENT its comment and EXEC
+the command to launch it."
+ (format "% -45s: %s%s"
+ (propertize exec 'face 'font-lock-builtin-face)
+ name
+ (if comment
+ (concat " - " comment)
+ "")))
+
+(defun counsel-linux-app-format-function-name-first (name comment exec)
+ "Format Linux application names with the NAME (and COMMENT) first.
+EXEC is the command to launch the application."
+ (format "%s%s (%s)"
+ name
+ (if comment
+ (concat " - " comment)
+ "")
+ (propertize exec 'face 'font-lock-builtin-face)))
+
+(defun counsel-linux-app-format-function-name-only (name comment _exec)
+ "Format Linux application names with the NAME (and COMMENT) only."
+ (format "%s%s"
+ name
+ (if comment
+ (concat " - " comment)
+ "")))
+
+(defun counsel-linux-app-format-function-command-only (_name _comment exec)
+ "Display only the command EXEC when formatting Linux application names."
+ exec)
+
+(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).
+This function always returns its elements in a stable order."
+ (let ((hash (make-hash-table :test #'equal))
+ result)
+ (dolist (dir counsel-linux-apps-directories)
+ (when (file-exists-p dir)
+ (let ((dir (file-name-as-directory dir)))
+ (dolist (file (directory-files-recursively dir ".*\\.desktop$"))
+ (let ((id (subst-char-in-string ?/ ?- (file-relative-name file dir))))
+ (unless (gethash id hash)
+ (push (cons id file) result)
+ (puthash id file hash)))))))
+ result))
+
+(defun counsel-linux-apps-parse (desktop-entries-alist)
+ "Parse the given alist of Linux desktop entries.
+Each entry in DESKTOP-ENTRIES-ALIST is a pair of ((id . file-name)).
+Any desktop entries that fail to parse are recorded in
+`counsel-linux-apps-faulty'."
+ (let (result)
+ (setq counsel-linux-apps-faulty nil)
+ (dolist (entry desktop-entries-alist result)
+ (let ((id (car entry))
+ (file (cdr entry)))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (goto-char (point-min))
+ (let ((start (re-search-forward "^\\[Desktop Entry\\] *$" nil t))
+ (end (re-search-forward "^\\[" nil t))
+ name comment exec)
+ (catch 'break
+ (unless start
+ (push file counsel-linux-apps-faulty)
+ (message "Warning: File %s has no [Desktop Entry] group" file)
+ (throw 'break nil))
+
+ (goto-char start)
+ (when (re-search-forward "^\\(Hidden\\|NoDisplay\\) *= *\\(1\\|true\\) *$" end t)
+ (throw 'break nil))
+ (setq name (match-string 1))
+
+ (goto-char start)
+ (unless (re-search-forward "^Type *= *Application *$" end t)
+ (throw 'break nil))
+ (setq name (match-string 1))
+
+ (goto-char start)
+ (unless (re-search-forward "^Name *= *\\(.+\\)$" end t)
+ (push file counsel-linux-apps-faulty)
+ (message "Warning: File %s has no Name" file)
+ (throw 'break nil))
+ (setq name (match-string 1))
+
+ (goto-char start)
+ (when (re-search-forward "^Comment *= *\\(.+\\)$" end t)
+ (setq comment (match-string 1)))
+
+ (goto-char start)
+ (unless (re-search-forward "^Exec *= *\\(.+\\)$" end t)
+ ;; Don't warn because this can technically be a valid desktop file.
+ (throw 'break nil))
+ (setq exec (match-string 1))
+
+ (goto-char start)
+ (when (re-search-forward "^TryExec *= *\\(.+\\)$" end t)
+ (let ((try-exec (match-string 1)))
+ (unless (locate-file try-exec exec-path nil #'file-executable-p)
+ (throw 'break nil))))
+
+ (push
+ (cons (funcall counsel-linux-app-format-function name comment exec) id)
+ result))))))))
+
+(defun counsel-linux-apps-list ()
+ "Return list of all Linux desktop applications."
+ (let* ((new-desktop-alist (counsel-linux-apps-list-desktop-files))
+ (new-files (mapcar 'cdr new-desktop-alist)))
+ (unless (and
+ (eq counsel-linux-app-format-function
+ counsel--linux-apps-cache-format-function)
+ (equal new-files counsel--linux-apps-cached-files)
+ (null (cl-find-if
+ (lambda (file)
+ (time-less-p
+ counsel--linux-apps-cache-timestamp
+ (nth 5 (file-attributes file))))
+ new-files)))
+ (setq counsel--linux-apps-cache (counsel-linux-apps-parse new-desktop-alist)
+ counsel--linux-apps-cache-format-function counsel-linux-app-format-function
+ counsel--linux-apps-cache-timestamp (current-time)
+ counsel--linux-apps-cached-files new-files)))
+ counsel--linux-apps-cache)
+
+
+(defun counsel-linux-app-action-default (desktop-shortcut)
+ "Launch DESKTOP-SHORTCUT."
+ (setq desktop-shortcut (cdr desktop-shortcut))
+ (call-process "gtk-launch" nil nil nil desktop-shortcut))
+
+(defun counsel-linux-app-action-file (desktop-shortcut)
+ "Launch DESKTOP-SHORTCUT with a selected file."
+ (setq desktop-shortcut (cdr desktop-shortcut))
+ (let ((file (read-file-name "Open: ")))
+ (if file
+ (call-process "gtk-launch" nil nil nil desktop-shortcut file)
+ (user-error "Cancelled"))))
+
+(defun counsel-linux-app-action-open-desktop (desktop-shortcut)
+ "Open DESKTOP-SHORTCUT."
+ (setq desktop-shortcut (cdr desktop-shortcut))
+ (let ((file
+ (cdr (assoc desktop-shortcut (counsel-linux-apps-list-desktop-files)))))
+ (if file
+ (find-file file)
+ (user-error "Cancelled"))))
+
+(ivy-set-actions
+ 'counsel-linux-app
+ '(("f" counsel-linux-app-action-file "run on a file")
+ ("d" counsel-linux-app-action-open-desktop "open desktop file")))
+
+;;;###autoload
+(defun counsel-linux-app ()
+ "Launch a Linux desktop application, similar to Alt-<F2>."
+ (interactive)
+ (ivy-read "Run a command: " (counsel-linux-apps-list)
+ :action #'counsel-linux-app-action-default
+ :caller 'counsel-linux-app))
+
+;;** `counsel-company'
+(defvar company-candidates)
+(defvar company-point)
+(defvar company-common)
+(declare-function company-complete "ext:company")
+(declare-function company-mode "ext:company")
+(declare-function company-complete-common "ext:company")
+
+;;;###autoload
+(defun counsel-company ()
+ "Complete using `company-candidates'."
+ (interactive)
+ (company-mode 1)
+ (unless company-candidates
+ (company-complete))
+ (when company-point
+ (when (looking-back company-common (line-beginning-position))
+ (setq ivy-completion-beg (match-beginning 0))
+ (setq ivy-completion-end (match-end 0)))
+ (ivy-read "company cand: " company-candidates
+ :action #'ivy-completion-in-region-action)))
+
+;;;** `counsel-colors'
+(defun counsel-colors--best-contrast-color (color)
+ "Choose the best-contrast foreground color for a background color COLOR.
+
+Use the relative luminance formula to improve the perceived contrast.
+If the relative luminance is beyond a given threshold, in this case a
+midpoint, then the chosen color is black, otherwise is white. This
+helps to improve the contrast and readability of a text regardless of
+the background color."
+ (let ((rgb (color-name-to-rgb color)))
+ (if rgb
+ (if (>
+ (+ (* (nth 0 rgb) 0.299)
+ (* (nth 1 rgb) 0.587)
+ (* (nth 2 rgb) 0.114))
+ 0.5)
+ "#000000"
+ "#FFFFFF")
+ color)))
+
+(defun counsel-colors--update-highlight (cand)
+ "Update the highlight face for the current candidate CAND.
+
+This is necessary because the default `ivy-current-match' face
+background mask most of the colors and you can not see the current
+candidate color when is selected, which is counter-intuitive and not
+user friendly. The default Emacs command `list-colors-display' have
+the same problem."
+ (when (> (length cand) 0)
+ (let ((color (substring-no-properties cand 26 33)))
+ (face-remap-add-relative
+ 'ivy-current-match
+ :background color
+ ;; Another alternatives like use the attribute
+ ;; `distant-foreground' or the function `color-complement-hex'
+ ;; do not work well here because they use the absolute
+ ;; luminance difference between the colors, when the human eye
+ ;; does not perceive all the colors with the same brightness.
+ :foreground (counsel-colors--best-contrast-color color)))))
+
+(defun counsel-colors-action-insert-name (x)
+ "Insert the X color name."
+ (let ((color (car (split-string (substring x 0 25)))))
+ (insert color)))
+
+(defun counsel-colors-action-insert-hex (x)
+ "Insert the X color hexadecimal rgb value."
+ (let ((rgb (substring x 26 33)))
+ (insert rgb)))
+
+(defun counsel-colors-action-kill-name (x)
+ "Kill the X color name."
+ (let ((color (car (split-string (substring x 0 25)))))
+ (kill-new color)))
+
+(defun counsel-colors-action-kill-hex (x)
+ "Kill the X color hexadecimal rgb value."
+ (let ((rgb (substring x 26 33)))
+ (kill-new rgb)))
+
+;;** `counsel-colors-emacs'
+(ivy-set-actions
+ 'counsel-colors-emacs
+ '(("n" counsel-colors-action-insert-name "insert color name")
+ ("h" counsel-colors-action-insert-hex "insert color hexadecimal value")
+ ("N" counsel-colors-action-kill-name "kill color name")
+ ("H" counsel-colors-action-kill-hex "kill color hexadecimal value")))
+
+(defvar counsel-colors-emacs-history nil
+ "History for `counsel-colors-emacs'.")
+
+(defun counsel-colors--name-to-hex (color)
+ "Return hexadecimal rgb value of a color from his name COLOR."
+ (apply 'color-rgb-to-hex (color-name-to-rgb color)))
+
+;;;###autoload
+(defun counsel-colors-emacs ()
+ "Show a list of all supported colors for a particular frame.
+
+You can insert or kill the name or the hexadecimal rgb value of the
+selected candidate."
+ (interactive)
+ (let ((minibuffer-allow-text-properties t))
+ (ivy-read "%d Emacs color: "
+ (mapcar (lambda (x)
+ (concat
+ (propertize
+ (format "%-25s" (car x))
+ 'result (car x))
+ (propertize
+ (format "%8s "
+ (counsel-colors--name-to-hex (car x)))
+ 'face (list :foreground (car x)))
+ (propertize
+ (format "%10s" " ")
+ 'face (list :background (car x)))
+ (propertize
+ (format " %-s" (mapconcat #'identity (cdr x) ", "))
+ 'face (list :foreground (car x)))))
+ (list-colors-duplicates))
+ :require-match t
+ :update-fn (lambda ()
+ (counsel-colors--update-highlight (ivy-state-current ivy-last)))
+ :action #'counsel-colors-action-insert-name
+ :history 'counsel-colors-emacs-history
+ :caller 'counsel-colors-emacs
+ :sort nil)))
+
+;;** `counsel-colors-web'
+(defvar counsel-colors--web-colors-alist
+ '(("aliceblue" . "#f0f8ff")
+ ("antiquewhite" . "#faebd7")
+ ("aqua" . "#00ffff")
+ ("aquamarine" . "#7fffd4")
+ ("azure" . "#f0ffff")
+ ("beige" . "#f5f5dc")
+ ("bisque" . "#ffe4c4")
+ ("black" . "#000000")
+ ("blanchedalmond" . "#ffebcd")
+ ("blue" . "#0000ff")
+ ("blueviolet" . "#8a2be2")
+ ("brown" . "#a52a2a")
+ ("burlywood" . "#deb887")
+ ("cadetblue" . "#5f9ea0")
+ ("chartreuse" . "#7fff00")
+ ("chocolate" . "#d2691e")
+ ("coral" . "#ff7f50")
+ ("cornflowerblue" . "#6495ed")
+ ("cornsilk" . "#fff8dc")
+ ("crimson" . "#dc143c")
+ ("cyan" . "#00ffff")
+ ("darkblue" . "#00008b")
+ ("darkcyan" . "#008b8b")
+ ("darkgoldenrod" . "#b8860b")
+ ("darkgray" . "#a9a9a9")
+ ("darkgreen" . "#006400")
+ ("darkkhaki" . "#bdb76b")
+ ("darkmagenta" . "#8b008b")
+ ("darkolivegreen" . "#556b2f")
+ ("darkorange" . "#ff8c00")
+ ("darkorchid" . "#9932cc")
+ ("darkred" . "#8b0000")
+ ("darksalmon" . "#e9967a")
+ ("darkseagreen" . "#8fbc8f")
+ ("darkslateblue" . "#483d8b")
+ ("darkslategray" . "#2f4f4f")
+ ("darkturquoise" . "#00ced1")
+ ("darkviolet" . "#9400d3")
+ ("deeppink" . "#ff1493")
+ ("deepskyblue" . "#00bfff")
+ ("dimgray" . "#696969")
+ ("dodgerblue" . "#1e90ff")
+ ("firebrick" . "#b22222")
+ ("floralwhite" . "#fffaf0")
+ ("forestgreen" . "#228b22")
+ ("fuchsia" . "#ff00ff")
+ ("gainsboro" . "#dcdcdc")
+ ("ghostwhite" . "#f8f8ff")
+ ("goldenrod" . "#daa520")
+ ("gold" . "#ffd700")
+ ("gray" . "#808080")
+ ("green" . "#008000")
+ ("greenyellow" . "#adff2f")
+ ("honeydew" . "#f0fff0")
+ ("hotpink" . "#ff69b4")
+ ("indianred" . "#cd5c5c")
+ ("indigo" . "#4b0082")
+ ("ivory" . "#fffff0")
+ ("khaki" . "#f0e68c")
+ ("lavenderblush" . "#fff0f5")
+ ("lavender" . "#e6e6fa")
+ ("lawngreen" . "#7cfc00")
+ ("lemonchiffon" . "#fffacd")
+ ("lightblue" . "#add8e6")
+ ("lightcoral" . "#f08080")
+ ("lightcyan" . "#e0ffff")
+ ("lightgoldenrodyellow" . "#fafad2")
+ ("lightgreen" . "#90ee90")
+ ("lightgrey" . "#d3d3d3")
+ ("lightpink" . "#ffb6c1")
+ ("lightsalmon" . "#ffa07a")
+ ("lightseagreen" . "#20b2aa")
+ ("lightskyblue" . "#87cefa")
+ ("lightslategray" . "#778899")
+ ("lightsteelblue" . "#b0c4de")
+ ("lightyellow" . "#ffffe0")
+ ("lime" . "#00ff00")
+ ("limegreen" . "#32cd32")
+ ("linen" . "#faf0e6")
+ ("magenta" . "#ff00ff")
+ ("maroon" . "#800000")
+ ("mediumaquamarine" . "#66cdaa")
+ ("mediumblue" . "#0000cd")
+ ("mediumorchid" . "#ba55d3")
+ ("mediumpurple" . "#9370d8")
+ ("mediumseagreen" . "#3cb371")
+ ("mediumslateblue" . "#7b68ee")
+ ("mediumspringgreen" . "#00fa9a")
+ ("mediumturquoise" . "#48d1cc")
+ ("mediumvioletred" . "#c71585")
+ ("midnightblue" . "#191970")
+ ("mintcream" . "#f5fffa")
+ ("mistyrose" . "#ffe4e1")
+ ("moccasin" . "#ffe4b5")
+ ("navajowhite" . "#ffdead")
+ ("navy" . "#000080")
+ ("oldlace" . "#fdf5e6")
+ ("olive" . "#808000")
+ ("olivedrab" . "#6b8e23")
+ ("orange" . "#ffa500")
+ ("orangered" . "#ff4500")
+ ("orchid" . "#da70d6")
+ ("palegoldenrod" . "#eee8aa")
+ ("palegreen" . "#98fb98")
+ ("paleturquoise" . "#afeeee")
+ ("palevioletred" . "#d87093")
+ ("papayawhip" . "#ffefd5")
+ ("peachpuff" . "#ffdab9")
+ ("peru" . "#cd853f")
+ ("pink" . "#ffc0cb")
+ ("plum" . "#dda0dd")
+ ("powderblue" . "#b0e0e6")
+ ("purple" . "#800080")
+ ("rebeccapurple" . "#663399")
+ ("red" . "#ff0000")
+ ("rosybrown" . "#bc8f8f")
+ ("royalblue" . "#4169e1")
+ ("saddlebrown" . "#8b4513")
+ ("salmon" . "#fa8072")
+ ("sandybrown" . "#f4a460")
+ ("seagreen" . "#2e8b57")
+ ("seashell" . "#fff5ee")
+ ("sienna" . "#a0522d")
+ ("silver" . "#c0c0c0")
+ ("skyblue" . "#87ceeb")
+ ("slateblue" . "#6a5acd")
+ ("slategray" . "#708090")
+ ("snow" . "#fffafa")
+ ("springgreen" . "#00ff7f")
+ ("steelblue" . "#4682b4")
+ ("tan" . "#d2b48c")
+ ("teal" . "#008080")
+ ("thistle" . "#d8bfd8")
+ ("tomato" . "#ff6347")
+ ("turquoise" . "#40e0d0")
+ ("violet" . "#ee82ee")
+ ("wheat" . "#f5deb3")
+ ("white" . "#ffffff")
+ ("whitesmoke" . "#f5f5f5")
+ ("yellow" . "#ffff00")
+ ("yellowgreen" . "#9acd32"))
+ "These are the colors defined by the W3C consortium to use in CSS sheets.
+
+All of these colors are compatible with any common browser. The
+colors gray, green, maroon and purple have alternative values as
+defined by the X11 standard, here they follow the W3C one.")
+
+(ivy-set-actions
+ 'counsel-colors-web
+ '(("n" counsel-colors-action-insert-name "insert name")
+ ("h" counsel-colors-action-insert-hex "insert hex")
+ ("N" counsel-colors-action-kill-name "kill rgb")
+ ("H" counsel-colors-action-kill-hex "kill hex")))
+
+(defvar counsel-colors-web-history nil
+ "History for `counsel-colors-web'.")
+
+;;;###autoload
+(defun counsel-colors-web ()
+ "Show a list of all W3C web colors for use in CSS.
+
+You can insert or kill the name or the hexadecimal rgb value of the
+selected candidate."
+ (interactive)
+ (let ((minibuffer-allow-text-properties t))
+ (ivy-read "%d Web color: "
+ (mapcar (lambda (x)
+ (concat
+ (propertize
+ (format "%-25s" (car x)))
+ (propertize
+ (format "%8s " (cdr x))
+ 'face (list :foreground (car x)))
+ (propertize
+ (format "%10s" " ")
+ 'face (list :background (cdr x)))))
+ counsel-colors--web-colors-alist)
+ :require-match t
+ :action #'counsel-colors-action-insert-name
+ :update-fn (lambda ()
+ (counsel-colors--update-highlight (ivy-state-current ivy-last)))
+ :history 'counsel-colors-web-history
+ :caller 'counsel-colors-web
+ :sort t)))
+
+
+;;** `counsel-faces'
+(defun counsel-faces-action-describe (x)
+ "Describe the face X."
+ (describe-face (intern x)))
+
+(defun counsel-faces-action-customize (x)
+ "Customize the face X."
+ (customize-face (intern x)))
+
+(ivy-set-actions
+ 'counsel-faces
+ '(("d" counsel-faces-action-describe "describe face")
+ ("c" counsel-faces-action-customize "customize face")
+ ("i" insert "insert face name")
+ ("k" kill-new "kill face name")))
+
+(defvar counsel-faces-history nil
+ "History for `counsel-faces'.")
+
+(defvar counsel-faces--sample-text
+ "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"
+ "Text string to display as the sample text for `counsel-faces'.")
+
+(defvar counsel--faces-fmt nil)
+
+(defun counsel--faces-format-function (cands)
+ "Transform CANDS into a string for `counsel-faces'."
+ (ivy--format-function-generic
+ (lambda (str)
+ (concat
+ (format counsel--faces-fmt
+ (ivy--add-face str 'ivy-current-match))
+ (propertize counsel-faces--sample-text 'face (intern str))))
+ (lambda (str)
+ (concat
+ (format counsel--faces-fmt
+ str)
+ (propertize counsel-faces--sample-text 'face (intern str))))
+ cands
+ "\n"))
+
+(defun counsel-faces ()
+ "Show a list of all defined faces.
+
+You can describe, customize, insert or kill the name or selected
+candidate."
+ (interactive)
+ (let* ((minibuffer-allow-text-properties t)
+ (max-length
+ (apply #'max
+ (mapcar
+ (lambda (x)
+ (length (symbol-name x)))
+ (face-list))))
+ (counsel--faces-fmt (format "%%-%ds " max-length))
+ (ivy-format-function #'counsel--faces-format-function))
+ (ivy-read "%d Face: " (face-list)
+ :require-match t
+ :action #'counsel-faces-action-describe
+ :history 'counsel-faces-history
+ :caller 'counsel-faces
+ :sort t)))
+
+;;** `counsel-command-history'
+(defun counsel-command-history-action-eval (cmd)
+ "Eval the command CMD."
+ (eval (read cmd)))
+
+(defun counsel-command-history-action-edit-and-eval (cmd)
+ "Edit and eval the command CMD."
+ (edit-and-eval-command "Eval: " (read cmd)))
+
+(ivy-set-actions
+ 'counsel-command-history
+ '(("r" counsel-command-history-action-eval "eval command")
+ ("e" counsel-command-history-action-edit-and-eval "edit and eval command")))
+
+(defun counsel-command-history ()
+ "Show the history of commands."
+ (interactive)
+ (ivy-read "%d Command: " (mapcar #'prin1-to-string command-history)
+ :require-match t
+ :action #'counsel-command-history-action-eval
+ :caller 'counsel-command-history))
+
+;;** `counsel-org-agenda-headlines'
+(defvar org-odd-levels-only)
+(declare-function org-set-startup-visibility "org")
+(declare-function org-show-entry "org")
+(declare-function org-map-entries "org")
+(declare-function org-heading-components "org")
+
+(defun counsel-org-agenda-headlines-action-goto (headline)
+ "Go to the `org-mode' agenda HEADLINE."
+ (find-file (nth 1 headline))
+ (org-set-startup-visibility)
+ (goto-char (nth 2 headline))
+ (org-show-entry))
+
+(ivy-set-actions
+ 'counsel-org-agenda-headlines
+ '(("g" counsel-org-agenda-headlines-action-goto "goto headline")))
+
+(defvar counsel-org-agenda-headlines-history nil
+ "History for `counsel-org-agenda-headlines'.")
+
+(defun counsel-org-agenda-headlines--candidates ()
+ "Return a list of completion candidates for `counsel-org-agenda-headlines'."
+ (org-map-entries
+ (lambda ()
+ (let* ((components (org-heading-components))
+ (level (make-string
+ (if org-odd-levels-only
+ (nth 1 components)
+ (nth 0 components))
+ ?*))
+ (todo (nth 2 components))
+ (priority (nth 3 components))
+ (text (nth 4 components))
+ (tags (nth 5 components)))
+ (list
+ (mapconcat
+ 'identity
+ (cl-remove-if 'null
+ (list
+ level
+ todo
+ (if priority (format "[#%c]" priority))
+ text
+ tags))
+ " ")
+ (buffer-file-name) (point))))
+ nil
+ 'agenda))
+
+;;;###autoload
+(defun counsel-org-agenda-headlines ()
+ "Choose from headers of `org-mode' files in the agenda."
+ (interactive)
+ (let ((minibuffer-allow-text-properties t))
+ (ivy-read "Org headline: "
+ (counsel-org-agenda-headlines--candidates)
+ :action #'counsel-org-agenda-headlines-action-goto
+ :history 'counsel-org-agenda-headlines-history
+ :caller 'counsel-org-agenda-headlines)))
+
+;;** `counsel-irony'
+;;;###autoload
+(defun counsel-irony ()
+ "Inline C/C++ completion using Irony."
+ (interactive)
+ (irony-completion-candidates-async 'counsel-irony-callback))
+
+(defun counsel-irony-callback (candidates)
+ "Callback function for Irony to search among CANDIDATES."
+ (interactive)
+ (let* ((symbol-bounds (irony-completion-symbol-bounds))
+ (beg (car symbol-bounds))
+ (end (cdr symbol-bounds))
+ (prefix (buffer-substring-no-properties beg end)))
+ (setq ivy-completion-beg beg
+ ivy-completion-end end)
+ (ivy-read "code: " (mapcar #'counsel-irony-annotate candidates)
+ :predicate (lambda (candidate)
+ (string-prefix-p prefix (car candidate)))
+ :caller 'counsel-irony
+ :action 'ivy-completion-in-region-action)))
+
+(defun counsel-irony-annotate (x)
+ "Make Ivy candidate from Irony candidate X."
+ (cons (concat (car x) (irony-completion-annotation x))
+ (car x)))
+
+(add-to-list 'ivy-display-functions-alist '(counsel-irony . ivy-display-function-overlay))
+
+(declare-function irony-completion-candidates-async "ext:irony-completion")
+(declare-function irony-completion-symbol-bounds "ext:irony-completion")
+(declare-function irony-completion-annotation "ext:irony-completion")
+
+;;** `counsel-apropos'
+;;;###autoload
+(defun counsel-apropos ()
+ "Show all matching symbols.
+See `apropos' for further information about what is considered
+a symbol and how to search for them."
+ (interactive)
+ (ivy-read "Search for symbol (word list or regexp): "
+ (counsel-symbol-list)
+ :history 'counsel-apropos-history
+ :action (lambda (pattern)
+ (when (= (length pattern) 0)
+ (user-error "Please specify a pattern"))
+ ;; If the user selected a candidate form the list, we use
+ ;; a pattern which matches only the selected symbol.
+ (if (memq this-command '(ivy-immediate-done ivy-alt-done))
+ ;; Regexp pattern are passed verbatim, other input is
+ ;; split into words.
+ (if (string-equal (regexp-quote pattern) pattern)
+ (apropos (split-string pattern "[ \t]+" t))
+ (apropos pattern))
+ (apropos (concat "^" pattern "$"))))
+ :caller 'counsel-apropos))
+
+(defun counsel-symbol-list ()
+ "Return a list of all symbols."
+ (let (cands)
+ (mapatoms
+ (lambda (symbol)
+ (when (or (boundp symbol) (fboundp symbol))
+ (push (symbol-name symbol) cands))))
+ (delete "" cands)))
+
+;;** `counsel-mode'
+(defvar counsel-mode-map
+ (let ((map (make-sparse-keymap)))
+ (dolist (binding
+ '((execute-extended-command . counsel-M-x)
+ (describe-bindings . counsel-descbinds)
+ (describe-function . counsel-describe-function)
+ (describe-variable . counsel-describe-variable)
+ (describe-face . counsel-describe-face)
+ (find-file . counsel-find-file)
+ (find-library . counsel-find-library)
+ (imenu . counsel-imenu)
+ (load-library . counsel-load-library)
+ (load-theme . counsel-load-theme)
+ (yank-pop . counsel-yank-pop)
+ (info-lookup-symbol . counsel-info-lookup-symbol)
+ (pop-mark . counsel-mark-ring)))
+ (define-key map (vector 'remap (car binding)) (cdr binding)))
+ map)
+ "Map for `counsel-mode'.
+Remaps built-in functions to counsel replacements.")
+
+(defcustom counsel-mode-override-describe-bindings nil
+ "Whether to override `describe-bindings' when `counsel-mode' is active."
+ :group 'ivy
+ :type 'boolean)
+
+(defun counsel-list-buffers-with-mode (mode)
+ "List all buffers with `major-mode' MODE.
+
+MODE is a symbol."
+ (save-current-buffer
+ (let (bufs)
+ (dolist (buf (buffer-list))
+ (set-buffer buf)
+ (and (equal major-mode mode)
+ (push (buffer-name buf) bufs)))
+ (nreverse bufs))))
+
+;;;###autoload
+(defun counsel-switch-to-shell-buffer ()
+ "Switch to a shell buffer, or create one."
+ (interactive)
+ (ivy-read "Switch to shell buffer: "
+ (counsel-list-buffers-with-mode 'shell-mode)
+ :action #'counsel-switch-to-buffer-or-window
+ :caller 'counsel-switch-to-shell-buffer))
+
+(defun counsel-switch-to-buffer-or-window (buffer-name)
+ "Display buffer BUFFER-NAME and select its window.
+
+This behaves as `switch-to-buffer', except when the buffer is
+already visible; in that case, select the window corresponding to
+the buffer."
+ (let ((buffer (get-buffer buffer-name)))
+ (if (not buffer)
+ (shell buffer-name)
+ (let (window-of-buffer-visible)
+ (catch 'found
+ (walk-windows (lambda (window)
+ (and (equal (window-buffer window) buffer)
+ (throw 'found (setq window-of-buffer-visible window))))))
+ (if window-of-buffer-visible
+ (select-window window-of-buffer-visible)
+ (switch-to-buffer buffer))))))
+
+;;;###autoload
+(define-minor-mode counsel-mode
+ "Toggle Counsel mode on or off.
+Turn Counsel mode on if ARG is positive, off otherwise. Counsel
+mode remaps built-in emacs functions that have counsel
+replacements. "
+ :group 'ivy
+ :global t
+ :keymap counsel-mode-map
+ :lighter " counsel"
+ (if counsel-mode
+ (progn
+ (when (and (fboundp 'advice-add)
+ counsel-mode-override-describe-bindings)
+ (advice-add #'describe-bindings :override #'counsel-descbinds))
+ (define-key minibuffer-local-shell-command-map (kbd "C-r")
+ 'counsel-shell-command-history)
+ (define-key read-expression-map (kbd "C-r")
+ 'counsel-expression-history))
+ (when (fboundp 'advice-remove)
+ (advice-remove #'describe-bindings #'counsel-descbinds))))
+
+(provide 'counsel)
+
+;;; counsel.el ends here
.emacs.d/elpa/counsel-20170911.1121/counsel.elc
Binary file
.emacs.d/elpa/hydra-20170903.218/hydra-autoloads.el
@@ -0,0 +1,77 @@
+;;; hydra-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "hydra" "hydra.el" (22977 29290 679943 777000))
+;;; Generated autoloads from hydra.el
+
+(autoload 'defhydra "hydra" "\
+Create a Hydra - a family of functions with prefix NAME.
+
+NAME should be a symbol, it will be the prefix of all functions
+defined here.
+
+BODY has the format:
+
+ (BODY-MAP BODY-KEY &rest BODY-PLIST)
+
+DOCSTRING will be displayed in the echo area to identify the
+Hydra. When DOCSTRING starts with a newline, special Ruby-style
+substitution will be performed by `hydra--format'.
+
+Functions are created on basis of HEADS, each of which has the
+format:
+
+ (KEY CMD &optional HINT &rest PLIST)
+
+BODY-MAP is a keymap; `global-map' is used quite often. Each
+function generated from HEADS will be bound in BODY-MAP to
+BODY-KEY + KEY (both are strings passed to `kbd'), and will set
+the transient map so that all following heads can be called
+though KEY only. BODY-KEY can be an empty string.
+
+CMD is a callable expression: either an interactive function
+name, or an interactive lambda, or a single sexp (it will be
+wrapped in an interactive lambda).
+
+HINT is a short string that identifies its head. It will be
+printed beside KEY in the echo erea if `hydra-is-helpful' is not
+nil. If you don't even want the KEY to be printed, set HINT
+explicitly to nil.
+
+The heads inherit their PLIST from BODY-PLIST and are allowed to
+override some keys. The keys recognized are :exit and :bind.
+:exit can be:
+
+- nil (default): this head will continue the Hydra state.
+- t: this head will stop the Hydra state.
+
+:bind can be:
+- nil: this head will not be bound in BODY-MAP.
+- a lambda taking KEY and CMD used to bind a head.
+
+It is possible to omit both BODY-MAP and BODY-KEY if you don't
+want to bind anything. In that case, typically you will bind the
+generated NAME/body command. This command is also the return
+result of `defhydra'.
+
+\(fn NAME BODY &optional DOCSTRING &rest HEADS)" nil t)
+
+(function-put 'defhydra 'lisp-indent-function 'defun)
+
+(function-put 'defhydra 'doc-string-elt '3)
+
+;;;***
+
+;;;### (autoloads nil nil ("hydra-examples.el" "hydra-ox.el" "hydra-pkg.el"
+;;;;;; "lv.el") (22977 29290 682943 747000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; hydra-autoloads.el ends here
.emacs.d/elpa/hydra-20170903.218/hydra-examples.el
@@ -0,0 +1,386 @@
+;;; hydra-examples.el --- Some applications for Hydra
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; These are the sample Hydras.
+;;
+;; If you want to use them plainly, set `hydra-examples-verbatim' to t
+;; before requiring this file. But it's probably better to only look
+;; at them and use them as templates for building your own.
+
+;;; Code:
+
+(require 'hydra)
+
+;;* Examples
+;;** Example 1: text scale
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-zoom (global-map "<f2>")
+ "zoom"
+ ("g" text-scale-increase "in")
+ ("l" text-scale-decrease "out")))
+
+;; This example generates three commands:
+;;
+;; `hydra-zoom/text-scale-increase'
+;; `hydra-zoom/text-scale-decrease'
+;; `hydra-zoom/body'
+;;
+;; In addition, two of them are bound like this:
+;;
+;; (global-set-key (kbd "<f2> g") 'hydra-zoom/text-scale-increase)
+;; (global-set-key (kbd "<f2> l") 'hydra-zoom/text-scale-decrease)
+;;
+;; Note that you can substitute `global-map' with e.g. `emacs-lisp-mode-map' if you need.
+;; The functions generated will be the same, except the binding code will change to:
+;;
+;; (define-key emacs-lisp-mode-map [f2 103]
+;; (function hydra-zoom/text-scale-increase))
+;; (define-key emacs-lisp-mode-map [f2 108]
+;; (function hydra-zoom/text-scale-decrease))
+
+;;** Example 2: move window splitter
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-splitter (global-map "C-M-s")
+ "splitter"
+ ("h" hydra-move-splitter-left)
+ ("j" hydra-move-splitter-down)
+ ("k" hydra-move-splitter-up)
+ ("l" hydra-move-splitter-right)))
+
+;;** Example 3: jump to error
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-error (global-map "M-g")
+ "goto-error"
+ ("h" first-error "first")
+ ("j" next-error "next")
+ ("k" previous-error "prev")
+ ("v" recenter-top-bottom "recenter")
+ ("q" nil "quit")))
+
+;; This example introduces only one new thing: since the command
+;; passed to the "q" head is nil, it will quit the Hydra without doing
+;; anything. Heads that quit the Hydra instead of continuing are
+;; referred to as having blue :color. All the other heads have red
+;; :color, unless other is specified.
+
+;;** Example 4: toggle rarely used modes
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defvar whitespace-mode nil)
+ (global-set-key
+ (kbd "C-c C-v")
+ (defhydra hydra-toggle-simple (:color blue)
+ "toggle"
+ ("a" abbrev-mode "abbrev")
+ ("d" toggle-debug-on-error "debug")
+ ("f" auto-fill-mode "fill")
+ ("t" toggle-truncate-lines "truncate")
+ ("w" whitespace-mode "whitespace")
+ ("q" nil "cancel"))))
+
+;; Note that in this case, `defhydra' returns the `hydra-toggle-simple/body'
+;; symbol, which is then passed to `global-set-key'.
+;;
+;; Another new thing is that both the keymap and the body prefix are
+;; skipped. This means that `defhydra' will bind nothing - that's why
+;; `global-set-key' is necessary.
+;;
+;; One more new thing is that you can assign a :color to the body. All
+;; heads will inherit this color. The code above is very much equivalent to:
+;;
+;; (global-set-key (kbd "C-c C-v a") 'abbrev-mode)
+;; (global-set-key (kbd "C-c C-v d") 'toggle-debug-on-error)
+;;
+;; The differences are:
+;;
+;; * You get a hint immediately after "C-c C-v"
+;; * You can cancel and call a command immediately, e.g. "C-c C-v C-n"
+;; is equivalent to "C-n" with Hydra approach, while it will error
+;; that "C-c C-v C-n" isn't bound with the usual approach.
+
+;;** Example 5: mini-vi
+(defun hydra-vi/pre ()
+ (set-cursor-color "#e52b50"))
+
+(defun hydra-vi/post ()
+ (set-cursor-color "#ffffff"))
+
+(when (bound-and-true-p hydra-examples-verbatim)
+ (global-set-key
+ (kbd "C-z")
+ (defhydra hydra-vi (:pre hydra-vi/pre :post hydra-vi/post :color amaranth)
+ "vi"
+ ("l" forward-char)
+ ("h" backward-char)
+ ("j" next-line)
+ ("k" previous-line)
+ ("m" set-mark-command "mark")
+ ("a" move-beginning-of-line "beg")
+ ("e" move-end-of-line "end")
+ ("d" delete-region "del" :color blue)
+ ("y" kill-ring-save "yank" :color blue)
+ ("q" nil "quit")))
+ (hydra-set-property 'hydra-vi :verbosity 1))
+
+;; This example introduces :color amaranth. It's similar to red,
+;; except while you can quit red with any binding which isn't a Hydra
+;; head, you can quit amaranth only with a blue head. So you can quit
+;; this mode only with "d", "y", "q" or "C-g".
+;;
+;; Another novelty are the :pre and :post handlers. :pre will be
+;; called before each command, while :post will be called when the
+;; Hydra quits. In this case, they're used to override the cursor
+;; color while Hydra is active.
+
+;;** Example 6: selective global bind
+(when (bound-and-true-p hydra-examples-verbatim)
+ (defhydra hydra-next-error (global-map "C-x")
+ "next-error"
+ ("`" next-error "next")
+ ("j" next-error "next" :bind nil)
+ ("k" previous-error "previous" :bind nil)))
+
+;; This example will bind "C-x `" in `global-map', but it will not
+;; bind "C-x j" and "C-x k".
+;; You can still "C-x `jjk" though.
+
+;;** Example 7: toggle with Ruby-style docstring
+(defvar whitespace-mode nil)
+(defhydra hydra-toggle (:color pink)
+ "
+_a_ abbrev-mode: %`abbrev-mode
+_d_ debug-on-error: %`debug-on-error
+_f_ auto-fill-mode: %`auto-fill-function
+_t_ truncate-lines: %`truncate-lines
+_w_ whitespace-mode: %`whitespace-mode
+
+"
+ ("a" abbrev-mode nil)
+ ("d" toggle-debug-on-error nil)
+ ("f" auto-fill-mode nil)
+ ("t" toggle-truncate-lines nil)
+ ("w" whitespace-mode nil)
+ ("q" nil "quit"))
+;; Recommended binding:
+;; (global-set-key (kbd "C-c C-v") 'hydra-toggle/body)
+
+;; Here, using e.g. "_a_" translates to "a" with proper face.
+;; More interestingly:
+;;
+;; "foobar %`abbrev-mode" means roughly (format "foobar %S" abbrev-mode)
+;;
+;; This means that you actually see the state of the mode that you're changing.
+
+;;** Example 8: the whole menu for `Buffer-menu-mode'
+(defhydra hydra-buffer-menu (:color pink
+ :hint nil)
+ "
+^Mark^ ^Unmark^ ^Actions^ ^Search
+^^^^^^^^----------------------------------------------------------------- (__)
+_m_: mark _u_: unmark _x_: execute _R_: re-isearch (oo)
+_s_: save _U_: unmark up _b_: bury _I_: isearch /------\\/
+_d_: delete ^ ^ _g_: refresh _O_: multi-occur / | ||
+_D_: delete up ^ ^ _T_: files only: % -28`Buffer-menu-files-only^^ * /\\---/\\
+_~_: modified ^ ^ ^ ^ ^^ ~~ ~~
+"
+ ("m" Buffer-menu-mark)
+ ("u" Buffer-menu-unmark)
+ ("U" Buffer-menu-backup-unmark)
+ ("d" Buffer-menu-delete)
+ ("D" Buffer-menu-delete-backwards)
+ ("s" Buffer-menu-save)
+ ("~" Buffer-menu-not-modified)
+ ("x" Buffer-menu-execute)
+ ("b" Buffer-menu-bury)
+ ("g" revert-buffer)
+ ("T" Buffer-menu-toggle-files-only)
+ ("O" Buffer-menu-multi-occur :color blue)
+ ("I" Buffer-menu-isearch-buffers :color blue)
+ ("R" Buffer-menu-isearch-buffers-regexp :color blue)
+ ("c" nil "cancel")
+ ("v" Buffer-menu-select "select" :color blue)
+ ("o" Buffer-menu-other-window "other-window" :color blue)
+ ("q" quit-window "quit" :color blue))
+;; Recommended binding:
+;; (define-key Buffer-menu-mode-map "." 'hydra-buffer-menu/body)
+
+;;** Example 9: s-expressions in the docstring
+;; You can inline s-expresssions into the docstring like this:
+(defvar dired-mode-map)
+(declare-function dired-mark "dired")
+(when (bound-and-true-p hydra-examples-verbatim)
+ (require 'dired)
+ (defhydra hydra-marked-items (dired-mode-map "")
+ "
+Number of marked items: %(length (dired-get-marked-files))
+"
+ ("m" dired-mark "mark")))
+
+;; This results in the following dynamic docstring:
+;;
+;; (format "Number of marked items: %S\n"
+;; (length (dired-get-marked-files)))
+;;
+;; You can use `format'-style width specs, e.g. % 10(length nil).
+
+;;** Example 10: apropos family
+(defhydra hydra-apropos (:color blue
+ :hint nil)
+ "
+_a_propos _c_ommand
+_d_ocumentation _l_ibrary
+_v_ariable _u_ser-option
+^ ^ valu_e_"
+ ("a" apropos)
+ ("d" apropos-documentation)
+ ("v" apropos-variable)
+ ("c" apropos-command)
+ ("l" apropos-library)
+ ("u" apropos-user-option)
+ ("e" apropos-value))
+;; Recommended binding:
+;; (global-set-key (kbd "C-c h") 'hydra-apropos/body)
+
+;;** Example 11: rectangle-mark-mode
+(require 'rect)
+(defhydra hydra-rectangle (:body-pre (rectangle-mark-mode 1)
+ :color pink
+ :post (deactivate-mark))
+ "
+ ^_k_^ _d_elete _s_tring
+_h_ _l_ _o_k _y_ank
+ ^_j_^ _n_ew-copy _r_eset
+^^^^ _e_xchange _u_ndo
+^^^^ ^ ^ _p_aste
+"
+ ("h" rectangle-backward-char nil)
+ ("l" rectangle-forward-char nil)
+ ("k" rectangle-previous-line nil)
+ ("j" rectangle-next-line nil)
+ ("e" hydra-ex-point-mark nil)
+ ("n" copy-rectangle-as-kill nil)
+ ("d" delete-rectangle nil)
+ ("r" (if (region-active-p)
+ (deactivate-mark)
+ (rectangle-mark-mode 1)) nil)
+ ("y" yank-rectangle nil)
+ ("u" undo nil)
+ ("s" string-rectangle nil)
+ ("p" kill-rectangle nil)
+ ("o" nil nil))
+
+;; Recommended binding:
+;; (global-set-key (kbd "C-x SPC") 'hydra-rectangle/body)
+
+;;** Example 12: org-agenda-view
+(defun org-agenda-cts ()
+ (and (eq major-mode 'org-agenda-mode)
+ (let ((args (get-text-property
+ (min (1- (point-max)) (point))
+ 'org-last-args)))
+ (nth 2 args))))
+
+(defhydra hydra-org-agenda-view (:hint none)
+ "
+_d_: ?d? day _g_: time grid=?g? _a_: arch-trees
+_w_: ?w? week _[_: inactive _A_: arch-files
+_t_: ?t? fortnight _f_: follow=?f? _r_: clock report=?r?
+_m_: ?m? month _e_: entry text=?e? _D_: include diary=?D?
+_y_: ?y? year _q_: quit _L__l__c_: log = ?l?"
+ ("SPC" org-agenda-reset-view)
+ ("d" org-agenda-day-view (if (eq 'day (org-agenda-cts)) "[x]" "[ ]"))
+ ("w" org-agenda-week-view (if (eq 'week (org-agenda-cts)) "[x]" "[ ]"))
+ ("t" org-agenda-fortnight-view (if (eq 'fortnight (org-agenda-cts)) "[x]" "[ ]"))
+ ("m" org-agenda-month-view (if (eq 'month (org-agenda-cts)) "[x]" "[ ]"))
+ ("y" org-agenda-year-view (if (eq 'year (org-agenda-cts)) "[x]" "[ ]"))
+ ("l" org-agenda-log-mode (format "% -3S" org-agenda-show-log))
+ ("L" (org-agenda-log-mode '(4)))
+ ("c" (org-agenda-log-mode 'clockcheck))
+ ("f" org-agenda-follow-mode (format "% -3S" org-agenda-follow-mode))
+ ("a" org-agenda-archives-mode)
+ ("A" (org-agenda-archives-mode 'files))
+ ("r" org-agenda-clockreport-mode (format "% -3S" org-agenda-clockreport-mode))
+ ("e" org-agenda-entry-text-mode (format "% -3S" org-agenda-entry-text-mode))
+ ("g" org-agenda-toggle-time-grid (format "% -3S" org-agenda-use-time-grid))
+ ("D" org-agenda-toggle-diary (format "% -3S" org-agenda-include-diary))
+ ("!" org-agenda-toggle-deadlines)
+ ("[" (let ((org-agenda-include-inactive-timestamps t))
+ (org-agenda-check-type t 'timeline 'agenda)
+ (org-agenda-redo)
+ (message "Display now includes inactive timestamps as well")))
+ ("q" (message "Abort") :exit t)
+ ("v" nil))
+
+;; Recommended binding:
+;; (define-key org-agenda-mode-map "v" 'hydra-org-agenda-view/body)
+
+;;* Helpers
+(require 'windmove)
+
+(defun hydra-move-splitter-left (arg)
+ "Move window splitter left."
+ (interactive "p")
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'right))
+ (shrink-window-horizontally arg)
+ (enlarge-window-horizontally arg)))
+
+(defun hydra-move-splitter-right (arg)
+ "Move window splitter right."
+ (interactive "p")
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'right))
+ (enlarge-window-horizontally arg)
+ (shrink-window-horizontally arg)))
+
+(defun hydra-move-splitter-up (arg)
+ "Move window splitter up."
+ (interactive "p")
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'up))
+ (enlarge-window arg)
+ (shrink-window arg)))
+
+(defun hydra-move-splitter-down (arg)
+ "Move window splitter down."
+ (interactive "p")
+ (if (let ((windmove-wrap-around))
+ (windmove-find-other-window 'up))
+ (shrink-window arg)
+ (enlarge-window arg)))
+
+(defvar rectangle-mark-mode)
+(defun hydra-ex-point-mark ()
+ "Exchange point and mark."
+ (interactive)
+ (if rectangle-mark-mode
+ (rectangle-exchange-point-and-mark)
+ (let ((mk (mark)))
+ (rectangle-mark-mode 1)
+ (goto-char mk))))
+
+(provide 'hydra-examples)
+
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
+;;; hydra-examples.el ends here
.emacs.d/elpa/hydra-20170903.218/hydra-ox.el
@@ -0,0 +1,127 @@
+;;; hydra-ox.el --- Org mode export widget implemented in Hydra
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This shows how a complex dispatch menu can be built with Hydra.
+
+;;; Code:
+
+(require 'hydra)
+(require 'org)
+(declare-function org-html-export-as-html 'ox-html)
+(declare-function org-html-export-to-html 'ox-html)
+(declare-function org-latex-export-as-latex 'ox-latex)
+(declare-function org-latex-export-to-latex 'ox-latex)
+(declare-function org-latex-export-to-pdf 'ox-latex)
+(declare-function org-ascii-export-as-ascii 'ox-ascii)
+(declare-function org-ascii-export-to-ascii 'ox-ascii)
+
+(defhydradio hydra-ox ()
+ (body-only "Export only the body.")
+ (export-scope "Export scope." [buffer subtree])
+ (async-export "When non-nil, export async.")
+ (visible-only "When non-nil, export visible only")
+ (force-publishing "Toggle force publishing"))
+
+(defhydra hydra-ox-html (:color blue)
+ "ox-html"
+ ("H" (org-html-export-as-html
+ hydra-ox/async-export
+ (eq hydra-ox/export-scope 'subtree)
+ hydra-ox/visible-only
+ hydra-ox/body-only)
+ "As HTML buffer")
+ ("h" (org-html-export-to-html
+ hydra-ox/async-export
+ (eq hydra-ox/export-scope 'subtree)
+ hydra-ox/visible-only
+ hydra-ox/body-only) "As HTML file")
+ ("o" (org-open-file
+ (org-html-export-to-html
+ hydra-ox/async-export
+ (eq hydra-ox/export-scope 'subtree)
+ hydra-ox/visible-only
+ hydra-ox/body-only)) "As HTML file and open")
+ ("b" hydra-ox/body "back")
+ ("q" nil "quit"))
+
+(defhydra hydra-ox-latex (:color blue)
+ "ox-latex"
+ ("L" org-latex-export-as-latex "As LaTeX buffer")
+ ("l" org-latex-export-to-latex "As LaTeX file")
+ ("p" org-latex-export-to-pdf "As PDF file")
+ ("o" (org-open-file (org-latex-export-to-pdf)) "As PDF file and open")
+ ("b" hydra-ox/body "back")
+ ("q" nil "quit"))
+
+(defhydra hydra-ox-text (:color blue)
+ "ox-text"
+ ("A" (org-ascii-export-as-ascii
+ nil nil nil nil
+ '(:ascii-charset ascii))
+ "As ASCII buffer")
+
+ ("a" (org-ascii-export-to-ascii
+ nil nil nil nil
+ '(:ascii-charset ascii))
+ "As ASCII file")
+ ("L" (org-ascii-export-as-ascii
+ nil nil nil nil
+ '(:ascii-charset latin1))
+ "As Latin1 buffer")
+ ("l" (org-ascii-export-to-ascii
+ nil nil nil nil
+ '(:ascii-charset latin1))
+ "As Latin1 file")
+ ("U" (org-ascii-export-as-ascii
+ nil nil nil nil
+ '(:ascii-charset utf-8))
+ "As UTF-8 buffer")
+ ("u" (org-ascii-export-to-ascii
+ nil nil nil nil
+ '(:ascii-charset utf-8))
+ "As UTF-8 file")
+ ("b" hydra-ox/body "back")
+ ("q" nil "quit"))
+
+(defhydra hydra-ox ()
+ "
+_C-b_ Body only: % -15`hydra-ox/body-only^^^ _C-v_ Visible only: %`hydra-ox/visible-only
+_C-s_ Export scope: % -15`hydra-ox/export-scope _C-f_ Force publishing: %`hydra-ox/force-publishing
+_C-a_ Async export: %`hydra-ox/async-export
+
+"
+ ("C-b" (hydra-ox/body-only) nil)
+ ("C-v" (hydra-ox/visible-only) nil)
+ ("C-s" (hydra-ox/export-scope) nil)
+ ("C-f" (hydra-ox/force-publishing) nil)
+ ("C-a" (hydra-ox/async-export) nil)
+ ("h" hydra-ox-html/body "Export to HTML" :exit t)
+ ("l" hydra-ox-latex/body "Export to LaTeX" :exit t)
+ ("t" hydra-ox-text/body "Export to Plain Text" :exit t)
+ ("q" nil "quit"))
+
+(define-key org-mode-map (kbd "C-c C-,") 'hydra-ox/body)
+
+(provide 'hydra-ox)
+
+;;; hydra-ox.el ends here
.emacs.d/elpa/hydra-20170903.218/hydra-ox.elc
Binary file
.emacs.d/elpa/hydra-20170903.218/hydra-pkg.el
@@ -0,0 +1,7 @@
+(define-package "hydra" "20170903.218" "Make bindings that stick around."
+ '((cl-lib "0.5"))
+ :url "https://github.com/abo-abo/hydra" :keywords
+ '("bindings"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
.emacs.d/elpa/hydra-20170903.218/hydra.el
@@ -0,0 +1,1404 @@
+;;; hydra.el --- Make bindings that stick around. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; Maintainer: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/hydra
+;; Version: 0.14.0
+;; Keywords: bindings
+;; Package-Requires: ((cl-lib "0.5"))
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package can be used to tie related commands into a family of
+;; short bindings with a common prefix - a Hydra.
+;;
+;; Once you summon the Hydra (through the prefixed binding), all the
+;; heads can be called in succession with only a short extension.
+;; The Hydra is vanquished once Hercules, any binding that isn't the
+;; Hydra's head, arrives. Note that Hercules, besides vanquishing the
+;; Hydra, will still serve his orignal purpose, calling his proper
+;; command. This makes the Hydra very seamless, it's like a minor
+;; mode that disables itself automagically.
+;;
+;; Here's an example Hydra, bound in the global map (you can use any
+;; keymap in place of `global-map'):
+;;
+;; (defhydra hydra-zoom (global-map "<f2>")
+;; "zoom"
+;; ("g" text-scale-increase "in")
+;; ("l" text-scale-decrease "out"))
+;;
+;; It allows to start a command chain either like this:
+;; "<f2> gg4ll5g", or "<f2> lgllg".
+;;
+;; Here's another approach, when you just want a "callable keymap":
+;;
+;; (defhydra hydra-toggle (:color blue)
+;; "toggle"
+;; ("a" abbrev-mode "abbrev")
+;; ("d" toggle-debug-on-error "debug")
+;; ("f" auto-fill-mode "fill")
+;; ("t" toggle-truncate-lines "truncate")
+;; ("w" whitespace-mode "whitespace")
+;; ("q" nil "cancel"))
+;;
+;; This binds nothing so far, but if you follow up with:
+;;
+;; (global-set-key (kbd "C-c C-v") 'hydra-toggle/body)
+;;
+;; you will have bound "C-c C-v a", "C-c C-v d" etc.
+;;
+;; Knowing that `defhydra' defines e.g. `hydra-toggle/body' command,
+;; you can nest Hydras if you wish, with `hydra-toggle/body' possibly
+;; becoming a blue head of another Hydra.
+;;
+;; If you want to learn all intricacies of using `defhydra' without
+;; having to figure it all out from this source code, check out the
+;; wiki: https://github.com/abo-abo/hydra/wiki. There's a wealth of
+;; information there. Everyone is welcome to bring the existing pages
+;; up to date and add new ones.
+;;
+;; Additionally, the file hydra-examples.el serves to demo most of the
+;; functionality.
+
+;;; Code:
+;;* Requires
+(require 'cl-lib)
+(require 'lv)
+(require 'ring)
+
+(defvar hydra-curr-map nil
+ "The keymap of the current Hydra called.")
+
+(defvar hydra-curr-on-exit nil
+ "The on-exit predicate for the current Hydra.")
+
+(defvar hydra-curr-foreign-keys nil
+ "The current :foreign-keys behavior.")
+
+(defvar hydra-curr-body-fn nil
+ "The current hydra-.../body function.")
+
+(defvar hydra-deactivate nil
+ "If a Hydra head sets this to t, exit the Hydra.
+This will be done even if the head wasn't designated for exiting.")
+
+(defvar hydra-amaranth-warn-message "An amaranth Hydra can only exit through a blue head"
+ "Amaranth Warning message. Shown when the user tries to press an unbound/non-exit key while in an amaranth head.")
+
+(defun hydra-set-transient-map (keymap on-exit &optional foreign-keys)
+ "Set KEYMAP to the highest priority.
+
+Call ON-EXIT when the KEYMAP is deactivated.
+
+FOREIGN-KEYS determines the deactivation behavior, when a command
+that isn't in KEYMAP is called:
+
+nil: deactivate KEYMAP and run the command.
+run: keep KEYMAP and run the command.
+warn: keep KEYMAP and issue a warning instead of running the command."
+ (if hydra-deactivate
+ (hydra-keyboard-quit)
+ (setq hydra-curr-map keymap)
+ (setq hydra-curr-on-exit on-exit)
+ (setq hydra-curr-foreign-keys foreign-keys)
+ (add-hook 'pre-command-hook 'hydra--clearfun)
+ (internal-push-keymap keymap 'overriding-terminal-local-map)))
+
+(defun hydra--clearfun ()
+ "Disable the current Hydra unless `this-command' is a head."
+ (unless (eq this-command 'hydra-pause-resume)
+ (when (or
+ (memq this-command '(handle-switch-frame
+ keyboard-quit))
+ (null overriding-terminal-local-map)
+ (not (or (eq this-command
+ (lookup-key hydra-curr-map (this-single-command-keys)))
+ (cl-case hydra-curr-foreign-keys
+ (warn
+ (setq this-command 'hydra-amaranth-warn))
+ (run
+ t)
+ (t nil)))))
+ (hydra-disable))))
+
+(defvar hydra--ignore nil
+ "When non-nil, don't call `hydra-curr-on-exit'.")
+
+(defvar hydra--input-method-function nil
+ "Store overridden `input-method-function' here.")
+
+(defun hydra-disable ()
+ "Disable the current Hydra."
+ (setq hydra-deactivate nil)
+ (remove-hook 'pre-command-hook 'hydra--clearfun)
+ (unless hydra--ignore
+ (if (fboundp 'remove-function)
+ (remove-function input-method-function #'hydra--imf)
+ (when hydra--input-method-function
+ (setq input-method-function hydra--input-method-function)
+ (setq hydra--input-method-function nil))))
+ (dolist (frame (frame-list))
+ (with-selected-frame frame
+ (when overriding-terminal-local-map
+ (internal-pop-keymap hydra-curr-map 'overriding-terminal-local-map))))
+ (unless hydra--ignore
+ (when hydra-curr-on-exit
+ (let ((on-exit hydra-curr-on-exit))
+ (setq hydra-curr-on-exit nil)
+ (funcall on-exit)))))
+
+(unless (fboundp 'internal-push-keymap)
+ (defun internal-push-keymap (keymap symbol)
+ (let ((map (symbol-value symbol)))
+ (unless (memq keymap map)
+ (unless (memq 'add-keymap-witness (symbol-value symbol))
+ (setq map (make-composed-keymap nil (symbol-value symbol)))
+ (push 'add-keymap-witness (cdr map))
+ (set symbol map))
+ (push keymap (cdr map))))))
+
+(unless (fboundp 'internal-pop-keymap)
+ (defun internal-pop-keymap (keymap symbol)
+ (let ((map (symbol-value symbol)))
+ (when (memq keymap map)
+ (setf (cdr map) (delq keymap (cdr map))))
+ (let ((tail (cddr map)))
+ (and (or (null tail) (keymapp tail))
+ (eq 'add-keymap-witness (nth 1 map))
+ (set symbol tail))))))
+
+(defun hydra-amaranth-warn ()
+ "Issue a warning that the current input was ignored."
+ (interactive)
+ (message hydra-amaranth-warn-message))
+
+;;* Customize
+(defgroup hydra nil
+ "Make bindings that stick around."
+ :group 'bindings
+ :prefix "hydra-")
+
+(defcustom hydra-is-helpful t
+ "When t, display a hint with possible bindings in the echo area."
+ :type 'boolean
+ :group 'hydra)
+
+(defcustom hydra-default-hint ""
+ "Default :hint property to use for heads when not specified in
+the body or the head."
+ :type 'sexp
+ :group 'hydra)
+
+(defcustom hydra-lv t
+ "When non-nil, `lv-message' (not `message') will be used to display hints."
+ :type 'boolean)
+
+(defcustom hydra-verbose nil
+ "When non-nil, hydra will issue some non essential style warnings."
+ :type 'boolean)
+
+(defcustom hydra-key-format-spec "%s"
+ "Default `format'-style specifier for _a_ syntax in docstrings.
+When nil, you can specify your own at each location like this: _ 5a_."
+ :type 'string)
+
+(defcustom hydra-doc-format-spec "%s"
+ "Default `format'-style specifier for ?a? syntax in docstrings."
+ :type 'string)
+
+(defcustom hydra-look-for-remap nil
+ "When non-nil, hydra binding behaves as keymap binding with [remap].
+When calling a head with a simple command, hydra will lookup for a potential
+remap command according to the current active keymap and call it instead if
+found"
+ :type 'boolean)
+
+(make-obsolete-variable
+ 'hydra-key-format-spec
+ "Since the docstrings are aligned by hand anyway, this isn't very useful."
+ "0.13.1")
+
+(defface hydra-face-red
+ '((t (:foreground "#FF0000" :bold t)))
+ "Red Hydra heads don't exit the Hydra.
+Every other command exits the Hydra."
+ :group 'hydra)
+
+(defface hydra-face-blue
+ '((((class color) (background light))
+ :foreground "#0000FF" :bold t)
+ (((class color) (background dark))
+ :foreground "#8ac6f2" :bold t))
+ "Blue Hydra heads exit the Hydra.
+Every other command exits as well.")
+
+(defface hydra-face-amaranth
+ '((t (:foreground "#E52B50" :bold t)))
+ "Amaranth body has red heads and warns on intercepting non-heads.
+Exitable only through a blue head.")
+
+(defface hydra-face-pink
+ '((t (:foreground "#FF6EB4" :bold t)))
+ "Pink body has red heads and runs intercepted non-heads.
+Exitable only through a blue head.")
+
+(defface hydra-face-teal
+ '((t (:foreground "#367588" :bold t)))
+ "Teal body has blue heads and warns on intercepting non-heads.
+Exitable only through a blue head.")
+
+;;* Fontification
+(defun hydra-add-font-lock ()
+ "Fontify `defhydra' statements."
+ (font-lock-add-keywords
+ 'emacs-lisp-mode
+ '(("(\\(defhydra\\)\\_> +\\(.*?\\)\\_>"
+ (1 font-lock-keyword-face)
+ (2 font-lock-type-face))
+ ("(\\(defhydradio\\)\\_> +\\(.*?\\)\\_>"
+ (1 font-lock-keyword-face)
+ (2 font-lock-type-face)))))
+
+;;* Find Function
+(eval-after-load 'find-func
+ '(defadvice find-function-search-for-symbol
+ (around hydra-around-find-function-search-for-symbol-advice
+ (symbol type library) activate)
+ "Navigate to hydras with `find-function-search-for-symbol'."
+ ad-do-it
+ ;; The orignial function returns (cons (current-buffer) (point))
+ ;; if it found the point.
+ (unless (cdr ad-return-value)
+ (with-current-buffer (find-file-noselect library)
+ (let ((sn (symbol-name symbol)))
+ (when (and (null type)
+ (string-match "\\`\\(hydra-[a-z-A-Z0-9]+\\)/\\(.*\\)\\'" sn)
+ (re-search-forward (concat "(defhydra " (match-string 1 sn))
+ nil t))
+ (goto-char (match-beginning 0)))
+ (cons (current-buffer) (point)))))))
+
+;;* Universal Argument
+(defvar hydra-base-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [?\C-u] 'hydra--universal-argument)
+ (define-key map [?-] 'hydra--negative-argument)
+ (define-key map [?0] 'hydra--digit-argument)
+ (define-key map [?1] 'hydra--digit-argument)
+ (define-key map [?2] 'hydra--digit-argument)
+ (define-key map [?3] 'hydra--digit-argument)
+ (define-key map [?4] 'hydra--digit-argument)
+ (define-key map [?5] 'hydra--digit-argument)
+ (define-key map [?6] 'hydra--digit-argument)
+ (define-key map [?7] 'hydra--digit-argument)
+ (define-key map [?8] 'hydra--digit-argument)
+ (define-key map [?9] 'hydra--digit-argument)
+ (define-key map [kp-0] 'hydra--digit-argument)
+ (define-key map [kp-1] 'hydra--digit-argument)
+ (define-key map [kp-2] 'hydra--digit-argument)
+ (define-key map [kp-3] 'hydra--digit-argument)
+ (define-key map [kp-4] 'hydra--digit-argument)
+ (define-key map [kp-5] 'hydra--digit-argument)
+ (define-key map [kp-6] 'hydra--digit-argument)
+ (define-key map [kp-7] 'hydra--digit-argument)
+ (define-key map [kp-8] 'hydra--digit-argument)
+ (define-key map [kp-9] 'hydra--digit-argument)
+ (define-key map [kp-subtract] 'hydra--negative-argument)
+ map)
+ "Keymap that all Hydras inherit. See `universal-argument-map'.")
+
+(defun hydra--universal-argument (arg)
+ "Forward to (`universal-argument' ARG)."
+ (interactive "P")
+ (setq prefix-arg (if (consp arg)
+ (list (* 4 (car arg)))
+ (if (eq arg '-)
+ (list -4)
+ '(4)))))
+
+(defun hydra--digit-argument (arg)
+ "Forward to (`digit-argument' ARG)."
+ (interactive "P")
+ (let* ((char (if (integerp last-command-event)
+ last-command-event
+ (get last-command-event 'ascii-character)))
+ (digit (- (logand char ?\177) ?0)))
+ (setq prefix-arg (cond ((integerp arg)
+ (+ (* arg 10)
+ (if (< arg 0)
+ (- digit)
+ digit)))
+ ((eq arg '-)
+ (if (zerop digit)
+ '-
+ (- digit)))
+ (t
+ digit)))))
+
+(defun hydra--negative-argument (arg)
+ "Forward to (`negative-argument' ARG)."
+ (interactive "P")
+ (setq prefix-arg (cond ((integerp arg) (- arg))
+ ((eq arg '-) nil)
+ (t '-))))
+
+;;* Repeat
+(defvar hydra-repeat--prefix-arg nil
+ "Prefix arg to use with `hydra-repeat'.")
+
+(defvar hydra-repeat--command nil
+ "Command to use with `hydra-repeat'.")
+
+(defun hydra-repeat (&optional arg)
+ "Repeat last command with last prefix arg.
+When ARG is non-nil, use that instead."
+ (interactive "p")
+ (if (eq arg 1)
+ (unless (string-match "hydra-repeat$" (symbol-name last-command))
+ (setq hydra-repeat--command last-command)
+ (setq hydra-repeat--prefix-arg last-prefix-arg))
+ (setq hydra-repeat--prefix-arg arg))
+ (setq current-prefix-arg hydra-repeat--prefix-arg)
+ (funcall hydra-repeat--command))
+
+;;* Misc internals
+(defun hydra--callablep (x)
+ "Test if X is callable."
+ (or (functionp x)
+ (and (consp x)
+ (memq (car x) '(function quote)))))
+
+(defun hydra--make-callable (x)
+ "Generate a callable symbol from X.
+If X is a function symbol or a lambda, return it. Otherwise, it
+should be a single statement. Wrap it in an interactive lambda."
+ (cond ((or (symbolp x) (functionp x))
+ x)
+ ((and (consp x) (eq (car x) 'function))
+ (cadr x))
+ (t
+ `(lambda ()
+ (interactive)
+ ,x))))
+
+(defun hydra-plist-get-default (plist prop default)
+ "Extract a value from a property list.
+PLIST is a property list, which is a list of the form
+\(PROP1 VALUE1 PROP2 VALUE2...).
+
+Return the value corresponding to PROP, or DEFAULT if PROP is not
+one of the properties on the list."
+ (if (memq prop plist)
+ (plist-get plist prop)
+ default))
+
+(defun hydra--head-property (h prop &optional default)
+ "Return for Hydra head H the value of property PROP.
+Return DEFAULT if PROP is not in H."
+ (hydra-plist-get-default (cl-cdddr h) prop default))
+
+(defun hydra--head-set-property (h prop value)
+ "In hydra Head H, set a property PROP to the value VALUE."
+ (cons (car h) (plist-put (cdr h) prop value)))
+
+(defun hydra--head-has-property (h prop)
+ "Return non nil if heads H has the property PROP."
+ (plist-member (cdr h) prop))
+
+(defun hydra--body-foreign-keys (body)
+ "Return what BODY does with a non-head binding."
+ (or
+ (plist-get (cddr body) :foreign-keys)
+ (let ((color (plist-get (cddr body) :color)))
+ (cl-case color
+ ((amaranth teal) 'warn)
+ (pink 'run)))))
+
+(defun hydra--body-exit (body)
+ "Return the exit behavior of BODY."
+ (or
+ (plist-get (cddr body) :exit)
+ (let ((color (plist-get (cddr body) :color)))
+ (cl-case color
+ ((blue teal) t)
+ (t nil)))))
+
+(defalias 'hydra--imf #'list)
+
+(defun hydra-default-pre ()
+ "Default setup that happens in each head before :pre."
+ (when (eq input-method-function 'key-chord-input-method)
+ (if (fboundp 'add-function)
+ (add-function :override input-method-function #'hydra--imf)
+ (unless hydra--input-method-function
+ (setq hydra--input-method-function input-method-function)
+ (setq input-method-function nil)))))
+
+(defvar hydra-timeout-timer (timer-create)
+ "Timer for `hydra-timeout'.")
+
+(defvar hydra-message-timer (timer-create)
+ "Timer for the hint.")
+
+(defvar hydra--work-around-dedicated t
+ "When non-nil, assume there's no bug in `pop-to-buffer'.
+`pop-to-buffer' should not select a dedicated window.")
+
+(defun hydra-keyboard-quit ()
+ "Quitting function similar to `keyboard-quit'."
+ (interactive)
+ (hydra-disable)
+ (cancel-timer hydra-timeout-timer)
+ (cancel-timer hydra-message-timer)
+ (setq hydra-curr-map nil)
+ (unless (and hydra--ignore
+ (null hydra--work-around-dedicated))
+ (if hydra-lv
+ (lv-delete-window)
+ (message "")))
+ nil)
+
+(defvar hydra-head-format "[%s]: "
+ "The formatter for each head of a plain docstring.")
+
+(defvar hydra-key-doc-function 'hydra-key-doc-function-default
+ "The function for formatting key-doc pairs.")
+
+(defun hydra-key-doc-function-default (key key-width doc doc-width)
+ "Doc"
+ (cond
+ ((equal key " ") (format (format "%%-%ds" (+ 3 key-width doc-width)) doc))
+ (t (format (format "%%%ds: %%%ds" key-width (- -1 doc-width)) key doc))))
+
+(defun hydra--to-string (x)
+ (if (stringp x)
+ x
+ (eval x)))
+
+(defun hydra--hint-heads-wocol (body heads)
+ "Generate a hint for the echo area.
+BODY, and HEADS are parameters to `defhydra'.
+Works for heads without a property :column."
+ (let (alist)
+ (dolist (h heads)
+ (let ((val (assoc (cadr h) alist))
+ (pstr (hydra-fontify-head h body)))
+ (unless (not (stringp (cl-caddr h)))
+ (if val
+ (setf (cadr val)
+ (concat (cadr val) " " pstr))
+ (push
+ (cons (cadr h)
+ (cons pstr (cl-caddr h)))
+ alist)))))
+ (let ((keys (nreverse (mapcar #'cdr alist)))
+ (n-cols (plist-get (cddr body) :columns))
+ res)
+ (setq res
+ (if n-cols
+ (let ((n-rows (1+ (/ (length keys) n-cols)))
+ (max-key-len (apply #'max (mapcar (lambda (x) (length (car x))) keys)))
+ (max-doc-len (apply #'max (mapcar (lambda (x)
+ (length (hydra--to-string (cdr x)))) keys))))
+ `(concat
+ "\n"
+ (mapconcat #'identity
+ (mapcar
+ (lambda (x)
+ (mapconcat
+ (lambda (y)
+ (and y
+ (funcall hydra-key-doc-function
+ (car y)
+ ,max-key-len
+ (hydra--to-string (cdr y))
+ ,max-doc-len))) x ""))
+ ',(hydra--matrix keys n-cols n-rows))
+ "\n")))
+
+
+ `(concat
+ (mapconcat
+ (lambda (x)
+ (let ((str (hydra--to-string (cdr x))))
+ (format
+ (if (> (length str) 0)
+ (concat hydra-head-format str)
+ "%s")
+ (car x))))
+ ',keys
+ ", ")
+ ,(if keys "." ""))))
+ (if (cl-every #'stringp
+ (mapcar 'cddr alist))
+ (eval res)
+ res))))
+
+(defun hydra--hint (body heads)
+ "Generate a hint for the echo area.
+BODY, and HEADS are parameters to `defhydra'."
+ (let* ((sorted-heads (hydra--sort-heads (hydra--normalize-heads heads)))
+ (heads-w-col (cl-remove-if-not (lambda (heads) (hydra--head-property (nth 0 heads) :column)) sorted-heads))
+ (heads-wo-col (cl-remove-if (lambda (heads) (hydra--head-property (nth 0 heads) :column)) sorted-heads)))
+ (concat (when heads-w-col
+ (concat "\n" (hydra--hint-from-matrix body (hydra--generate-matrix heads-w-col))))
+ (when heads-wo-col
+ (hydra--hint-heads-wocol body (car heads-wo-col))))))
+
+(defvar hydra-fontify-head-function nil
+ "Possible replacement for `hydra-fontify-head-default'.")
+
+(defun hydra-fontify-head-default (head body)
+ "Produce a pretty string from HEAD and BODY.
+HEAD's binding is returned as a string with a colored face."
+ (let* ((foreign-keys (hydra--body-foreign-keys body))
+ (head-exit (hydra--head-property head :exit))
+ (head-color
+ (if head-exit
+ (if (eq foreign-keys 'warn)
+ 'teal
+ 'blue)
+ (cl-case foreign-keys
+ (warn 'amaranth)
+ (run 'pink)
+ (t 'red)))))
+ (when (and (null (cadr head))
+ (not head-exit))
+ (hydra--complain "nil cmd can only be blue"))
+ (propertize
+ (replace-regexp-in-string "%" "%%" (car head))
+ 'face
+ (or (hydra--head-property head :face)
+ (cl-case head-color
+ (blue 'hydra-face-blue)
+ (red 'hydra-face-red)
+ (amaranth 'hydra-face-amaranth)
+ (pink 'hydra-face-pink)
+ (teal 'hydra-face-teal)
+ (t (error "Unknown color for %S" head)))))))
+
+(defun hydra-fontify-head-greyscale (head _body)
+ "Produce a pretty string from HEAD and BODY.
+HEAD's binding is returned as a string wrapped with [] or {}."
+ (format
+ (if (hydra--head-property head :exit)
+ "[%s]"
+ "{%s}") (car head)))
+
+(defun hydra-fontify-head (head body)
+ "Produce a pretty string from HEAD and BODY."
+ (funcall (or hydra-fontify-head-function 'hydra-fontify-head-default)
+ head body))
+
+(defun hydra--strip-align-markers (str)
+ "Remove ^ from STR, unless they're escaped: \\^."
+ (let ((start 0))
+ (while (setq start (string-match "\\\\?\\^" str start))
+ (if (eq (- (match-end 0) (match-beginning 0)) 2)
+ (progn
+ (setq str (replace-match "^" nil nil str))
+ (cl-incf start))
+ (setq str (replace-match "" nil nil str))))
+ str))
+
+(defvar hydra-docstring-keys-translate-alist
+ '(("โ" . "<up>")
+ ("โ" . "<down>")
+ ("โ" . "<right>")
+ ("โ" . "<left>")
+ ("โซ" . "DEL")
+ ("โฆ" . "<deletechar>")
+ ("โ" . "RET")))
+
+(defconst hydra-width-spec-regex " ?-?[0-9]*?"
+ "Regex for the width spec in keys and %` quoted sexps.")
+
+(defvar hydra-key-regex "\\[\\|]\\|[-[:alnum:] ~.,;:/|?<>={}*+#%@!&^โโโโโซโฆโ'`()\"$]+?"
+ "Regex for the key quoted in the docstring.")
+
+(defun hydra--format (_name body docstring heads)
+ "Generate a `format' statement from STR.
+\"%`...\" expressions are extracted into \"%S\".
+_NAME, BODY, DOCSTRING and HEADS are parameters of `defhydra'.
+The expressions can be auto-expanded according to NAME."
+ (unless (memq 'elisp--witness--lisp (mapcar #'cadr heads))
+ (setq docstring (hydra--strip-align-markers docstring))
+ (setq docstring (replace-regexp-in-string "___" "_ฮฒ_" docstring))
+ (let ((rest (if (eq (plist-get (cddr body) :hint) 'none)
+ ""
+ (hydra--hint body heads)))
+ (start 0)
+ varlist
+ offset)
+ (while (setq start
+ (string-match
+ (format
+ "\\(?:%%\\( ?-?[0-9]*s?\\)\\(`[a-z-A-Z/0-9]+\\|(\\)\\)\\|\\(?:[_?]\\(%s\\)\\(%s\\)[_?]\\)"
+ hydra-width-spec-regex
+ hydra-key-regex)
+ docstring start))
+ (cond ((eq ?? (aref (match-string 0 docstring) 0))
+ (let* ((key (match-string 4 docstring))
+ (head (assoc key heads)))
+ (if head
+ (progn
+ (push (nth 2 head) varlist)
+ (setq docstring
+ (replace-match
+ (or
+ hydra-doc-format-spec
+ (concat "%" (match-string 3 docstring) "s"))
+ t nil docstring)))
+ (setq start (match-end 0))
+ (warn "Unrecognized key: ?%s?" key))))
+ ((eq ?_ (aref (match-string 0 docstring) 0))
+ (let* ((key (match-string 4 docstring))
+ (key (if (equal key "ฮฒ") "_" key))
+ normal-key
+ (head (or (assoc key heads)
+ (when (setq normal-key
+ (cdr (assoc
+ key hydra-docstring-keys-translate-alist)))
+ (assoc normal-key heads)))))
+ (if head
+ (progn
+ (push (hydra-fontify-head (if normal-key
+ (cons key (cdr head))
+ head)
+ body)
+ varlist)
+ (let ((replacement
+ (or
+ hydra-key-format-spec
+ (concat "%" (match-string 3 docstring) "s"))))
+ (setq docstring
+ (replace-match replacement t nil docstring))
+ (setq start (+ start (length replacement)))))
+ (setq start (match-end 0))
+ (warn "Unrecognized key: _%s_" key))))
+
+ (t
+ (let* ((varp (if (eq ?` (aref (match-string 2 docstring) 0)) 1 0))
+ (spec (match-string 1 docstring))
+ (lspec (length spec)))
+ (setq offset
+ (with-temp-buffer
+ (insert (substring docstring (+ 1 start varp
+ (length spec))))
+ (goto-char (point-min))
+ (push (read (current-buffer)) varlist)
+ (- (point) (point-min))))
+ (when (or (zerop lspec)
+ (/= (aref spec (1- (length spec))) ?s))
+ (setq spec (concat spec "S")))
+ (setq docstring
+ (concat
+ (substring docstring 0 start)
+ "%" spec
+ (substring docstring (+ start offset 1 lspec varp))))))))
+ (if (eq ?\n (aref docstring 0))
+ `(concat (format ,(substring docstring 1) ,@(nreverse varlist))
+ ,rest)
+ (let ((r `(replace-regexp-in-string
+ " +$" ""
+ (concat ,docstring ": "
+ (replace-regexp-in-string
+ "\\(%\\)" "\\1\\1" ,rest)))))
+ (if (stringp rest)
+ `(format ,(eval r))
+ `(format ,r)))))))
+
+(defun hydra--complain (format-string &rest args)
+ "Forward to (`message' FORMAT-STRING ARGS) unless `hydra-verbose' is nil."
+ (if hydra-verbose
+ (apply #'error format-string args)
+ (apply #'message format-string args)))
+
+(defun hydra--doc (body-key body-name heads)
+ "Generate a part of Hydra docstring.
+BODY-KEY is the body key binding.
+BODY-NAME is the symbol that identifies the Hydra.
+HEADS is a list of heads."
+ (format
+ "Create a hydra with %s body and the heads:\n\n%s\n\n%s"
+ (if body-key
+ (format "a \"%s\"" body-key)
+ "no")
+ (mapconcat
+ (lambda (x)
+ (format "\"%s\": `%S'" (car x) (cadr x)))
+ heads ",\n")
+ (format "The body can be accessed via `%S'." body-name)))
+
+(defun hydra--call-interactively-remap-maybe (cmd)
+ "`call-interactively' the given CMD or its remapped equivalent.
+Only when `hydra-look-for-remap' is non nil."
+ (let ((remapped-cmd (if hydra-look-for-remap
+ (command-remapping `,cmd)
+ nil)))
+ (if remapped-cmd
+ (call-interactively `,remapped-cmd)
+ (call-interactively `,cmd))))
+
+(defun hydra--call-interactively (cmd name)
+ "Generate a `call-interactively' statement for CMD.
+Set `this-command' to NAME."
+ (if (and (symbolp name)
+ (not (memq name '(nil body))))
+ `(progn
+ (setq this-command ',name)
+ (hydra--call-interactively-remap-maybe #',cmd))
+ `(hydra--call-interactively-remap-maybe #',cmd)))
+
+(defun hydra--make-defun (name body doc head
+ keymap body-pre body-before-exit
+ &optional body-after-exit)
+ "Make a defun wrapper, using NAME, BODY, DOC, HEAD, and KEYMAP.
+NAME and BODY are the arguments to `defhydra'.
+DOC was generated with `hydra--doc'.
+HEAD is one of the HEADS passed to `defhydra'.
+BODY-PRE is added to the start of the wrapper.
+BODY-BEFORE-EXIT will be called before the hydra quits.
+BODY-AFTER-EXIT is added to the end of the wrapper."
+ (let ((cmd-name (hydra--head-name head name))
+ (cmd (when (car head)
+ (hydra--make-callable
+ (cadr head))))
+ (doc (if (car head)
+ (format "%s\n\nCall the head: `%S'." doc (cadr head))
+ doc))
+ (hint (intern (format "%S/hint" name)))
+ (body-foreign-keys (hydra--body-foreign-keys body))
+ (body-timeout (plist-get body :timeout))
+ (body-idle (plist-get body :idle)))
+ `(defun ,cmd-name ()
+ ,doc
+ (interactive)
+ (hydra-default-pre)
+ ,@(when body-pre (list body-pre))
+ ,@(if (hydra--head-property head :exit)
+ `((hydra-keyboard-quit)
+ (setq hydra-curr-body-fn ',(intern (format "%S/body" name)))
+ ,@(if body-after-exit
+ `((unwind-protect
+ ,(when cmd
+ (hydra--call-interactively cmd (cadr head)))
+ ,body-after-exit))
+ (when cmd
+ `(,(hydra--call-interactively cmd (cadr head))))))
+ (delq
+ nil
+ `((let ((hydra--ignore ,(not (eq (cadr head) 'body))))
+ (hydra-keyboard-quit)
+ (setq hydra-curr-body-fn ',(intern (format "%S/body" name))))
+ ,(when cmd
+ `(condition-case err
+ ,(hydra--call-interactively cmd (cadr head))
+ ((quit error)
+ (message (error-message-string err))
+ (unless hydra-lv
+ (sit-for 0.8)))))
+ ,(if (and body-idle (eq (cadr head) 'body))
+ `(hydra-idle-message ,body-idle ,hint ',name)
+ `(hydra-show-hint ,hint ',name))
+ (hydra-set-transient-map
+ ,keymap
+ (lambda () (hydra-keyboard-quit) ,body-before-exit)
+ ,(when body-foreign-keys
+ (list 'quote body-foreign-keys)))
+ ,body-after-exit
+ ,(when body-timeout
+ `(hydra-timeout ,body-timeout))))))))
+
+(defvar hydra-props-alist nil)
+
+(defun hydra-set-property (name key val)
+ "Set hydra property.
+NAME is the symbolic name of the hydra.
+KEY and VAL are forwarded to `plist-put'."
+ (let ((entry (assoc name hydra-props-alist))
+ plist)
+ (when (null entry)
+ (add-to-list 'hydra-props-alist (list name))
+ (setq entry (assoc name hydra-props-alist)))
+ (setq plist (cdr entry))
+ (setcdr entry (plist-put plist key val))))
+
+(defun hydra-get-property (name key)
+ "Get hydra property.
+NAME is the symbolic name of the hydra.
+KEY is forwarded to `plist-get'."
+ (let ((entry (assoc name hydra-props-alist)))
+ (when entry
+ (plist-get (cdr entry) key))))
+
+(defun hydra-show-hint (hint caller)
+ (let ((verbosity (plist-get (cdr (assoc caller hydra-props-alist))
+ :verbosity)))
+ (cond ((eq verbosity 0))
+ ((eq verbosity 1)
+ (message (eval hint)))
+ (t
+ (when hydra-is-helpful
+ (if hydra-lv
+ (lv-message (eval hint))
+ (message (eval hint))))))))
+
+(defmacro hydra--make-funcall (sym)
+ "Transform SYM into a `funcall' to call it."
+ `(when (and ,sym (symbolp ,sym))
+ (setq ,sym `(funcall #',,sym))))
+
+(defun hydra--head-name (h name)
+ "Return the symbol for head H of hydra with NAME."
+ (let ((str (format "%S/%s" name
+ (cond ((symbolp (cadr h))
+ (cadr h))
+ ((and (consp (cadr h))
+ (eq (cl-caadr h) 'function))
+ (cadr (cadr h)))
+ (t
+ (concat "lambda-" (car h)))))))
+ (when (and (hydra--head-property h :exit)
+ (not (memq (cadr h) '(body nil))))
+ (setq str (concat str "-and-exit")))
+ (intern str)))
+
+(defun hydra--delete-duplicates (heads)
+ "Return HEADS without entries that have the same CMD part.
+In duplicate HEADS, :cmd-name is modified to whatever they duplicate."
+ (let ((ali '(((hydra-repeat . nil) . hydra-repeat)))
+ res entry)
+ (dolist (h heads)
+ (if (setq entry (assoc (cons (cadr h)
+ (hydra--head-property h :exit))
+ ali))
+ (setf (cl-cdddr h) (plist-put (cl-cdddr h) :cmd-name (cdr entry)))
+ (push (cons (cons (cadr h)
+ (hydra--head-property h :exit))
+ (plist-get (cl-cdddr h) :cmd-name))
+ ali)
+ (push h res)))
+ (nreverse res)))
+
+(defun hydra--pad (lst n)
+ "Pad LST with nil until length N."
+ (let ((len (length lst)))
+ (if (= len n)
+ lst
+ (append lst (make-list (- n len) nil)))))
+
+(defmacro hydra-multipop (lst n)
+ "Return LST's first N elements while removing them."
+ `(if (<= (length ,lst) ,n)
+ (prog1 ,lst
+ (setq ,lst nil))
+ (prog1 ,lst
+ (setcdr
+ (nthcdr (1- ,n) (prog1 ,lst (setq ,lst (nthcdr ,n ,lst))))
+ nil))))
+
+(defun hydra--matrix (lst rows cols)
+ "Create a matrix from elements of LST.
+The matrix size is ROWS times COLS."
+ (let ((ls (copy-sequence lst))
+ res)
+ (dotimes (_c cols)
+ (push (hydra--pad (hydra-multipop ls rows) rows) res))
+ (nreverse res)))
+
+(defun hydra--cell (fstr names)
+ "Format a rectangular cell based on FSTR and NAMES.
+FSTR is a format-style string with two string inputs: one for the
+doc and one for the symbol name.
+NAMES is a list of variables."
+ (let ((len (cl-reduce
+ (lambda (acc it) (max (length (symbol-name it)) acc))
+ names
+ :initial-value 0)))
+ (mapconcat
+ (lambda (sym)
+ (if sym
+ (format fstr
+ (documentation-property sym 'variable-documentation)
+ (let ((name (symbol-name sym)))
+ (concat name (make-string (- len (length name)) ?^)))
+ sym)
+ ""))
+ names
+ "\n")))
+
+(defun hydra--vconcat (strs &optional joiner)
+ "Glue STRS vertically. They must be the same height.
+JOINER is a function similar to `concat'."
+ (setq joiner (or joiner #'concat))
+ (mapconcat
+ (lambda (s)
+ (if (string-match " +$" s)
+ (replace-match "" nil nil s)
+ s))
+ (apply #'cl-mapcar joiner
+ (mapcar
+ (lambda (s) (split-string s "\n"))
+ strs))
+ "\n"))
+
+(defvar hydra-cell-format "% -20s %% -8`%s"
+ "The default format for docstring cells.")
+
+(defun hydra--table (names rows cols &optional cell-formats)
+ "Format a `format'-style table from variables in NAMES.
+The size of the table is ROWS times COLS.
+CELL-FORMATS are `format' strings for each column.
+If CELL-FORMATS is a string, it's used for all columns.
+If CELL-FORMATS is nil, `hydra-cell-format' is used for all columns."
+ (setq cell-formats
+ (cond ((null cell-formats)
+ (make-list cols hydra-cell-format))
+ ((stringp cell-formats)
+ (make-list cols cell-formats))
+ (t
+ cell-formats)))
+ (hydra--vconcat
+ (cl-mapcar
+ #'hydra--cell
+ cell-formats
+ (hydra--matrix names rows cols))
+ (lambda (&rest x)
+ (mapconcat #'identity x " "))))
+
+(defun hydra-reset-radios (names)
+ "Set varibles NAMES to their defaults.
+NAMES should be defined by `defhydradio' or similar."
+ (dolist (n names)
+ (set n (aref (get n 'range) 0))))
+
+;; Following functions deal with automatic docstring table generation from :column head property
+(defun hydra--normalize-heads (heads)
+ "Ensure each head from HEADS have a property :column.
+Set it to the same value as preceding head or nil if no previous value
+was defined."
+ (let ((current-col nil))
+ (mapcar (lambda (head)
+ (if (hydra--head-has-property head :column)
+ (setq current-col (hydra--head-property head :column)))
+ (hydra--head-set-property head :column current-col))
+ heads)))
+
+(defun hydra--sort-heads (normalized-heads)
+ "Return a list of heads with non-nil doc grouped by column property.
+Each head of NORMALIZED-HEADS must have a column property."
+ (let* ((heads-wo-nil-doc (cl-remove-if-not (lambda (head) (nth 2 head)) normalized-heads))
+ (columns-list (delete-dups (mapcar (lambda (head) (hydra--head-property head :column))
+ normalized-heads)))
+ (get-col-index-fun (lambda (head) (cl-position (hydra--head-property head :column)
+ columns-list
+ :test 'equal)))
+ (heads-sorted (cl-sort heads-wo-nil-doc (lambda (it other)
+ (< (funcall get-col-index-fun it)
+ (funcall get-col-index-fun other))))))
+ ;; this operation partition the sorted head list into lists of heads with same column property
+ (cl-loop for head in heads-sorted
+ for column-name = (hydra--head-property head :column)
+ with prev-column-name = (hydra--head-property (nth 0 heads-sorted) :column)
+ unless (equal prev-column-name column-name) collect heads-one-column into heads-all-columns
+ and do (setq heads-one-column nil)
+ collect head into heads-one-column
+ do (setq prev-column-name column-name)
+ finally return (append heads-all-columns (list heads-one-column)))))
+
+(defun hydra--pad-heads (heads-groups padding-head)
+ "Return a copy of HEADS-GROUPS padded where applicable with PADDING-HEAD."
+ (cl-loop for heads-group in heads-groups
+ for this-head-group-length = (length heads-group)
+ with head-group-max-length = (apply #'max (mapcar (lambda (heads) (length heads)) heads-groups))
+ if (<= this-head-group-length head-group-max-length)
+ collect (append heads-group (make-list (- head-group-max-length this-head-group-length) padding-head))
+ into balanced-heads-groups
+ else collect heads-group into balanced-heads-groups
+ finally return balanced-heads-groups))
+
+(defun hydra--generate-matrix (heads-groups)
+ "Return a copy of HEADS-GROUPS decorated with table formating information.
+Details of modification:
+2 virtual heads acting as table header were added to each heads-group.
+Each head is decorated with 2 new properties max-doc-len and max-key-len
+representing the maximum dimension of their owning group.
+ Every heads-group have equal length by adding padding heads where applicable."
+ (when heads-groups
+ (cl-loop for heads-group in (hydra--pad-heads heads-groups '(" " nil " " :exit t))
+ for column-name = (hydra--head-property (nth 0 heads-group) :column)
+ for max-key-len = (apply #'max (mapcar (lambda (x) (length (car x))) heads-group))
+ for max-doc-len = (apply #'max
+ (length column-name)
+ (mapcar (lambda (x) (length (hydra--to-string (nth 2 x)))) heads-group))
+ for header-virtual-head = `(" " nil ,column-name :column ,column-name :exit t)
+ for separator-virtual-head = `(" " nil ,(make-string (+ 2 max-doc-len max-key-len) ?-) :column ,column-name :exit t)
+ for decorated-heads = (copy-tree (apply 'list header-virtual-head separator-virtual-head heads-group))
+ collect (mapcar (lambda (it)
+ (hydra--head-set-property it :max-key-len max-key-len)
+ (hydra--head-set-property it :max-doc-len max-doc-len))
+ decorated-heads)
+ into decorated-heads-matrix
+ finally return decorated-heads-matrix)))
+
+(defun hydra--hint-from-matrix (body heads-matrix)
+ "Generate a formated table-style docstring according to BODY and HEADS-MATRIX.
+HEADS-MATRIX is expected to be a list of heads with following features:
+Each heads must have the same length
+Each head must have a property max-key-len and max-doc-len."
+ (when heads-matrix
+ (cl-loop with first-heads-col = (nth 0 heads-matrix)
+ with last-row-index = (- (length first-heads-col) 1)
+ for row-index from 0 to last-row-index
+ for heads-in-row = (mapcar (lambda (heads) (nth row-index heads)) heads-matrix)
+ concat (concat
+ (replace-regexp-in-string "\s+$" ""
+ (mapconcat (lambda (head)
+ (funcall hydra-key-doc-function
+ (hydra-fontify-head head body) ;; key
+ (hydra--head-property head :max-key-len)
+ (nth 2 head) ;; doc
+ (hydra--head-property head :max-doc-len)))
+ heads-in-row "| ")) "\n")
+ into matrix-image
+ finally return matrix-image)))
+;; previous functions dealt with automatic docstring table generation from :column head property
+
+(defun hydra-idle-message (secs hint name)
+ "In SECS seconds display HINT."
+ (cancel-timer hydra-message-timer)
+ (setq hydra-message-timer (timer-create))
+ (timer-set-time hydra-message-timer
+ (timer-relative-time (current-time) secs))
+ (timer-set-function
+ hydra-message-timer
+ (lambda ()
+ (hydra-show-hint hint name)
+ (cancel-timer hydra-message-timer)))
+ (timer-activate hydra-message-timer))
+
+(defun hydra-timeout (secs &optional function)
+ "In SECS seconds call FUNCTION, then function `hydra-keyboard-quit'.
+Cancel the previous `hydra-timeout'."
+ (cancel-timer hydra-timeout-timer)
+ (setq hydra-timeout-timer (timer-create))
+ (timer-set-time hydra-timeout-timer
+ (timer-relative-time (current-time) secs))
+ (timer-set-function
+ hydra-timeout-timer
+ `(lambda ()
+ ,(when function
+ `(funcall ,function))
+ (hydra-keyboard-quit)))
+ (timer-activate hydra-timeout-timer))
+
+;;* Macros
+;;;###autoload
+(defmacro defhydra (name body &optional docstring &rest heads)
+ "Create a Hydra - a family of functions with prefix NAME.
+
+NAME should be a symbol, it will be the prefix of all functions
+defined here.
+
+BODY has the format:
+
+ (BODY-MAP BODY-KEY &rest BODY-PLIST)
+
+DOCSTRING will be displayed in the echo area to identify the
+Hydra. When DOCSTRING starts with a newline, special Ruby-style
+substitution will be performed by `hydra--format'.
+
+Functions are created on basis of HEADS, each of which has the
+format:
+
+ (KEY CMD &optional HINT &rest PLIST)
+
+BODY-MAP is a keymap; `global-map' is used quite often. Each
+function generated from HEADS will be bound in BODY-MAP to
+BODY-KEY + KEY (both are strings passed to `kbd'), and will set
+the transient map so that all following heads can be called
+though KEY only. BODY-KEY can be an empty string.
+
+CMD is a callable expression: either an interactive function
+name, or an interactive lambda, or a single sexp (it will be
+wrapped in an interactive lambda).
+
+HINT is a short string that identifies its head. It will be
+printed beside KEY in the echo erea if `hydra-is-helpful' is not
+nil. If you don't even want the KEY to be printed, set HINT
+explicitly to nil.
+
+The heads inherit their PLIST from BODY-PLIST and are allowed to
+override some keys. The keys recognized are :exit and :bind.
+:exit can be:
+
+- nil (default): this head will continue the Hydra state.
+- t: this head will stop the Hydra state.
+
+:bind can be:
+- nil: this head will not be bound in BODY-MAP.
+- a lambda taking KEY and CMD used to bind a head.
+
+It is possible to omit both BODY-MAP and BODY-KEY if you don't
+want to bind anything. In that case, typically you will bind the
+generated NAME/body command. This command is also the return
+result of `defhydra'."
+ (declare (indent defun) (doc-string 3))
+ (setq heads (copy-tree heads))
+ (cond ((stringp docstring))
+ ((and (consp docstring)
+ (memq (car docstring) '(hydra--table concat format)))
+ (setq docstring (concat "\n" (eval docstring))))
+ (t
+ (setq heads (cons docstring heads))
+ (setq docstring "hydra")))
+ (when (keywordp (car body))
+ (setq body (cons nil (cons nil body))))
+ (condition-case-unless-debug err
+ (let* ((keymap (copy-keymap hydra-base-map))
+ (keymap-name (intern (format "%S/keymap" name)))
+ (body-name (intern (format "%S/body" name)))
+ (body-key (cadr body))
+ (body-plist (cddr body))
+ (body-map (or (car body)
+ (plist-get body-plist :bind)))
+ (body-pre (plist-get body-plist :pre))
+ (body-body-pre (plist-get body-plist :body-pre))
+ (body-before-exit (or (plist-get body-plist :post)
+ (plist-get body-plist :before-exit)))
+ (body-after-exit (plist-get body-plist :after-exit))
+ (body-inherit (plist-get body-plist :inherit))
+ (body-foreign-keys (hydra--body-foreign-keys body))
+ (body-exit (hydra--body-exit body)))
+ (dolist (base body-inherit)
+ (setq heads (append heads (copy-sequence (eval base)))))
+ (dolist (h heads)
+ (let ((len (length h)))
+ (cond ((< len 2)
+ (error "Each head should have at least two items: %S" h))
+ ((= len 2)
+ (setcdr (cdr h)
+ (list
+ (hydra-plist-get-default
+ body-plist :hint hydra-default-hint)))
+ (setcdr (nthcdr 2 h) (list :exit body-exit)))
+ (t
+ (let ((hint (cl-caddr h)))
+ (unless (or (null hint)
+ (stringp hint)
+ (consp hint))
+ (let ((inherited-hint
+ (hydra-plist-get-default
+ body-plist :hint hydra-default-hint)))
+ (setcdr (cdr h) (cons
+ (if (eq 'none inherited-hint)
+ nil
+ inherited-hint)
+ (cddr h))))))
+ (let ((hint-and-plist (cddr h)))
+ (if (null (cdr hint-and-plist))
+ (setcdr hint-and-plist (list :exit body-exit))
+ (let* ((plist (cl-cdddr h))
+ (h-color (plist-get plist :color)))
+ (if h-color
+ (progn
+ (plist-put plist :exit
+ (cl-case h-color
+ ((blue teal) t)
+ (t nil)))
+ (cl-remf (cl-cdddr h) :color))
+ (let ((h-exit (hydra-plist-get-default plist :exit 'default)))
+ (plist-put plist :exit
+ (if (eq h-exit 'default)
+ body-exit
+ h-exit))))))))))
+ (plist-put (cl-cdddr h) :cmd-name (hydra--head-name h name))
+ (when (null (cadr h)) (plist-put (cl-cdddr h) :exit t)))
+ (let ((doc (hydra--doc body-key body-name heads))
+ (heads-nodup (hydra--delete-duplicates heads)))
+ (mapc
+ (lambda (x)
+ (define-key keymap (kbd (car x))
+ (plist-get (cl-cdddr x) :cmd-name)))
+ heads)
+ (hydra--make-funcall body-pre)
+ (hydra--make-funcall body-body-pre)
+ (hydra--make-funcall body-before-exit)
+ (hydra--make-funcall body-after-exit)
+ (when (memq body-foreign-keys '(run warn))
+ (unless (cl-some
+ (lambda (h)
+ (hydra--head-property h :exit))
+ heads)
+ (error
+ "An %S Hydra must have at least one blue head in order to exit"
+ body-foreign-keys)))
+ `(progn
+ ;; create keymap
+ (set (defvar ,keymap-name
+ nil
+ ,(format "Keymap for %S." name))
+ ',keymap)
+ ;; declare heads
+ (set (defvar ,(intern (format "%S/heads" name))
+ nil
+ ,(format "Heads for %S." name))
+ ',(mapcar (lambda (h)
+ (let ((j (copy-sequence h)))
+ (cl-remf (cl-cdddr j) :cmd-name)
+ j))
+ heads))
+ (set
+ (defvar ,(intern (format "%S/hint" name)) nil
+ ,(format "Dynamic hint for %S." name))
+ ',(hydra--format name body docstring heads))
+ ;; create defuns
+ ,@(mapcar
+ (lambda (head)
+ (hydra--make-defun name body doc head keymap-name
+ body-pre
+ body-before-exit
+ body-after-exit))
+ heads-nodup)
+ ;; free up keymap prefix
+ ,@(unless (or (null body-key)
+ (null body-map)
+ (hydra--callablep body-map))
+ `((unless (keymapp (lookup-key ,body-map (kbd ,body-key)))
+ (define-key ,body-map (kbd ,body-key) nil))))
+ ;; bind keys
+ ,@(delq nil
+ (mapcar
+ (lambda (head)
+ (let ((name (hydra--head-property head :cmd-name)))
+ (when (and (cadr head)
+ (or body-key body-map))
+ (let ((bind (hydra--head-property head :bind body-map))
+ (final-key
+ (if body-key
+ (vconcat (kbd body-key) (kbd (car head)))
+ (kbd (car head)))))
+ (cond ((null bind) nil)
+ ((hydra--callablep bind)
+ `(funcall ,bind ,final-key (function ,name)))
+ ((and (symbolp bind)
+ (if (boundp bind)
+ (keymapp (symbol-value bind))
+ t))
+ `(define-key ,bind ,final-key (quote ,name)))
+ (t
+ (error "Invalid :bind property `%S' for head %S" bind head)))))))
+ heads))
+ ,(hydra--make-defun
+ name body doc '(nil body)
+ keymap-name
+ (or body-body-pre body-pre) body-before-exit
+ '(setq prefix-arg current-prefix-arg)))))
+ (error
+ (hydra--complain "Error in defhydra %S: %s" name (cdr err))
+ nil)))
+
+(defmacro defhydradio (name _body &rest heads)
+ "Create radios with prefix NAME.
+_BODY specifies the options; there are none currently.
+HEADS have the format:
+
+ (TOGGLE-NAME &optional VALUE DOC)
+
+TOGGLE-NAME will be used along with NAME to generate a variable
+name and a function that cycles it with the same name. VALUE
+should be an array. The first element of VALUE will be used to
+inialize the variable.
+VALUE defaults to [nil t].
+DOC defaults to TOGGLE-NAME split and capitalized."
+ (declare (indent defun))
+ `(progn
+ ,@(apply #'append
+ (mapcar (lambda (h)
+ (hydra--radio name h))
+ heads))
+ (defvar ,(intern (format "%S/names" name))
+ ',(mapcar (lambda (h) (intern (format "%S/%S" name (car h))))
+ heads))))
+
+(defun hydra--radio (parent head)
+ "Generate a hydradio with PARENT from HEAD."
+ (let* ((name (car head))
+ (full-name (intern (format "%S/%S" parent name)))
+ (doc (cadr head))
+ (val (or (cl-caddr head) [nil t])))
+ `((defvar ,full-name ,(hydra--quote-maybe (aref val 0)) ,doc)
+ (put ',full-name 'range ,val)
+ (defun ,full-name ()
+ (hydra--cycle-radio ',full-name)))))
+
+(defun hydra--quote-maybe (x)
+ "Quote X if it's a symbol."
+ (cond ((null x)
+ nil)
+ ((symbolp x)
+ (list 'quote x))
+ (t
+ x)))
+
+(defun hydra--cycle-radio (sym)
+ "Set SYM to the next value in its range."
+ (let* ((val (symbol-value sym))
+ (range (get sym 'range))
+ (i 0)
+ (l (length range)))
+ (setq i (catch 'done
+ (while (< i l)
+ (if (equal (aref range i) val)
+ (throw 'done (1+ i))
+ (cl-incf i)))
+ (error "Val not in range for %S" sym)))
+ (set sym
+ (aref range
+ (if (>= i l)
+ 0
+ i)))))
+
+(defvar hydra-pause-ring (make-ring 10)
+ "Ring for paused hydras.")
+
+(defun hydra-pause-resume ()
+ "Quit the current hydra and save it to the stack.
+If there's no active hydra, pop one from the stack and call its body.
+If the stack is empty, call the last hydra's body."
+ (interactive)
+ (cond (hydra-curr-map
+ (ring-insert hydra-pause-ring hydra-curr-body-fn)
+ (hydra-keyboard-quit))
+ ((zerop (ring-length hydra-pause-ring))
+ (funcall hydra-curr-body-fn))
+ (t
+ (funcall (ring-remove hydra-pause-ring 0)))))
+
+;; Local Variables:
+;; outline-regexp: ";;\\([;*]+ [^\s\t\n]\\|###autoload\\)\\|("
+;; indent-tabs-mode: nil
+;; End:
+
+(provide 'hydra)
+
+;;; hydra.el ends here
.emacs.d/elpa/hydra-20170903.218/hydra.elc
Binary file
.emacs.d/elpa/hydra-20170903.218/lv.el
@@ -0,0 +1,117 @@
+;;; lv.el --- Other echo area
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package provides `lv-message' intended to be used in place of
+;; `message' when semi-permanent hints are needed, in order to not
+;; interfere with Echo Area.
+;;
+;; "ะฏ ัะธั
ะพ-ัะธั
ะพ ะฟiะดะณะปัะดะฐั,
+;; ะ ัiัััั ัะพะฑi, ัะบ ะฑะฐัั ัะพ,
+;; ะจะพ ัััะฐัะธัั i ะฝะต ะฟiะดะฟััะบะฐั,
+;; ะ iะฝัi ะฟโััั ัะตะฑะต, ัะบ ะฒะพะดั ะฟiัะพะบ."
+;; -- ะะฝะดััะน ะัะทัะผะตะฝะบะพ, L.V.
+
+;;; Code:
+
+(defgroup lv nil
+ "The other echo area."
+ :group 'minibuffer
+ :group 'hydra)
+
+(defcustom lv-use-separator nil
+ "Whether to draw a line between the LV window and the Echo Area."
+ :group 'lv
+ :type 'boolean)
+
+(defface lv-separator
+ '((((class color) (background light)) :background "grey80")
+ (((class color) (background dark)) :background "grey30"))
+ "Face used to draw line between the lv window and the echo area.
+This is only used if option `lv-use-separator' is non-nil.
+Only the background color is significant."
+ :group 'lv)
+
+(defvar lv-wnd nil
+ "Holds the current LV window.")
+
+(defun lv-window ()
+ "Ensure that LV window is live and return it."
+ (if (window-live-p lv-wnd)
+ lv-wnd
+ (let ((ori (selected-window))
+ buf)
+ (prog1 (setq lv-wnd
+ (select-window
+ (let ((ignore-window-parameters t))
+ (split-window
+ (frame-root-window) -1 'below))))
+ (if (setq buf (get-buffer " *LV*"))
+ (switch-to-buffer buf)
+ (switch-to-buffer " *LV*")
+ (set-window-hscroll lv-wnd 0)
+ (setq window-size-fixed t)
+ (setq mode-line-format nil)
+ (setq cursor-type nil)
+ (set-window-dedicated-p lv-wnd t)
+ (set-window-parameter lv-wnd 'no-other-window t))
+ (select-window ori)))))
+
+(defvar golden-ratio-mode)
+
+(defvar lv-force-update nil
+ "When non-nil, `lv-message' will refresh even for the same string.")
+
+(defun lv-message (format-string &rest args)
+ "Set LV window contents to (`format' FORMAT-STRING ARGS)."
+ (let* ((str (apply #'format format-string args))
+ (n-lines (cl-count ?\n str))
+ deactivate-mark
+ golden-ratio-mode)
+ (with-selected-window (lv-window)
+ (unless (and (string= (buffer-string) str)
+ (null lv-force-update))
+ (delete-region (point-min) (point-max))
+ (insert str)
+ (when (and (window-system) lv-use-separator)
+ (unless (looking-back "\n" nil)
+ (insert "\n"))
+ (insert
+ (propertize "__" 'face 'lv-separator 'display '(space :height (1)))
+ (propertize "\n" 'face 'lv-separator 'line-height t)))
+ (set (make-local-variable 'window-min-height) n-lines)
+ (setq truncate-lines (> n-lines 1))
+ (let ((window-resize-pixelwise t)
+ (window-size-fixed nil))
+ (fit-window-to-buffer nil nil 1)))
+ (goto-char (point-min)))))
+
+(defun lv-delete-window ()
+ "Delete LV window and kill its buffer."
+ (when (window-live-p lv-wnd)
+ (let ((buf (window-buffer lv-wnd)))
+ (delete-window lv-wnd)
+ (kill-buffer buf))))
+
+(provide 'lv)
+
+;;; lv.el ends here
.emacs.d/elpa/hydra-20170903.218/lv.elc
Binary file
.emacs.d/elpa/ivy-20170911.1034/colir.el
@@ -0,0 +1,114 @@
+;;; colir.el --- Color blending library -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; 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 http://en.wikipedia.org/wiki/Blend_modes.
+
+;;; Code:
+
+(require 'color)
+
+(defcustom colir-compose-method 'colir-compose-alpha
+ "Select a method to compose two color channels."
+ :type '(choice
+ (const colir-compose-alpha)
+ (const colir-compose-overlay)
+ (const colir-compose-soft-light))
+ :group 'ivy)
+
+(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-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)
+ (while (/= start end)
+ (setq next (next-single-property-change start 'face object end))
+ (setq prev (get-text-property start 'face object))
+ (when (listp prev)
+ (setq prev (cl-find-if #'atom prev)))
+ (if (facep prev)
+ (let ((background-prev (face-background prev)))
+ (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))))
+ prev)
+ (list face prev))
+ object)))
+ (put-text-property start next 'face face object))
+ (setq start next))))
+
+(provide 'colir)
+
+;;; colir.el ends here
.emacs.d/elpa/ivy-20170911.1034/colir.elc
Binary file
.emacs.d/elpa/ivy-20170911.1034/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Ivy: (ivy). Using Ivy for completion.
.emacs.d/elpa/ivy-20170911.1034/ivy-autoloads.el
@@ -0,0 +1,135 @@
+;;; ivy-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "ivy" "ivy.el" (22977 29291 974930 936000))
+;;; Generated autoloads from ivy.el
+
+(autoload 'ivy-resume "ivy" "\
+Resume the last completion session.
+
+\(fn)" t nil)
+
+(autoload 'ivy-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+PROMPT is a format string, normally ending in a colon and a
+space; %d anywhere in the string is replaced by the current
+number of matching candidates. For the literal % character,
+escape it with %%. See also `ivy-count-format'.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for `completing-read' compat.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected, i.e. custom text.
+
+If INITIAL-INPUT is not 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'.
+
+If PRESELECT is not nil, then select the corresponding candidate
+out of the ones that match the INITIAL-INPUT.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the current candidate(s) is changed.
+
+When SORT is t, use `ivy-sort-functions-alist' for sorting.
+
+ACTION is a lambda function to call after selecting a result. It
+takes a single string argument.
+
+UNWIND is a lambda function to call before exiting.
+
+RE-BUILDER is a lambda function to call to transform text into a
+regex pattern.
+
+MATCHER is to override matching.
+
+DYNAMIC-COLLECTION is a boolean to specify if the list of
+candidates is updated after each input by calling COLLECTION.
+
+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 UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION 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.
+
+\(fn)" t nil)
+
+(autoload 'ivy-switch-view "ivy" "\
+Switch to one of the window views stored by `ivy-push-view'.
+
+\(fn)" t nil)
+
+(autoload 'ivy-switch-buffer-other-window "ivy" "\
+Switch to another buffer in another window.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("colir.el" "ivy-overlay.el" "ivy-pkg.el")
+;;;;;; (22977 29291 971930 965000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ivy-autoloads.el ends here
.emacs.d/elpa/ivy-20170911.1034/ivy-help.org
@@ -0,0 +1,138 @@
+* 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-toggle-fuzzy=) - toggle regex matcher.
+- ~w~ and ~s~ scroll the actions list.
+
+Minibuffer editing is disabled when Hydra is active.
.emacs.d/elpa/ivy-20170911.1034/ivy-overlay.el
@@ -0,0 +1,128 @@
+;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2017 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; 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
+ '((t (:background "black"
+ :foreground "white")))
+ "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'.")
+
+(defun ivy-left-pad (str width)
+ "Pad STR from left with WIDTH spaces."
+ (let ((padding (make-string width ?\ )))
+ (mapconcat (lambda (x)
+ (setq x (concat padding x))
+ (if (> (length x) (window-width))
+ (concat
+ (substring x 0 (- (window-width) 4))
+ "...")
+ x))
+ (split-string str "\n")
+ "\n")))
+
+(declare-function company-abort "ext:company")
+
+(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)))
+
+(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 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))
+ (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position)))
+ (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")
+(defvar org-indent-indentation-per-level)
+(defvar ivy-last)
+(defvar ivy-text)
+(defvar ivy-completion-beg)
+(declare-function ivy--get-window "ivy")
+
+(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))
+ (or
+ (< (- (window-width) (current-column))
+ (length (ivy-state-current ivy-last)))
+ (<= (window-height) (+ ivy-height 2))))
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str)))
+ (add-face-text-property (minibuffer-prompt-end) (point-max)
+ '(:foreground "white"))
+ (let ((cursor-pos (1+ (- (point) (minibuffer-prompt-end))))
+ (ivy-window (ivy--get-window ivy-last)))
+ (setq cursor-type nil)
+ (with-selected-window ivy-window
+ (when cursor-type
+ (setq ivy--old-cursor-type cursor-type))
+ (setq cursor-type nil)
+ (let ((overlay-str
+ (concat
+ (buffer-substring (max 1 (1- (point))) (point))
+ ivy-text
+ (if (eolp)
+ " "
+ "")
+ (buffer-substring (point) (line-end-position))
+ (ivy-left-pad
+ str
+ (+ (if (eq major-mode 'org-mode)
+ (* org-indent-indentation-per-level (org-current-level))
+ 0)
+ (save-excursion
+ (goto-char ivy-completion-beg)
+ (current-column)))))))
+ (add-face-text-property cursor-pos (1+ cursor-pos)
+ 'ivy-cursor t overlay-str)
+ (ivy-overlay-show-after overlay-str))))))
+
+(provide 'ivy-overlay)
+;;; ivy-overlay.el ends here
.emacs.d/elpa/ivy-20170911.1034/ivy-overlay.elc
Binary file
.emacs.d/elpa/ivy-20170911.1034/ivy-pkg.el
@@ -0,0 +1,7 @@
+(define-package "ivy" "20170911.1034" "Incremental Vertical completYon"
+ '((emacs "24.1"))
+ :url "https://github.com/abo-abo/swiper" :keywords
+ '("matching"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
.emacs.d/elpa/ivy-20170911.1034/ivy.el
@@ -0,0 +1,3993 @@
+;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.9.1
+;; Package-Requires: ((emacs "24.1"))
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; 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 'ffap)
+(require 'ivy-overlay)
+
+;;* 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-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-modified-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting modified file visiting buffers.")
+
+(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.")
+
+(setcdr (assoc load-file-name custom-current-group-alist) 'ivy)
+
+(defcustom ivy-height 10
+ "Number of lines for the minibuffer window."
+ :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-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 (unless (version< emacs-version "24.5") '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 as of Emacs 24.5. 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 'minibuffer-keyboard-quit
+ "The handler for when `ivy-backward-delete-char' throws.
+Usually a quick exit out of the minibuffer."
+ :type '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 bookmarks to `ivy-switch-buffer'."
+ :type 'boolean)
+
+(defcustom ivy-display-function nil
+ "Decide where to display the candidates.
+This function takes a string with the current matching candidates
+and has to display it somewhere.
+See https://github.com/abo-abo/swiper/wiki/ivy-display-function."
+ :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)))
+
+(defvar ivy-display-functions-alist
+ '((ivy-completion-in-region . ivy-display-function-overlay))
+ "An alist for customizing `ivy-display-function'.")
+
+(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)
+ (webjump . ivy-completing-read-with-empty-string-def))
+ "An alist of handlers to replace `completing-read' in `ivy-mode'."
+ :type '(alist :key-type function :value-type 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--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 CMD extra exit points to ACTIONS."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd
+ (delete-dups
+ (append
+ actions
+ (plist-get ivy--actions-list cmd))))))
+
+(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)))
+
+(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 (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 [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 "<next>") 'ivy-scroll-up-command)
+ (define-key map (kbd "<prior>") '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-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 (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)
+ 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)
+
+(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))
+
+(defun ivy-thing-at-point ()
+ "Return a string that corresponds to the current thing at point."
+ (or
+ (thing-at-point 'url)
+ (and (eq (ivy-state-collection ivy-last) 'read-file-name-internal)
+ (ffap-file-at-point))
+ (let (s)
+ (cond ((stringp (setq s (thing-at-point 'symbol)))
+ (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-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.")
+
+(defcustom ivy-case-fold-search-default 'auto
+ "The default value for `ivy-case-fold-search'."
+ :type '(choice
+ (const :tag "Auto" auto)
+ (const :tag "Always" always)
+ (const :tag "Never" nil)))
+
+(defvar ivy-case-fold-search ivy-case-fold-search-default
+ "Store the current overriding `case-fold-search'.")
+
+(defvar Info-current-file)
+
+(defun ivy-re-to-str (re)
+ (if (stringp re)
+ re
+ (caar re)))
+
+(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."
+ `(progn
+ (put 'quit 'error-message "")
+ (run-at-time nil nil
+ (lambda ()
+ (put 'quit 'error-message "Quit")
+ ,@body))
+ (minibuffer-keyboard-quit)))
+
+(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."
+ (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' explicitely 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)
+
+(defun ivy--prompt-selectable-p ()
+ "Return t if the prompt line is selectable."
+ (and ivy-use-selectable-prompt
+ (memq (ivy-state-require-match ivy-last)
+ '(nil confirm confirm-after-completion))))
+
+(defun ivy--prompt-selected-p ()
+ "Return t if the prompt line is selected."
+ (and (ivy--prompt-selectable-p)
+ (= 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-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")))
+
+(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 (null (ivy--actionp actions))
+ t
+ (let* ((hint (funcall ivy-read-action-format-function (cdr actions)))
+ (resize-mini-windows t)
+ (key (string (read-key hint)))
+ (action-idx (cl-position-if
+ (lambda (x) (equal (car x) key))
+ (cdr actions))))
+ (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-shrink-after-dispatching ()
+ "Shrink the window after dispatching when action list is too large."
+ (let ((window (selected-window)))
+ (window-resize window (- ivy-height (window-height window)))))
+
+(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 tramp-get-completion-function "tramp")
+(declare-function Info-find-node "info")
+
+(defun ivy-alt-done (&optional arg)
+ "Exit the minibuffer with the selected candidate.
+When ARG is t, exit with current text, ignoring the candidates."
+ (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))))
+
+(defun ivy--directory-done ()
+ "Handle exit from the minibuffer when completing file names."
+ (let (dir)
+ (cond
+ ((equal ivy-text "/sudo::")
+ (setq dir (concat ivy-text ivy--directory))
+ (ivy--cd dir)
+ (ivy--exhibit))
+ ((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))
+ ((and (not (string= ivy-text ""))
+ (ignore-errors (file-exists-p ivy-text)))
+ (if (file-directory-p ivy-text)
+ (ivy--cd (expand-file-name
+ (file-name-as-directory ivy-text) ivy--directory))
+ (ivy-done)))
+ ((or (and (equal ivy--directory "/")
+ (string-match "\\`[^/]+:.*:.*\\'" ivy-text))
+ (string-match "\\`/[^/]+:.*:.*\\'" ivy-text))
+ (ivy-done))
+ ((or (and (equal ivy--directory "/")
+ (cond ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text))
+ ((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)
+ (require 'tramp)
+ (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 (cl-delete-duplicates res :test #'equal))
+ (let* ((old-ivy-last ivy-last)
+ (enable-recursive-minibuffers t)
+ (host (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)
+ (if (and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (or (and (equal ivy--directory "/")
+ (string-match "\\`[^/]+:.*\\'" ivy-text))
+ (string-match "\\`/" 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)))
+ (or (ivy-partial)
+ (when (or (eq this-command last-command)
+ (eq ivy--length 1))
+ (ivy-alt-done)))))
+
+(defun ivy-partial ()
+ "Complete the minibuffer text as much as possible."
+ (interactive)
+ (let* ((parts (or (split-string ivy-text " " t) (list "")))
+ (postfix (car (last parts)))
+ (case-fold-search (and ivy-case-fold-search
+ (or (eq ivy-case-fold-search 'always)
+ (string= ivy-text (downcase ivy-text)))))
+ (completion-ignore-case case-fold-search)
+ (startp (string-match "^\\^" postfix))
+ (new (try-completion (if startp
+ (substring postfix 1)
+ postfix)
+ (if (ivy-state-dynamic-collection ivy-last)
+ ivy--all-candidates
+ (mapcar (lambda (str)
+ (let ((i (string-match postfix str)))
+ (when i
+ (substring str i))))
+ ivy--old-cands)))))
+ (cond ((eq new t) nil)
+ ((string= new ivy-text) nil)
+ (new
+ (delete-region (minibuffer-prompt-end) (point-max))
+ (setcar (last parts)
+ (if startp
+ (concat "^" new)
+ new))
+ (insert (mapconcat #'identity parts " ")
+ (if ivy-tab-space " " ""))
+ 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)
+ (insert (setf (ivy-state-current ivy-last)
+ (if (and ivy--directory
+ (not (eq (ivy-state-history ivy-last)
+ 'grep-files-history)))
+ (expand-file-name ivy-text ivy--directory)
+ ivy-text)))
+ (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 (eq (ivy-state-caller ivy-last) 'swiper)
+ (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-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 (unless (eq (ivy-state-collection ivy-last)
+ 'read-file-name-internal)
+ (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)
+ :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)
+ (unless (<= ivy-height 2)
+ (setq-local max-mini-window-height
+ (cl-decf ivy-height))
+ (window-resize (selected-window) -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 (or (and (ivy--prompt-selectable-p) -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 (and (zerop ivy--index) (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)))
+ ;; 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
+ (if (= (length (window-list)) 1)
+ (selected-window)
+ (next-window))))
+ (selected-window)))
+
+(defun ivy--actionp (x)
+ "Return non-nil when X is a list of actions."
+ (and x (listp 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 (counsel-locate \"lispy.el\")))
+ ;; do whatever with str - the corresponding file 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))))
+
+(defun ivy-call ()
+ "Call the current action without exiting completion."
+ (interactive)
+ (unless
+ (or
+ ;; this is needed for testing in ivy-with which seems to call ivy-call
+ ;; again, and this-command is nil in that case.
+ (null this-command)
+ (memq this-command '(ivy-done
+ ivy-alt-done
+ ivy-dispatching-done)))
+ (setq ivy-current-prefix-arg current-prefix-arg))
+ (unless ivy-inhibit-action
+ (let ((action (ivy--get-action ivy-last)))
+ (when action
+ (let* ((collection (ivy-state-collection ivy-last))
+ (x (cond
+ ;; Alist type.
+ ((and (consp collection)
+ (consp (car collection))
+ ;; Previously, the cdr of the selected
+ ;; candidate would be returned. Now, the
+ ;; whole candidate is returned.
+ (let (idx)
+ (if (setq idx (get-text-property
+ 0 'idx (ivy-state-current ivy-last)))
+ (nth idx collection)
+ (assoc (ivy-state-current ivy-last)
+ collection)))))
+ (ivy--directory
+ (expand-file-name
+ (ivy-state-current ivy-last)
+ ivy--directory))
+ ((equal (ivy-state-current ivy-last) "")
+ ivy-text)
+ (t
+ (ivy-state-current ivy-last)))))
+ (if (eq action 'identity)
+ (funcall action x)
+ (select-window (ivy--get-window ivy-last))
+ (prog1 (with-current-buffer (ivy-state-buffer ivy-last)
+ (unwind-protect (funcall action x)
+ (ivy-recursive-restore)))
+ (unless (or (eq ivy-exit 'done)
+ (equal (selected-window)
+ (active-minibuffer-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 down 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-next-history-element (arg)
+ "Forward to `next-history-element' with ARG."
+ (interactive "p")
+ (if (and (= minibuffer-history-position 0)
+ (equal ivy-text ""))
+ (progn
+ (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 (ffap-url-p ivy--default))
+ (not (ivy-state-dynamic-collection ivy-last))
+ (> (point) (minibuffer-prompt-end)))
+ (undo-boundary)
+ (insert "\\_>")
+ (goto-char (minibuffer-prompt-end))
+ (insert "\\_<")
+ (forward-char (+ 2 (length ivy--default)))))
+ (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 (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 (_)
+ (funcall 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))))
+
+(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
+ (ivy--sorted-files (setq ivy--directory dir)))
+ (setq ivy-text "")
+ (delete-minibuffer-contents)))
+
+(defun ivy-backward-delete-char ()
+ "Forward to `backward-delete-char'.
+On error (read-only), call `ivy-on-del-error-function'."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (file-name-directory
+ (directory-file-name
+ (expand-file-name
+ ivy--directory))))
+ (ivy--exhibit))
+ (condition-case nil
+ (backward-delete-char 1)
+ (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 (= (point) (line-end-position))
+ (delete-char arg)))
+
+(defun ivy-forward-char (arg)
+ "Forward to `forward-char' ARG."
+ (interactive "p")
+ (unless (= (point) (line-end-position))
+ (forward-char arg)))
+
+(defun ivy-kill-word (arg)
+ "Forward to `kill-word' ARG."
+ (interactive "p")
+ (unless (= (point) (line-end-position))
+ (kill-word arg)))
+
+(defun ivy-kill-line ()
+ "Forward to `kill-line'."
+ (interactive)
+ (if (eolp)
+ (kill-region (minibuffer-prompt-end) (point))
+ (kill-line)))
+
+(defun ivy-backward-kill-word ()
+ "Forward to `backward-kill-word'."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (file-name-directory
+ (directory-file-name
+ (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-function 'ivy-format-function-default
+ "Function to transform the list of candidates into a string.
+This string is inserted into the minibuffer."
+ :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)))
+
+(eval-after-load 'avy
+ '(add-to-list 'avy-styles-alist '(ivy-avy . pre)))
+
+(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))
+ (candidate
+ (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))))
+ (setq avy-action #'identity)
+ (avy--process
+ (nreverse candidates)
+ (avy--style-fn avy-style)))))
+ (when (number-or-marker-p candidate)
+ (goto-char candidate)
+ (when (eq ivy-format-function 'ivy-format-function-arrow)
+ (forward-char 2))
+ (ivy--done
+ (buffer-substring-no-properties
+ (point) (line-end-position))))))
+
+(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< x y)
+ t)
+ (if (get-text-property 0 'dirp y)
+ nil
+ (string< x y))))
+
+(declare-function ido-file-extension-lessp "ido")
+
+(defun ivy-sort-file-function-using-ido (x y)
+ "Compare two files X and Y using `ido-file-extensions-order'.
+
+This function is suitable as a replacement for
+`ivy-sort-file-function-default' in `ivy-sort-functions-alist'."
+ (if (and (bound-and-true-p ido-file-extensions-order))
+ (ido-file-extension-lessp x y)
+ (ivy-sort-file-function-default x y)))
+
+(defcustom ivy-sort-functions-alist
+ '((read-file-name-internal . ivy-sort-file-function-default)
+ (internal-complete-buffer . nil)
+ (counsel-git-grep-function . nil)
+ (Man-goto-section . nil)
+ (org-refile . nil)
+ (t . string-lessp))
+ "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 "No sort" nil)
+ (function :tag "Custom function")
+ (repeat (function :tag "Custom function"))))
+ :group 'ivy)
+
+(defun ivy--sort-function (collection)
+ "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'."
+ (cdr (assoc collection ivy-sort-functions-alist)))
+
+(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 (assoc (ivy-state-collection ivy-last) ivy-sort-functions-alist)))
+ (when (consp (cdr cell))
+ (setcdr cell `(,@(cddr cell) ,(cadr cell)))
+ (ivy--reset-state ivy-last))))
+
+(defvar ivy-index-functions-alist
+ '((swiper . ivy-recompute-index-swiper)
+ (swiper-multi . ivy-recompute-index-swiper)
+ (counsel-git-grep . ivy-recompute-index-swiper)
+ (counsel-grep . ivy-recompute-index-swiper-async)
+ (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'.
+
+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 buidler function.")
+
+(defvar ivy-initial-inputs-alist
+ '((org-refile . "^")
+ (org-agenda-refile . "^")
+ (org-capture-refile . "^")
+ (counsel-M-x . "^")
+ (counsel-describe-function . "^")
+ (counsel-describe-variable . "^")
+ (man . "^")
+ (woman . "^"))
+ "Command to initial input table.")
+
+(defcustom ivy-sort-max-size 30000
+ "Sorting won't be done for collections larger than this."
+ :type 'integer)
+
+(defun ivy--sorted-files (dir)
+ "Return the list of files in DIR.
+Directories come first."
+ (let* ((default-directory dir)
+ (predicate (ivy-state-predicate ivy-last))
+ (seq (condition-case nil
+ (all-completions "" 'read-file-name-internal)
+ (error
+ (directory-files dir))))
+ sort-fn)
+ (if (equal dir "/")
+ seq
+ (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 (string-match-p "/\\'" x)))
+ seq)))
+ (when sort-fn
+ (setq seq (cl-sort seq sort-fn)))
+ (dolist (dir ivy-extra-directories)
+ (push dir seq))
+ (if predicate
+ (cl-remove-if-not predicate seq)
+ seq))))
+
+(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.")
+
+;;** Entry Point
+;;;###autoload
+(cl-defun ivy-read (prompt collection
+ &key
+ predicate require-match initial-input
+ history preselect def keymap update-fn sort
+ action unwind re-builder matcher
+ dynamic-collection caller)
+ "Read a string in the minibuffer, with completion.
+
+PROMPT is a format string, normally ending in a colon and a
+space; %d anywhere in the string is replaced by the current
+number of matching candidates. For the literal % character,
+escape it with %%. See also `ivy-count-format'.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for `completing-read' compat.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected, i.e. custom text.
+
+If INITIAL-INPUT is not 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'.
+
+If PRESELECT is not nil, then select the corresponding candidate
+out of the ones that match the INITIAL-INPUT.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the current candidate(s) is changed.
+
+When SORT is t, use `ivy-sort-functions-alist' for sorting.
+
+ACTION is a lambda function to call after selecting a result. It
+takes a single string argument.
+
+UNWIND is a lambda function to call before exiting.
+
+RE-BUILDER is a lambda function to call to transform text into a
+regex pattern.
+
+MATCHER is to override matching.
+
+DYNAMIC-COLLECTION is a boolean to specify if the list of
+candidates is updated after each input by calling COLLECTION.
+
+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."
+ (let ((extra-actions (delete-dups
+ (append (plist-get ivy--actions-list t)
+ (plist-get ivy--actions-list this-command)
+ (plist-get ivy--actions-list caller)))))
+ (when extra-actions
+ (setq action
+ (cond ((functionp action)
+ `(1
+ ("o" ,action "default")
+ ,@extra-actions))
+ ((null action)
+ `(1
+ ("o" identity "default")
+ ,@extra-actions))
+ (t
+ (delete-dups (append action extra-actions)))))))
+ (let ((extra-sources (plist-get ivy--sources-list caller)))
+ (if extra-sources
+ (progn
+ (setq ivy--extra-candidates nil)
+ (dolist (source extra-sources)
+ (cond ((equal source '(original-source))
+ (setq ivy--extra-candidates
+ (cons source ivy--extra-candidates)))
+ ((null (cdr source))
+ (setq ivy--extra-candidates
+ (cons
+ (list (car source) (funcall (car source)))
+ ivy--extra-candidates))))))
+ (setq ivy--extra-candidates '((original-source)))))
+ (let ((ivy-recursive-last (and (active-minibuffer-window) ivy-last))
+ (transformer-fn
+ (plist-get ivy--display-transformers-list
+ (or caller (and (functionp collection)
+ collection))))
+ (ivy-display-function
+ (unless (window-minibuffer-p)
+ (cdr (assoc caller ivy-display-functions-alist)))))
+ (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 update-fn
+ :sort sort
+ :action 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 transformer-fn
+ :directory default-directory
+ :caller caller
+ :def def))
+ (ivy--reset-state ivy-last)
+ (prog1
+ (unwind-protect
+ (minibuffer-with-setup-hook
+ #'ivy--minibuffer-setup
+ (let* ((hist (or history 'ivy-history))
+ (minibuffer-completion-table collection)
+ (minibuffer-completion-predicate predicate)
+ (resize-mini-windows
+ (cond
+ ((display-graphic-p) nil)
+ ((null resize-mini-windows) 'grow-only)
+ (t resize-mini-windows))))
+ (if (and ivy-auto-select-single-candidate
+ (= (length ivy--all-candidates) 1))
+ (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))))))))
+ (ivy-state-current ivy-last)))
+ (remove-hook 'post-command-hook #'ivy--exhibit)
+ (ivy-overlay-cleanup)
+ (when (setq unwind (ivy-state-unwind ivy-last))
+ (funcall unwind))
+ (unless (eq ivy-exit 'done)
+ (ivy-recursive-restore)))
+ (ivy-call)
+ (when (> (length (ivy-state-current ivy-last)) 0)
+ (remove-text-properties 0 1 '(idx) (ivy-state-current ivy-last))))))
+
+(defun ivy--reset-state (state)
+ "Reset the ivy to STATE.
+This is useful for recursive `ivy-read'."
+ (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))
+ (sort (ivy-state-sort state))
+ (re-builder (ivy-state-re-builder state))
+ (dynamic-collection (ivy-state-dynamic-collection state))
+ (initial-input (ivy-state-initial-input state))
+ (require-match (ivy-state-require-match state))
+ (caller (ivy-state-caller state))
+ (def (ivy-state-def state)))
+ (unless initial-input
+ (setq initial-input (cdr (assoc (or caller this-command)
+ ivy-initial-inputs-alist))))
+ (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 (assoc collection ivy-re-builders-alist)))
+ (and caller
+ (cdr (assoc caller ivy-re-builders-alist)))
+ (cdr (assoc this-command ivy-re-builders-alist))
+ (cdr (assoc t 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)
+ (setq ivy--highlight-function
+ (or (cdr (assoc ivy--regex-function ivy-highlight-functions-alist))
+ #'ivy--highlight-default))
+ (let (coll sort-fn)
+ (cond ((eq collection 'Info-read-node-name-1)
+ (if (equal Info-current-file "dir")
+ (setq coll
+ (mapcar (lambda (x) (format "(%s)" x))
+ (cl-delete-duplicates
+ (all-completions "(" collection predicate)
+ :test #'equal)))
+ (setq coll (all-completions "" collection predicate))))
+ ((eq collection 'read-file-name-internal)
+ (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))
+ (setf (ivy-state-def state) (setq def nil)))
+ (setq ivy--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 (file-name-directory preselect)))
+ (unless (or (null preselect-directory)
+ (string= preselect-directory
+ default-directory))
+ (setq ivy--directory preselect-directory))
+ (setf
+ (ivy-state-preselect state)
+ (setq preselect (file-name-nondirectory preselect)))))
+ (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)))
+ (unless (and (ivy-state-action ivy-last)
+ (not (equal (ivy--get-action ivy-last) 'identity)))
+ (setq initial-input nil))))
+ ((eq collection 'internal-complete-buffer)
+ (setq coll (ivy--buffer-list "" ivy-use-virtual-buffers predicate)))
+ (dynamic-collection
+ (setq coll (funcall collection ivy-text)))
+ ((and (consp collection) (listp (car collection)))
+ (if (and sort (setq sort-fn (ivy--sort-function caller)))
+ (progn
+ (setq sort nil)
+ (setq coll (mapcar #'car
+ (cl-sort
+ (copy-sequence collection)
+ sort-fn))))
+ (setq collection
+ (setf (ivy-state-collection ivy-last)
+ (cl-remove-if-not predicate collection)))
+ (setq coll (all-completions "" collection)))
+ (let ((i 0))
+ (ignore-errors
+ ;; cm can be read-only
+ (dolist (cm coll)
+ (add-text-properties 0 1 `(idx ,i) cm)
+ (cl-incf i)))))
+ ((or (functionp collection)
+ (byte-code-function-p collection)
+ (vectorp collection)
+ (hash-table-p collection)
+ (and (listp collection) (symbolp (car collection))))
+ (setq coll (all-completions "" collection predicate)))
+ (t
+ (setq coll collection)))
+ (when def
+ (cond ((listp def)
+ (setq coll (cl-union def coll :test 'equal)))
+ ((member def coll))
+ (t
+ (push def coll))))
+ (when sort
+ (if (and (functionp collection)
+ (setq sort-fn (ivy--sort-function collection)))
+ (when (not (eq collection 'read-file-name-internal))
+ (setq coll (cl-sort coll sort-fn)))
+ (when (and (not (eq history 'org-refile-history))
+ (<= (length coll) ivy-sort-max-size)
+ (setq sort-fn (ivy--sort-function caller)))
+ (setq coll (cl-sort (copy-sequence coll) sort-fn)))))
+ (setq coll (ivy--set-candidates coll))
+ (setq ivy--old-re nil)
+ (setq ivy--old-cands nil)
+ (when (integerp preselect)
+ (setq ivy--old-re "")
+ (ivy-set-index preselect))
+ (when initial-input
+ ;; Needed for anchor to work
+ (setq ivy--old-cands coll)
+ (setq ivy--old-cands (ivy--filter initial-input coll)))
+ (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 prompt))
+ (setf (ivy-state-initial-input ivy-last) initial-input)))
+
+(defun ivy-add-prompt-count (prompt)
+ "Add count information to PROMPT."
+ (cond ((string-match "%.*d" prompt)
+ prompt)
+ ((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 (length (number-to-string
+ (length ivy--all-candidates))))
+ (s (copy-sequence ivy-count-format)))
+ (string-match "%d" s)
+ (match-end 0)
+ (string-match "%d" s (match-end 0))
+ (setq s (replace-match (format "%%-%dd" w) nil nil s))
+ (string-match "%d" s)
+ (concat (replace-match (format "%%%dd" w) nil nil s)
+ prompt)))
+ ((string-match "%.*d" ivy-count-format)
+ (concat ivy-count-format prompt))
+ (ivy--directory
+ prompt)
+ (t
+ prompt)))
+
+;;;###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
+ (when (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth))
+ (assoc 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)))
+ (ivy-read (replace-regexp-in-string "%" "%%" 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 "\\+" initial-input))
+ (replace-regexp-in-string
+ "\\+" "\\\\+" initial-input))
+ (t
+ initial-input))
+ :preselect (if (listp def) (car def) def)
+ :def (if (listp def) (car def) def)
+ :history history
+ :keymap nil
+ :sort t
+ :caller (cond ((called-interactively-p 'any)
+ this-command)
+ ((and collection (symbolp collection))
+ collection))))))
+
+(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 (featurep 'multiple-cursors)
+ (mc/all-fake-cursors)))
+ (pt (point))
+ (beg ivy-completion-beg)
+ (end ivy-completion-end))
+ (when ivy-completion-beg
+ (delete-region
+ ivy-completion-beg
+ ivy-completion-end))
+ (setq ivy-completion-beg
+ (move-marker (make-marker) (point)))
+ (insert (substring-no-properties str))
+ (setq ivy-completion-end
+ (move-marker (make-marker) (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)))
+ (move-marker (overlay-get cursor 'point) (point))
+ (move-marker (overlay-get cursor 'mark) (point)))))))
+
+(defun ivy-completion-common-length (str)
+ "Return the length of the first `completions-common-part' face in STR."
+ (let ((pos 0)
+ (len (length str))
+ face-sym)
+ (while (and (<= pos len)
+ (let ((prop (or (prog1 (get-text-property
+ pos 'face str)
+ (setq face-sym 'face))
+ (prog1 (get-text-property
+ pos 'font-lock-face str)
+ (setq face-sym 'font-lock-face)))))
+ (not (eq 'completions-common-part
+ (if (listp prop) (car prop) prop)))))
+ (setq pos (1+ pos)))
+ (if (< pos len)
+ (or (next-single-property-change pos face-sym str) len)
+ 0)))
+
+(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 case-fold-search)
+ (comps
+ (completion-all-completions str collection predicate (- end start)))
+ (ivy--prompts-list (if (window-minibuffer-p)
+ ivy--prompts-list
+ '(ivy-completion-in-region (lambda nil)))))
+ (if (null comps)
+ (message "No matches")
+ (let ((len (min (ivy-completion-common-length (car comps))
+ (length str))))
+ (nconc comps nil)
+ (setq ivy-completion-beg (- end len))
+ (setq ivy-completion-end end)
+ (if (null (cdr comps))
+ (if (string= str (car comps))
+ (message "Sole match")
+ (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))))
+ (let* ((w (1+ (floor (log (length comps) 10))))
+ (ivy-count-format (if (string= ivy-count-format "")
+ ivy-count-format
+ (format "%%-%dd " w)))
+ (prompt (format "(%s): " str)))
+ (and
+ (ivy-read (if (string= ivy-count-format "")
+ prompt
+ (replace-regexp-in-string "%" "%%" prompt))
+ ;; remove 'completions-first-difference face
+ (mapcar #'substring-no-properties comps)
+ :predicate predicate
+ :action #'ivy-completion-in-region-action
+ :caller 'ivy-completion-in-region)
+ t)))))))
+
+(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)
+ preselect)
+ ((cl-position preselect candidates :test #'equal))
+ ((stringp preselect)
+ (let ((re preselect))
+ (cl-position-if
+ (lambda (x)
+ (string-match re x))
+ candidates)))))
+
+;;* 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 a list by single spaces.
+The remaining spaces stick to their left.
+This allows to \"quote\" N spaces by inputting N+1 spaces."
+ (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 start1 (match-end 0))
+ (setq start0 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)))
+ (nreverse res)))
+
+(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
+ (prog1 (cdr hashed)
+ (setq ivy--subexps (car hashed)))
+ (when (string-match "\\([^\\]\\|^\\)\\\\$" str)
+ (setq str (substring str 0 -1)))
+ (cdr (puthash str
+ (let ((subs (ivy--split str)))
+ (if (= (length subs) 1)
+ (cons
+ (setq ivy--subexps 0)
+ (car subs))
+ (cons
+ (setq ivy--subexps (length subs))
+ (mapconcat
+ (lambda (x)
+ (if (string-match "\\`\\\\([^?].*\\\\)\\'" x)
+ x
+ (format "\\(%s\\)" x)))
+ subs
+ (if greedy
+ ".*"
+ ".*?")))))
+ ivy--regex-hash)))))
+
+(defun ivy--legal-regex-p (str)
+ "Return t if STR is valid regular expression."
+ (condition-case nil
+ (progn
+ (string-match-p str "")
+ t)
+ (invalid-regexp nil)))
+
+(defun ivy--regex-or-literal (str)
+ "If STR isn't a legal regex, escape it."
+ (if (ivy--legal-regex-p str) str (regexp-quote str)))
+
+(defun ivy--split-negation (str)
+ "Split STR into text before and after !.
+Don't split if it's escaped with \\!.
+
+Assumes there is at most one unescaped !."
+ (let (parts
+ (part ""))
+ (mapc
+ (lambda (char)
+ (let ((prev-char (if (zerop (length part))
+ nil
+ (elt part (1- (length part))))))
+ ;; Split on !, unless it's escaped.
+ (cond
+ ;; Store "\!" as "!".
+ ((and (eq char ?!) (eq prev-char ?\\))
+ (setq part (concat (substring part 0 (1- (length part)))
+ "!")))
+ ;; Split on "!".
+ ((eq char ?!)
+ (push part parts)
+ (setq part ""))
+ ;; Otherwise, append the current character.
+ (t
+ (setq part (concat part (string char)))))))
+ str)
+ (unless (zerop (length part))
+ (push part parts))
+ (setq parts (nreverse parts))
+ ;; If we have more than unescaped !, just discard the extra parts
+ ;; rather than crashing. We can't warn or error because the
+ ;; minibuffer is already active.
+ (when (> (length parts) 2)
+ (setq parts (list (cl-first parts) (cl-second parts))))
+ parts))
+
+(defun ivy--split-spaces (str)
+ "Split STR on spaces, unless they're preceded by \\.
+No unescaped spaces are present in the output."
+ (let (parts
+ (part ""))
+ (mapc
+ (lambda (char)
+ (let ((prev-char (if (zerop (length part))
+ nil
+ (elt part (1- (length part))))))
+ (cond
+ ;; Store "\ " as " ".
+ ((and (eq char ?\s) (eq prev-char ?\\))
+ (setq part (concat (substring part 0 (1- (length part)))
+ " ")))
+ ;; Split on " ".
+ ((eq char ?\s)
+ (unless (zerop (length part))
+ (push part parts))
+ (setq part ""))
+ ;; Otherwise, append the current character.
+ (t
+ (setq part (concat part (string char)))))))
+ str)
+ (unless (zerop (length part))
+ (push part parts))
+ (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\"
+
+If STR isn't a valid input, fall back to exact matching:
+foo[ -> matches \"foo\[\" (invalid regex, so literal [ character)
+
+Returns a list suitable for `ivy-re-match'."
+ (let* (regex-parts
+ (raw-parts (ivy--split-negation str)))
+ (dolist (part (ivy--split-spaces (car raw-parts)))
+ (push (cons (ivy--regex-or-literal part) t) regex-parts))
+ (when (cdr raw-parts)
+ (dolist (part (ivy--split-spaces (cadr raw-parts)))
+ (push (cons (ivy--regex-or-literal 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 (split-string str "!" t)))
+ (cl-case (length parts)
+ (0
+ "")
+ (1
+ (if (string= (substring str 0 1) "!")
+ (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."
+ (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str)
+ (prog1
+ (concat (match-string 1 str)
+ (mapconcat
+ (lambda (x)
+ (format "\\(%c\\)" x))
+ (string-to-list (match-string 2 str))
+ ".*?")
+ (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."
+ :group 'ivy
+ :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."
+ (set (make-local-variable 'completion-show-inline-help) nil)
+ (set (make-local-variable 'minibuffer-default-add-function)
+ (lambda ()
+ (list ivy--default)))
+ (set (make-local-variable 'inhibit-field-text-motion) nil)
+ (when (display-graphic-p)
+ (setq truncate-lines ivy-truncate-lines))
+ (setq-local max-mini-window-height ivy-height)
+ (when (and ivy-fixed-height-minibuffer
+ (not (eq (ivy-state-caller ivy-last) 'ivy-completion-in-region)))
+ (set-window-text-height (selected-window)
+ (+ ivy-height
+ (if ivy-add-newline-after-prompt
+ 1
+ 0))))
+ (add-hook 'post-command-hook #'ivy--exhibit nil t)
+ ;; show completions with empty input
+ (ivy--exhibit))
+
+(defun ivy--input ()
+ "Return the current minibuffer input."
+ ;; assume one-line minibuffer input
+ (buffer-substring-no-properties
+ (minibuffer-prompt-end)
+ (line-end-position)))
+
+(defun ivy--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)
+ "Remove unwanted text properties from STR."
+ (remove-text-properties 0 (length str) '(field) str)
+ str)
+
+(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 STD-PROPS.
+The returned value should be the updated PROMPT.")
+
+(defun ivy-set-prompt-text-properties-default (prompt std-props)
+ "Set text properties of PROMPT.
+STD-PROPS is a property list containing the default text properties."
+ (ivy--set-match-props prompt "confirm"
+ `(face ivy-confirm-face ,@std-props))
+ (ivy--set-match-props prompt "match required"
+ `(face ivy-match-required-face ,@std-props))
+ prompt)
+
+(defun ivy-prompt ()
+ "Return the current prompt."
+ (let ((fn (plist-get ivy--prompts-list (ivy-state-caller ivy-last))))
+ (if fn
+ (condition-case nil
+ (funcall fn)
+ (error
+ (warn "`counsel-prompt-function' should take 0 args")
+ ;; 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 ": "))
+ (setq head (substring ivy--prompt 0 -1))
+ (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-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--prompt-selectable-p)
+ (if (or (= ivy--index -1)
+ (= ivy--length 0))
+ (add-face-text-property
+ (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match)
+ (remove-text-properties
+ (minibuffer-prompt-end) (line-end-position) '(face))))
+ ;; get out of the prompt area
+ (constrain-to-field nil (point-max))))))
+
+(defun ivy--set-match-props (str match props &optional subexp)
+ "Set text properties of STR that match MATCH to PROPS.
+SUBEXP is a number which specifies the regexp group to use.
+If nil, the text properties are applied to the whole match."
+ (when (null subexp)
+ (setq subexp 0))
+ (when (string-match match str)
+ (set-text-properties
+ (match-beginning subexp)
+ (match-end subexp)
+ props
+ str)))
+
+(defvar inhibit-message)
+
+(defun ivy--sort-maybe (collection)
+ "Sort COLLECTION if needed."
+ (let ((sort (ivy-state-sort ivy-last)))
+ (if (null sort)
+ collection
+ (let ((sort-fn (or (and (functionp sort) sort)
+ (ivy--sort-function (ivy-state-collection ivy-last))
+ (ivy--sort-function t))))
+ (if (functionp sort-fn)
+ (cl-sort (copy-sequence collection) sort-fn)
+ 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-slash ()
+ "Handle slash when completing file names."
+ (when (or (and (eq this-command 'self-insert-command)
+ (eolp))
+ (eq this-command 'ivy-partial-or-done))
+ (cond ((member ivy-text ivy--all-candidates)
+ (ivy--cd (expand-file-name ivy-text ivy--directory)))
+ ((string-match "//\\'" ivy-text)
+ (if (and default-directory
+ (string-match "\\`[[:alpha:]]:/" default-directory))
+ (ivy--cd (match-string 0 default-directory))
+ (ivy--cd "/")))
+ ((string-match "\\`/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 (file-exists-p ivy-text)
+ (not (string= ivy-text "/"))
+ (file-directory-p ivy-text))
+ (ivy--cd (expand-file-name ivy-text)))
+ ((and (or (> ivy--index 0)
+ (= ivy--length 1)
+ (not (string= ivy-text "/")))
+ (let ((default-directory ivy--directory))
+ (and
+ (not (equal (ivy-state-current ivy-last) ""))
+ (file-directory-p (ivy-state-current ivy-last))
+ (file-exists-p (ivy-state-current ivy-last)))))
+ (when (eq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected)
+ (ivy--cd
+ (expand-file-name (ivy-state-current ivy-last) ivy--directory)))
+ (when (and (eq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create)
+ (not (string= ivy-text "/")))
+ (ivy--create-and-cd (expand-file-name ivy-text ivy--directory))))
+ (t
+ (when (and
+ (eq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create)
+ (not (string= ivy-text "/")))
+ (ivy--create-and-cd (expand-file-name ivy-text ivy--directory)))))))
+
+(defcustom ivy-magic-tilde t
+ "When non-nil, ~ will move home when selecting files.
+Otherwise, ~/ will move home."
+ :type 'boolean)
+
+(defun ivy--exhibit ()
+ "Insert Ivy completions display.
+Should be run via minibuffer `post-command-hook'."
+ (when (memq 'ivy--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))
+ (unless (equal ivy--old-text ivy-text)
+ (while-no-input
+ (setq ivy--all-candidates
+ (ivy--sort-maybe
+ (funcall (ivy-state-collection ivy-last) ivy-text)))
+ (setq ivy--old-text ivy-text)))
+ (when ivy--all-candidates
+ (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 (expand-file-name "~/")))
+ ((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 (and (> (length ivy-text) 0)
+ (eq (aref ivy-text 0)
+ ?\ ))
+ (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--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)))
+ deactivate-mark)
+ (ivy--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)
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert text)))))
+ (when (display-graphic-p)
+ (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)))))))
+
+(declare-function colir-blend-face-background "ext:colir")
+
+(defun ivy--add-face (str face)
+ "Propertize STR with FACE.
+`font-lock-append-text-property' is used, since it's better than
+`propertize' or `add-face-text-property' in this case."
+ (require 'colir)
+ (condition-case nil
+ (progn
+ (colir-blend-face-background 0 (length str) face str)
+ (let ((foreground (face-foreground face)))
+ (when foreground
+ (add-face-text-property
+ 0 (length str)
+ `(:foreground ,foreground)
+ nil
+ str))))
+ (error
+ (ignore-errors
+ (font-lock-append-text-property 0 (length str) '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 the case folding between nil and auto/always.
+
+If auto, `case-fold-search' is t, when the input is all lower case,
+otherwise nil.
+
+If always, `case-fold-search' is always t, regardless of the input.
+
+Otherwise `case-fold-search' is always nil, regardless of the input.
+
+In any completion session, the case folding starts in
+`ivy-case-fold-search-default'."
+ (interactive)
+ (setq ivy-case-fold-search
+ (if ivy-case-fold-search
+ nil
+ (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)
+ "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."
+ (let ((re-list (if (stringp re) (list (cons re t)) re))
+ (res candidates))
+ (dolist (re re-list)
+ (setq res
+ (ignore-errors
+ (funcall
+ (if (cdr re)
+ #'cl-remove-if-not
+ #'cl-remove-if)
+ (let ((re-str (car re)))
+ (lambda (x) (string-match re-str x)))
+ res))))
+ res))
+
+(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 (if (listp re) (caar re) re))
+ (matcher (ivy-state-matcher ivy-last))
+ (case-fold-search
+ (and ivy-case-fold-search
+ (or (eq ivy-case-fold-search 'always)
+ (string= name (downcase name)))))
+ (cands (cond
+ (matcher
+ (funcall matcher re candidates))
+ ((and ivy--old-re
+ (stringp re)
+ (stringp ivy--old-re)
+ (not (string-match "\\\\" ivy--old-re))
+ (not (equal ivy--old-re ""))
+ (memq (cl-search
+ (if (string-match "\\\\)\\'" ivy--old-re)
+ (substring ivy--old-re 0 -2)
+ ivy--old-re)
+ re)
+ '(0 2)))
+ (ignore-errors
+ (cl-remove-if-not
+ (lambda (x) (string-match re x))
+ ivy--old-cands)))
+ (t
+ (ivy--re-filter re candidates)))))
+ (if (memq (cdr (assoc (ivy-state-caller ivy-last)
+ ivy-index-functions-alist))
+ '(ivy-recompute-index-swiper
+ ivy-recompute-index-swiper-async))
+ (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)))
+
+(defcustom ivy-sort-matches-functions-alist
+ '((t . nil)
+ (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))
+ (cl-sort (copy-sequence candidates)
+ (lambda (f1 f2)
+ (time-less-p
+ (nth 5 (file-attributes f2))
+ (nth 5 (file-attributes f1)))))))
+
+(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 ((key (or (ivy-state-caller ivy-last)
+ (when (functionp (ivy-state-collection ivy-last))
+ (ivy-state-collection ivy-last))))
+ fun)
+ (cond ((and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy))
+ (ivy--flx-sort name candidates))
+ ((setq fun (cdr (or (assoc key ivy-sort-matches-functions-alist)
+ (assoc t ivy-sort-matches-functions-alist))))
+ (funcall fun 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-match "^\\^" name) (string= name ""))
+ candidates
+ (let ((re-prefix (concat "^" (funcall ivy--regex-function name)))
+ res-prefix
+ res-noprefix)
+ (dolist (s candidates)
+ (if (string-match 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-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-match "^\\^" name) (string= name ""))
+ candidates
+ (let* ((base-re (funcall ivy--regex-function name))
+ (base-re (if (consp base-re) (caar base-re) base-re))
+ (re-prefix (concat "^\\*" base-re))
+ res-prefix
+ res-noprefix
+ res-virtual-prefix
+ res-virtual-noprefix)
+ (unless (cl-find-if (lambda (s) (string-match re-prefix s)) candidates)
+ (setq re-prefix (concat "^" base-re)))
+ (dolist (s candidates)
+ (cond
+ ((and (assoc s ivy--virtual-buffers) (string-match re-prefix s))
+ (push s res-virtual-prefix))
+ ((assoc s ivy--virtual-buffers)
+ (push s res-virtual-noprefix))
+ ((string-match 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)))))
+
+(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 (and caller (cdr (assoc caller ivy-index-functions-alist)))
+ (cdr (assoc t ivy-index-functions-alist))
+ #'ivy-recompute-index-zero)))
+ (unless (eq this-command 'ivy-resume)
+ (ivy-set-index
+ (or
+ (cl-position (if (and (> (length name) 0)
+ (eq ?^ (aref name 0)))
+ (substring name 1)
+ name) cands
+ :test #'equal)
+ (and ivy--directory
+ (cl-position
+ (concat re-str "/") cands
+ :test #'equal))
+ (and (eq caller 'ivy-switch-buffer)
+ (> (length name) 0)
+ 0)
+ (and (not (string= name ""))
+ (not (and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy)
+ (< (length cands) 200)))
+ ivy--old-cands
+ (cl-position (nth ivy--index ivy--old-cands)
+ cands))
+ (funcall func re-str cands))))
+ (when (or (string= name "")
+ (string= name "^"))
+ (ivy-set-index
+ (or (ivy--preselect-index
+ (ivy-state-preselect ivy-last)
+ 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 (read (get-text-property 0 'swiper-line-number c)))
+ (setq res i))
+ (cl-incf i))
+ res))))
+ (error 0)))
+
+(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-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"))))
+
+(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.")
+
+(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)
+ (nth (1+ (mod (+ i 2) (1- (length ivy-minibuffer-faces))))
+ ivy-minibuffer-faces)
+ str))
+ str))
+
+(defun ivy--flx-sort (name cands)
+ "Sort according to closeness to string NAME the string list CANDS."
+ (condition-case nil
+ (let* (
+ ;; an optimized regex for fuzzy matching
+ ;; "abc" โ "\\`[^a]*a[^b]*b[^c]*c"
+ (fuzzy-regex (if (= (elt name 0) ?^)
+ (concat "^"
+ (regexp-quote (substring name 1 2))
+ (mapconcat
+ (lambda (x)
+ (setq x (string x))
+ (concat "[^" x "]*" (regexp-quote x)))
+ (substring name 2)
+ ""))
+ (concat "^"
+ (mapconcat
+ (lambda (x)
+ (setq x (string x))
+ (concat "[^" x "]*" (regexp-quote x)))
+ name
+ ""))))
+
+ ;; strip off the leading "^" for flx matching
+ (flx-name (if (string-match "^\\^" name)
+ (substring name 1)
+ name))
+
+ (cands-left)
+ (cands-to-sort))
+
+ ;; filter out non-matching candidates
+ (dolist (cand cands)
+ (when (string-match fuzzy-regex cand)
+ (push cand cands-left)))
+
+ ;; pre-sort the candidates by length before partitioning
+ (setq cands-left (sort cands-left
+ (lambda (c1 c2)
+ (< (length c1)
+ (length c2)))))
+
+ ;; partition the candidates into sorted and unsorted groups
+ (dotimes (_n (min (length cands-left) ivy-flx-limit))
+ (push (pop cands-left) cands-to-sort))
+
+ (append
+ ;; 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."
+ (if (> (string-width str) width)
+ (concat (substring str 0 (min (- width 3)
+ (- (length str) 3))) "...")
+ str))
+
+(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--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
+ ""))
+
+(defun ivy-add-face-text-property (start end face str)
+ "Add face property to the text from START to END.
+FACE is the face to apply to STR."
+ (if (fboundp 'add-face-text-property)
+ (add-face-text-property
+ start end face nil str)
+ (font-lock-append-text-property
+ start end 'face face str)))
+
+(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)
+ (nth (1+ (mod (+ i 2) (1- (length ivy-minibuffer-faces))))
+ ivy-minibuffer-faces)
+ str))
+ (cl-incf i))))
+ str)
+
+(defun ivy--highlight-fuzzy (str)
+ "Highlight STR, using the fuzzy method."
+ (if ivy--flx-featurep
+ (let ((flx-name (if (string-match "^\\^" ivy-text)
+ (substring ivy-text 1)
+ 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 ((start
+ (if (and (memq (ivy-state-caller ivy-last)
+ '(counsel-git-grep counsel-ag counsel-rg counsel-pt))
+ (string-match "^[^:]+:[^:]+:" str))
+ (match-end 0)
+ 0)))
+ (ignore-errors
+ (while (and (string-match ivy--old-re str start)
+ (> (- (match-end 0) (match-beginning 0)) 0))
+ (setq start (match-end 0))
+ (let ((i 0))
+ (while (<= i ivy--subexps)
+ (let ((face
+ (cond ((zerop ivy--subexps)
+ (cadr ivy-minibuffer-faces))
+ ((zerop i)
+ (car ivy-minibuffer-faces))
+ (t
+ (nth (1+ (mod (+ i 2)
+ (1- (length ivy-minibuffer-faces))))
+ ivy-minibuffer-faces)))))
+ (ivy-add-face-text-property
+ (match-beginning i) (match-end i)
+ face str))
+ (cl-incf i))))))
+ str)
+
+(defun ivy--format-minibuffer-line (str)
+ "Format line STR for use in minibuffer."
+ (if (eq ivy-display-style 'fancy)
+ (funcall ivy--highlight-function (copy-sequence str))
+ (copy-sequence str)))
+
+(ivy-set-display-transformer
+ 'counsel-find-file 'ivy-read-file-transformer)
+(ivy-set-display-transformer
+ 'read-file-name-internal 'ivy-read-file-transformer)
+
+(defun ivy-read-file-transformer (str)
+ "Transform candidate STR when reading files."
+ (if (string-match-p "/\\'" str)
+ (propertize str 'face 'ivy-subdir)
+ str))
+
+(defun ivy--format (cands)
+ "Return a string for CANDS suitable for display in the minibuffer.
+CANDS is a list of 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* ((half-height (/ ivy-height 2))
+ (start (max 0 (- ivy--index half-height)))
+ (end (min (+ start (1- ivy-height)) ivy--length))
+ (start (max 0 (min start (- end (1- ivy-height)))))
+ (cands (cl-subseq cands start end))
+ (index (- ivy--index start))
+ transformer-fn)
+ (setf (ivy-state-current ivy-last) (copy-sequence (nth index cands)))
+ (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+ (with-ivy-window
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (setq cands (mapcar transformer-fn cands)))))
+ (let* ((ivy--index index)
+ (cands (mapcar
+ #'ivy--format-minibuffer-line
+ cands))
+ (res (concat "\n" (funcall ivy-format-function cands))))
+ (put-text-property 0 (length res) 'read-only nil res)
+ res))))
+
+(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 "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))
+ (let (virtual-buffers)
+ (bookmark-maybe-load-default-file)
+ (dolist (head (append
+ (copy-sequence recentf-list)
+ (delete " - no file -"
+ (delq nil (mapcar #'bookmark-get-filename
+ (copy-sequence bookmark-alist))))))
+ (let ((file-name (if (stringp head)
+ head
+ (cdr head)))
+ name)
+ (setq name
+ (if (eq ivy-virtual-abbreviate 'name)
+ (file-name-nondirectory file-name)
+ (expand-file-name file-name)))
+ (when (equal name "")
+ (if (consp head)
+ (setq name (car head))
+ (setq name (file-name-nondirectory
+ (directory-file-name file-name)))))
+ (and (not (equal name ""))
+ (null (get-file-buffer file-name))
+ (not (assoc name virtual-buffers))
+ (push (cons 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 . org-level-4))
+ "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
+ (append
+ (mapcar
+ (lambda (x)
+ (if (with-current-buffer x
+ (and default-directory
+ (file-remote-p
+ (abbreviate-file-name default-directory))))
+ (propertize x 'face 'ivy-remote)
+ (let ((face (with-current-buffer x
+ (cdr (assoc major-mode
+ 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 mulitple window splits.")
+
+(defun ivy-default-view-name ()
+ "Return default name for new view."
+ (let* ((default-view-name
+ (concat "{} "
+ (mapconcat #'identity
+ (cl-sort
+ (mapcar (lambda (w)
+ (with-current-buffer (window-buffer w)
+ (if (buffer-file-name)
+ (file-name-nondirectory
+ (buffer-file-name))
+ (buffer-name))))
+ (window-list))
+ #'string<)
+ " ")))
+ (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 ()
+ "Push the current window tree on `ivy-views'.
+Currently, the split configuration (i.e. horizonal 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)
+ (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 (ivy-read "Name view: " nil
+ :initial-input (ivy-default-view-name))))
+ (when view-name
+ (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)))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (ivy-set-view-recur v))
+ (when views
+ (setq wnd2 (split-window-vertically))))))
+ ((eq (car view) 'horz)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-horizontally))
+ (views (cdr view))
+ (v (pop views)))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (ivy-set-view-recur v))
+ (when views
+ (setq wnd2 (split-window-horizontally))))))
+ ((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."
+ (with-ivy-window
+ (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))))
+
+(defvar ivy-switch-buffer-map (make-sparse-keymap))
+
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("k"
+ (lambda (x)
+ (kill-buffer x)
+ (ivy--reset-state ivy-last))
+ "kill")
+ ("j"
+ ivy--switch-buffer-other-window-action
+ "other window")
+ ("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)))))
+
+(ivy-set-display-transformer
+ 'ivy-switch-buffer 'ivy-switch-buffer-transformer)
+(ivy-set-display-transformer
+ 'internal-complete-buffer 'ivy-switch-buffer-transformer)
+
+(defun ivy-append-face (str face)
+ "Append to STR the property FACE."
+ (let ((new (copy-sequence str)))
+ (font-lock-append-text-property
+ 0 (length new) 'face face new)
+ new))
+
+(defun ivy-switch-buffer-transformer (str)
+ "Transform candidate STR when switching buffers."
+ (let ((b (get-buffer str)))
+ (if (and b
+ (buffer-file-name b)
+ (buffer-modified-p b))
+ (ivy-append-face str 'ivy-modified-buffer)
+ str)))
+
+(defun ivy-switch-buffer-occur ()
+ "Occur function for `ivy-switch-buffer' using `ibuffer'."
+ (let* ((cand-regexp
+ (concat "\\(" (mapconcat #'regexp-quote ivy--old-cands "\\|") "\\)"))
+ (new-qualifier `((name . ,cand-regexp))))
+ (ibuffer nil (buffer-name) new-qualifier)))
+
+;;;###autoload
+(defun ivy-switch-buffer ()
+ "Switch to another buffer."
+ (interactive)
+ (let ((this-command 'ivy-switch-buffer))
+ (ivy-read "Switch to buffer: " 'internal-complete-buffer
+ :matcher #'ivy--switch-buffer-matcher
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-action
+ :keymap ivy-switch-buffer-map
+ :caller 'ivy-switch-buffer)))
+
+;;;###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))
+
+(define-obsolete-function-alias 'ivy-recentf 'counsel-recentf "0.8.0")
+
+(defun ivy-yank-word ()
+ "Pull next word from buffer into search string."
+ (interactive)
+ (let (amend)
+ (with-ivy-window
+ (let ((pt (point))
+ (le (line-end-position)))
+ (forward-word 1)
+ (if (> (point) le)
+ (goto-char pt)
+ (setq amend (buffer-substring-no-properties pt (point))))))
+ (when amend
+ (insert (replace-regexp-in-string " +" " " amend)))))
+
+(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)
+ (if (and ivy--directory
+ (string-match "/$" (ivy-state-current ivy-last)))
+ (insert (substring (ivy-state-current ivy-last) 0 -1))
+ (insert (ivy-state-current ivy-last))))
+
+(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)
+ :group 'ivy)
+
+(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 (assoc 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)))
+
+(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."
+ (interactive)
+ (let ((enable-recursive-minibuffers t)
+ (history (symbol-value (ivy-state-history ivy-last)))
+ (old-last ivy-last)
+ (ivy-recursive-restore nil))
+ (ivy-read "Reverse-i-search: "
+ history
+ :action (lambda (x)
+ (ivy--reset-state
+ (setq ivy-last old-last))
+ (delete-minibuffer-contents)
+ (insert (substring-no-properties x))
+ (ivy--cd-maybe)))))
+
+(defun ivy-restrict-to-matches ()
+ "Restrict candidates to current input and erase input."
+ (interactive)
+ (delete-minibuffer-contents)
+ (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)
+ 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-occur-next-line (&optional arg)
+ "Move the cursor down ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (forward-line arg)
+ (when ivy-calling
+ (ivy-occur-press)))
+
+(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")
+ (forward-line (- arg))
+ (when ivy-calling
+ (ivy-occur-press)))
+
+(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 (kbd "C-d") 'ivy-occur-delete-candidate)
+ 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)))
+
+(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)))
+
+(ivy-set-occur 'ivy-switch-buffer 'ivy-switch-buffer-occur)
+(ivy-set-occur 'ivy-switch-buffer-other-window 'ivy-switch-buffer-occur)
+
+(defun ivy--occur-insert-lines (cands)
+ "Insert CANDS into `ivy-occur' buffer."
+ (dolist (str cands)
+ (add-text-properties
+ 0 (length str)
+ `(mouse-face
+ highlight
+ help-echo "mouse-1: call ivy-action")
+ str)
+ (insert str "\n"))
+ (goto-char (point-min))
+ (forward-line 4))
+
+(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 (plist-get ivy--occurs-list caller))
+ (buffer
+ (generate-new-buffer
+ (format "*ivy-occur%s \"%s\"*"
+ (if caller
+ (concat " " (prin1-to-string caller))
+ "")
+ ivy-text))))
+ (with-current-buffer buffer
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (if occur-fn
+ (funcall occur-fn)
+ (ivy-occur-mode)
+ (insert (format "%d candidates:\n" (length ivy--old-cands)))
+ (read-only-mode)
+ (ivy--occur-insert-lines
+ (mapcar
+ (lambda (cand) (concat " " cand))
+ ivy--old-cands))))
+ (setf (ivy-state-text ivy-last) ivy-text)
+ (setq ivy-occur-last ivy-last)
+ (setq-local ivy--directory ivy--directory))
+ (ivy-exit-with-action
+ `(lambda (_) (pop-to-buffer ,buffer))))))
+
+(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 orignal 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))
+ (cond ((eq caller 'swiper)
+ (let ((buffer (ivy-state-buffer ivy-occur-last)))
+ (unless (buffer-live-p buffer)
+ (error "Buffer was killed"))
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (funcall (plist-get ivy--occurs-list caller) t)
+ (ivy-occur-grep-mode))))
+ ((memq caller '(counsel-git-grep counsel-grep counsel-ag counsel-rg))
+ (let ((inhibit-read-only t))
+ (erase-buffer)
+ (funcall (plist-get ivy--occurs-list caller)))))
+ (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)
+(defvar counsel-grep-last-line)
+
+(defun ivy-occur-press ()
+ "Execute action for the current candidate."
+ (interactive)
+ (when (save-excursion
+ (beginning-of-line)
+ (looking-at "\\(?:./\\| \\)\\(.*\\)$"))
+ (when (memq (ivy-state-caller ivy-occur-last)
+ '(swiper counsel-git-grep counsel-grep counsel-ag counsel-rg
+ counsel-describe-function counsel-describe-variable))
+ (let ((window (ivy-state-window ivy-occur-last)))
+ (when (or (null (window-live-p window))
+ (equal window (selected-window)))
+ (save-selected-window
+ (setf (ivy-state-window ivy-occur-last)
+ (display-buffer (ivy-state-buffer ivy-occur-last)
+ 'display-buffer-pop-up-window))))))
+ (let* ((ivy-last ivy-occur-last)
+ (ivy-text (ivy-state-text ivy-last))
+ (str (buffer-substring
+ (match-beginning 1)
+ (match-end 1)))
+ (coll (ivy-state-collection ivy-last))
+ (action (ivy--get-action ivy-last))
+ (ivy-exit 'done))
+ (with-ivy-window
+ (setq counsel-grep-last-line nil)
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (funcall action
+ (if (and (consp coll)
+ (consp (car coll)))
+ (assoc str coll)
+ str)))
+ (if (memq (ivy-state-caller ivy-last)
+ '(swiper counsel-git-grep counsel-grep counsel-ag counsel-rg))
+ (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)))
+
+(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'.")
+
+(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)
+ (view-mode)
+ (goto-char (point-min))))
+ (if (eq this-command 'ivy-help)
+ (switch-to-buffer buf)
+ (with-ivy-window
+ (pop-to-buffer buf)))
+ (view-mode)
+ (goto-char (point-min))))
+
+(provide 'ivy)
+
+;;; ivy.el ends here
.emacs.d/elpa/ivy-20170911.1034/ivy.elc
Binary file
.emacs.d/elpa/ivy-20170911.1034/ivy.info
@@ -0,0 +1,1864 @@
+This is ivy.info, produced by makeinfo version 5.2 from ivy.texi.
+
+Ivy manual, version 0.8.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 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, with the Front-Cover Texts
+ being โA GNU Manual,โ and with the Back-Cover Texts as in (a)
+ below. A copy of the license is included in the section entitled
+ โGNU Free Documentation License.โ
+
+ (a) The FSFโs Back-Cover Text is: โYou have the freedom to copy and
+ modify this GNU manual.โ
+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
+***************
+
+Ivy manual, version 0.8.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 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, with the Front-Cover Texts
+ being โA GNU Manual,โ and with the Back-Cover Texts as in (a)
+ below. A copy of the license is included in the section entitled
+ โGNU Free Documentation License.โ
+
+ (a) The FSFโs Back-Cover Text is: โYou have the freedom to copy and
+ modify this GNU 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::
+
+
+
+API
+
+* Required arguments for โivy-readโ::
+* Optional arguments for โivy-readโ::
+* Example - โcounsel-describe-functionโ::
+* Example - โcounsel-locateโ::
+
+
+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-functionโ). 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.1 is the oldest version to run Ivy. Emacs 24.5.1 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โ โswiperโ โRETโ
+
+ Ivy is installed as part of โswiperโ package. โswiperโ 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. See the code
+below for adding MELPA to the list of package archives:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa" . "http://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
+=======================
+
+The recommended key bindings are:
+
+Ivy-based interface to standard commands
+........................................
+
+ (global-set-key (kbd "C-s") 'swiper)
+ (global-set-key (kbd "M-x") 'counsel-M-x)
+ (global-set-key (kbd "C-x C-f") 'counsel-find-file)
+ (global-set-key (kbd "<f1> f") 'counsel-describe-function)
+ (global-set-key (kbd "<f1> v") 'counsel-describe-variable)
+ (global-set-key (kbd "<f1> l") 'counsel-find-library)
+ (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
+ (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
+
+Ivy-based interface to shell and system tools
+.............................................
+
+ (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 k") 'counsel-ag)
+ (global-set-key (kbd "C-x l") 'counsel-locate)
+ (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
+
+Ivy-resume and other commands
+.............................
+
+ โivy-resumeโ resumes the last Ivy-based completion.
+
+ (global-set-key (kbd "C-c C-r") 'ivy-resume)
+
+
+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.
+
+ Warp-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 <tab>")
+ "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โ. Applies an action and moves to next
+ line.
+
+ 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โ.
+
+โ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 additioanl bindings:
+
+โcโ (โivy-toggle-callingโ)
+..........................
+
+ Toggle calling the action after each candidate change. It modifies
+ โjโ to โjgโ, โkโ to โkgโ etc.
+
+โmโ (โivy-toggle-fuzzyโ)
+........................
+
+ Toggle 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).
+
+
+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 โjโ (โ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)
+
+
+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โ and valid only in Emacs versions
+ 24.5 or newer.
+
+ Set โivy-display-styleโ to โnilโ for a plain minibuffer.
+
+ -- User Option: ivy-on-del-error-function
+ Specify what when โDELโ (โivy-backward-delete-charโ) throws.
+
+ 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โ
+.......
+
+ Magit requires this setting for ivy completion:
+
+ (setq magit-completing-read-function 'ivy-completing-read)
+
+โfind-file-in-projectโ
+......................
+
+ It 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)
+
+
+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.
+
+Using TRAMP
+...........
+
+ 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.
+
+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.
+
+
+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โ::
+
+
+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 format string normally ending in a colon and a space.
+
+ โ%dโ anywhere in the string is replaced by the current number of
+ matching candidates. To use a literal โ%โ character, escape it as
+ โ%%โ. See also โivy-count-formatโ.
+
+โ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โ
+...........
+
+ When set to a string value, select the first candidate matching
+ this value.
+
+ When set to an integer value, select the candidate with that index
+ value.
+
+ Every time the input becomes empty, the item corresponding to 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 (counsel-symbol-at-point)
+ :history 'counsel-describe-symbol-history
+ :require-match t
+ :sort 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 โcounsel-symbol-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 โsortโ argument is set to โtโ so choosing between similar
+ candidates becomes easier. Sometimes, the collection size will
+ exceed โivy-sort-max-sizeโ, which is 30000 by default. In that
+ case the sorting will not happen to avoid delays.
+
+ Adjust this variable to choose between sorting time and completion
+ start-up time.
+ โข 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โ, 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)
+ (if (< (length str) 3)
+ (counsel-more-chars 3)
+ (counsel--async-command
+ (format "locate %s '%s'"
+ (mapconcat #'identity counsel-locate-options " ")
+ (counsel-unquote-regex-parens
+ (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.
+ โข โcounsel-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: 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-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 32)
+* 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-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-fuzzy: Hydra in the minibuffer.
+ (line 40)
+* 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)
+* //: File Name Completion. (line 25)
+* <: Hydra in the minibuffer.
+ (line 50)
+* >: Hydra in the minibuffer.
+ (line 45)
+* ~: File Name Completion. (line 30)
+* 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)
+* j: Saving the current completion session to a buffer.
+ (line 16)
+* j <1>: 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: Top1355
+Node: Introduction4402
+Node: Installation6913
+Node: Installing from Emacs Package Manager7367
+Node: Installing from the Git repository8326
+Node: Getting started9176
+Node: Basic customization9483
+Node: Key bindings10078
+Node: Global key bindings10270
+Node: Minibuffer key bindings11658
+Node: Key bindings for navigation12890
+Node: Key bindings for single selection action then exit minibuffer14097
+Node: Key bindings for multiple selections and actions keep minibuffer open16814
+Node: Key bindings that alter the minibuffer input19206
+Node: Other key bindings21094
+Node: Hydra in the minibuffer21472
+Node: Saving the current completion session to a buffer23549
+Node: Completion Styles24961
+Node: ivy--regex-plus26719
+Node: ivy--regex-ignore-order28205
+Node: ivy--regex-fuzzy28573
+Node: Customization29070
+Node: Faces29256
+Node: Defcustoms31393
+Node: Actions32570
+Node: What are actions?32896
+Node: How can different actions be called?33729
+Node: How to modify the actions list?34300
+Node: Example - add two actions to each command34960
+Node: How to undo adding the two actions35919
+Node: How to add actions to a specific command36371
+Node: Example - define a new command with several actions36787
+Node: Test the above function with โivy-occurโ37730
+Node: Packages38578
+Node: Commands39436
+Node: File Name Completion39621
+Node: Buffer Name Completion41947
+Node: Counsel commands42567
+Node: API43214
+Node: Required arguments for โivy-readโ43791
+Node: Optional arguments for โivy-readโ44456
+Node: Example - โcounsel-describe-functionโ47690
+Node: Example - โcounsel-locateโ51094
+Node: Variable Index54942
+Node: Keystroke Index61843
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
.emacs.d/elpa/ivy-hydra-20170703.2350/ivy-hydra-autoloads.el
@@ -0,0 +1,15 @@
+;;; ivy-hydra-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("ivy-hydra.el") (22977 29292 681923 926000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ivy-hydra-autoloads.el ends here
.emacs.d/elpa/ivy-hydra-20170703.2350/ivy-hydra-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "ivy-hydra" "20170703.2350" "Additional key bindings for Ivy" '((emacs "24.1") (ivy "0.9.0") (hydra "0.13.4")) :commit "ae438ff62fa3d9b98d899afc0e97c13be2148725" :url "https://github.com/abo-abo/swiper" :keywords '("completion" "matching" "bindings"))
.emacs.d/elpa/ivy-hydra-20170703.2350/ivy-hydra.el
@@ -0,0 +1,116 @@
+;;; ivy-hydra.el --- Additional key bindings for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Package-Version: 20170703.2350
+;; Version: 0.9.1
+;; Package-Requires: ((emacs "24.1") (ivy "0.9.0") (hydra "0.13.4"))
+;; Keywords: completion, matching, bindings
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; 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 (assoc 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)
+ ;; actions
+ ("o" keyboard-escape-quit :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" 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.")
+
+(defun ivy-dispatching-done-hydra ()
+ "Select one of the available actions and call `ivy-done'."
+ (interactive)
+ (let* ((actions (ivy-state-action ivy-last))
+ (estimated-len (+ 25 (length
+ (mapconcat
+ (lambda (x) (format "[%s] %s" (nth 0 x) (nth 2 x)))
+ (cdr actions) ", "))))
+ (n-columns (if (> estimated-len (window-width))
+ ivy-dispatching-done-columns
+ nil)))
+ (if (null (ivy--actionp actions))
+ (ivy-done)
+ (funcall
+ (eval
+ `(defhydra ivy-read-action (:color teal :columns ,n-columns)
+ "action"
+ ,@(mapcar (lambda (x)
+ (list (nth 0 x)
+ `(progn
+ (ivy-set-action ',(nth 1 x))
+ (ivy-done))
+ (nth 2 x)))
+ (cdr actions))
+ ("M-o" nil "back")
+ ("C-g" nil)))))))
+
+(define-key ivy-minibuffer-map (kbd "M-o") 'ivy-dispatching-done-hydra)
+
+(provide 'ivy-hydra)
+
+;;; ivy-hydra.el ends here
.emacs.d/elpa/ivy-hydra-20170703.2350/ivy-hydra.elc
Binary file
.emacs.d/elpa/s-20170906.1304/s-autoloads.el
@@ -0,0 +1,15 @@
+;;; s-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("s.el") (22970 55043 602679 488000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; s-autoloads.el ends here
.emacs.d/elpa/s-20170906.1304/s-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "s" "20170906.1304" "The long lost Emacs string manipulation library." 'nil :commit "3a95064647d1f39b90e65a56f1fdfceb7c329f75" :keywords '("strings"))
.emacs.d/elpa/s-20170906.1304/s.el
@@ -0,0 +1,642 @@
+;;; s.el --- The long lost Emacs string manipulation library.
+
+;; Copyright (C) 2012-2015 Magnar Sveen
+
+;; Author: Magnar Sveen <magnars@gmail.com>
+;; Version: 1.10.0
+;; Package-Version: 20170906.1304
+;; Keywords: strings
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The long lost Emacs string manipulation library.
+;;
+;; See documentation on https://github.com/magnars/s.el#functions
+
+;;; Code:
+
+;; Silence byte-compiler
+(defvar ucs-normalize-combining-chars) ; Defined in `ucs-normalize'
+(autoload 'slot-value "eieio")
+
+(defun s-trim-left (s)
+ "Remove whitespace at the beginning of S."
+ (save-match-data
+ (if (string-match "\\`[ \t\n\r]+" s)
+ (replace-match "" t t s)
+ s)))
+
+(defun s-trim-right (s)
+ "Remove whitespace at the end of S."
+ (save-match-data
+ (if (string-match "[ \t\n\r]+\\'" s)
+ (replace-match "" t t s)
+ s)))
+
+(defun s-trim (s)
+ "Remove whitespace at the beginning and end of S."
+ (s-trim-left (s-trim-right s)))
+
+(defun s-collapse-whitespace (s)
+ "Convert all adjacent whitespace characters to a single space."
+ (replace-regexp-in-string "[ \t\n\r]+" " " s))
+
+(defun s-split (separator s &optional omit-nulls)
+ "Split S into substrings bounded by matches for regexp SEPARATOR.
+If OMIT-NULLS is non-nil, zero-length substrings are omitted.
+
+This is a simple wrapper around the built-in `split-string'."
+ (save-match-data
+ (split-string s separator omit-nulls)))
+
+(defun s-split-up-to (separator s n &optional omit-nulls)
+ "Split S up to N times into substrings bounded by matches for regexp SEPARATOR.
+
+If OMIT-NULLS is non-nil, zero-length substrings are omitted.
+
+See also `s-split'."
+ (save-match-data
+ (let ((op 0)
+ (r nil))
+ (with-temp-buffer
+ (insert s)
+ (setq op (goto-char (point-min)))
+ (while (and (re-search-forward separator nil t)
+ (< 0 n))
+ (let ((sub (buffer-substring op (match-beginning 0))))
+ (unless (and omit-nulls
+ (equal sub ""))
+ (push sub r)))
+ (setq op (goto-char (match-end 0)))
+ (setq n (1- n)))
+ (let ((sub (buffer-substring op (point-max))))
+ (unless (and omit-nulls
+ (equal sub ""))
+ (push sub r))))
+ (nreverse r))))
+
+(defun s-lines (s)
+ "Splits S into a list of strings on newline characters."
+ (s-split "\\(\r\n\\|[\n\r]\\)" s))
+
+(defun s-join (separator strings)
+ "Join all the strings in STRINGS with SEPARATOR in between."
+ (mapconcat 'identity strings separator))
+
+(defun s-concat (&rest strings)
+ "Join all the string arguments into one string."
+ (apply 'concat strings))
+
+(defun s-prepend (prefix s)
+ "Concatenate PREFIX and S."
+ (concat prefix s))
+
+(defun s-append (suffix s)
+ "Concatenate S and SUFFIX."
+ (concat s suffix))
+
+(defun s-repeat (num s)
+ "Make a string of S repeated NUM times."
+ (let (ss)
+ (while (> num 0)
+ (setq ss (cons s ss))
+ (setq num (1- num)))
+ (apply 'concat ss)))
+
+(defun s-chop-suffix (suffix s)
+ "Remove SUFFIX if it is at end of S."
+ (let ((pos (- (length suffix))))
+ (if (and (>= (length s) (length suffix))
+ (string= suffix (substring s pos)))
+ (substring s 0 pos)
+ s)))
+
+(defun s-chop-suffixes (suffixes s)
+ "Remove SUFFIXES one by one in order, if they are at the end of S."
+ (while suffixes
+ (setq s (s-chop-suffix (car suffixes) s))
+ (setq suffixes (cdr suffixes)))
+ s)
+
+(defun s-chop-prefix (prefix s)
+ "Remove PREFIX if it is at the start of S."
+ (let ((pos (length prefix)))
+ (if (and (>= (length s) (length prefix))
+ (string= prefix (substring s 0 pos)))
+ (substring s pos)
+ s)))
+
+(defun s-chop-prefixes (prefixes s)
+ "Remove PREFIXES one by one in order, if they are at the start of S."
+ (while prefixes
+ (setq s (s-chop-prefix (car prefixes) s))
+ (setq prefixes (cdr prefixes)))
+ s)
+
+(defun s-shared-start (s1 s2)
+ "Returns the longest prefix S1 and S2 have in common."
+ (let ((search-length (min (length s1) (length s2)))
+ (i 0))
+ (while (and (< i search-length)
+ (= (aref s1 i) (aref s2 i)))
+ (setq i (1+ i)))
+ (substring s1 0 i)))
+
+(defun s-shared-end (s1 s2)
+ "Returns the longest suffix S1 and S2 have in common."
+ (let* ((l1 (length s1))
+ (l2 (length s2))
+ (search-length (min l1 l2))
+ (i 0))
+ (while (and (< i search-length)
+ (= (aref s1 (- l1 i 1)) (aref s2 (- l2 i 1))))
+ (setq i (1+ i)))
+ ;; If I is 0, then it means that there's no common suffix between
+ ;; S1 and S2.
+ ;;
+ ;; However, since (substring s (- 0)) will return the whole
+ ;; string, `s-shared-end' should simply return the empty string
+ ;; when I is 0.
+ (if (zerop i)
+ ""
+ (substring s1 (- i)))))
+
+(defun s-chomp (s)
+ "Remove one trailing `\\n`, `\\r` or `\\r\\n` from S."
+ (s-chop-suffixes '("\n" "\r") s))
+
+(defun s-truncate (len s)
+ "If S is longer than LEN, cut it down to LEN - 3 and add ... at the end."
+ (if (> (length s) len)
+ (format "%s..." (substring s 0 (- len 3)))
+ s))
+
+(defun s-word-wrap (len s)
+ "If S is longer than LEN, wrap the words with newlines."
+ (save-match-data
+ (with-temp-buffer
+ (insert s)
+ (let ((fill-column len))
+ (fill-region (point-min) (point-max)))
+ (buffer-substring (point-min) (point-max)))))
+
+(defun s-center (len s)
+ "If S is shorter than LEN, pad it with spaces so it is centered."
+ (let ((extra (max 0 (- len (length s)))))
+ (concat
+ (make-string (ceiling extra 2) ? )
+ s
+ (make-string (floor extra 2) ? ))))
+
+(defun s-pad-left (len padding s)
+ "If S is shorter than LEN, pad it with PADDING on the left."
+ (let ((extra (max 0 (- len (length s)))))
+ (concat (make-string extra (string-to-char padding))
+ s)))
+
+(defun s-pad-right (len padding s)
+ "If S is shorter than LEN, pad it with PADDING on the right."
+ (let ((extra (max 0 (- len (length s)))))
+ (concat s
+ (make-string extra (string-to-char padding)))))
+
+(defun s-left (len s)
+ "Returns up to the LEN first chars of S."
+ (if (> (length s) len)
+ (substring s 0 len)
+ s))
+
+(defun s-right (len s)
+ "Returns up to the LEN last chars of S."
+ (let ((l (length s)))
+ (if (> l len)
+ (substring s (- l len) l)
+ s)))
+
+(defun s-ends-with? (suffix s &optional ignore-case)
+ "Does S end with SUFFIX?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences.
+
+Alias: `s-suffix?'"
+ (let ((start-pos (- (length s) (length suffix))))
+ (and (>= start-pos 0)
+ (eq t (compare-strings suffix nil nil
+ s start-pos nil ignore-case)))))
+
+(defun s-starts-with? (prefix s &optional ignore-case)
+ "Does S start with PREFIX?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences.
+
+Alias: `s-prefix?'. This is a simple wrapper around the built-in
+`string-prefix-p'."
+ (string-prefix-p prefix s ignore-case))
+
+(defun s--truthy? (val)
+ (not (null val)))
+
+(defun s-contains? (needle s &optional ignore-case)
+ "Does S contain NEEDLE?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+ (let ((case-fold-search ignore-case))
+ (s--truthy? (string-match-p (regexp-quote needle) s))))
+
+(defun s-equals? (s1 s2)
+ "Is S1 equal to S2?
+
+This is a simple wrapper around the built-in `string-equal'."
+ (string-equal s1 s2))
+
+(defun s-less? (s1 s2)
+ "Is S1 less than S2?
+
+This is a simple wrapper around the built-in `string-lessp'."
+ (string-lessp s1 s2))
+
+(defun s-matches? (regexp s &optional start)
+ "Does REGEXP match S?
+If START is non-nil the search starts at that index.
+
+This is a simple wrapper around the built-in `string-match-p'."
+ (s--truthy? (string-match-p regexp s start)))
+
+(defun s-blank? (s)
+ "Is S nil or the empty string?"
+ (or (null s) (string= "" s)))
+
+(defun s-blank-str? (s)
+ "Is S nil or the empty string or string only contains whitespace?"
+ (or (s-blank? s) (s-blank? (s-trim s))))
+
+(defun s-present? (s)
+ "Is S anything but nil or the empty string?"
+ (not (s-blank? s)))
+
+(defun s-presence (s)
+ "Return S if it's `s-present?', otherwise return nil."
+ (and (s-present? s) s))
+
+(defun s-lowercase? (s)
+ "Are all the letters in S in lower case?"
+ (let ((case-fold-search nil))
+ (not (string-match-p "[[:upper:]]" s))))
+
+(defun s-uppercase? (s)
+ "Are all the letters in S in upper case?"
+ (let ((case-fold-search nil))
+ (not (string-match-p "[[:lower:]]" s))))
+
+(defun s-mixedcase? (s)
+ "Are there both lower case and upper case letters in S?"
+ (let ((case-fold-search nil))
+ (s--truthy?
+ (and (string-match-p "[[:lower:]]" s)
+ (string-match-p "[[:upper:]]" s)))))
+
+(defun s-capitalized? (s)
+ "In S, is the first letter upper case, and all other letters lower case?"
+ (let ((case-fold-search nil))
+ (s--truthy?
+ (string-match-p "^[[:upper:]][^[:upper:]]*$" s))))
+
+(defun s-numeric? (s)
+ "Is S a number?"
+ (s--truthy?
+ (string-match-p "^[0-9]+$" s)))
+
+(defun s-replace (old new s)
+ "Replaces OLD with NEW in S."
+ (replace-regexp-in-string (regexp-quote old) new s t t))
+
+(defun s--aget (alist key)
+ (cdr (assoc-string key alist)))
+
+(defun s-replace-all (replacements s)
+ "REPLACEMENTS is a list of cons-cells. Each `car` is replaced with `cdr` in S."
+ (replace-regexp-in-string (regexp-opt (mapcar 'car replacements))
+ (lambda (it) (s--aget replacements it))
+ s t t))
+
+(defun s-downcase (s)
+ "Convert S to lower case.
+
+This is a simple wrapper around the built-in `downcase'."
+ (downcase s))
+
+(defun s-upcase (s)
+ "Convert S to upper case.
+
+This is a simple wrapper around the built-in `upcase'."
+ (upcase s))
+
+(defun s-capitalize (s)
+ "Convert the first word's first character to upper case and the rest to lower case in S."
+ (concat (upcase (substring s 0 1)) (downcase (substring s 1))))
+
+(defun s-titleize (s)
+ "Convert each word's first character to upper case and the rest to lower case in S.
+
+This is a simple wrapper around the built-in `capitalize'."
+ (capitalize s))
+
+(defmacro s-with (s form &rest more)
+ "Threads S through the forms. Inserts S as the last item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, inserts the first form as the
+last item in second form, etc."
+ (declare (debug (form &rest [&or (function &rest form) fboundp])))
+ (if (null more)
+ (if (listp form)
+ `(,(car form) ,@(cdr form) ,s)
+ (list form s))
+ `(s-with (s-with ,s ,form) ,@more)))
+
+(put 's-with 'lisp-indent-function 1)
+
+(defun s-index-of (needle s &optional ignore-case)
+ "Returns first index of NEEDLE in S, or nil.
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+ (let ((case-fold-search ignore-case))
+ (string-match-p (regexp-quote needle) s)))
+
+(defun s-reverse (s)
+ "Return the reverse of S."
+ (save-match-data
+ (if (multibyte-string-p s)
+ (let ((input (string-to-list s))
+ output)
+ (require 'ucs-normalize)
+ (while input
+ ;; Handle entire grapheme cluster as a single unit
+ (let ((grapheme (list (pop input))))
+ (while (memql (car input) ucs-normalize-combining-chars)
+ (push (pop input) grapheme))
+ (setq output (nconc (nreverse grapheme) output))))
+ (concat output))
+ (concat (nreverse (string-to-list s))))))
+
+(defun s-match-strings-all (regex string)
+ "Return a list of matches for REGEX in STRING.
+
+Each element itself is a list of matches, as per
+`match-string'. Multiple matches at the same position will be
+ignored after the first."
+ (save-match-data
+ (let ((all-strings ())
+ (i 0))
+ (while (and (< i (length string))
+ (string-match regex string i))
+ (setq i (1+ (match-beginning 0)))
+ (let (strings
+ (num-matches (/ (length (match-data)) 2))
+ (match 0))
+ (while (/= match num-matches)
+ (push (match-string match string) strings)
+ (setq match (1+ match)))
+ (push (nreverse strings) all-strings)))
+ (nreverse all-strings))))
+
+(defun s-matched-positions-all (regexp string &optional subexp-depth)
+ "Return a list of matched positions for REGEXP in STRING.
+SUBEXP-DEPTH is 0 by default."
+ (if (null subexp-depth)
+ (setq subexp-depth 0))
+ (save-match-data
+ (let ((pos 0) result)
+ (while (and (string-match regexp string pos)
+ (< pos (length string)))
+ (let ((m (match-end subexp-depth)))
+ (push (cons (match-beginning subexp-depth) (match-end subexp-depth)) result)
+ (setq pos (match-end 0))))
+ (nreverse result))))
+
+(defun s-match (regexp s &optional start)
+ "When the given expression matches the string, this function returns a list
+of the whole matching string and a string for each matched subexpressions.
+If it did not match the returned value is an empty list (nil).
+
+When START is non-nil the search will start at that index."
+ (save-match-data
+ (if (string-match regexp s start)
+ (let ((match-data-list (match-data))
+ result)
+ (while match-data-list
+ (let* ((beg (car match-data-list))
+ (end (cadr match-data-list))
+ (subs (if (and beg end) (substring s beg end) nil)))
+ (setq result (cons subs result))
+ (setq match-data-list
+ (cddr match-data-list))))
+ (nreverse result)))))
+
+(defun s-slice-at (regexp s)
+ "Slices S up at every index matching REGEXP."
+ (if (= 0 (length s)) (list "")
+ (save-match-data
+ (let (i)
+ (setq i (string-match regexp s 1))
+ (if i
+ (cons (substring s 0 i)
+ (s-slice-at regexp (substring s i)))
+ (list s))))))
+
+(defun s-split-words (s)
+ "Split S into list of words."
+ (s-split
+ "[^[:word:]0-9]+"
+ (let ((case-fold-search nil))
+ (replace-regexp-in-string
+ "\\([[:lower:]]\\)\\([[:upper:]]\\)" "\\1 \\2"
+ (replace-regexp-in-string "\\([[:upper:]]\\)\\([[:upper:]][0-9[:lower:]]\\)" "\\1 \\2" s)))
+ t))
+
+(defun s--mapcar-head (fn-head fn-rest list)
+ "Like MAPCAR, but applies a different function to the first element."
+ (if list
+ (cons (funcall fn-head (car list)) (mapcar fn-rest (cdr list)))))
+
+(defun s-lower-camel-case (s)
+ "Convert S to lowerCamelCase."
+ (s-join "" (s--mapcar-head 'downcase 'capitalize (s-split-words s))))
+
+(defun s-upper-camel-case (s)
+ "Convert S to UpperCamelCase."
+ (s-join "" (mapcar 'capitalize (s-split-words s))))
+
+(defun s-snake-case (s)
+ "Convert S to snake_case."
+ (s-join "_" (mapcar 'downcase (s-split-words s))))
+
+(defun s-dashed-words (s)
+ "Convert S to dashed-words."
+ (s-join "-" (mapcar 'downcase (s-split-words s))))
+
+(defun s-capitalized-words (s)
+ "Convert S to Capitalized words."
+ (let ((words (s-split-words s)))
+ (s-join " " (cons (capitalize (car words)) (mapcar 'downcase (cdr words))))))
+
+(defun s-titleized-words (s)
+ "Convert S to Titleized Words."
+ (s-join " " (mapcar 's-titleize (s-split-words s))))
+
+(defun s-word-initials (s)
+ "Convert S to its initials."
+ (s-join "" (mapcar (lambda (ss) (substring ss 0 1))
+ (s-split-words s))))
+
+;; Errors for s-format
+(progn
+ (put 's-format-resolve
+ 'error-conditions
+ '(error s-format s-format-resolve))
+ (put 's-format-resolve
+ 'error-message
+ "Cannot resolve a template to values"))
+
+(defun s-format (template replacer &optional extra)
+ "Format TEMPLATE with the function REPLACER.
+
+REPLACER takes an argument of the format variable and optionally
+an extra argument which is the EXTRA value from the call to
+`s-format'.
+
+Several standard `s-format' helper functions are recognized and
+adapted for this:
+
+ (s-format \"${name}\" 'gethash hash-table)
+ (s-format \"${name}\" 'aget alist)
+ (s-format \"$0\" 'elt sequence)
+
+The REPLACER function may be used to do any other kind of
+transformation."
+ (let ((saved-match-data (match-data)))
+ (unwind-protect
+ (replace-regexp-in-string
+ "\\$\\({\\([^}]+\\)}\\|[0-9]+\\)"
+ (lambda (md)
+ (let ((var
+ (let ((m (match-string 2 md)))
+ (if m m
+ (string-to-number (match-string 1 md)))))
+ (replacer-match-data (match-data)))
+ (unwind-protect
+ (let ((v
+ (cond
+ ((eq replacer 'gethash)
+ (funcall replacer var extra))
+ ((eq replacer 'aget)
+ (funcall 's--aget extra var))
+ ((eq replacer 'elt)
+ (funcall replacer extra var))
+ ((eq replacer 'oref)
+ (funcall #'slot-value extra (intern var)))
+ (t
+ (set-match-data saved-match-data)
+ (if extra
+ (funcall replacer var extra)
+ (funcall replacer var))))))
+ (if v (format "%s" v) (signal 's-format-resolve md)))
+ (set-match-data replacer-match-data)))) template
+ ;; Need literal to make sure it works
+ t t)
+ (set-match-data saved-match-data))))
+
+(defvar s-lex-value-as-lisp nil
+ "If `t' interpolate lisp values as lisp.
+
+`s-lex-format' inserts values with (format \"%S\").")
+
+(defun s-lex-fmt|expand (fmt)
+ "Expand FMT into lisp."
+ (list 's-format fmt (quote 'aget)
+ (append '(list)
+ (mapcar
+ (lambda (matches)
+ (list
+ 'cons
+ (cadr matches)
+ `(format
+ (if s-lex-value-as-lisp "%S" "%s")
+ ,(intern (cadr matches)))))
+ (s-match-strings-all "${\\([^}]+\\)}" fmt)))))
+
+(defmacro s-lex-format (format-str)
+ "`s-format` with the current environment.
+
+FORMAT-STR may use the `s-format' variable reference to refer to
+any variable:
+
+ (let ((x 1))
+ (s-lex-format \"x is: ${x}\"))
+
+The values of the variables are interpolated with \"%s\" unless
+the variable `s-lex-value-as-lisp' is `t' and then they are
+interpolated with \"%S\"."
+ (declare (debug (form)))
+ (s-lex-fmt|expand format-str))
+
+(defun s-count-matches (regexp s &optional start end)
+ "Count occurrences of `regexp' in `s'.
+
+`start', inclusive, and `end', exclusive, delimit the part of `s'
+to match. "
+ (save-match-data
+ (with-temp-buffer
+ (insert s)
+ (goto-char (point-min))
+ (count-matches regexp (or start 1) (or end (point-max))))))
+
+(defun s-wrap (s prefix &optional suffix)
+ "Wrap string S with PREFIX and optionally SUFFIX.
+
+Return string S with PREFIX prepended. If SUFFIX is present, it
+is appended, otherwise PREFIX is used as both prefix and
+suffix."
+ (concat prefix s (or suffix prefix)))
+
+
+;;; Aliases
+
+(defalias 's-blank-p 's-blank?)
+(defalias 's-blank-str-p 's-blank-str?)
+(defalias 's-capitalized-p 's-capitalized?)
+(defalias 's-contains-p 's-contains?)
+(defalias 's-ends-with-p 's-ends-with?)
+(defalias 's-equals-p 's-equals?)
+(defalias 's-less-p 's-less?)
+(defalias 's-lowercase-p 's-lowercase?)
+(defalias 's-matches-p 's-matches?)
+(defalias 's-mixedcase-p 's-mixedcase?)
+(defalias 's-numeric-p 's-numeric?)
+(defalias 's-prefix-p 's-starts-with?)
+(defalias 's-prefix? 's-starts-with?)
+(defalias 's-present-p 's-present?)
+(defalias 's-starts-with-p 's-starts-with?)
+(defalias 's-suffix-p 's-ends-with?)
+(defalias 's-suffix? 's-ends-with?)
+(defalias 's-uppercase-p 's-uppercase?)
+
+
+(provide 's)
+;;; s.el ends here
.emacs.d/elpa/s-20170906.1304/s.elc
Binary file
.emacs.d/elpa/swiper-20170911.1036/swiper-autoloads.el
@@ -0,0 +1,32 @@
+;;; swiper-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "swiper" "swiper.el" (22977 29293 461916 191000))
+;;; Generated autoloads from swiper.el
+
+(autoload 'swiper-avy "swiper" "\
+Jump to one of the current swiper candidates.
+
+\(fn)" t nil)
+
+(autoload 'swiper "swiper" "\
+`isearch' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'swiper-all "swiper" "\
+Run `swiper' for all open buffers.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; swiper-autoloads.el ends here
.emacs.d/elpa/swiper-20170911.1036/swiper-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "swiper" "20170911.1036" "Isearch with an overview. Oh, man!" '((emacs "24.1") (ivy "0.9.0")) :commit "0a1d361b926291874124f8c63a653d83ead64a36" :url "https://github.com/abo-abo/swiper" :keywords '("matching"))
.emacs.d/elpa/swiper-20170911.1036/swiper.el
@@ -0,0 +1,970 @@
+;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Package-Version: 20170911.1036
+;; Version: 0.9.1
+;; Package-Requires: ((emacs "24.1") (ivy "0.9.0"))
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package gives an overview of the current regex search
+;; candidates. The search regex can be split into groups with a
+;; space. Each group is highlighted with a different face.
+;;
+;; It can double as a quick `regex-builder', although only single
+;; lines will be matched.
+
+;;; Code:
+(require 'ivy)
+
+(defgroup swiper nil
+ "`isearch' with an overview."
+ :group 'matching
+ :prefix "swiper-")
+
+(defface swiper-match-face-1
+ '((t (:inherit isearch-lazy-highlight-face)))
+ "The background face for `swiper' matches.")
+
+(defface swiper-match-face-2
+ '((t (:inherit isearch)))
+ "Face for `swiper' matches modulo 1.")
+
+(defface swiper-match-face-3
+ '((t (:inherit match)))
+ "Face for `swiper' matches modulo 2.")
+
+(defface swiper-match-face-4
+ '((t (:inherit isearch-fail)))
+ "Face for `swiper' matches modulo 3.")
+
+(defface swiper-line-face
+ '((t (:inherit highlight)))
+ "Face for current `swiper' line.")
+
+(defcustom swiper-faces '(swiper-match-face-1
+ swiper-match-face-2
+ swiper-match-face-3
+ swiper-match-face-4)
+ "List of `swiper' faces for group matches."
+ :group 'ivy-faces
+ :type 'list)
+
+(defcustom swiper-min-highlight 2
+ "Only highlight matches for regexps at least this long."
+ :type 'integer)
+
+(defcustom swiper-include-line-number-in-search nil
+ "Include line number in text of search candidates."
+ :type 'boolean
+ :group 'swiper)
+
+(defcustom swiper-goto-start-of-match nil
+ "When non-nil, go to the start of the match, not its end."
+ :type 'boolean
+ :group 'swiper)
+
+(defvar swiper-map
+ (let ((map (make-sparse-keymap)))
+ (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)
+ (define-key map (kbd "C-7") 'swiper-mc)
+ (define-key map (kbd "C-c C-f") 'swiper-toggle-face-matching)
+ map)
+ "Keymap for swiper.")
+
+(defun swiper-query-replace ()
+ "Start `query-replace' with string to replace from last search string."
+ (interactive)
+ (if (null (window-minibuffer-p))
+ (user-error "Should only be called in the minibuffer through `swiper-map'")
+ (let* ((enable-recursive-minibuffers t)
+ (from (ivy--regex ivy-text))
+ (to (minibuffer-with-setup-hook
+ (lambda ()
+ (setq minibuffer-default
+ (if (string-match "\\`\\\\_<\\(.*\\)\\\\_>\\'" ivy-text)
+ (match-string 1 ivy-text)
+ ivy-text)))
+ (read-from-minibuffer (format "Query replace %s with: " from)))))
+ (swiper--cleanup)
+ (ivy-exit-with-action
+ (lambda (_)
+ (with-ivy-window
+ (move-beginning-of-line 1)
+ (perform-replace from to
+ t t nil)))))))
+
+(defun swiper-all-query-replace ()
+ "Start `query-replace' with string to replace from last search string."
+ (interactive)
+ (if (null (window-minibuffer-p))
+ (user-error
+ "Should only be called in the minibuffer through `swiper-all-map'")
+ (let* ((enable-recursive-minibuffers t)
+ (from (ivy--regex ivy-text))
+ (to (query-replace-read-to from "Query replace" t)))
+ (swiper--cleanup)
+ (ivy-exit-with-action
+ (lambda (_)
+ (let ((wnd-conf (current-window-configuration))
+ (inhibit-message t))
+ (unwind-protect
+ (dolist (cand ivy--old-cands)
+ (let ((buffer (get-text-property 0 'buffer cand)))
+ (switch-to-buffer buffer)
+ (goto-char (point-min))
+ (perform-replace from to t t nil)))
+ (set-window-configuration wnd-conf))))))))
+
+(defvar avy-background)
+(defvar avy-all-windows)
+(defvar avy-style)
+(defvar avy-keys)
+(declare-function avy--regex-candidates "ext:avy")
+(declare-function avy--process "ext:avy")
+(declare-function avy--overlay-post "ext:avy")
+(declare-function avy-action-goto "ext:avy")
+(declare-function avy-candidate-beg "ext:avy")
+(declare-function avy--done "ext:avy")
+(declare-function avy--make-backgrounds "ext:avy")
+(declare-function avy-window-list "ext:avy")
+(declare-function avy-read "ext:avy")
+(declare-function avy-read-de-bruijn "ext:avy")
+(declare-function avy-tree "ext:avy")
+(declare-function avy-push-mark "ext:avy")
+(declare-function avy--remove-leading-chars "ext:avy")
+
+;;;###autoload
+(defun swiper-avy ()
+ "Jump to one of the current swiper candidates."
+ (interactive)
+ (unless (require 'avy nil 'noerror)
+ (error "Package avy isn't installed"))
+ (unless (string= ivy-text "")
+ (let* ((avy-all-windows nil)
+ ;; We'll have overlapping overlays, so we sort all the
+ ;; overlays in the visible region by their start, and then
+ ;; throw out non-Swiper overlays or overlapping Swiper
+ ;; overlays.
+ (visible-overlays (cl-sort (with-ivy-window
+ (overlays-in (window-start)
+ (window-end)))
+ #'< :key #'overlay-start))
+ (min-overlay-start 0)
+ (overlays-for-avy (cl-remove-if-not
+ (lambda (ov)
+ (when (and (>= (overlay-start ov)
+ min-overlay-start)
+ (memq (overlay-get ov 'face)
+ swiper-faces))
+ (setq min-overlay-start (overlay-start ov))))
+ visible-overlays))
+ (candidates (append
+ (mapcar (lambda (ov)
+ (cons (overlay-start ov)
+ (overlay-get ov 'window)))
+ overlays-for-avy)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region (window-start) (window-end))
+ (goto-char (point-min))
+ (forward-line)
+ (let ((cands))
+ (while (< (point) (point-max))
+ (push (cons (1+ (point))
+ (selected-window))
+ cands)
+ (forward-line))
+ cands)))))
+ (candidate (unwind-protect
+ (prog2
+ (avy--make-backgrounds
+ (append (avy-window-list)
+ (list (ivy-state-window ivy-last))))
+ (if (eq avy-style 'de-bruijn)
+ (avy-read-de-bruijn
+ candidates avy-keys)
+ (avy-read (avy-tree candidates avy-keys)
+ #'avy--overlay-post
+ #'avy--remove-leading-chars))
+ (avy-push-mark))
+ (avy--done))))
+ (if (window-minibuffer-p (cdr candidate))
+ (progn
+ (ivy-set-index (- (line-number-at-pos (car candidate)) 2))
+ (ivy--exhibit)
+ (ivy-done)
+ (ivy-call))
+ (ivy-quit-and-run
+ (avy-action-goto (avy-candidate-beg candidate)))))))
+
+(declare-function mc/create-fake-cursor-at-point "ext:multiple-cursors-core")
+(declare-function multiple-cursors-mode "ext:multiple-cursors-core")
+
+(defun swiper-mc ()
+ "Create a fake cursor for each `swiper' candidate."
+ (interactive)
+ (unless (require 'multiple-cursors nil t)
+ (error "Multiple-cursors isn't installed"))
+ (unless (window-minibuffer-p)
+ (error "Call me only from `swiper'"))
+ (let ((cands (nreverse ivy--old-cands)))
+ (unless (string= ivy-text "")
+ (ivy-exit-with-action
+ (lambda (_)
+ (let (cand)
+ (while (setq cand (pop cands))
+ (swiper--action cand)
+ (when cands
+ (mc/create-fake-cursor-at-point))))
+ (multiple-cursors-mode 1))))))
+
+(defun swiper-recenter-top-bottom (&optional arg)
+ "Call (`recenter-top-bottom' ARG)."
+ (interactive "P")
+ (with-ivy-window
+ (recenter-top-bottom arg)))
+
+(defvar swiper-font-lock-exclude
+ '(bookmark-bmenu-mode
+ package-menu-mode
+ gnus-summary-mode
+ gnus-article-mode
+ gnus-group-mode
+ emms-playlist-mode
+ emms-stream-mode
+ erc-mode
+ forth-mode
+ forth-block-mode
+ nix-mode
+ org-agenda-mode
+ dired-mode
+ jabber-chat-mode
+ elfeed-search-mode
+ elfeed-show-mode
+ fundamental-mode
+ Man-mode
+ woman-mode
+ mu4e-view-mode
+ mu4e-headers-mode
+ notmuch-tree-mode
+ notmuch-search-mode
+ help-mode
+ debbugs-gnu-mode
+ occur-mode
+ occur-edit-mode
+ bongo-mode
+ bongo-library-mode
+ bongo-playlist-mode
+ eww-mode
+ twittering-mode
+ vc-dir-mode
+ rcirc-mode
+ circe-channel-mode
+ circe-server-mode
+ circe-query-mode
+ sauron-mode
+ w3m-mode)
+ "List of major-modes that are incompatible with `font-lock-ensure'.")
+
+(defun swiper-font-lock-ensure-p ()
+ "Return non-nil if we should `font-lock-ensure'."
+ (or (derived-mode-p 'magit-mode)
+ (bound-and-true-p magit-blame-mode)
+ (memq major-mode swiper-font-lock-exclude)))
+
+(defun swiper-font-lock-ensure ()
+ "Ensure the entired buffer is highlighted."
+ (unless (swiper-font-lock-ensure-p)
+ (unless (or (> (buffer-size) 100000) (null font-lock-mode))
+ (if (fboundp 'font-lock-ensure)
+ (font-lock-ensure)
+ (with-no-warnings (font-lock-fontify-buffer))))))
+
+(defvar swiper--format-spec ""
+ "Store the current candidates format spec.")
+
+(defvar swiper--width nil
+ "Store the number of digits needed for the longest line nubmer.")
+
+(defvar swiper-use-visual-line nil
+ "When non-nil, use `line-move' instead of `forward-line'.")
+
+(declare-function outline-show-all "outline")
+
+(defun swiper--candidates (&optional numbers-width)
+ "Return a list of this buffer lines.
+
+NUMBERS-WIDTH, when specified, is used for width spec of line
+numbers; replaces calculating the width from buffer line count."
+ (if (and visual-line-mode
+ ;; super-slow otherwise
+ (< (buffer-size) 20000))
+ (progn
+ (when (eq major-mode 'org-mode)
+ (require 'outline)
+ (if (fboundp 'outline-show-all)
+ (outline-show-all)
+ (with-no-warnings
+ (show-all))))
+ (setq swiper-use-visual-line t))
+ (setq swiper-use-visual-line nil))
+ (let ((n-lines (count-lines (point-min) (point-max))))
+ (unless (zerop n-lines)
+ (setq swiper--width (or numbers-width
+ (1+ (floor (log n-lines 10)))))
+ (setq swiper--format-spec
+ (format "%%-%dd " swiper--width))
+ (let ((line-number 0)
+ (advancer (if swiper-use-visual-line
+ (lambda (arg) (line-move arg t))
+ #'forward-line))
+ candidates)
+ (save-excursion
+ (goto-char (point-min))
+ (swiper-font-lock-ensure)
+ (while (< (point) (point-max))
+ (let ((str (concat
+ " "
+ (replace-regexp-in-string
+ "\t" " "
+ (if swiper-use-visual-line
+ (buffer-substring
+ (save-excursion
+ (beginning-of-visual-line)
+ (point))
+ (save-excursion
+ (end-of-visual-line)
+ (point)))
+ (buffer-substring
+ (point)
+ (line-end-position)))))))
+ (setq str (ivy-cleanup-string str))
+ (let ((line-number-str
+ (format swiper--format-spec (cl-incf line-number))))
+ (if swiper-include-line-number-in-search
+ (setq str (concat line-number-str str))
+ (put-text-property
+ 0 1 'display line-number-str str))
+ (put-text-property
+ 0 1 'swiper-line-number line-number-str str))
+ (push str candidates))
+ (funcall advancer 1))
+ (nreverse candidates))))))
+
+(defvar swiper--opoint 1
+ "The point when `swiper' starts.")
+
+;;;###autoload
+(defun swiper (&optional initial-input)
+ "`isearch' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+ (interactive)
+ (swiper--ivy (swiper--candidates) initial-input))
+
+(declare-function string-trim-right "subr-x")
+(defvar swiper--current-window-start nil)
+
+(defun swiper-occur (&optional revert)
+ "Generate a custom occur buffer for `swiper'.
+When REVERT is non-nil, regenerate the current *ivy-occur* buffer."
+ (require 'subr-x)
+ (let* ((buffer (ivy-state-buffer ivy-last))
+ (fname (propertize
+ (with-ivy-window
+ (if (buffer-file-name buffer)
+ (file-name-nondirectory
+ (buffer-file-name buffer))
+ (buffer-name buffer)))
+ 'face
+ 'compilation-info))
+ (cands (mapcar
+ (lambda (s)
+ (format "%s:%s:%s"
+ fname
+ (propertize
+ (string-trim-right
+ (get-text-property 0 'swiper-line-number s))
+ 'face 'compilation-line-number)
+ (substring s 1)))
+ (if (null revert)
+ ivy--old-cands
+ (setq ivy--old-re nil)
+ (let ((ivy--regex-function 'swiper--re-builder))
+ (ivy--filter
+ (progn (string-match "\"\\(.*\\)\"" (buffer-name))
+ (match-string 1 (buffer-name)))
+ (with-current-buffer buffer
+ (swiper--candidates))))))))
+ (unless (eq major-mode 'ivy-occur-grep-mode)
+ (ivy-occur-grep-mode)
+ (font-lock-mode -1))
+ (setq swiper--current-window-start nil)
+ (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
+ default-directory))
+ (insert (format "%d candidates:\n" (length cands)))
+ (ivy--occur-insert-lines
+ (mapcar
+ (lambda (cand) (concat "./" cand))
+ cands))
+ (goto-char (point-min))
+ (forward-line 4)))
+
+(ivy-set-occur 'swiper 'swiper-occur)
+
+(declare-function evil-set-jump "ext:evil-jumps")
+
+(defvar swiper--current-line nil)
+(defvar swiper--current-match-start nil)
+(defvar swiper--point-min nil)
+(defvar swiper--point-max nil)
+
+(defun swiper--init ()
+ "Perform initialization common to both completion methods."
+ (setq swiper--current-line nil)
+ (setq swiper--current-match-start nil)
+ (setq swiper--current-window-start nil)
+ (setq swiper--opoint (point))
+ (setq swiper--point-min (point-min))
+ (setq swiper--point-max (point-max))
+ (when (bound-and-true-p evil-mode)
+ (evil-set-jump)))
+
+(declare-function char-fold-to-regexp "char-fold")
+
+(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
+ (or (cdr (assoc 'swiper ivy-re-builders-alist))
+ (cdr (assoc t ivy-re-builders-alist))))
+ (re (cond
+ ((equal str "")
+ "")
+ ((equal str "^")
+ (setq ivy--subexps 0)
+ ".")
+ ((string-match "^\\^" str)
+ (let ((re (funcall re-builder (substring str 1))))
+ (if (zerop ivy--subexps)
+ (prog1 (format "^ ?\\(%s\\)" re)
+ (setq ivy--subexps 1))
+ (format "^ %s" re))))
+ ((eq (bound-and-true-p search-default-mode) 'char-fold-to-regexp)
+ (mapconcat #'char-fold-to-regexp (ivy--split str) ".*"))
+ (t
+ (funcall re-builder str)))))
+ re))
+
+(defvar swiper-history nil
+ "History for `swiper'.")
+
+(defvar swiper-invocation-face nil
+ "The face at the point of invocation of `swiper'.")
+
+(defun swiper--ivy (candidates &optional initial-input)
+ "Select one of CANDIDATES and move there.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+ (swiper--init)
+ (setq swiper-invocation-face
+ (plist-get (text-properties-at (point)) 'face))
+ (let ((preselect
+ (if swiper-use-visual-line
+ (count-screen-lines
+ (point-min)
+ (save-excursion (beginning-of-visual-line) (point)))
+ (1- (line-number-at-pos))))
+ (minibuffer-allow-text-properties t)
+ res)
+ (unwind-protect
+ (and
+ (setq res
+ (ivy-read
+ "Swiper: "
+ candidates
+ :initial-input initial-input
+ :keymap swiper-map
+ :preselect preselect
+ :require-match t
+ :update-fn #'swiper--update-input-ivy
+ :unwind #'swiper--cleanup
+ :action #'swiper--action
+ :re-builder #'swiper--re-builder
+ :history 'swiper-history
+ :caller 'swiper))
+ (point))
+ (unless res
+ (goto-char swiper--opoint)))))
+
+(defun swiper-toggle-face-matching ()
+ "Toggle matching only the candidates with `swiper-invocation-face'."
+ (interactive)
+ (setf (ivy-state-matcher ivy-last)
+ (if (ivy-state-matcher ivy-last)
+ nil
+ #'swiper--face-matcher))
+ (setq ivy--old-re nil))
+
+(defun swiper--face-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES.
+Matched candidates should have `swiper-invocation-face'."
+ (cl-remove-if-not
+ (lambda (x)
+ (and
+ (string-match regexp x)
+ (let ((s (match-string 0 x))
+ (i 0))
+ (while (and (< i (length s))
+ (text-property-any
+ i (1+ i)
+ 'face swiper-invocation-face
+ s))
+ (cl-incf i))
+ (eq i (length s)))))
+ candidates))
+
+(defun swiper--ensure-visible ()
+ "Remove overlays hiding point."
+ (let ((overlays (overlays-at (1- (point))))
+ ov expose)
+ (while (setq ov (pop overlays))
+ (if (and (invisible-p (overlay-get ov 'invisible))
+ (setq expose (overlay-get ov 'isearch-open-invisible)))
+ (funcall expose ov)))))
+
+(defvar swiper--overlays nil
+ "Store overlays.")
+
+(defun swiper--cleanup ()
+ "Clean up the overlays."
+ (while swiper--overlays
+ (delete-overlay (pop swiper--overlays)))
+ (save-excursion
+ (goto-char (point-min))
+ (isearch-clean-overlays)))
+
+(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* ((re (funcall ivy--regex-function ivy-text))
+ (re (if (stringp re) re (caar re)))
+ (re (replace-regexp-in-string
+ " " "\t"
+ re))
+ (str (get-text-property 0 'swiper-line-number (ivy-state-current ivy-last)))
+ (num (if (string-match "^[0-9]+" str)
+ (string-to-number (match-string 0 str))
+ 0)))
+ (unless (eq this-command 'ivy-yank-word)
+ (when (cl-plusp num)
+ (unless (if swiper--current-line
+ (eq swiper--current-line num)
+ (eq (line-number-at-pos) num))
+ (goto-char swiper--point-min)
+ (if swiper-use-visual-line
+ (line-move (1- num))
+ (forward-line (1- num))))
+ (if (and (equal ivy-text "")
+ (>= swiper--opoint (line-beginning-position))
+ (<= swiper--opoint (line-end-position)))
+ (goto-char swiper--opoint)
+ (if (eq swiper--current-line num)
+ (when swiper--current-match-start
+ (goto-char swiper--current-match-start))
+ (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))
+ (unless (and (>= (point) (window-start))
+ (<= (point) (window-end (ivy-state-window ivy-last) t)))
+ (recenter))
+ (setq swiper--current-window-start (window-start))))
+ (swiper--add-overlays
+ re
+ (max (window-start) swiper--point-min)
+ (min (window-end (selected-window) t) swiper--point-max))))))
+
+(defun swiper--add-overlays (re &optional beg end wnd)
+ "Add overlays for RE regexp in visible part of the current buffer.
+BEG and END, when specified, are the point bounds.
+WND, when specified is the window."
+ (setq wnd (or wnd (ivy-state-window ivy-last)))
+ (let ((ov (if visual-line-mode
+ (make-overlay
+ (save-excursion
+ (beginning-of-visual-line)
+ (point))
+ (save-excursion
+ (end-of-visual-line)
+ (point)))
+ (make-overlay
+ (line-beginning-position)
+ (1+ (line-end-position))))))
+ (overlay-put ov 'face 'swiper-line-face)
+ (overlay-put ov 'window wnd)
+ (push ov swiper--overlays)
+ (let* ((wh (window-height))
+ (beg (or beg (save-excursion
+ (forward-line (- wh))
+ (point))))
+ (end (or end (save-excursion
+ (forward-line wh)
+ (point))))
+ (case-fold-search (and ivy-case-fold-search
+ (string= re (downcase re)))))
+ (when (>= (length re) swiper-min-highlight)
+ (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))
+ (let ((mb (match-beginning 0))
+ (me (match-end 0)))
+ (unless (> (- me mb) 2017)
+ (swiper--add-overlay mb me
+ (if (zerop ivy--subexps)
+ (cadr swiper-faces)
+ (car swiper-faces))
+ wnd 0)))
+ (let ((i 1)
+ (j 0))
+ (while (<= (cl-incf j) ivy--subexps)
+ (let ((bm (match-beginning j))
+ (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))))
+ (swiper--add-overlay
+ bm em
+ (nth (1+ (mod (+ i 2) (1- (length swiper-faces))))
+ swiper-faces)
+ wnd i)
+ (cl-incf i)))))))))))
+
+(defun swiper--add-overlay (beg end face wnd priority)
+ "Add overlay bound by BEG and END to `swiper--overlays'.
+FACE, WND and PRIORITY are properties corresponding to
+the face, window and priority of the overlay."
+ (let ((overlay (make-overlay beg end)))
+ (push overlay swiper--overlays)
+ (overlay-put overlay 'face face)
+ (overlay-put overlay 'window wnd)
+ (overlay-put overlay 'priority priority)))
+
+(defcustom swiper-action-recenter nil
+ "When non-nil, recenter after exiting `swiper'."
+ :type 'boolean)
+(defvar evil-search-module)
+(defvar evil-ex-search-pattern)
+(defvar evil-ex-search-persistent-highlight)
+(defvar evil-ex-search-direction)
+(declare-function evil-ex-search-activate-highlight "evil-ex")
+
+
+(defun swiper--action (x)
+ "Goto line X."
+ (let ((ln (1- (read (or (get-text-property 0 'swiper-line-number x)
+ (and (string-match ":\\([0-9]+\\):.*\\'" x)
+ (match-string-no-properties 1 x))))))
+ (re (ivy--regex ivy-text)))
+ (if (null x)
+ (user-error "No candidates")
+ (with-ivy-window
+ (unless (equal (current-buffer)
+ (ivy-state-buffer ivy-last))
+ (switch-to-buffer (ivy-state-buffer ivy-last)))
+ (goto-char swiper--point-min)
+ (funcall (if swiper-use-visual-line
+ #'line-move
+ #'forward-line)
+ ln)
+ (when (and (re-search-forward re (line-end-position) t) swiper-goto-start-of-match)
+ (goto-char (match-beginning 0)))
+ (swiper--ensure-visible)
+ (cond (swiper-action-recenter
+ (recenter))
+ (swiper--current-window-start
+ (set-window-start (selected-window) swiper--current-window-start)))
+ (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)
+ (when (and (bound-and-true-p evil-mode)
+ (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)))
+
+(defvar swiper-multi-buffers nil
+ "Store the current list of buffers.")
+
+(defvar swiper-multi-candidates nil
+ "Store the list of candidates for `swiper-multi'.")
+
+(defun swiper-multi-prompt ()
+ "Return prompt for `swiper-multi'."
+ (format "Buffers (%s): "
+ (mapconcat #'identity swiper-multi-buffers ", ")))
+
+(defun swiper-multi ()
+ "Select one or more buffers.
+Run `swiper' for those buffers."
+ (interactive)
+ (setq swiper-multi-buffers nil)
+ (let ((ivy-use-virtual-buffers nil))
+ (ivy-read (swiper-multi-prompt)
+ 'internal-complete-buffer
+ :action 'swiper-multi-action-1))
+ (ivy-read "Swiper: " swiper-multi-candidates
+ :action 'swiper-multi-action-2
+ :unwind #'swiper--cleanup
+ :caller 'swiper-multi))
+
+(defun swiper-multi-action-1 (x)
+ "Add X to list of selected buffers `swiper-multi-buffers'.
+If X is already part of the list, remove it instead. Quit the selection if
+X is selected by either `ivy-done', `ivy-alt-done' or `ivy-immediate-done',
+otherwise continue prompting for buffers."
+ (if (member x swiper-multi-buffers)
+ (progn
+ (setq swiper-multi-buffers (delete x swiper-multi-buffers)))
+ (unless (equal x "")
+ (setq swiper-multi-buffers (append swiper-multi-buffers (list x)))))
+ (let ((prompt (swiper-multi-prompt)))
+ (setf (ivy-state-prompt ivy-last) prompt)
+ (setq ivy--prompt (concat "%-4d " prompt)))
+ (cond ((memq this-command '(ivy-done
+ ivy-alt-done
+ ivy-immediate-done))
+ (setq swiper-multi-candidates
+ (swiper--multi-candidates
+ (mapcar #'get-buffer swiper-multi-buffers))))
+ ((eq this-command 'ivy-call)
+ (with-selected-window (active-minibuffer-window)
+ (delete-minibuffer-contents)))))
+
+(defun swiper-multi-action-2 (x)
+ "Move to candidate X from `swiper-multi'."
+ (when (> (length x) 0)
+ (let ((buffer-name (get-text-property 0 'buffer x)))
+ (when buffer-name
+ (with-ivy-window
+ (switch-to-buffer buffer-name)
+ (goto-char (point-min))
+ (forward-line (1- (read (get-text-property 0 'swiper-line-number x))))
+ (re-search-forward
+ (ivy--regex ivy-text)
+ (line-end-position) t)
+ (isearch-range-invisible (line-beginning-position)
+ (line-end-position))
+ (unless (eq ivy-exit 'done)
+ (swiper--cleanup)
+ (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun swiper-all-buffer-p (buffer)
+ "Return non-nil if BUFFER should be considered by `swiper-all'."
+ (let ((major-mode (with-current-buffer buffer major-mode)))
+ (cond
+ ;; Ignore TAGS buffers, they tend to add duplicate results.
+ ((eq major-mode #'tags-table-mode) nil)
+ ;; Always consider dired buffers, even though they're not backed
+ ;; by a file.
+ ((eq major-mode #'dired-mode) t)
+ ;; Always consider stash buffers too, as they may have
+ ;; interesting content not present in any buffers. We don't #'
+ ;; quote to satisfy the byte-compiler.
+ ((eq major-mode 'magit-stash-mode) t)
+ ;; Email buffers have no file, but are useful to search
+ ((eq major-mode 'gnus-article-mode) t)
+ ;; Otherwise, only consider the file if it's backed by a file.
+ (t (buffer-file-name buffer)))))
+
+;;* `swiper-all'
+(defun swiper-all-function (str)
+ "Search in all open buffers for STR."
+ (if (and (< (length str) 3))
+ (list "" (format "%d chars more" (- 3 (length ivy-text))))
+ (let* ((buffers (cl-remove-if-not #'swiper-all-buffer-p (buffer-list)))
+ (re-full (funcall ivy--regex-function str))
+ re re-tail
+ cands match
+ (case-fold-search
+ (and ivy-case-fold-search
+ (string= str (downcase str)))))
+ (if (stringp re-full)
+ (setq re re-full)
+ (setq re (caar re-full))
+ (setq re-tail (cdr re-full)))
+ (dolist (buffer buffers)
+ (with-current-buffer buffer
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward re nil t)
+ (setq match (if (memq major-mode '(org-mode dired-mode))
+ (buffer-substring-no-properties
+ (line-beginning-position)
+ (line-end-position))
+ (buffer-substring
+ (line-beginning-position)
+ (line-end-position))))
+ (put-text-property
+ 0 1 'buffer
+ (buffer-name)
+ match)
+ (put-text-property 0 1 'point (point) match)
+ (when (or (null re-tail) (ivy-re-match re-tail match))
+ (push match cands))))))
+ (setq ivy--old-re re-full)
+ (if (null cands)
+ (list "")
+ (setq ivy--old-cands (nreverse cands))))))
+
+(defvar swiper-window-width 80)
+
+(defun swiper--all-format-function (cands)
+ "Format CANDS for `swiper-all'.
+See `ivy-format-function' for further information."
+ (let* ((ww swiper-window-width)
+ (col2 1)
+ (cands-with-buffer
+ (mapcar (lambda (s)
+ (let ((buffer (get-text-property 0 'buffer s)))
+ (setq col2 (max col2 (length buffer)))
+ (cons s buffer))) cands))
+ (col1 (- ww 4 col2)))
+ (setq cands
+ (mapcar (lambda (x)
+ (if (cdr x)
+ (let ((s (ivy--truncate-string (car x) col1)))
+ (concat
+ s
+ (make-string
+ (max 0
+ (- ww (string-width s) (length (cdr x))))
+ ?\ )
+ (cdr x)))
+ (car x)))
+ cands-with-buffer))
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face str 'ivy-current-match))
+ (lambda (str)
+ str)
+ cands
+ "\n")))
+
+(defvar swiper-all-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "M-q") 'swiper-all-query-replace)
+ map)
+ "Keymap for `swiper-all'.")
+
+;;;###autoload
+(defun swiper-all ()
+ "Run `swiper' for all open buffers."
+ (interactive)
+ (let* ((swiper-window-width (- (frame-width) (if (display-graphic-p) 0 1)))
+ (ivy-format-function #'swiper--all-format-function))
+ (ivy-read "swiper-all: " 'swiper-all-function
+ :action 'swiper-all-action
+ :unwind #'swiper--cleanup
+ :update-fn (lambda ()
+ (swiper-all-action (ivy-state-current ivy-last)))
+ :dynamic-collection t
+ :keymap swiper-all-map
+ :caller 'swiper-multi)))
+
+(defun swiper-all-action (x)
+ "Move to candidate X from `swiper-all'."
+ (when (> (length x) 0)
+ (let ((buffer-name (get-text-property 0 'buffer x)))
+ (when buffer-name
+ (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))
+ (unless (eq ivy-exit 'done)
+ (swiper--cleanup)
+ (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun swiper--multi-candidates (buffers)
+ "Extract candidates from BUFFERS."
+ (let* ((ww (window-width))
+ (res nil)
+ (column-2 (apply #'max
+ (mapcar
+ (lambda (b)
+ (length (buffer-name b)))
+ buffers)))
+ (column-1 (- ww 4 column-2 1)))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (setq res
+ (append
+ (mapcar
+ (lambda (s)
+ (setq s (concat (ivy--truncate-string s column-1) " "))
+ (let ((len (length s)))
+ (put-text-property
+ (1- len) len 'display
+ (concat
+ (make-string
+ (max 0
+ (- ww (string-width s) (length (buffer-name)) 3))
+ ?\ )
+ (buffer-name))
+ s)
+ s))
+ (swiper--candidates 4))
+ res))
+ nil))
+ res))
+
+(provide 'swiper)
+
+;;; swiper.el ends here
.emacs.d/elpa/swiper-20170911.1036/swiper.elc
Binary file