]> code.delx.au - gnu-emacs-elpa/commitdiff
Merge commit 'db005182ad0fd05c07e8e5c085abe6c750e6c578' from ivy
authorOleh Krehel <ohwoeowho@gmail.com>
Mon, 25 Apr 2016 10:10:45 +0000 (12:10 +0200)
committerOleh Krehel <ohwoeowho@gmail.com>
Mon, 25 Apr 2016 10:10:45 +0000 (12:10 +0200)
15 files changed:
packages/ivy/.dir-locals.el [new file with mode: 0644]
packages/ivy/Makefile
packages/ivy/README.md
packages/ivy/colir.el
packages/ivy/counsel.el
packages/ivy/doc/Changelog.org
packages/ivy/doc/ivy-help.org [new file with mode: 0644]
packages/ivy/doc/ivy-ox.el [new file with mode: 0644]
packages/ivy/doc/ivy.org
packages/ivy/doc/ivy.texi
packages/ivy/doc/style.css [deleted file]
packages/ivy/ivy-hydra.el
packages/ivy/ivy-test.el
packages/ivy/ivy.el
packages/ivy/swiper.el

diff --git a/packages/ivy/.dir-locals.el b/packages/ivy/.dir-locals.el
new file mode 100644 (file)
index 0000000..3bcda92
--- /dev/null
@@ -0,0 +1,5 @@
+;;; Directory Local Variables
+;;; For more information see (info "(emacs) Directory Variables")
+
+((emacs-lisp-mode
+  (indent-tabs-mode . nil)))
index b3857c98bfd4ba026e95ac66bef553eb82b286b2..c362e309ec996c5ad7dc68ac29eb36dd3b89cd19 100644 (file)
@@ -1,6 +1,6 @@
 emacs ?= emacs
 
-LOAD = -l colir.el -l ivy.el -l swiper.el
+LOAD = -l colir.el -l ivy.el -l swiper.el -l counsel.el
 
 .PHONY: all compile clean
 
@@ -10,7 +10,7 @@ test:
        $(emacs) -batch $(LOAD) -l ivy-test.el -f ert-run-tests-batch-and-exit
 
 compile:
-       $(emacs) -batch $(LOAD) --eval "(mapc #'byte-compile-file '(\"ivy.el\" \"swiper.el\" \"counsel.el\"))"
+       $(emacs) -batch --eval "(progn (add-to-list 'load-path default-directory) (mapc #'byte-compile-file '(\"ivy.el\" \"swiper.el\" \"counsel.el\")))"
 
 clean:
        rm -f *.elc
index 0d80f8dfd1c9d96958235bbd87138adb49427901..3348189f26a6b90456dba863578df654cb60d607 100644 (file)
@@ -1,8 +1,8 @@
-[![Build Status](https://travis-ci.org/abo-abo/swiper.svg?branch=master)](https://travis-ci.org/abo-abo/swiper)
+[![Build Status](https://travis-ci.org/abo-abo/swiper.svg?branch=master)](https://travis-ci.org/abo-abo/swiper) [![MELPA](https://melpa.org/packages/swiper-badge.svg)](https://melpa.org/#/swiper)
 
 ## Swiper
 
-Package for GNU Emacs that gives you an overview as you search for a regex
+Package for GNU Emacs that shows an overview during regex searching.
 
 ![swiper.png](http://oremacs.com/download/swiper.png)
 
@@ -17,19 +17,33 @@ There's also a ten minute [video demo](https://www.youtube.com/watch?v=VvnJQpTFV
 
 ## Ivy
 
-Ivy is a generic completion method for Emacs, similar to
-`icomplete-mode`. It aims to be more efficient, more simple, and more
-pleasant to use than the alternatives. It's also highly customizable
-and very small.
+Ivy is a generic completion mechanism for Emacs. While it operates
+similarly to other completion schemes such as `icomplete-mode`, Ivy
+aims to be more efficient, smaller, simpler, and smoother to use yet
+highly customizable.
 
-To try it, just call <kbd>M-x</kbd> `ivy-mode`, and all generic
-completion, including file and buffer names, will be done with Ivy.
+To try Ivy, just call <kbd>M-x</kbd> `ivy-mode`. This will enable
+generic Ivy completion, including specific completion for file and
+buffer names.
 
 ## Installation
 
-You can install the package from MELPA / GNU ELPA.
-Here is some typical configuration:
+Install the `swiper` package from MELPA / GNU ELPA.
 
+## Documentation
+
+### Manual
+The manual is available as [HTML](http://oremacs.com/swiper/).
+
+After installing from MELPA, the manual is also available through the `(ivy)` Info node.
+
+The source file for the Info page is
+[here](https://github.com/abo-abo/swiper/blob/master/doc/ivy.org).
+
+### Wiki
+Ivy and Swiper wiki is here: [the wiki](https://github.com/abo-abo/swiper/wiki).
+
+### Small config example
 ```elisp
 (ivy-mode 1)
 (setq ivy-use-virtual-buffers t)
@@ -48,4 +62,21 @@ Here is some typical configuration:
 (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)
+(define-key read-expression-map (kbd "C-r") 'counsel-expression-history)
 ```
+
+## Contributing
+
+### Copyright Assignment
+
+Swiper is subject to the same [copyright assignment](http://www.gnu.org/prep/maintain/html_node/Copyright-Papers.html) policy as Emacs itself, org-mode, CEDET and other packages in [GNU ELPA](http://elpa.gnu.org/packages/). Any [legally significant](http://www.gnu.org/prep/maintain/html_node/Legally-Significant.html#Legally-Significant) contributions can only be accepted after the author has completed their paperwork. Please see [the request form](http://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/Copyright/request-assign.future) if you want to proceed.
+
+The copyright assignment isn't a big deal, it just says that the copyright for your submitted changes to Emacs belongs to the FSF. This assignment works for all projects related to Emacs. To obtain it, you need to send one email, then send one letter (if you live in the US, it's digital), and wait for some time (in my case, I had to wait for one month).
+
+### Style
+
+The basic code style guide is to use `(setq indent-tabs-mode nil)`. It is provided for you in [.dir-locals.el](https://github.com/abo-abo/swiper/blob/master/.dir-locals.el), please obey it.
+
+Before submitting the change, run `make compile` and `make test` to make sure that it doesn't introduce new compile warnings or test failures. Also run <kbd>M-x</kbd> `checkdoc` to see that your changes obey the documentation guidelines.
+
+Use your own judgment for the commit messages, I recommend a verbose style using `magit-commit-add-log`.
index e11ef7dd17d13e9811fdde41997c197076a44182..792033fca394b5fc38e93782cec6b906f1e1debe 100644 (file)
@@ -77,11 +77,11 @@ 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)
-            prev (get-text-property start 'face object))
+      (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 prev
+      (if (facep prev)
           (let ((background-prev (face-background prev)))
             (progn
               (put-text-property
index 9c86ec0f05792211e2b470249b93d6b991ed6c0f..2d612e3a62f4ad22119b70e2feda8c0119eabf11 100644 (file)
@@ -4,8 +4,8 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.1.0
-;; Package-Requires: ((emacs "24.1") (swiper "0.4.0"))
+;; Version: 0.8.0
+;; Package-Requires: ((emacs "24.1") (swiper "0.8.0"))
 ;; Keywords: completion, matching
 
 ;; This file is part of GNU Emacs.
 
 (require 'swiper)
 (require 'etags)
+(require 'esh-util)
 
-(defvar counsel-completion-beg nil
-  "Completion bounds start.")
+;;* 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)
+  (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 though text properties."
+  (let ((str (copy-sequence str)))
+    (put-text-property
+     0 1 'display
+     (concat prefix (substring str 0 1))
+     str)
+    str))
+
+;;* 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 in seconds between starting a process and
+  receiving all candidates.")
+
+(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.")
+
+(defun counsel--async-command (cmd &optional process-sentinel process-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)
+  (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 (setq ivy--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)))))
+
+(defun counsel--async-filter (process str)
+  "Receive from PROCESS the output STR.
+Update the minibuffer with the amount of lines collected every
+0.5 seconds since the last update."
+  (with-current-buffer (process-buffer process)
+    (insert str))
+  (let (size)
+    (when (time-less-p
+           ;; 0.5s
+           '(0 0 500000 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
+         (split-string
+          (buffer-string)
+          counsel-async-split-string-re
+          t)))
+      (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)
 
-(defvar counsel-completion-end nil
-  "Completion bounds end.")
+(defun counsel-prompt-function-default (prompt)
+  "Return PROMPT appended with a semicolon."
+  (format "%s: " prompt))
 
+(defun counsel-delete-process ()
+  (let ((process (get-process " *counsel*")))
+    (when process
+      (delete-process process))))
+
+;;* Completion at point
+;;** `counsel-el'
 ;;;###autoload
 (defun counsel-el ()
   "Elisp completion at point."
          symbol-names)
     (if bnd
         (progn
-          (setq counsel-completion-beg
+          (setq ivy-completion-beg
                 (move-marker (make-marker) (car bnd)))
-          (setq counsel-completion-end
+          (setq ivy-completion-end
                 (move-marker (make-marker) (cdr bnd))))
-      (setq counsel-completion-beg nil)
-      (setq counsel-completion-end nil))
+      (setq ivy-completion-beg nil)
+      (setq ivy-completion-end nil))
     (if (string= str "")
         (mapatoms
          (lambda (x)
     (ivy-read "Symbol name: " symbol-names
               :predicate (and funp #'functionp)
               :initial-input str
-              :action #'counsel--el-action)))
+              :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")
 (defun counsel-cl ()
   "Common Lisp completion at point."
   (interactive)
-  (setq counsel-completion-beg (slime-symbol-start-pos))
-  (setq counsel-completion-end (slime-symbol-end-pos))
+  (setq ivy-completion-beg (slime-symbol-start-pos))
+  (setq ivy-completion-end (slime-symbol-end-pos))
   (ivy-read "Symbol name: "
             (car (slime-contextual-completions
-                  counsel-completion-beg
-                  counsel-completion-end))
-            :action #'counsel--el-action))
-
-(defun counsel--el-action (symbol)
-  "Insert SYMBOL, erasing the previous one."
-  (when (stringp symbol)
-    (with-ivy-window
-      (when counsel-completion-beg
-        (delete-region
-         counsel-completion-beg
-         counsel-completion-end))
-      (setq counsel-completion-beg
-            (move-marker (make-marker) (point)))
-      (insert symbol)
-      (setq counsel-completion-end
-            (move-marker (make-marker) (point))))))
+                  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")
   (let ((bnd (bounds-of-thing-at-point 'symbol)))
     (if bnd
         (progn
-          (setq counsel-completion-beg (car bnd))
-          (setq counsel-completion-end (cdr bnd)))
-      (setq counsel-completion-beg nil)
-      (setq counsel-completion-end nil)))
+          (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))
+      (jedi:complete-request))
   (ivy-read "Symbol name: " (jedi:ac-direct-matches)
             :action #'counsel--py-action))
 
   "Insert SYMBOL, erasing the previous one."
   (when (stringp symbol)
     (with-ivy-window
-      (when counsel-completion-beg
+      (when ivy-completion-beg
         (delete-region
-         counsel-completion-beg
-         counsel-completion-end))
-      (setq counsel-completion-beg
+         ivy-completion-beg
+         ivy-completion-end))
+      (setq ivy-completion-beg
             (move-marker (make-marker) (point)))
       (insert symbol)
-      (setq counsel-completion-end
+      (setq ivy-completion-end
             (move-marker (make-marker) (point)))
       (when (equal (get-text-property 0 'symbol symbol) "f")
         (insert "()")
-        (setq counsel-completion-end
+        (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 ()
+  "Insert a Unicode character at point."
+  (interactive)
+  (let ((minibuffer-allow-text-properties t))
+    (setq ivy-completion-beg (point))
+    (setq ivy-completion-end (point))
+    (ivy-read "Unicode name: "
+              (mapcar (lambda (x)
+                        (propertize
+                         (format "% -6X% -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))
+                          (setq ivy-completion-end (point))))
+              :history 'counsel-unicode-char-history)))
+
+;;* 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)
 
 (defun counsel--find-symbol (x)
   "Find symbol definition that corresponds to string X."
-  (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 fild definition of %s"
-                      sym)))))))
-
-(defvar counsel-describe-symbol-history nil
-  "History for `counsel-describe-variable' and `counsel-describe-function'.")
-
-(defun counsel-symbol-at-point ()
-  "Return current symbol at point as a string."
-  (let ((s (thing-at-point 'symbol)))
-    (and (stringp s)
-         (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s)
-             (match-string 1 s)
-           s))))
+  (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 fild 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."
      "Describe variable: "
      (counsel-variable-list)
      :keymap counsel-describe-map
-     :preselect (counsel-symbol-at-point)
+     :preselect (ivy-thing-at-point)
      :history 'counsel-describe-symbol-history
      :require-match t
      :sort t
                 (intern x)))
      :caller 'counsel-describe-variable)))
 
-(ivy-set-actions
- 'counsel-describe-variable
- '(("i" counsel-info-lookup-symbol "info")
-   ("d" counsel--find-symbol "definition")))
-
+;;** `counsel-describe-function'
 (ivy-set-actions
  'counsel-describe-function
  '(("i" counsel-info-lookup-symbol "info")
    ("d" counsel--find-symbol "definition")))
 
-(ivy-set-actions
- 'counsel-M-x
- '(("d" counsel--find-symbol "definition")))
-
 ;;;###autoload
 (defun counsel-describe-function ()
   "Forward to `describe-function'."
                      (push (symbol-name x) cands))))
                 cands)
               :keymap counsel-describe-map
-              :preselect (counsel-symbol-at-point)
+              :preselect (ivy-thing-at-point)
               :history 'counsel-describe-symbol-history
               :require-match t
               :sort t
                          (intern x)))
               :caller 'counsel-describe-function)))
 
+;;** `counsel-info-lookup-symbol'
 (defvar info-lookup-mode)
 (declare-function info-lookup->completions "info-look")
 (declare-function info-lookup->mode-value "info-look")
   (require 'info-look)
   (info-lookup 'symbol symbol mode))
 
-(defvar counsel-unicode-char-history nil
-  "History for `counsel-unicode-char'.")
+;;** `counsel-M-x'
+(ivy-set-actions
+ 'counsel-M-x
+ '(("d" counsel--find-symbol "definition")
+   ("h" (lambda (x) (describe-function (intern x))) "help")))
 
-;;;###autoload
-(defun counsel-unicode-char ()
-  "Insert a Unicode character at point."
-  (interactive)
-  (let ((minibuffer-allow-text-properties t))
-    (setq counsel-completion-beg (point))
-    (setq counsel-completion-end (point))
-    (ivy-read "Unicode name: "
-              (mapcar (lambda (x)
-                        (propertize
-                         (format "% -60s%c" (car x) (cdr x))
-                         'result (cdr x)))
-                      (ucs-names))
-              :action (lambda (char)
-                        (with-ivy-window
-                          (delete-region counsel-completion-beg counsel-completion-end)
-                          (setq counsel-completion-beg (point))
-                          (insert-char (get-text-property 0 'result char))
-                          (setq counsel-completion-end (point))))
-              :history 'counsel-unicode-char-history)))
+(ivy-set-display-transformer
+ 'counsel-M-x
+ 'counsel-M-x-transformer)
+
+(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 ()
+  "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 ")))
 
-(declare-function cider-sync-request:complete "ext:cider-client")
 ;;;###autoload
-(defun counsel-clj ()
-  "Clojure completion at point."
+(defun counsel-M-x (&optional initial-input)
+  "Ivy version of `execute-extended-command'.
+Optional INITIAL-INPUT is the initial input in the minibuffer."
   (interactive)
-  (counsel--generic
-   (lambda (str)
-     (mapcar
-      #'cl-caddr
-      (cider-sync-request:complete str ":same")))))
+  (unless initial-input
+    (setq initial-input (cdr (assoc this-command
+                                    ivy-initial-inputs-alist))))
+  (let* ((cands obarray)
+         (pred 'commandp)
+         (sort t))
+    (when (require 'smex nil 'noerror)
+      (unless smex-initialized-p
+        (smex-initialize))
+      (smex-detect-new-commands)
+      (smex-update)
+      (setq cands smex-ido-cache)
+      (setq pred nil)
+      (setq sort nil))
+    (ivy-read (counsel--M-x-prompt) cands
+              :predicate pred
+              :require-match t
+              :history 'extended-command-history
+              :action
+              (lambda (cmd)
+                (when (featurep 'smex)
+                  (smex-rank (intern cmd)))
+                (let ((prefix-arg current-prefix-arg)
+                      (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'
 ;;;###autoload
-(defun counsel-git ()
-  "Find file in the current Git repository."
+(defun counsel-load-library ()
+  "Load a selected the Emacs Lisp library.
+The libraries are offered from `load-path'."
   (interactive)
-  (let* ((default-directory (locate-dominating-file
-                             default-directory ".git"))
-         (cands (split-string
-                 (shell-command-to-string
-                  "git ls-files --full-name --")
-                 "\n"
-                 t))
-         (action `(lambda (x)
-                    (let ((default-directory ,default-directory))
-                      (find-file x)))))
-    (ivy-read "Find file: " cands
-              :action action)))
-
-(defvar counsel--git-grep-dir nil
-  "Store the base git directory.")
-
-(defvar counsel--git-grep-count nil
-  "Store the line count in current repository.")
-
-(defun counsel-more-chars (n)
-  "Return two fake candidates prompting for at least N input."
-  (list ""
-        (format "%d chars more" (- n (length ivy-text)))))
-
-(defvar counsel-git-grep-cmd "git --no-pager grep --full-name -n --no-color -i -e %S"
-  "Store the command for `counsel-git-grep'.")
-
-(defun counsel-git-grep-function (string &optional _pred &rest _unused)
-  "Grep in the current git repository for STRING."
-  (if (and (> counsel--git-grep-count 20000)
-           (< (length string) 3))
-      (counsel-more-chars 3)
-    (let* ((default-directory counsel--git-grep-dir)
-           (cmd (format counsel-git-grep-cmd
-                        (setq ivy--old-re (ivy--regex string t)))))
-      (if (<= counsel--git-grep-count 20000)
-          (split-string (shell-command-to-string cmd) "\n" t)
-        (counsel--gg-candidates (ivy--regex string))
-        nil))))
-
-(defvar counsel-git-grep-map
+  (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)
+    (ivy-read "Load library: " (nreverse res)
+              :action (lambda (x)
+                        (load-library
+                         (get-text-property 0 'full-name x)))
+              :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))
+        (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)
+  (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 "\f")
+      (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)
+  (let ((cmd (cdr x)))
+    (describe-function cmd)))
+
+(defun counsel-descbinds-action-find (x)
+  (let ((cmd (cdr x)))
+    (counsel--find-symbol (symbol-name cmd))))
+
+(defun counsel-descbinds-action-info (x)
+  (let ((cmd (cdr 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.
+Describe the selected candidate."
+  (interactive)
+  (ivy-read "Bindings: " (counsel--descbinds-cands prefix buffer)
+            :action #'counsel-descbinds-action-describe
+            :history 'counsel-descbinds-history
+            :caller 'counsel-descbinds))
+;;* Git
+;;** `counsel-git'
+(defvar counsel--git-dir nil
+  "Store the base git directory.")
+
+(ivy-set-actions
+ 'counsel-git
+ '(("j"
+    find-file-other-window
+    "other")))
+
+;;;###autoload
+(defun counsel-git ()
+  "Find file in the current Git repository."
+  (interactive)
+  (setq counsel--git-dir (expand-file-name
+                          (locate-dominating-file
+                           default-directory ".git")))
+  (let* ((default-directory counsel--git-dir)
+         (cands (split-string
+                 (shell-command-to-string
+                  "git ls-files --full-name --")
+                 "\n"
+                 t)))
+    (ivy-read (funcall counsel-prompt-function "Find file")
+              cands
+              :action #'counsel-git-action)))
+
+(defun counsel-git-action (x)
+  (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") 'counsel-git-grep-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))
 
-(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-grep-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)))))))))))
+(ivy-set-occur 'counsel-git-grep 'counsel-git-grep-occur)
+(ivy-set-display-transformer 'counsel-git-grep 'counsel-git-grep-transformer)
 
-(defun counsel-git-grep-recenter ()
-  (interactive)
-  (with-ivy-window
-    (counsel-git-grep-action ivy--current)
-    (recenter-top-bottom)))
+(defvar counsel-git-grep-cmd "git --no-pager grep --full-name -n --no-color -i -e %S"
+  "Store the command for `counsel-git-grep'.")
+
+(defvar counsel--git-grep-dir nil
+  "Store the base git directory.")
+
+(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
+  '("git --no-pager grep --full-name -n --no-color -i -e %S")
+  "History for `counsel-git-grep' shell commands.")
+
+(defun counsel-prompt-function-dir (prompt)
+  "Return PROMPT appended with the parent directory."
+  (let ((directory counsel--git-grep-dir))
+    (format "%s [%s]: "
+            prompt
+            (let ((dir-list (eshell-split-path directory)))
+              (if (> (length dir-list) 3)
+                  (apply #'concat
+                         (append '("...")
+                                 (cl-subseq dir-list (- (length dir-list) 3))))
+                directory)))))
+
+(defun counsel-git-grep-function (string &optional _pred &rest _unused)
+  "Grep in the current git repository for STRING."
+  (if (and (> counsel--git-grep-count 20000)
+           (< (length string) 3))
+      (counsel-more-chars 3)
+    (let* ((default-directory counsel--git-grep-dir)
+           (cmd (format counsel-git-grep-cmd
+                        (setq ivy--old-re (ivy--regex string t)))))
+      (if (<= 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)
   (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" x)
           (swiper--cleanup)
           (swiper--add-overlays (ivy--regex ivy-text)))))))
 
-(defvar counsel-git-grep-history nil
-  "History for `counsel-git-grep'.")
-
-(defvar counsel-git-grep-cmd-history
-  '("git --no-pager grep --full-name -n --no-color -i -e %S")
-  "History for `counsel-git-grep' shell commands.")
-
-;;;###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")
-  (cond
-    ((stringp cmd)
-     (setq counsel-git-grep-cmd cmd))
-    (cmd
-     (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)))
-    (t
-     (setq counsel-git-grep-cmd "git --no-pager grep --full-name -n --no-color -i -e %S")))
-  (setq counsel--git-grep-dir
-        (locate-dominating-file default-directory ".git"))
-  (if (null counsel--git-grep-dir)
-      (error "Not in a git repository")
-    (setq counsel--git-grep-count (counsel--gg-count "" t))
-    (ivy-read "git grep: " 'counsel-git-grep-function
-              :initial-input initial-input
-              :matcher #'counsel-git-grep-matcher
-              :dynamic-collection (> counsel--git-grep-count 20000)
-              :keymap counsel-git-grep-map
-              :action #'counsel-git-grep-action
-              :unwind #'swiper--cleanup
-              :history 'counsel-git-grep-history
-              :caller 'counsel-git-grep)))
-
-(defcustom counsel-find-file-at-point nil
-  "When non-nil, add file-at-point to the list of candidates."
-  :type 'boolean
-  :group 'ivy)
-
-(declare-function ffap-guesser "ffap")
-
-(defvar counsel-find-file-map (make-sparse-keymap))
-
-;;;###autoload
-(defun counsel-find-file ()
-  "Forward to `find-file'."
-  (interactive)
-  (ivy-read "Find file: " 'read-file-name-internal
-            :matcher #'counsel--find-file-matcher
-            :action
-            (lambda (x)
-              (with-ivy-window
-                (find-file (expand-file-name x ivy--directory))))
-            :preselect (when counsel-find-file-at-point
-                         (require 'ffap)
-                         (ffap-guesser))
-            :require-match 'confirm-after-completion
-            :history 'file-name-history
-            :keymap counsel-find-file-map))
-
-(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.
-Possible value: \"\\(?:\\`[#.]\\)\\|\\(?:[#~]\\'\\)\"."
-  :group 'ivy)
-
-(defun counsel--find-file-matcher (regexp candidates)
-  "Return REGEXP-matching CANDIDATES.
-Skip some dotfiles unless `ivy-text' requires them."
-  (let ((res (cl-remove-if-not
-              (lambda (x)
-                (string-match regexp x))
-              candidates)))
-    (if (or (null counsel-find-file-ignore-regexp)
-            (string-match counsel-find-file-ignore-regexp ivy-text))
-        res
-      (cl-remove-if
-       (lambda (x)
-         (string-match counsel-find-file-ignore-regexp x))
-       res))))
-
 (defun counsel-git-grep-matcher (regexp candidates)
   (or (and (equal regexp ivy--old-re)
            ivy--old-cands)
@@ -535,214 +840,65 @@ Skip some dotfiles unless `ivy-text' requires them."
                  candidates))
         (setq ivy--old-re regexp))))
 
-(defvar counsel--async-time nil
-  "Store the time when a new process was started.
-Or the time of the last minibuffer update.")
-
-(defun counsel--async-command (cmd)
-  (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-time (current-time))
-    (set-process-sentinel proc #'counsel--async-sentinel)
-    (set-process-filter proc #'counsel--async-filter)))
-
-(defun counsel--async-sentinel (process event)
-  (if (string= event "finished\n")
-      (progn
-        (with-current-buffer (process-buffer process)
-          (setq ivy--all-candidates
-                (ivy--sort-maybe
-                 (split-string (buffer-string) "\n" t)))
-          (if (null ivy--old-cands)
-              (setq ivy--index
-                    (or (ivy--preselect-index
-                         (ivy-state-preselect ivy-last)
-                         ivy--all-candidates)
-                        0))
-            (ivy--recompute-index
-             ivy-text
-             (funcall ivy--regex-function ivy-text)
-             ivy--all-candidates))
-          (setq ivy--old-cands ivy--all-candidates))
-        (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--async-filter (process str)
-  "Receive from PROCESS the output STR.
-Update the minibuffer with the amount of lines collected every
-0.5 seconds since the last update."
-  (with-current-buffer (process-buffer process)
-    (insert str))
-  (let (size)
-    (when (time-less-p
-           ;; 0.5s
-           '(0 0 500000 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--insert-minibuffer
-       (format "\ncollected: %d" size))
-      (setq counsel--async-time (current-time)))))
-
-(defun counsel-locate-action-extern (x)
-  "Use xdg-open shell command on X."
-  (call-process shell-file-name nil
-                nil nil
-                shell-command-switch
-                (format "%s %s"
-                        (if (eq system-type 'darwin)
-                                    "open"
-                                  "xdg-open")
-                        (shell-quote-argument x))))
-
-(declare-function dired-jump "dired-x")
-(defun counsel-locate-action-dired (x)
-  "Use `dired-jump' on X."
-  (dired-jump nil x))
-
-(defvar counsel-locate-history nil
-  "History for `counsel-locate'.")
-
-(defcustom counsel-locate-options (if (eq system-type 'darwin)
-                                      '("-i")
-                                    '("-i" "--regex"))
-  "Command line options for `locate`."
-  :group 'ivy
-  :type  '(repeat string))
-
-(ivy-set-actions
- 'counsel-locate
- '(("x" counsel-locate-action-extern "xdg-open")
-   ("d" counsel-locate-action-dired "dired")))
-
-(defun counsel-unquote-regex-parens (str)
-  (replace-regexp-in-string
-   "\\\\)" ")"
-   (replace-regexp-in-string
-    "\\\\(" "("
-    str)))
-
-(defun counsel-locate-function (str &rest _u)
-  (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...")))
-
-(defun counsel-delete-process ()
-  (let ((process (get-process " *counsel*")))
-    (when process
-      (delete-process process))))
+(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)
 
 ;;;###autoload
-(defun counsel-locate (&optional initial-input)
-  "Call the \"locate\" shell command.
+(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")
+  (cond
+    ((stringp cmd)
+     (setq counsel-git-grep-cmd cmd))
+    (cmd
+     (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)))
+    (t
+     (setq counsel-git-grep-cmd "git --no-pager grep --full-name -n --no-color -i -e %S")))
+  (setq counsel--git-grep-dir
+        (locate-dominating-file default-directory ".git"))
+  (if (null counsel--git-grep-dir)
+      (error "Not in a git repository")
+    (setq counsel--git-grep-count (counsel--gg-count "" t))
+    (ivy-read
+     (funcall counsel-prompt-function "git grep")
+     'counsel-git-grep-function
+     :initial-input initial-input
+     :matcher #'counsel-git-grep-matcher
+     :dynamic-collection (> counsel--git-grep-count 20000)
+     :keymap counsel-git-grep-map
+     :action #'counsel-git-grep-action
+     :unwind #'swiper--cleanup
+     :history 'counsel-git-grep-history
+     :caller 'counsel-git-grep)))
+
+(defun counsel-git-grep-switch-cmd ()
+  "Set `counsel-git-grep-cmd' to a different value."
   (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))
-
-(defun counsel--generic (completion-fn)
-  "Complete thing at point with COMPLETION-FN."
-  (let* ((bnd (bounds-of-thing-at-point 'symbol))
-         (str (if bnd
-                  (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))))
-
-(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 though text properties."
-  (let ((str (copy-sequence str)))
-    (put-text-property
-     0 1 'display
-     (concat prefix (substring str 0 1))
-     str)
-    str))
-
-;;;###autoload
-(defun counsel-load-library ()
-  "Load a selected the Emacs Lisp library.
-The libraries are offered from `load-path'."
-  (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)
-    (ivy-read "Load library: " (nreverse res)
-              :action (lambda (x)
-                        (load-library
-                         (get-text-property 0 'full-name x)))
-              :keymap counsel-describe-map)))
+  (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.")
@@ -822,142 +978,586 @@ When NO-ASYNC is non-nil, do it synchronously."
                (when (= 0 (cl-incf counsel-gg-state))
                  (ivy--exhibit)))))))))
 
-(defun counsel--M-x-transformer (cand-pair)
-  "Add a binding to CAND-PAIR cdr if the car is bound in the current window.
-CAND-PAIR is (command-name . extra-info)."
-  (let* ((command-name (car cand-pair))
-         (extra-info (cdr cand-pair))
-         (binding (substitute-command-keys (format "\\[%s]" command-name))))
-    (setq binding (replace-regexp-in-string "C-x 6" "<f2>" binding))
-    (if (string-match "^M-x" binding)
-        cand-pair
-      (cons command-name
-            (if extra-info
-                (format " %s (%s)" extra-info (propertize binding 'face 'font-lock-keyword-face))
-              (format " (%s)" (propertize binding 'face 'font-lock-keyword-face)))))))
+(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-grep-dir))
+  (let ((cands (split-string
+                (shell-command-to-string
+                 (format counsel-git-grep-cmd
+                         (setq ivy--old-re (ivy--regex ivy-text t))))
+                "\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))))
 
-(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-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-grep-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)))))))))))
 
-(defun counsel--M-x-prompt ()
-  "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 ")))
+(defun counsel-git-grep-recenter ()
+  (interactive)
+  (with-ivy-window
+    (counsel-git-grep-action ivy--current)
+    (recenter-top-bottom)))
+
+;;** `counsel-git-stash'
+(defun counsel-git-stash-kill-action (x)
+  (when (string-match "\\([^:]+\\):" x)
+    (kill-new (message (format "git stash apply %s" (match-string 1 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."
+(defun counsel-git-stash ()
+  "Search through all available git stashes."
   (interactive)
-  (unless initial-input
-    (setq initial-input (cdr (assoc this-command
-                                    ivy-initial-inputs-alist))))
-  (let* ((store ivy-format-function)
-         (ivy-format-function
-          (lambda (cand-pairs)
-            (funcall
-             store
-             (with-ivy-window
-               (mapcar #'counsel--M-x-transformer cand-pairs)))))
-         (cands obarray)
-         (pred 'commandp)
-         (sort t))
-    (when (require 'smex nil 'noerror)
-      (unless smex-initialized-p
-        (smex-initialize))
-      (smex-detect-new-commands)
-      (smex-update)
-      (setq cands smex-ido-cache)
-      (setq pred nil)
-      (setq sort nil))
-    (ivy-read (counsel--M-x-prompt) cands
-              :predicate pred
-              :require-match t
-              :history 'extended-command-history
-              :action
-              (lambda (cmd)
-                (when (featurep 'smex)
-                  (smex-rank (intern cmd)))
-                (let ((prefix-arg current-prefix-arg)
-                      (ivy-format-function store))
-                  (command-execute (intern cmd) 'record)))
-              :sort sort
-              :keymap counsel-describe-map
-              :initial-input initial-input
-              :caller 'counsel-M-x)))
+  (let ((dir (locate-dominating-file default-directory ".git")))
+    (if (null dir)
+        (error "Not in a git repository")
+      (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'
+(defun counsel-git-log-function (input)
+  (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 "GIT_PAGER=cat git log --grep '%s'"
+             (replace-regexp-in-string
+              "\\.\\*\\?" ".*"
+              ivy--old-re)))
+    nil))
 
-(declare-function powerline-reset "ext:powerline")
+(defun counsel-git-log-action (x)
+  (message "%S" (kill-new x)))
 
-(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))
-        (when (fboundp 'powerline-reset)
-          (powerline-reset)))
-    (error "Problem loading theme %s" x)))
+(defcustom counsel-yank-pop-truncate-radius 2
+  "When non-nil, truncate the display of long strings."
+  :type 'integer
+  :group 'ivy)
+
+;;;###autoload
+(defun counsel-git-log ()
+  "Call the \"git log --grep\" shell command."
+  (interactive)
+  (let ((counsel-async-split-string-re "\ncommit ")
+        (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)
+(ivy-set-actions
+ 'counsel-find-file
+ '(("f" find-file-other-window "other window")))
+
+(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" "\\`\\.")
+          (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")
+
+;;;###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
+                (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 ()
+  "Whe 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)
+        (memq major-mode '(magit-commit-mode)))
+       (match-string-no-properties 0)))
+
+(defun counsel-github-url-p ()
+  "Return a Github issue URL at point."
+  (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."
+  (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)))))))
+
+;;** `counsel-locate'
+(defcustom counsel-locate-options nil
+  "Command line options for `locate`."
+  :group 'ivy
+  :type '(repeat string))
+
+(make-obsolete-variable 'counsel-locate-options 'counsel-locate-cmd "0.7.0")
+
+(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 on X."
+  (call-process shell-file-name nil
+                nil nil
+                shell-command-switch
+                (format "%s %s"
+                        (if (eq system-type 'darwin)
+                            "open"
+                          "xdg-open")
+                        (shell-quote-argument x))))
+
+(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."
+  (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."
+  (format "locate -i '%s'" input))
+
+(defun counsel-locate-cmd-mdfind (input)
+  "Return a shell command based on INPUT."
+  (format "mdfind -name '%s'" input))
+
+(defun counsel-locate-cmd-es (input)
+  "Return a shell command based on INPUT."
+  (format "es.exe -i -r %s"
+          (counsel-unquote-regex-parens
+           (ivy--regex input t))))
+
+(defun counsel-locate-function (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))
+
+;;* Grep
+;;** `counsel-ag'
+(defvar counsel-ag-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-l") 'counsel-git-grep-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 `cousel-ag-function' to construct the
+command. %S will be replaced 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)
+  "Grep in the current directory for STRING."
+  (if (< (length string) 3)
+      (counsel-more-chars 3)
+    (let ((default-directory counsel--git-grep-dir)
+          (regex (counsel-unquote-regex-parens
+                  (setq ivy--old-re
+                        (ivy--regex string)))))
+      (counsel--async-command
+       (format counsel-ag-base-command (shell-quote-argument regex)))
+      nil)))
+
+;;;###autoload
+(defun counsel-ag (&optional initial-input initial-directory)
+  "Grep for a string in the current directory using ag.
+INITIAL-INPUT can be given as the initial minibuffer input."
+  (interactive
+   (list nil
+         (when current-prefix-arg
+           (read-directory-name (concat
+                                 (car (split-string counsel-ag-base-command))
+                                 " in directory: ")))))
+  (setq counsel--git-grep-dir (or initial-directory default-directory))
+  (ivy-read (funcall counsel-prompt-function
+                     (car (split-string counsel-ag-base-command)))
+            'counsel-ag-function
+            :initial-input initial-input
+            :dynamic-collection t
+            :keymap counsel-ag-map
+            :history 'counsel-git-grep-history
+            :action #'counsel-git-grep-action
+            :unwind (lambda ()
+                      (counsel-delete-process)
+                      (swiper--cleanup))
+            :caller 'counsel-ag))
+
+(defun counsel-ag-occur ()
+  "Generate a custom occur buffer for `counsel-ag'."
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode))
+  (setq default-directory counsel--git-grep-dir)
+  (let* ((regex (counsel-unquote-regex-parens
+                 (setq ivy--old-re
+                       (ivy--regex
+                        (progn (string-match "\"\\(.*\\)\"" (buffer-name))
+                               (match-string 1 (buffer-name)))))))
+         (cands (split-string
+                 (shell-command-to-string
+                  (format counsel-ag-base-command (shell-quote-argument regex)))
+                 "\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))))
+
+;;** `counsel-pt'
+(defcustom counsel-pt-base-command "pt --nocolor --nogroup -e %s -- ."
+  "Used to in place of `counsel-ag-base-command' to search with
+pt using `counsel-ag'."
+  :type 'string
+  :group 'ivy)
 
 ;;;###autoload
-(defun counsel-load-theme ()
-  "Forward to `load-theme'.
-Usable with `ivy-resume', `ivy-next-line-and-call' and
-`ivy-previous-line-and-call'."
+(defun counsel-pt ()
+  "Grep for a string in the current directory using pt.
+This uses `counsel-ag' with `counsel-pt-base-command' replacing
+`counsel-ag-base-command'."
   (interactive)
-  (ivy-read "Load custom theme: "
-            (mapcar 'symbol-name
-                    (custom-available-themes))
-            :action #'counsel--load-theme-action))
+  (let ((counsel-ag-base-command counsel-pt-base-command))
+    (call-interactively 'counsel-ag)))
+
+;;** `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)
 
-(defvar rhythmbox-library)
-(declare-function rhythmbox-load-library "ext:helm-rhythmbox")
-(declare-function dbus-call-method "dbus")
-(declare-function rhythmbox-song-uri "ext:helm-rhythmbox")
-(declare-function helm-rhythmbox-candidates "ext:helm-rhythmbox")
+(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 counsel--git-grep-dir))
+      nil)))
 
-(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" (rhythmbox-song-uri song))))
+(defun counsel-grep-action (x)
+  (with-ivy-window
+    (swiper--cleanup)
+    (let ((default-directory (file-name-directory counsel--git-grep-dir))
+          file-name line-number)
+      (when (cond ((string-match "\\`\\([0-9]+\\):\\(.*\\)\\'" x)
+                   (setq file-name counsel--git-grep-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))
+        (find-file file-name)
+        (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)
+        (if (eq ivy-exit 'done)
+            (swiper--ensure-visible)
+          (isearch-range-invisible (line-beginning-position)
+                                   (line-end-position))
+          (swiper--add-overlays (ivy--regex ivy-text)))))))
 
-(defvar counsel-rhythmbox-history nil
-  "History for `counsel-rhythmbox'.")
+(defun counsel-grep-occur ()
+  "Generate a custom occur buffer for `counsel-grep'."
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode))
+  (let ((cands
+         (split-string
+          (shell-command-to-string
+           (format counsel-grep-base-command
+                   (counsel-unquote-regex-parens
+                    (setq ivy--old-re
+                          (ivy--regex
+                           (progn (string-match "\"\\(.*\\)\"" (buffer-name))
+                                  (match-string 1 (buffer-name))) t)))
+                   counsel--git-grep-dir))
+          "\n" t))
+        (file (file-name-nondirectory counsel--git-grep-dir)))
+    ;; 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 "./" file ":" cand))
+      cands))))
+
+(ivy-set-occur 'counsel-grep 'counsel-grep-occur)
+(counsel-set-async-exit-code 'counsel-grep 1 "")
 
 ;;;###autoload
-(defun counsel-rhythmbox ()
-  "Choose a song from the Rhythmbox library to play or enqueue."
+(defun counsel-grep ()
+  "Grep for a string in the current file."
   (interactive)
-  (unless (require 'helm-rhythmbox nil t)
-    (error "Please install `helm-rhythmbox'"))
-  (unless rhythmbox-library
-    (rhythmbox-load-library)
-    (while (null rhythmbox-library)
-      (sit-for 0.1)))
-  (ivy-read "Rhythmbox: "
-            (helm-rhythmbox-candidates)
-            :history 'counsel-rhythmbox-history
-            :action
-            '(1
-              ("p" helm-rhythmbox-play-song "Play song")
-              ("e" counsel-rhythmbox-enqueue-song "Enqueue song"))
-            :caller 'counsel-rhythmbox))
+  (setq counsel-grep-last-line nil)
+  (setq counsel--git-grep-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)
+                                                (buffer-substring-no-properties
+                                                 (line-beginning-position)
+                                                 (line-end-position)))
+                             :history 'counsel-git-grep-history
+                             :update-fn (lambda ()
+                                          (counsel-grep-action ivy--current))
+                             :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)
+
+;;;###autoload
+(defun counsel-grep-or-swiper ()
+  "Call `swiper' for small buffers and `counsel-grep' for large ones."
+  (interactive)
+  (if (and (buffer-file-name)
+           (not (buffer-narrowed-p))
+           (not (ignore-errors
+                  (file-remote-p (buffer-file-name))))
+           (> (buffer-size)
+              (if (eq major-mode 'org-mode)
+                  (/ counsel-grep-swiper-limit 4)
+                counsel-grep-swiper-limit)))
+      (progn
+        (save-buffer)
+        (counsel-grep))
+    (swiper--ivy (swiper--candidates))))
+
+;;** `counsel-recoll'
+(defun counsel-recoll-function (string)
+  "Grep in the current directory for STRING."
+  (if (< (length string) 3)
+      (counsel-more-chars 3)
+    (counsel--async-command
+     (format "recoll -t -b '%s'" 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)
+  (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.")
 
@@ -1097,7 +1697,8 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and
                   (delete-dups
                    (all-completions str 'org-tags-completion-function)))
                 :history 'org-tags-history
-                :action 'counsel-org-tag-action))))
+                :action 'counsel-org-tag-action
+                :caller 'counsel-org-tag))))
 
 ;;;###autoload
 (defun counsel-org-tag-agenda ()
@@ -1111,111 +1712,7 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and
            (org-agenda-set-tags nil nil))
       (fset 'org-set-tags store))))
 
-(defun counsel-ag-function (string &optional _pred &rest _unused)
-  "Grep in the current directory for STRING."
-  (if (< (length string) 3)
-      (counsel-more-chars 3)
-    (let ((default-directory counsel--git-grep-dir)
-          (regex (counsel-unquote-regex-parens
-                  (setq ivy--old-re
-                        (ivy--regex string)))))
-      (counsel--async-command
-       (format "ag --vimgrep %S" regex))
-      nil)))
-
-;;;###autoload
-(defun counsel-ag (&optional initial-input initial-directory)
-  "Grep for a string in the current directory using ag.
-INITIAL-INPUT can be given as the initial minibuffer input."
-  (interactive)
-  (setq counsel--git-grep-dir (or initial-directory default-directory))
-  (ivy-read "ag: " 'counsel-ag-function
-            :initial-input initial-input
-            :dynamic-collection t
-            :history 'counsel-git-grep-history
-            :action #'counsel-git-grep-action
-            :unwind (lambda ()
-                      (counsel-delete-process)
-                      (swiper--cleanup))))
-
-;;;###autoload
-(defun counsel-grep ()
-  "Grep for a string in the current file."
-  (interactive)
-  (setq counsel--git-grep-dir (buffer-file-name))
-  (ivy-read "grep: " 'counsel-grep-function
-            :dynamic-collection t
-            :preselect (format "%d:%s"
-                               (line-number-at-pos)
-                               (buffer-substring-no-properties
-                                (line-beginning-position)
-                                (line-end-position)))
-            :history 'counsel-git-grep-history
-            :update-fn (lambda ()
-                         (counsel-grep-action ivy--current))
-            :action #'counsel-grep-action
-            :unwind (lambda ()
-                      (counsel-delete-process)
-                      (swiper--cleanup))
-            :caller 'counsel-grep))
-
-(defun counsel-grep-function (string &optional _pred &rest _unused)
-  "Grep in the current directory for STRING."
-  (if (< (length string) 3)
-      (counsel-more-chars 3)
-    (let ((regex (counsel-unquote-regex-parens
-                  (setq ivy--old-re
-                        (ivy--regex string)))))
-      (counsel--async-command
-       (format "grep -nP --ignore-case '%s' %s" regex counsel--git-grep-dir))
-      nil)))
-
-(defun counsel-grep-action (x)
-  (when (string-match "\\`\\([0-9]+\\):\\(.*\\)\\'" x)
-    (with-ivy-window
-      (let ((file-name counsel--git-grep-dir)
-            (line-number (match-string-no-properties 1 x)))
-        (find-file file-name)
-        (goto-char (point-min))
-        (forward-line (1- (string-to-number line-number)))
-        (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
-        (unless (eq ivy-exit 'done)
-          (swiper--cleanup)
-          (swiper--add-overlays (ivy--regex ivy-text)))))))
-
-(defun counsel-recoll-function (string &optional _pred &rest _unused)
-  "Grep in the current directory for STRING."
-  (if (< (length string) 3)
-      (counsel-more-chars 3)
-    (counsel--async-command
-     (format "recoll -t -b '%s'" 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)
-  (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)))))))
-
+;;** `counsel-tmm'
 (defvar tmm-km-list nil)
 (declare-function tmm-get-keymap "tmm")
 (declare-function tmm--completion-table "tmm")
@@ -1241,16 +1738,62 @@ INITIAL-INPUT can be given as the initial minibuffer input."
            (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])))
 
-(defcustom counsel-yank-pop-truncate nil
-  "When non-nil, truncate the display of long strings."
-  :group 'ivy)
+;;** `counsel-yank-pop'
+(defun counsel--yank-pop-truncate (str)
+  (condition-case nil
+      (let* ((lines (split-string str "\n" t))
+             (n (length lines))
+             (first-match (cl-position-if
+                           (lambda (s) (string-match ivy--old-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)))
+
+(defun counsel--yank-pop-format-function (cand-pairs)
+  (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
+   "\n"))
+
+(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))))
 
 ;;;###autoload
 (defun counsel-yank-pop ()
@@ -1258,43 +1801,330 @@ INITIAL-INPUT can be given as the initial minibuffer input."
   (interactive)
   (if (eq last-command 'yank)
       (progn
-        (setq counsel-completion-end (point))
-        (setq counsel-completion-beg
+        (setq ivy-completion-end (point))
+        (setq ivy-completion-beg
               (save-excursion
                 (search-backward (car kill-ring))
                 (point))))
-    (setq counsel-completion-beg (point))
-    (setq counsel-completion-end (point)))
+    (setq ivy-completion-beg (point))
+    (setq ivy-completion-end (point)))
   (let ((candidates (cl-remove-if
                      (lambda (s)
                        (or (< (length s) 3)
                            (string-match "\\`[\n[:blank:]]+\\'" s)))
                      (delete-dups kill-ring))))
-    (when counsel-yank-pop-truncate
-      (setq candidates
-            (mapcar (lambda (s)
-                      (if (string-match "\\`\\(.*\n.*\n.*\n.*\\)\n" s)
-                          (progn
-                            (let ((s (copy-sequence s)))
-                              (put-text-property
-                               (match-end 1)
-                               (length s)
-                               'display
-                               " [...]"
-                               s)
-                              s))
-                        s))
-                    candidates)))
-    (ivy-read "kill-ring: " candidates
-              :action 'counsel-yank-pop-action)))
+    (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))))
+
+;;** `counsel-imenu'
+(defvar imenu-auto-rescan)
+(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 prefix (if prefix ".") (car elm))))
+                   (list (cons key
+                               ;; create a imenu candidate here
+                               (cons key (if (overlayp (cdr elm))
+                                             (overlay-start (cdr elm))
+                                           (cdr elm))))))))
+             alist))
 
-(defun counsel-yank-pop-action (s)
-  "Insert S into the buffer, overwriting the previous yank."
-  (with-ivy-window
-    (delete-region counsel-completion-beg
-                   counsel-completion-end)
-    (insert (substring-no-properties s))
-    (setq counsel-completion-end (point))))
+;;;###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)
+         (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 candidate)))
+              :caller 'counsel-imenu)))
+
+;;** `counsel-list-processes'
+(defun counsel-list-processes-action-delete (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)
+  (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 action
+                :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-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
+             (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))
+
+;;* Misc OS
+;;** `counsel-rhythmbox'
+(defvar helm-rhythmbox-library)
+(declare-function helm-rhythmbox-load-library "ext:helm-rhythmbox")
+(declare-function dbus-call-method "dbus")
+(declare-function dbus-get-property "dbus")
+(declare-function helm-rhythmbox-song-uri "ext:helm-rhythmbox")
+(declare-function helm-rhythmbox-candidates "ext:helm-rhythmbox")
+
+(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" (helm-rhythmbox-song-uri song))))
+
+(defvar counsel-rhythmbox-history nil
+  "History for `counsel-rhythmbox'.")
+
+(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)
+  (unless (require 'helm-rhythmbox nil t)
+    (error "Please install `helm-rhythmbox'"))
+  (unless helm-rhythmbox-library
+    (helm-rhythmbox-load-library)
+    (while (null helm-rhythmbox-library)
+      (sit-for 0.1)))
+  (ivy-read "Rhythmbox: "
+            (helm-rhythmbox-candidates)
+            :history 'counsel-rhythmbox-history
+            :preselect (counsel-rhythmbox-current-song)
+            :action
+            '(1
+              ("p" helm-rhythmbox-play-song "Play song")
+              ("e" counsel-rhythmbox-enqueue-song "Enqueue song"))
+            :caller 'counsel-rhythmbox))
+;;** `counsel-linux-app'
+(defvar counsel-linux-apps-alist nil
+  "List of data located in /usr/share/applications.")
+
+(defvar counsel-linux-apps-faulty nil
+  "List of faulty data located in /usr/share/applications.")
+
+(defun counsel-linux-apps-list ()
+  (let ((files
+         (delete
+          ".." (delete
+                "." (file-expand-wildcards "/usr/share/applications/*.desktop")))))
+    (dolist (file (cl-set-difference files (append (mapcar 'car counsel-linux-apps-alist)
+                                                   counsel-linux-apps-faulty)
+                                     :test 'equal))
+      (with-temp-buffer
+        (insert-file-contents (expand-file-name file "/usr/share/applications"))
+        (let (name comment exec)
+          (goto-char (point-min))
+          (if (re-search-forward "^Name *= *\\(.*\\)$" nil t)
+              (setq name (match-string 1))
+            (error "File %s has no Name" file))
+          (goto-char (point-min))
+          (when (re-search-forward "^Comment *= *\\(.*\\)$" nil t)
+            (setq comment (match-string 1)))
+          (goto-char (point-min))
+          (when (re-search-forward "^Exec *= *\\(.*\\)$" nil t)
+            (setq exec (match-string 1)))
+          (if (and exec (not (equal exec "")))
+              (add-to-list
+               'counsel-linux-apps-alist
+               (cons (format "% -45s: %s%s"
+                             (propertize exec 'face 'font-lock-builtin-face)
+                             name
+                             (if comment
+                                 (concat " - " comment)
+                               ""))
+                     file))
+            (add-to-list 'counsel-linux-apps-faulty file))))))
+  counsel-linux-apps-alist)
+
+(defun counsel-linux-app-action-default (desktop-shortcut)
+  "Launch DESKTOP-SHORTCUT."
+  (call-process-shell-command
+   (format "gtk-launch %s" (file-name-nondirectory desktop-shortcut))))
+
+(defun counsel-linux-app-action-file (desktop-shortcut)
+  "Launch DESKTOP-SHORTCUT with a selected file."
+  (let* ((entry (rassoc desktop-shortcut counsel-linux-apps-alist))
+         (short-name (and entry
+                          (string-match "\\([^ ]*\\) " (car entry))
+                          (match-string 1 (car entry))))
+         (file (and short-name
+                    (read-file-name
+                     (format "Run %s on: " short-name)))))
+    (if file
+        (call-process-shell-command
+         (format "gtk-launch %s %s"
+                 (file-name-nondirectory desktop-shortcut)
+                 file))
+      (user-error "cancelled"))))
+
+(ivy-set-actions
+ 'counsel-linux-app
+ '(("f" counsel-linux-app-action-file "run on a 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-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)
+                (find-file . counsel-find-file)
+                (imenu . counsel-imenu)
+                (load-library . counsel-load-library)
+                (load-theme . counsel-load-theme)
+                (yank-pop . counsel-yank-pop)))
+      (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)
+
+;;;###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
+      (when (and (fboundp 'advice-add)
+                 counsel-mode-override-describe-bindings)
+        (advice-add #'describe-bindings :override #'counsel-descbinds))
+    (when (fboundp 'advice-remove)
+      (advice-remove #'describe-bindings #'counsel-descbinds))))
 
 (provide 'counsel)
 
index 21076dea1dabbfee813729dadfecfe7246dfbde6..df721d3cf961e83825bd7524139b06cbc4850a02 100644 (file)
@@ -614,3 +614,573 @@ Complete Common Lisp symbols using SLIME.
 *** =counsel-yank-pop=
 Give completion for inserting from the kill ring.
 See =counsel-yank-pop-truncate= defcustom and [[https://github.com/abo-abo/swiper/issues/218][#218]].
+
+* 0.8.0
+** Package rename
+Due to popular demand, =swiper-0.7.0= is succeeded by =ivy-0.8.0= in GNU
+ELPA. The contents of the package don't change, only the name. Make
+sure to remove the =~/.emacs.d/elpa/swiper-0.7.0= directory if you
+have it and ~M-x~ =package-install ivy=.
+** Documentation
+HTML documentation is available at http://oremacs.com/swiper/.
+
+Texinfo documentation is in doc/ivy.texi.
+
+The HTML file shouldn't be in this repository to avoid bloat, instead
+it's in the gh-pages branch at
+https://github.com/abo-abo/swiper/tree/gh-pages.
+** Fixes
+*** ivy-read
+**** Fix recursive minibuffer exit with ~C-g~
+Make it so e.g. ~C-h f C-h v C-g~ goes back to the =describe-function= selection.
+**** Ensure the return result
+In some cases, =read-from-minibuffer= will return the whole minibuffer
+contents (i.e. all available candidates). Return =ivy--current= instead.
+**** Properly support matching ignoring order
+See [[https://github.com/abo-abo/swiper/issues/296][#296]] and [[https://github.com/abo-abo/swiper/issues/329][#329]].
+**** Insert intermediate candidates during async completions
+See [[https://github.com/abo-abo/swiper/issues/340][#340]].
+**** Initialize =ivy-last= to empty state
+See [[https://github.com/abo-abo/swiper/issues/352][#352]].
+**** Fix extra actions for =completing-read=
+See [[https://github.com/abo-abo/swiper/issues/337][#337]].
+**** Support a list of symbols as collection
+See [[https://github.com/abo-abo/swiper/issues/375][#375]].
+**** Define =setq-local= and =defvar-local= unless defined
+With this commit, Ivy works on emacs-24.2.
+See [[https://github.com/abo-abo/swiper/issues/415][#415]].
+**** Make ~M-o~ not modify the action
+See [[https://github.com/abo-abo/swiper/issues/454][#454]].
+**** Make sure user keybindings are respected
+See [[https://github.com/abo-abo/swiper/issues/466][#466]].
+**** Fix =read-file-name= with a specified dir
+See [[https://github.com/abo-abo/swiper/issues/475][#475]].
+**** Don't highlight the match in the file part
+See [[https://github.com/abo-abo/swiper/issues/483][#483]].
+**** Add a few tests for alists
+*** ivy-occur
+**** Fix =default-directory=
+This way, =next-error= etc will work properly.
+*** ivy--resize-minibuffer-to-fit
+**** Fix for small delta
+See [[https://github.com/abo-abo/swiper/issues/339][#339]].
+**** Check =frame-root-window-p=
+See [[https://github.com/abo-abo/swiper/issues/380][#380]].
+*** ivy-completing-read
+**** Use =completing-read-default= for tmm
+See [[https://github.com/abo-abo/swiper/issues/316][#316]].
+*** ivy--regex-plus
+**** Recognize ! at the beginning of the str
+See [[https://github.com/abo-abo/swiper/issues/318][#318]].
+**** Prettify a bit
+See [[https://github.com/abo-abo/swiper/issues/344][#344]].
+**** Don't consider =\\(?...\)= a group
+See [[https://github.com/abo-abo/swiper/issues/393][#393]].
+*** ivy--get-window
+**** Always return a valid window
+Even if =state= is invalid.
+*** ivy--recompute-index
+**** Update =cl-position= logic
+See [[https://github.com/abo-abo/swiper/issues/207][#207]].
+*** ivy-reverse-i-search
+**** Fix due to recursive update
+See [[https://github.com/abo-abo/swiper/issues/323][#323]].
+*** ivy--reset-state
+**** Don't null =initial-input=
+This is specifically for ='read-file-name-internal= collection.  The
+input needs to be set to nil for e.g. =rgrep=, which supplies the
+*absolute* path as =initial-input=, resulting in a mess.
+
+For now, don't set input to nil if =:action= was passed to =ivy-read=.
+See [[https://github.com/abo-abo/swiper/issues/336][#336]].
+**** Don't deactivate region
+See [[https://github.com/abo-abo/swiper/issues/377][#377]].
+*** ivy-completion-in-region
+**** Use =completion-all-completions=
+See [[https://github.com/abo-abo/swiper/issues/341][#341]].
+**** Optimize for 1 candidate
+When there's only one candidate, call the action immediately.
+**** Add feedback for 1 candidate
+When the sole completion is the same as the input, notify the user.
+See [[https://github.com/abo-abo/swiper/issues/350][#350]].
+**** Bind =completion-ignore-case=
+It's convenient to have it the same value as =case-fold-search=.
+*** ivy-read-action
+**** Give enough minibuffer space
+See [[https://github.com/abo-abo/swiper/issues/402][#402]].
+**** Allow to customize the action hint formatter
+See [[https://github.com/abo-abo/swiper/issues/469][#469]].
+*** ivy-count-format
+**** Fix for nil value
+See [[https://github.com/abo-abo/swiper/issues/349][#349]].
+*** ivy-switch-buffer
+**** Don't fall back to =switch-to-buffer=
+See [[https://github.com/abo-abo/swiper/issues/410][#410]].
+*** ivy-next-history-element
+**** No "\\_<" for dynamic-collection
+"\\_<" regex is Emacs-specific and should only be done if
+=:dynamic-collection= is nil.  It is nil for =counsel-git-grep= with
+repositories < 20000 lines, but non-nil for larger ones.
+
+Fixes [[https://github.com/abo-abo/swiper/issues/409][#409]].
+*** ivy-occur-press
+**** Pulse no longer
+Repeated pulses within a short time span resulted in horrible window
+flickering.
+*** ivy-resume
+**** Add a guard against null =:action=
+*** ivy-avy
+**** Make ~C-g~ cancel gracefully
+See abo-abo/avy[[https://github.com/abo-abo/swiper/issues/140][#140]].
+*** ivy-dispatching-done
+Allow to exit with no candidates.
+*** swiper
+**** Improve for multiple occurrences on one line
+See [[https://github.com/abo-abo/swiper/issues/314][#314]].
+**** Fix "backward" search
+When none of the previous candidates after the point match the current
+input, instead of returning 0, return the index of the last matching
+candidate.  This is a good choice, because that candidate is the
+closest to the point of the initial search start.
+
+See [[https://github.com/abo-abo/swiper/issues/319][#319]].
+**** Return point
+See [[https://github.com/abo-abo/swiper/issues/370][#370]].
+**** Update =regexp-search-ring=
+See [[https://github.com/abo-abo/swiper/issues/89][#89]].
+**** Always remove '(field) text property
+Allows to search better in modes for shell interaction.
+*** swiper-font-lock-ensure
+**** Add modes
+Add bongo-library-mode, bongo-playlist-mode, sauron-mode.
+
+See [[https://github.com/abo-abo/swiper/issues/19][#19]].
+**** Don't fail when font-lock is off
+See [[https://github.com/abo-abo/swiper/issues/400][#400]].
+*** swiper--multi-candidates
+**** Add check for =make-string=
+See [[https://github.com/abo-abo/swiper/issues/481][#481]].
+*** counsel--async-sentinel
+**** Fix issue with =ivy--regex-ignore-order=
+See [[https://github.com/abo-abo/swiper/issues/342][#342]].
+**** Re-display when no cands
+**** Recognize error codes other than 1
+See [[https://github.com/abo-abo/swiper/issues/394][#394]].
+*** consel-git
+**** Fix window selection.
+Use =with-ivy-window=, so that each new file chosen with e.g. ~C-M-n~ is
+selected in the same window.
+*** counsel-recoll
+**** Add =:unwind=
+See [[https://github.com/abo-abo/swiper/issues/403][#403]].
+*** compilation warnings
+See [[https://github.com/abo-abo/swiper/issues/324][#324]].
+** New Features
+*** ivy-read
+**** Use =flx= for highlighting fuzzy matches
+See [[https://github.com/abo-abo/swiper/issues/207][#207]].
+**** Simplify the signature for =:dynamic-collection= functions
+When given =:dynamic-collection=, assume the collection function only
+needs one argument - the string input.
+**** Modify ~M-n~ prediction when region is active
+When the region is active and ~M-n~ is called, insert the region
+contents into the minibuffer and deactivate the region. The region
+deactivation is done for =swiper=, to make it easier to search for
+multiple words or a subword.
+**** Allow to compose collections
+***** Example 1: async collection
+Stack =recentf= on top of =counsel-locate=:
+
+#+begin_src elisp
+(defun small-test ()
+  (cl-subseq recentf-list 0 10))
+
+(ivy-set-sources
+ 'counsel-locate
+ '((small-test)
+   (original-source)))
+#+end_src
+
+Here, (original-source) represents the async candidates of
+=counsel-locate=. All extra sources are static - each function is called
+once to generate a list of strings, which will be filtered later.
+
+The order matters, so you can have e.g.:
+
+#+begin_src elisp
+(ivy-set-sources
+ 'counsel-locate
+ '((original-source)
+   (small-test)))
+#+end_src
+
+See [[https://github.com/abo-abo/swiper/issues/373][#373]].
+***** Example 2: sync collection
+#+begin_src elisp
+(defun my-extra-source ()
+  (append
+   (when (eq 'Git (vc-backend (buffer-file-name)))
+     (list "git1" "git2" "git3"))
+   (when (file-exists-p "doc/Changelog.org")
+     (list (propertize "doc/Changelog.org" 'face '(:background "red"))))))
+
+(defun my-find-file ()
+  (interactive)
+  (ivy-read "Find file: " 'read-file-name-internal
+            :action (lambda (x)
+                      (with-ivy-window
+                        (find-file (expand-file-name x ivy--directory))))
+            :require-match 'confirm-after-completion
+            :history 'file-name-history
+            :caller 'my-find-file))
+
+(ivy-set-sources
+ 'my-find-file
+ '((my-extra-source)
+   (original-source)))
+#+end_src
+
+The function =my-find-file= knows nothing about the extra source, it's
+only purpose is to introduce a =:caller= to attach things to, as to not
+to mess up e.g. =counsel-find-file=.
+
+The function =my-extra-source= gets called once in =ivy-read= via
+=ivy--reset-state=. It takes no args and returns a list of strings,
+possibly empty.
+**** Improve documentation UI
+Bind ~C-h m~ to =ivy-help=.
+
+=ivy-help-file= is a new defvar pointing to the ivy-help.org file.
+
+Bind ~D~ in =hydra-ivy= to go to hydra's definition.
+
+See [[https://github.com/abo-abo/swiper/issues/376][#376]] and [[https://github.com/abo-abo/swiper/issues/379][#379]].
+**** Add ignore pattern toggling
+~C-c C-a~ is bound to =ivy-toggle-ignore= - a new command to toggle ignore
+patterns (user-configured filtering). If the ignore patterns are
+enabled and there are zero candidates after ignoring, display the ones
+that match the current text. This feature currently works for
+=ivy-switch-buffer= and =counsel-find-file=.
+
+See [[https://github.com/abo-abo/swiper/issues/369][#369]].
+*** ivy-mode
+**** Set =completion-in-region-function=
+See [[https://github.com/abo-abo/swiper/issues/331][#331]].
+**** Improve ~M-n~ for ='read-file-name-internal=
+*** ivy-set-occur
+Allows to customize =ivy-occur= per-command.
+**** =ivy-switch-buffer=
+Add custom occur.
+See [[https://github.com/abo-abo/swiper/issues/438][#438]] and [[https://github.com/abo-abo/swiper/issues/440][#440]].
+*** ivy-occur-mode
+**** New commands on ~j~, ~k~, ~c~
+(ivy-occur-toggle-calling): New command bound to ~c~.
+(ivy-occur-next-line): New command bound to ~j~.
+(ivy-occur-previous-line): New command bound to ~k~.
+
+This makes =ivy-occur= much more convenient, instead of ~gjgjgjg~, just
+~cjjj~. Especially good for commands that change the contents of the
+other window, like =describe-function= or =counsel-git-grep=.
+
+Example:
+
+- ~C-h f~ (=describe-funtion=)
+- =run= (=self-insert-command=)
+- ~C-c C-o~ (=ivy-occur=); ~C-o u~ also works.
+- ~cjjjjkkkk~
+**** New command =ivy-occur-revert-buffer= on ~g~
+Does what e.g. =revert-buffer= does for *Help* buffers.
+
+Has special handling for =counsel-git-grep=, =counsel-ag= and
+=counsel-grep=: will run the shell command once more and reflect the
+updates in files.
+
+Move =ivy-occur-press= from ~g~ to ~f~.
+**** Improve the feedback for ~j~ and ~k~
+The overlays will be more responsive now.
+*** ivy-re-builders-alist
+**** Allow =this-command= to be a key
+Example:
+#+begin_src elisp
+(defun asdf ()
+  (interactive)
+  (completing-read "prompt: " '("abc" "abcd" "def")))
+
+(global-set-key (kbd "C-c t") 'asdf)
+
+(setq ivy-re-builders-alist
+      '(
+        (asdf . ivy--regex-fuzzy)
+        (t . ivy--regex-plus)))
+#+end_src
+This is useful for commands that you didn't write. For new commands
+that you write, consider using =ivy-read= and =:caller=.
+
+See [[https://github.com/abo-abo/swiper/issues/330][#330]].
+*** ivy-set-actions
+**** Call with =t= to affect all commands
+Example:
+
+#+begin_src elisp
+(ivy-set-actions
+ t
+ '(("i" insert "insert")))
+#+end_src
+
+Now an "insert" action will be available for all =ivy-read= sessions
+when pressing ~M-o~.
+
+See [[https://github.com/abo-abo/swiper/issues/337][#337]].
+*** ivy-faces
+New defcustom group.
+See [[https://github.com/abo-abo/swiper/issues/389][#389]].
+*** ivy-flx-limit
+New variable. Configure when =flx= is used.
+See [[https://github.com/abo-abo/swiper/issues/207][#207]].
+*** ivy-ignore-buffers
+New defcustom. See [[https://github.com/abo-abo/swiper/issues/366][#366]].
+*** ivy-inhibit-action
+New variable. See [[https://github.com/abo-abo/swiper/issues/363][#363]].
+*** ivy-do-completion-in-region
+New defcustom. See [[https://github.com/abo-abo/swiper/issues/367][#367]].
+*** ivy-fixed-height-minibuffer
+New defcustom.
+
+When non nil, fix the height of the minibuffer during ivy completion
+at =ivy-height=. This effectively sets the minimum height at this level
+and tries to ensure that it does not change depending on the number of
+candidates.
+
+See [[https://github.com/abo-abo/swiper/issues/353][#353]].
+*** ivy-set-display-transformer
+New API function.
+
+Now used by =switch-to-buffer= and =read-file-name=.
+
+See [[https://github.com/abo-abo/swiper/issues/399][#399]].
+*** ivy-ignore-buffers
+New defcustom similar to =ido-ignore-buffers=.
+
+See [[https://github.com/abo-abo/swiper/issues/382][#382]].
+*** ivy-add-newline-after-prompt
+New defcustom.
+
+See [[https://github.com/abo-abo/swiper/issues/451][#451]].
+*** ivy-switch-buffer
+**** Add virtual views
+=ivy-views= variable stores pre-defined views. Allows to set a window
+configuration with many buffers from =ivy-switch-buffer=.
+
+How to use: just set =ivy-views= appropriately. An example value is
+provided (but nulled, so that it's empty initially).
+*** ivy-use-ignore-default
+New defcustom
+
+See [[https://github.com/abo-abo/swiper/issues/477][#477]].
+*** swiper
+**** Improve =swiper-query-replace=
+To replace a symbol with a similar symbol,
+
+1. Press ~C-s M-n~ for =swiper= and select the symbol at point as input.
+2. Press ~M-q~ for =swiper-query-replace=
+3. Press ~M-n~ to yank the symbol to replace.
+4. Edit the replacement and ~RET~.
+
+Here step-3 was modified to yank e.g. "symbol" instead of
+"\_<symbol\_>" previously.
+
+*** swiper-font-lock-exclude
+New variable for major modes that misbehave with =font-lock-ensure=.
+See [[https://github.com/abo-abo/swiper/issues/346][#346]].
+*** swiper-all
+**** New auto-updates position
+See [[https://github.com/abo-abo/swiper/issues/401][#401]].
+*** counsel-mode
+A minor-mode that remaps built-in functions that have counsel
+replacements available.
+
+See [[https://github.com/abo-abo/swiper/issues/414][#414]].
+**** Allow use of describe-prefix-bindings
+See [[https://github.com/abo-abo/swiper/issues/441][#441]].
+*** counsel-find-file
+**** Add =initial-input=
+See [[https://github.com/abo-abo/swiper/issues/336][#336]].
+**** Change tramp prompt from "Find File: " to "user@host: "
+**** Bind =counsel-up-directory= to ~C-DEL~
+New function that moves up to the parent directory and at the same
+time preselects the current directory. This is useful for moving up
+and down a file tree quickly.
+
+See [[https://github.com/abo-abo/swiper/issues/343][#343]].
+**** Customize =M-n= action
+This feature allows to quickly visit Github issues from either
+=magit-commit-mode= or from a version-controlled file. The point has to
+be at the "#" char in e.g. "[[https://github.com/abo-abo/swiper/issues/123][#123]]", that represents an issue.
+
+It's possible to customize =ivy-ffap-url-functions= to do a similar
+thing for places other than Github.
+
+The ~C-x C-f M-n~ key binding will work better with =counsel-find-file=,
+for plain =find-file= it will open a =dired= buffer in addition to opening
+the URL.
+**** Can un-ignore dotfiles with a leading dot input
+When =ivy-text= starts with a dot, don't use
+=counsel-find-file-ignore-regexp=. The generic way to do this is with
+~C-c C-a~ (=ivy-toggle-ignore=), but this is faster and more convenient.
+
+See [[https://github.com/abo-abo/swiper/issues/408][#408]].
+**** Bind ~M-o f~ to =find-file-other-window=
+**** Correctly expand file name at point
+See [[https://github.com/abo-abo/swiper/issues/430][#430]].
+**** Add display transformer
+See [[https://github.com/abo-abo/swiper/issues/458][#458]].
+**** Add magic slash that changes the directory
+Update to the behavior: the slash ("/") will enter a directory even if
+its name isn't completely typed out if either:
+
+1. It's the only candidate.
+2. The candidate index isn't 0, i.e. "C-n" has been typed at least once.
+3. The input isn't "/".
+
+The above rules still allow to keep the old behavior with "//" moving
+to root and "/ssh:" opening tramp.
+
+This is an experimental feature, please report if it breaks someone's
+workflow.
+
+See [[https://github.com/abo-abo/swiper/issues/321][#321]] and [[https://github.com/abo-abo/swiper/issues/480][#480]].
+*** counsel-git-grep
+**** Bind ~C-c C-m~ to =counsel-git-grep-switch-cmd=
+The initial command always runs on all files.
+
+To run only on *.el files, ~C-c C-m~ followed by ~M-i~ =-- *.el=.
+To run on *.c and *.h files, ~C-c C-m~ followed by ~M-i~ =-- *.c *.h=.
+To switch to all files again, ~C-c C-m~ and select the appropriate
+entry.
+
+See [[https://github.com/abo-abo/swiper/issues/420][#420]].
+*** counsel-locate
+**** counsel-locate-cmd
+New defcustom that replaces =counsel-locate-options=.
+
+See [[https://github.com/abo-abo/swiper/issues/385][#385]].
+**** counsel-locate-cmd-mdfind
+New function.
+See [[https://github.com/abo-abo/swiper/issues/390][#390]].
+**** counsel-locate-cmd-es
+New function.
+See [[https://github.com/abo-abo/swiper/issues/426][#426]].
+*** counsel-yank-pop
+**** Truncate during display
+During the completion, only the context around the match will be shown.
+By default, the context is +2 lines above and +2 lines below the match.
+It can be adjusted with =counsel-yank-pop-truncate-radius=.
+Additionally, =ivy-height= is temporarily bound to 5 during completion.
+This way, the maximum minibuffer height should be 1+4*5=21 lines.
+
+See [[https://github.com/abo-abo/swiper/issues/315][#315]].
+*** counsel-unicode-char
+Display hex codes in left column.
+*** counsel-rhythmbox
+**** Preselect the current song
+*** counsel-ag
+**** =counsel-ag-base-command=
+Allows the command run by =counsel-ag-function= to be customized. There
+are several reasons to allow this: The vimgrep option is a recent
+addition; on windows it's more convenient to use pt; and the user
+might want to customize ignored files.
+
+Standard value:
+#+begin_src elisp
+(setq counsel-ag-base-command "ag --nocolor --nogroup %s -- .")
+#+end_src
+
+See [[https://github.com/abo-abo/swiper/issues/335][#335]].
+**** Add dir prompt for ~C-u~
+See [[https://github.com/abo-abo/swiper/issues/429][#429]].
+**** Add =counsel-ag-map=
+See [[https://github.com/abo-abo/swiper/issues/462][#462]].
+*** counsel-async-split-string-re
+New defcustom.
+*** counsel--async-cmd
+**** Add optional exit-code table
+This argument can be used to associate exit codes with the underlying
+reason. Used in counsel-ag-function to signal that an exit code of 1
+means that no matches were found.
+
+See [[https://github.com/abo-abo/swiper/issues/421][#421]].
+*** counsel-prompt-function
+New defcustom
+
+See [[https://github.com/abo-abo/swiper/issues/424][#424]] and [[https://github.com/abo-abo/swiper/issues/425][#425]].
+*** counsel-grep
+**** Reveal outlines
+Just like =swiper=.
+**** Should pick candidates closest to point
+Fixes the algorithm selecting the first matching candidate in case
+there are 0 matching candidates following point. Now the last matching
+candidate will be selected, resulting in less scrolling.
+**** Speed up x40 times
+The default shell command will not use =--ignore-case= switch for
+=grep=. It's a bit less convenient, but results in a huge speed-up.
+*** counsel-M-x
+**** Add help action
+Bound to ~M-o h~ by default.
+
+See [[https://github.com/abo-abo/swiper/issues/452][#452]].
+** New Commands
+*** =counsel-tmm=
+Completion for the menu bar items. For example:
+
+=counsel-tmm= -> =Options= -> =Set Default Font...=.
+
+Thanks to completion, the latter stages of the chain would look like: =op= ~RET~ =set= ~RET~.
+*** =counsel-imenu=
+Jump to a buffer position indexed by imenu.
+*** =counsel-decbinds=
+Show a list of all defined keys, and their definitions. Describe the
+selected candidate.
+See [[https://github.com/abo-abo/swiper/issues/332][#332]].
+*** =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.
+
+See [[https://github.com/abo-abo/swiper/issues/357][#357]] and [[https://github.com/abo-abo/swiper/issues/398][#398]].
+*** =ivy-switch-buffer-other-window=
+Remap =switch-to-buffer-other-window= to =ivy-switch-buffer-other-window= for =ivy-mode=.
+
+See [[https://github.com/abo-abo/swiper/issues/361][#361]].
+*** =counsel-git-stash=
+Search through all available git stashes.
+
+See [[https://github.com/abo-abo/swiper/issues/374][#374]].
+*** =counsel-git-log=
+Call the =git log --grep= shell command and search through the output.
+*** =counsel-pt=
+Grep for a string in the current directory using pt.
+
+See [[https://github.com/abo-abo/swiper/issues/434][#434]].
+*** =counsel-linux-app=
+Launch a Linux desktop application, similar to Alt-<F2>.
+
+See [[https://github.com/abo-abo/swiper/issues/446][#446]].
+*** =counsel-ace-link=
+Ivy completion for =ace-link=.
+*** =counsel-esh-history=
+Browse Eshell history.
+
+See [[https://github.com/abo-abo/swiper/issues/459][#459]].
+*** =counsel-shell-history=
+Browse shell history.
+*** =counsel-grep-or-swiper=
+New command: automatically use =swiper= for smaller buffers and
+=counsel-grep= for larger buffers.
+
+Adjust with:
+#+begin_src elisp
+(setq counsel-grep-swiper-limit 300000)
+#+end_src
+
+By default, the splitting predicate is 300K bytes in a file.
diff --git a/packages/ivy/doc/ivy-help.org b/packages/ivy/doc/ivy-help.org
new file mode 100644 (file)
index 0000000..989c0e4
--- /dev/null
@@ -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.
diff --git a/packages/ivy/doc/ivy-ox.el b/packages/ivy/doc/ivy-ox.el
new file mode 100644 (file)
index 0000000..cb69c7f
--- /dev/null
@@ -0,0 +1,193 @@
+;;; ivy-ox.el --- org-export settings for Ivy
+
+;; Copyright (C) 2015  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;* ox-texinfo
+(require 'ox-texinfo)
+(org-export-define-backend 'texinfo
+  '((bold . org-texinfo-bold)
+    (center-block . org-texinfo-center-block)
+    (clock . org-texinfo-clock)
+    (code . org-texinfo-kbd)
+    (drawer . org-texinfo-drawer)
+    (dynamic-block . org-texinfo-dynamic-block)
+    (entity . org-texinfo-entity)
+    (example-block . org-texinfo-example-block)
+    (export-block . org-texinfo-export-block)
+    (export-snippet . org-texinfo-export-snippet)
+    (fixed-width . org-texinfo-fixed-width)
+    (footnote-definition . org-texinfo-footnote-definition)
+    (footnote-reference . org-texinfo-footnote-reference)
+    (headline . org-texinfo-headline)
+    (inline-src-block . org-texinfo-inline-src-block)
+    (inlinetask . org-texinfo-inlinetask)
+    (italic . org-texinfo-italic)
+    (item . org-texinfo-item)
+    (keyword . org-texinfo-keyword)
+    (line-break . org-texinfo-line-break)
+    (link . org-texinfo-link)
+    (node-property . org-texinfo-node-property)
+    (paragraph . org-texinfo-paragraph)
+    (plain-list . org-texinfo-plain-list)
+    (plain-text . org-texinfo-plain-text)
+    (planning . org-texinfo-planning)
+    (property-drawer . org-texinfo-property-drawer)
+    (quote-block . org-texinfo-quote-block)
+    (radio-target . org-texinfo-radio-target)
+    (section . org-texinfo-section)
+    (special-block . org-texinfo-special-block)
+    (src-block . org-texinfo-src-block)
+    (statistics-cookie . org-texinfo-statistics-cookie)
+    (subscript . org-texinfo-subscript)
+    (superscript . org-texinfo-superscript)
+    (table . org-texinfo-table)
+    (table-cell . org-texinfo-table-cell)
+    (table-row . org-texinfo-table-row)
+    (target . org-texinfo-target)
+    (template . org-texinfo-template)
+    (timestamp . org-texinfo-timestamp)
+    (verbatim . org-texinfo-code)
+    (verse-block . org-texinfo-verse-block))
+  :filters-alist
+  '((:filter-headline . org-texinfo--filter-section-blank-lines)
+    (:filter-parse-tree . org-texinfo--normalize-headlines)
+    (:filter-section . org-texinfo--filter-section-blank-lines))
+  :menu-entry
+  '(?i "Export to Texinfo"
+    ((?t "As TEXI file" org-texinfo-export-to-texinfo)
+     (?i "As INFO file" org-texinfo-export-to-info)
+     (?o "As INFO file and open"
+      (lambda (a s v b)
+        (if a (org-texinfo-export-to-info t s v b)
+          (org-open-file (org-texinfo-export-to-info nil s v b)))))))
+  :options-alist
+  '((:texinfo-filename "TEXINFO_FILENAME" nil nil t)
+    (:texinfo-class "TEXINFO_CLASS" nil org-texinfo-default-class t)
+    (:texinfo-header "TEXINFO_HEADER" nil nil newline)
+    (:texinfo-post-header "TEXINFO_POST_HEADER" nil nil newline)
+    (:subtitle "SUBTITLE" nil nil parse)
+    (:subauthor "SUBAUTHOR" nil nil newline)
+    (:texinfo-dircat "TEXINFO_DIR_CATEGORY" nil nil t)
+    (:texinfo-dirtitle "TEXINFO_DIR_TITLE" nil nil t)
+    (:texinfo-dirdesc "TEXINFO_DIR_DESC" nil nil t)
+    (:texinfo-printed-title "TEXINFO_PRINTED_TITLE" nil nil t)
+    ;; Other variables.
+    (:texinfo-classes nil nil org-texinfo-classes)
+    (:texinfo-format-headline-function nil nil org-texinfo-format-headline-function)
+    (:texinfo-node-description-column nil nil org-texinfo-node-description-column)
+    (:texinfo-active-timestamp-format nil nil org-texinfo-active-timestamp-format)
+    (:texinfo-inactive-timestamp-format nil nil org-texinfo-inactive-timestamp-format)
+    (:texinfo-diary-timestamp-format nil nil org-texinfo-diary-timestamp-format)
+    (:texinfo-link-with-unknown-path-format nil nil org-texinfo-link-with-unknown-path-format)
+    (:texinfo-tables-verbatim nil nil org-texinfo-tables-verbatim)
+    (:texinfo-table-scientific-notation nil nil org-texinfo-table-scientific-notation)
+    (:texinfo-def-table-markup nil nil org-texinfo-def-table-markup)
+    (:texinfo-text-markup-alist nil nil org-texinfo-text-markup-alist)
+    (:texinfo-format-drawer-function nil nil org-texinfo-format-drawer-function)
+    (:texinfo-format-inlinetask-function nil nil org-texinfo-format-inlinetask-function)))
+
+(defun org-texinfo-kbd (code _contents _info)
+  "Transcode a CODE object from Org to Texinfo."
+  (format "@kbd{%s}" (org-element-property :value code)))
+
+(defun org-texinfo-plain-list (plain-list contents info)
+  "Transcode a PLAIN-LIST element from Org to Texinfo.
+CONTENTS is the contents of the list.  INFO is a plist holding
+contextual information."
+  (let* ((attr (org-export-read-attribute :attr_texinfo plain-list))
+         (indic (or (plist-get attr :indic)
+                    (plist-get info :texinfo-def-table-markup)))
+         (table-type (plist-get attr :table-type))
+         (type (org-element-property :type plain-list))
+         (list-type (cond
+                      ((eq type 'ordered) "enumerate")
+                      ((eq type 'unordered) "itemize")
+                      ((member table-type '("ftable" "vtable")) table-type)
+                      (t "table"))))
+    (if (equal list-type "table")
+        (mapconcat (lambda (s)
+                     (cond ((string-match "\\`User Option @code{\\(.*\\)}$" s)
+                            (format "@defopt %s\n%s\n@end defopt\n"
+                                    (match-string-no-properties 1 s)
+                                    (string-trim
+                                     (substring s (1+ (match-end 1))))))
+                           ((string-match "\\(.*\\)$" s)
+                            (let* ((line (match-string 1 s))
+                                   (body (string-trim
+                                          (substring s (1+ (match-end 1)))))
+                                   (symbol-index
+                                    (if (string-match "@code{\\(\\(?:ivy\\|swiper\\|counsel\\)-[^}]+\\)}" line)
+                                        (format "@vindex %s\n" (match-string 1 line))
+                                      ""))
+                                   (key-index
+                                    (apply #'concat
+                                           (mapcar
+                                            (lambda (s)
+                                              (format "@kindex %s\n" s))
+                                            (iox-extract-kbd line)))))
+                              (format "@subsubheading %s\n%s@indentedblock\n%s\n@end indentedblock"
+                                      line
+                                      (concat symbol-index
+                                              key-index)
+                                      body)))
+                           (t
+                            (concat "@subsubheading " s))))
+                   (split-string (substring-no-properties contents) "^@item " t)
+                   "\n")
+      (format "@%s\n%s@end %s"
+              (if (eq type 'descriptive) (concat list-type " " indic) list-type)
+              contents
+              list-type))))
+
+(defun iox-extract-kbd (str)
+  (let ((start 0)
+        res)
+    (while (string-match "@kbd{\\([^}]+\\)}" str start)
+      (setq start (match-end 0))
+      (push (match-string 1 str) res))
+    (nreverse res)))
+
+;;* ox-html
+(require 'ox-html)
+(setq org-html-validation-link nil)
+(setq org-html-postamble nil)
+(setq org-html-text-markup-alist
+      '((bold . "<b>%s</b>")
+        (code . "<kbd>%s</kbd>")
+        (italic . "<i>%s</i>")
+        (strike-through . "<del>%s</del>")
+        (underline . "<span class=\"underline\">%s</span>")
+        (verbatim . "<code>%s</code>")))
+(setq org-html-style-default nil)
+
+(defvar ivy-info-dir (file-name-directory
+                      (or load-file-name
+                          (buffer-file-name))))
+
+(defun info-ivy ()
+  (interactive)
+  (let ((buf (get-buffer "*info*")))
+    (when buf
+      (kill-buffer buf)))
+  (Info-find-node
+   (expand-file-name "ivy.info" ivy-info-dir)
+   "Top"))
+
+(provide 'ivy-ox)
index b26b00e49742dc7852ba453c0fb441f1b9082b48..8c0f35757f7d6d976007a6960d5fcf33efa41123 100644 (file)
@@ -1,40 +1,67 @@
 #+TITLE: Ivy User Manual
 #+AUTHOR: Oleh Krehel
 #+EMAIL: ohwoeowho@gmail.com
-#+DATE: 2015
 #+LANGUAGE: en
 
 #+TEXINFO_DIR_CATEGORY: Emacs
 #+TEXINFO_DIR_TITLE: Ivy: (ivy).
 #+TEXINFO_DIR_DESC: Using Ivy for completion.
-#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css"/>
-
+#+SETUPFILE: ~/git/org-html-themes/setup/theme-readtheorg.setup
+#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="kbd-style.css"/>
 #+OPTIONS: H:6 num:6 toc:4
 #+STARTUP: indent
-* Macros                                                                              :noexport:
-#+MACRO: defopt #+TEXINFO: @defopt $1
-#+MACRO: endopt #+TEXINFO: @end defopt
+* Setup                                                                               :noexport:
+#+BEGIN_SRC elisp :exports results :results silent
+(add-to-list 'load-path default-directory)
+(require 'ivy-ox)
+#+END_SRC
+* Writing this manual                                                                 :noexport:
+To highlight a section without introducing a new subheading use
+definition lists. The definition list "owns" the subsequent text if
+the text is indented by 5 spaces. Use ~C-q~ to indent the
+paragraphs. Start new paragraphs with 5 spaces indented. To separate
+definition lists from regular lists, use two newlines.
+
+A typical definition list:
+#+BEGIN_EXAMPLE
+- ~C-M-j~ (=ivy-immediate-done=) ::
+#+END_EXAMPLE
+The code and kbd part is recognized and added as =@vindex= and
+=@kindex= respectively.
+
+Use definition lists to declare a =@defopt= section for =defcustom=
+or =defvar=. For proper Texinfo export, use this form:
+
+#+BEGIN_EXAMPLE
+User Option =ivy-wrap= ::
+#+END_EXAMPLE
+
+Set =CUSTOM_ID= property to name each heading. For example, =worf='s
+~C-u L~. This will result in consistent HTML node names.
+
+Keep one empty line before each source block for proper Texinfo
+exports.
 * Copying
 :PROPERTIES:
 :COPYING:  t
+:CUSTOM_ID: copying
 :END:
-
-#+BEGIN_TEXINFO
-@ifnottex
+#+TEXINFO: @ifnottex
 Ivy manual, version 0.7.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, @code{ivy-mode} completes the selection process by narrowing
+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. @end ifnottex
+through powerful regular expressions.
+#+TEXINFO: @end ifnottex
 
-Copyright @copyright{} 2015 Free Software Foundation, Inc.
+Copyright (C) 2015 Free Software Foundation, Inc.
 
-@quotation
+#+BEGIN_QUOTE
 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
@@ -44,10 +71,13 @@ 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.''
-@end quotation
-#+END_TEXINFO
+#+END_QUOTE
 
+#+HTML: <a href="https://github.com/abo-abo/swiper/blob/master/doc/ivy.org">This manual source</a>
 * Introduction
+:PROPERTIES:
+:CUSTOM_ID: introduction
+:END:
 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
@@ -56,56 +86,58 @@ number of choices.
 Ivy strives for minimalism, simplicity, customizability and
 discoverability.
 
-#+BEGIN_TEXINFO
-@subsubheading Minimalism
-#+END_TEXINFO
-Uncluttered minibuffer is minimalism. Ivy shows the completion
-defaults, the number of matches, and 10 candidate matches below the
-input line. Customize =ivy-length= to adjust the number of candidate
-matches displayed in the minibuffer.
-
-#+BEGIN_TEXINFO
-@subsubheading Simplicity
-#+END_TEXINFO
-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.
-
-#+BEGIN_TEXINFO
-@subsubheading Customizability
-#+END_TEXINFO
-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. 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.
-
-#+BEGIN_TEXINFO
-@subsubheading Discoverability
-#+END_TEXINFO
-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.
+- 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. 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.
 
 * Installation
+:PROPERTIES:
+:CUSTOM_ID: installation
+:END:
 
 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.
+
 ** Installing from Emacs Package Manager
+:PROPERTIES:
+:CUSTOM_ID: installing-from-emacs-package-manager
+:END:
 
 ~M-x~ =package-install= ~RET~ =swiper= ~RET~
 
@@ -129,35 +161,43 @@ After this do ~M-x~ =package-refresh-contents= ~RET~, followed by
 For package manager details, see [[info:emacs#Packages]].
 
 ** Installing from the Git repository
+:PROPERTIES:
+:CUSTOM_ID: installing-from-the-git-repository
+:END:
 
-Why install from Git?
+- 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
+    - 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:
-#+begin_src sh
-cd ~/git && git clone https://github.com/abo-abo/swiper
-cd swiper && make compile
-#+end_src
+- Configuration steps ::
+     First clone the Swiper repository with:
 
-Then add this to Emacs init:
-#+begin_src elisp
-(add-to-list 'load-path "~/git/swiper/")
-(require 'ivy)
-#+end_src
+     #+begin_src sh
+     cd ~/git && git clone https://github.com/abo-abo/swiper
+     cd swiper && make compile
+     #+end_src
 
-To update the code:
-#+begin_src sh
-git pull
-make
-#+end_src
+     Second, add these lines to the Emacs init file:
 
-* Getting started
+     #+begin_src elisp
+     (add-to-list 'load-path "~/git/swiper/")
+     (require 'ivy)
+     #+end_src
+
+     Then, update the code with:
 
+     #+begin_src sh
+     git pull
+     make
+     #+end_src
+
+* Getting started
+:PROPERTIES:
+:CUSTOM_ID: getting-started
+:END:
 First enable Ivy completion everywhere:
 
 #+begin_src elisp
@@ -166,64 +206,88 @@ First enable Ivy completion everywhere:
 
 Note: =ivy-mode= can be toggled on and off with ~M-x~ =ivy-mode=.
 ** Basic customization
-Here are some basic settings particularly useful for new Ivy
-users:
+:PROPERTIES:
+:CUSTOM_ID: basic-customization
+:END:
+Here are some basic settings particularly useful for new Ivy users:
+
 #+begin_src elisp
 (setq ivy-use-virtual-buffers t)
 (setq ivy-height 10)
-(setq ivy-display-style 'fancy)
 (setq ivy-count-format "(%d/%d) ")
 #+end_src
 
-For additional customizations, refer to =M-x describe-variable=
+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.
 
 * Key bindings
+:PROPERTIES:
+:CUSTOM_ID: key-bindings
+:END:
 ** Global key bindings
+:PROPERTIES:
+:CUSTOM_ID: global-key-bindings
+:END:
+The recommended key bindings are:
 
-Recommended key bindings are:
-#+BEGIN_TEXINFO
-@subsubheading Ivy-based interface to standard commands
-#+END_TEXINFO
-#+begin_src elisp
-(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-load-library)
-(global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
-(global-set-key (kbd "<f2> u") 'counsel-unicode-char)
-#+end_src
-#+BEGIN_TEXINFO
-@subsubheading Ivy-based interface to shell and system tools
-#+END_TEXINFO
-#+begin_src elisp
-(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)
-#+end_src
-#+BEGIN_TEXINFO
-@subsubheading Ivy-resume and other commands
-#+END_TEXINFO
-=ivy-resume= resumes the last Ivy-based completion.
-#+begin_src elisp
-(global-set-key (kbd "C-c C-r") 'ivy-resume)
-#+end_src
+- Ivy-based interface to standard commands ::
+
+     #+begin_src elisp
+     (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-load-library)
+     (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
+     (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
+     #+end_src
+
+- Ivy-based interface to shell and system tools ::
+
+     #+begin_src elisp
+     (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)
+     #+end_src
+
+- Ivy-resume and other commands ::
+
+     =ivy-resume= resumes the last Ivy-based completion.
+
+     #+begin_src elisp
+     (global-set-key (kbd "C-c C-r") 'ivy-resume)
+     #+end_src
 
 ** Minibuffer key bindings
+:PROPERTIES:
+:CUSTOM_ID: minibuffer-key-bindings
+:END:
 
+#+VINDEX: ivy-minibuffer-map
 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 through the =keymap= argument to
-=ivy-read=. These keys, also active in the minibuffer, are described
-under their respective commands.
+=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=.
 
 *** Key bindings for navigation
+:PROPERTIES:
+:CUSTOM_ID: key-bindings-for-navigation
+:END:
 
 - ~C-n~ (=ivy-next-line=) selects the next candidate
 - ~C-p~ (=ivy-previous-line=) selects the previous candidate
@@ -232,20 +296,24 @@ under their respective commands.
 - ~C-v~ (=ivy-scroll-up-command=) scrolls up by =ivy-height= lines
 - ~M-v~ (=ivy-scroll-down-command=) scrolls down by =ivy-height= lines
 
-{{{defopt(ivy-wrap)}}}
-This user option allows to get the wrap-around behavior for ~C-n~ and
-~C-p~.  When set to =t=, =ivy-next-line= and =ivy-previous-line= will
-cycle past the last and the first candidates respectively.
 
-This behavior is off by default.
-{{{endopt}}}
+- 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.
 
-{{{defopt(ivy-height)}}}
-Use this variable to adjust the minibuffer height, and therefore the
-scroll size for ~C-v~ and ~M-v~.
-{{{endopt}}}
+     =ivy-height= is 10 lines by default.
 
 *** Key bindings for single selection, action, then exit minibuffer
+:PROPERTIES:
+:CUSTOM_ID: key-bindings-for-single-selection-action-then-exit-minibuffer
+:END:
 
 Ivy can offer several actions from which to choose which action to
 run. This "calling an action" operates on the selected candidate. For
@@ -257,44 +325,52 @@ 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 exits the
-minibuffer.
+- ~C-m~ or ~RET~ (=ivy-done=) ::
+     Calls the default action and then exits the minibuffer.
 
-~M-o~ (=ivy-dispatching-done=) presents all available valid actions
-from which to choose. When there is only one action available, there
-is no difference between ~M-o~ and ~C-m~.
+- ~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=) calls the alternate action, such as completing
-a directory name in a file list whereas ~C-m~ will select that directory
-and exit the minibuffer.
+- ~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=.
 
-Exiting the minibuffer also closes the Ivy window (as specified by
-=ivy-height=). This closing and exiting sequence is conveniently off
-when applying multiple actions. Multiple actions and multiple
-selections as covered in the next section of this manual.
+- ~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=).
 
-~TAB~ (=ivy-partial-or-done=) attempts partial completion, extending
-current input as much as possible.
+     Example ERT test:
 
-~TAB TAB~ is the same as ~C-j~.
+     #+begin_src elisp
+     (should
+      (equal (ivy-with
+              '(progn
+                (ivy-read "Test: " '("can do" "can't, sorry" "other"))
+                ivy-text)
+              "c <tab>")
+             "can"))
+     #+end_src
 
-~C-M-j~ (=ivy-immediate-done=) is useful when there is no match for
-the given input. Or there is an incorrect partial match. ~C-M-j~ with
-=find-file= lists ignores the partial match and instead takes the
-current input to create a new directory with =dired-create-directory=.
+- ~C-M-j~ (=ivy-immediate-done=) ::
+     Exits with /the current input/ instead of /the current candidate/
+     (like other commands).
 
-=ivy-immediate-done= illustrates how Ivy distinguishes between calling
-an action on the /currently selected/ candidate and calling an action
-on the /current input/.
+     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.
 
-#+BEGIN_TEXINFO
-Invoking avy completion with @kbd{C-'} (@code{ivy-avy}).
-#+END_TEXINFO
-~C-`~ uses avy's visible jump mechanism, which can further reduce
-Ivy's line-by-line scrolling that requires multiple ~C-n~ or ~C-p~
-keystrokes.
+- ~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~.
 
 *** Key bindings for multiple selections and actions, keep minibuffer open
+:PROPERTIES:
+:CUSTOM_ID: key-bindings-for-multiple-selections-and-actions-keep-minibuffer-open
+:END:
 
 For repeatedly applying multiple actions or acting on multiple
 candidates, Ivy does not close the minibuffer between commands. It
@@ -304,118 +380,243 @@ 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 the default action,
-~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-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~.
 
-~RET~ exits the minibuffer.
+- ~C-M-n~ (=ivy-next-line-and-call=) ::
+     Combines ~C-n~ and ~C-M-m~. Applies an action and moves to next
+     line.
 
-=ivy-resume= recalls the state of the completion session just before
-its last exit. Useful after an accidental ~C-m~ (=ivy-done=).
+     Comes in handy when opening multiple files from
+     =counsel-find-file=, =counsel-git-grep=, =counsel-ag=, or
+     =counsel-locate= lists. Just hold ~C-M-n~ for rapid-fire default
+     action on each successive element of the list.
 
-~C-M-o~ (=ivy-dispatching-call=) is a non-exiting version of ~M-o~
-(=ivy-dispatching-done=) that can accumulate candidates into a queue.
-For example, for playback in =counsel-rhythmbox=, ~C-M-o e~ en-queues
-the selected candidate, and ~C-n C-m~ plays the next one in the queue.
+- ~C-M-p~ (=ivy-previous-line-and-call=) ::
+     Combines ~C-p~ and ~C-M-m~.
 
-~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=, or
-=counsel-locate= lists. Just hold ~C-M-n~ for rapid-fire default
-action on each successive element of the list.
+     Similar to the above except it moves through the list in the
+     other direction.
 
-~C-M-p~ (=ivy-previous-line-and-call=) combines ~C-p~ and ~C-M-m~. Is
-the same as above except that 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=).
+
+*** Key bindings that alter the minibuffer input
+:PROPERTIES:
+:CUSTOM_ID: key-bindings-that-alter-the-minibuffer-input
+:END:
 
-*** Key bindings that alter minibuffer input
+- ~M-n~ (=ivy-next-history-element=) ::
+     Cycles forward through the Ivy command history.
 
-~M-n~ (=ivy-next-history-element=) and ~M-p~
-(=ivy-previous-history-element=) cycle 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.
+     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-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-p~ (=ivy-previous-history-element=) ::
+     Cycles forward through the Ivy command history.
 
-~M-j~ (=ivy-yank-word=) inserts sub-word at point into minibuffer. This
-is similar to ~C-s C-w~ with =isearch=. Ivy reserves ~C-w~ for
-=kill-region=.
+- ~M-i~ (=ivy-insert-current=) ::
+     Inserts the current candidate 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.
+     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.
 
-~C-r~ (=ivy-reverse-i-search=) works just like ~C-r~ at bash command
-prompt, where the completion candidates are the history items. Upon
-completion, the selected candidate string is inserted into the
-minibuffer.
+- ~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.
 
 *** Other key bindings
+:PROPERTIES:
+:CUSTOM_ID: other-key-bindings
+:END:
 
-~M-w~ (=ivy-kill-ring-save=) copies selected candidates to the kill
-ring; when the region is active, copies active region.
+- ~M-w~ (=ivy-kill-ring-save=) ::
+     Copies selected candidates to the kill ring.
+
+     Copies the region if the region is active.
 
 *** Hydra in the minibuffer
+:PROPERTIES:
+:CUSTOM_ID: hydra-in-the-minibuffer
+:END:
+
+- ~C-o~ (=hydra-ivy/body=) ::
+     Invokes the hydra menu with short key bindings.
 
-~C-o~ (=hydra-ivy/body=) invokes Hydra menus with key shortcuts.
+When Hydra is active, minibuffer editing is disabled and menus
+display short aliases:
 
-~C-o~ or ~i~ resumes editing.
+| 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 has other benefits besides certain shorter key
-bindings:
-- ~<~ and ~>~ to adjust height of minibuffer,
-- describes the current completion state, such as case folding and the
-  current action.
+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.
 
-Minibuffer editing is disabled when Hydra is active.
+- ~<~ (=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).
 
 *** Saving the current completion session to a buffer
+:PROPERTIES:
+:CUSTOM_ID: saving-the-current-completion-session-to-a-buffer
+:END:
+
+- ~C-c C-o~ (=ivy-occur=) ::
+     Saves the current candidates to a new buffer and exits
+     completion.
 
-~C-c C-o~ (=ivy-occur=) saves the current candidates to a new buffer;
-the list is active in the new buffer.
+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.
 
-~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
+Ivy takes care of naming buffers uniquely by constructing descriptive
+names. For example: =*ivy-occur counsel-describe-variable
 "function$*=.
 
-* Completion styles
+* Completion Styles
+:PROPERTIES:
+:CUSTOM_ID: completion-styles
+:END:
+
+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=.
 
-Ivy's completion functions rely on the highly configurable regex
-builder.
+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:
+
 #+begin_src elisp
 (setq ivy-re-builders-alist
       '((t . ivy--regex-plus)))
 #+end_src
 
-The default =ivy--regex-plus= narrowing is always invoked unless
-specified otherwise. For example, file name completion may have a
-custom completion function:
+This example shows a custom regex builder assigned to file name
+completion:
+
 #+begin_src elisp
 (setq ivy-re-builders-alist
       '((read-file-name-internal . ivy--regex-fuzzy)
         (t . ivy--regex-plus)))
 #+end_src
 
-Ivy's flexibility extends to using different styles of completion
-mechanics (regex-builders) for different types of lists. Despite this
-flexibility, Ivy operates within a consistent and uniform interface.
-The main regex-builders currently in Ivy are:
+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=.
 
 ** ivy--regex-plus
+:PROPERTIES:
+:CUSTOM_ID: ivy--regex-plus
+:END:
 
 =ivy--regex-plus= is Ivy's default completion method.
 
@@ -423,54 +624,662 @@ The main regex-builders currently in Ivy are:
 rebuilding it into a regex.
 
 As the search string is typed in Ivy's minibuffer, it is transformed
-into proper regex syntax. If the string is "for example", it is
+into valid regex syntax. If the string is ="for example"=, it is
 transformed into
 
-#+BEGIN_EXAMPLE
+#+begin_src elisp
 "\\(for\\).*\\(example\\)"
-#+END_EXAMPLE
+#+end_src
 
-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. For literal white space matching in Ivy, use an extra space:
-to match one space type two spaces, to match two spaces type three
-spaces, and so on.
+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.
-
-#+BEGIN_EXAMPLE
-Standard regexp identifiers work:
-
-"^", "$", "\b" or "[a-z]"
-#+END_EXAMPLE
+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, standard regexp
-identifiers work as usual. The exceptions are spaces, which
-translate to ".*", and "!" that signal the beginning of a negation
-group.
+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.
 
 ** ivy--regex-ignore-order
+:PROPERTIES:
+:CUSTOM_ID: ivy--regex-ignore-order
+:END:
 
 =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". Otherwise =ivy--regex-plus=
-normal behavior is to honor the order of regexp tokens.
+searching for matching candidates. For instance, the input
+="for example"= will match ="example test for"=.
 
 ** ivy--regex-fuzzy
+:PROPERTIES:
+:CUSTOM_ID: ivy--regex-fuzzy
+:END:
 
 =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
+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.
+
+
+* Customization
+:PROPERTIES:
+:CUSTOM_ID: customization
+:END:
+** Faces
+:PROPERTIES:
+:CUSTOM_ID: faces
+:END:
+- =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:
+
+     #+begin_src elisp
+     (setq confirm-nonexistent-file-or-buffer t)
+     #+end_src
+
+     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:
+
+     #+begin_src elisp
+     (setq ivy-use-virtual-buffers t)
+     #+end_src
+** Defcustoms
+:PROPERTIES:
+:CUSTOM_ID: defcustoms
+:END:
+- 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:
+
+     #+begin_src elisp
+     (setq ivy-count-format "")
+     #+end_src
+
+     To also display the current candidate:
+
+     #+begin_src elisp
+     (setq ivy-count-format "(%d/%d) ")
+     #+end_src
+
+     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.
+
+** Actions
+:PROPERTIES:
+:CUSTOM_ID: actions
+:END:
+*** What are actions?
+:PROPERTIES:
+:CUSTOM_ID: what-are-actions
+:END:
+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.
+
+     #+begin_src elisp
+     (defun ivy-insert-action (x)
+       (with-ivy-window
+         (insert x)))
+     #+end_src
+
+*** How can different actions be called?
+:PROPERTIES:
+:CUSTOM_ID: how-can-different-actions-be-called
+:END:
+- ~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.
+
+*** How to modify the actions list?
+:PROPERTIES:
+:CUSTOM_ID: how-to-modify-the-actions-list
+:END:
+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~.
+
+*** Example - add two actions to each command
+:PROPERTIES:
+:CUSTOM_ID: example---add-two-actions-to-each-command
+:END:
+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.
+
+#+begin_src elisp
+(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")))
+#+end_src
+
+Then in any completion session, ~M-o y~ invokes =ivy-yank-action=, and
+~M-o i~ invokes =ivy-copy-to-buffer-action=.
+
+**** How to undo adding the two actions
+:PROPERTIES:
+:CUSTOM_ID: how-to-undo-adding-the-two-actions
+:END:
+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:
+
+#+begin_src elisp
+(ivy-set-actions t nil)
+#+end_src
+
+**** How to add actions to a specific command
+:PROPERTIES:
+:CUSTOM_ID: how-to-add-actions-to-a-specific-command
+:END:
+Use the command name as the key:
+
+#+begin_src elisp
+(ivy-set-actions
+ 'swiper
+ '(("i" ivy-copy-to-buffer-action "insert")
+   ("y" ivy-yank-action "yank")))
+#+end_src
+
+*** Example - define a new command with several actions
+:PROPERTIES:
+:CUSTOM_ID: example---define-a-new-command-with-several-actions
+:END:
+#+begin_src elisp
+(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"))))
+#+end_src
+
+The number 1 above is the index of the default action. Each
+action has its own string description for easy selection.
+
+**** Test the above function with =ivy-occur=
+:PROPERTIES:
+:CUSTOM_ID: test-the-above-function-with-ivy-occur
+:END:
+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...
+
+** Packages
+:PROPERTIES:
+:CUSTOM_ID: packages
+:END:
+- =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 requries this setting for ivy completion:
+
+     #+begin_src elisp
+     (setq magit-completing-read-function 'ivy-completing-read)
+     #+end_src
+- =find-file-in-project= ::
+     It uses ivy by default if Ivy is installed.
+- =projectile= ::
+     Projectile requires this seeting for ivy completion:
+
+     #+begin_src elisp
+     (setq projectile-completion-system 'ivy)
+     #+end_src
+- =helm-make= ::
+     Helm-make requires this seeting for ivy completion.
+
+     #+begin_src elisp
+     (setq helm-make-completion-method 'ivy)
+     #+end_src
+
+* Commands
+:PROPERTIES:
+:CUSTOM_ID: commands
+:END:
+** File Name Completion
+:PROPERTIES:
+:CUSTOM_ID: file-name-completion
+:END:
+Since file name completion is ubiquitious, 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-q~ (=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.
+
+- 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.
+
+** Buffer Name Completion
+:PROPERTIES:
+:CUSTOM_ID: buffer-name-completion
+:END:
+- 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:
+
+     #+begin_src elisp
+     (setq ivy-use-virtual-buffers t)
+     #+end_src
+     will add additional virual buffers to the buffers list for recent
+     files. Selecting such virtual buffers, which are highlighted with
+     =ivy-virtual= face, will open the corresponding file.
+
+** Counsel commands
+:PROPERTIES:
+:CUSTOM_ID: counsel-commands
+:END:
+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.
+* API
+:PROPERTIES:
+:CUSTOM_ID: api
+:END:
+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=.
+
+** Required arguments for =ivy-read=
+:PROPERTIES:
+:CUSTOM_ID: required-arguments-for-ivy-read
+:END:
+- =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=.
+
+** Optional arguments for =ivy-read=
+:PROPERTIES:
+:CUSTOM_ID: optional-arguments-for-ivy-read
+:END:
+- =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 mathing
+     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.
+** Example - =counsel-describe-function=
+:PROPERTIES:
+:CUSTOM_ID: example---counsel-describe-function
+:END:
+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.
+
+#+begin_src elisp
+(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))
+#+end_src
+
+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=.
+** Example - =counsel-locate=
+:PROPERTIES:
+:CUSTOM_ID: example---counsel-locate
+:END:
+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.
+
+#+begin_src elisp
+(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))
+#+end_src
+
+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.
+
 * Variable Index
-#+BEGIN_TEXINFO
-@printindex vr
-#+END_TEXINFO
+:PROPERTIES:
+:INDEX:    vr
+:CUSTOM_ID: variable-index
+:END:
+
+* Keystroke Index
+:PROPERTIES:
+:CUSTOM_ID: key-index
+:INDEX:    ky
+:END:
index b06c68cf78bcdd65df12133916dfb436b3efadc5..64afd6b593d5fde3a888b113f3bdc73a5132d529 100644 (file)
@@ -17,9 +17,10 @@ filtering, previewing, and applying actions on selected items. When
 active, @code{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. @end ifnottex
+through powerful regular expressions.
+@end ifnottex
 
-Copyright @copyright{} 2015 Free Software Foundation, Inc.
+Copyright (C) 2015 Free Software Foundation, Inc.
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -61,8 +62,12 @@ modify this GNU manual.''
 * Installation::
 * Getting started::
 * Key bindings::
-* Completion styles::
+* Completion Styles::
+* Customization::
+* Commands::
+* API::
 * Variable Index::
+* Keystroke Index::
 
 @detailmenu
 --- The Detailed Node Listing ---
@@ -86,15 +91,51 @@ 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 minibuffer input::
+* Key bindings that alter the minibuffer input::
 * Other key bindings::
 * Hydra in the minibuffer::
 * Saving the current completion session to a buffer::
-Completion styles
+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 @code{ivy-occur}::
+Commands
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+API
+
+* Required arguments for @code{ivy-read}::
+* Optional arguments for @code{ivy-read}::
+* Example - @code{counsel-describe-function}::
+* Example - @code{counsel-locate}::
 @end detailmenu
 @end menu
 
@@ -110,46 +151,55 @@ Ivy strives for minimalism, simplicity, customizability and
 discoverability.
 
 @subsubheading Minimalism
+@indentedblock
 Uncluttered minibuffer is minimalism. Ivy shows the completion
-defaults, the number of matches, and 10 candidate matches below the
-input line. Customize @code{ivy-length} to adjust the number of candidate
-matches displayed in the minibuffer.
-
+defaults, the number of matches, and 10 candidate matches below
+the input line. Customize @code{ivy-height} to adjust the number of
+candidate matches displayed in the minibuffer.
+@end indentedblock
 @subsubheading 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 @code{fundamental-mode} as possible. @kbd{SPC} inserts a
-space, for example, instead of being bound to the more complex
-@code{minibuffer-complete-word}. Ivy's code uses easy-to-examine global
-variables; avoids needless complications with branch-introducing
-custom macros.
-
+@indentedblock
+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 @code{fundamental-mode} as
+possible. @kbd{SPC} inserts a space, for example, instead of being
+bound to the more complex @code{minibuffer-complete-word}. Ivy's code
+uses easy-to-examine global variables; avoids needless
+complications with branch-introducing custom macros.
+@end indentedblock
 @subsubheading Customizability
+@indentedblock
 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 @code{->}, instead of highlighting the selected candidate with the
-@code{ivy-current-match} face. Or take the customization of actions, say
-after the candidate function is selected. @kbd{RET} uses
-@code{counsel-describe-function} to describe the function, whereas @kbd{M-o d}
-jumps to that function's definition in the code. The @kbd{M-o} prefix can
-be uniformly used with characters like @kbd{d} to group similar actions.
-
+interfaces of completion to tailor the selection process. For
+example, adding a custom display function that points to a
+selected candidate with @code{->}, instead of highlighting the
+selected candidate with the @code{ivy-current-match} face. Or take the
+customization of actions, say after the candidate function is
+selected. @kbd{RET} uses @code{counsel-describe-function} to describe the
+function, whereas @kbd{M-o d} jumps to that function's definition in
+the code. The @kbd{M-o} prefix can be uniformly used with characters
+like @kbd{d} to group similar actions.
+@end indentedblock
 @subsubheading Discoverability
-Ivy displays easily discoverable commands through the hydra facility.
-@kbd{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 @kbd{C-o} in the
-minibuffer while in the midst of the Ivy interaction. This
-discoverability minimizes exiting Ivy interface for documentation
-look-ups.
+@indentedblock
+Ivy displays easily discoverable commands through the hydra
+facility.  @kbd{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 @kbd{C-o} in the minibuffer while in the midst of the Ivy
+interaction. This discoverability minimizes exiting Ivy interface
+for documentation look-ups.
+@end indentedblock
 
 @node Installation
 @chapter 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::
@@ -168,7 +218,6 @@ command.
 For current hourly builds, use the MELPA archives. See the code below
 for adding MELPA to the list of package archives:
 
-
 @lisp
 (require 'package)
 (add-to-list 'package-archives
@@ -183,8 +232,8 @@ For package manager details, see @ref{Packages,,,emacs,}.
 @node Installing from the Git repository
 @section Installing from the Git repository
 
-Why install from Git?
-
+@subsubheading Why install from Git?
+@indentedblock
 @itemize
 @item
 No need to wait for MELPA's hourly builds
@@ -193,36 +242,38 @@ Easy to revert to previous versions
 @item
 Contribute to Ivy's development; send patches; pull requests
 @end itemize
+@end indentedblock
 
-@strong{Configuration steps}
 
-First clone the Swiper repository:
+@subsubheading Configuration steps
+@indentedblock
+First clone the Swiper repository with:
 
 @example
-cd ~/git && git clone https://github.com/abo-abo/swiper
-cd swiper && make compile
+     cd ~/git && git clone https://github.com/abo-abo/swiper
+     cd swiper && make compile
 @end example
 
-Then add this to Emacs init:
+Second, add these lines to the Emacs init file:
 
 @lisp
-(add-to-list 'load-path "~/git/swiper/")
-(require 'ivy)
+     (add-to-list 'load-path "~/git/swiper/")
+     (require 'ivy)
 @end lisp
 
-To update the code:
+Then, update the code with:
 
 @example
-git pull
-make
+     git pull
+     make
 @end example
+@end indentedblock
 
 @node Getting started
 @chapter Getting started
 
 First enable Ivy completion everywhere:
 
-
 @lisp
 (ivy-mode 1)
 @end lisp
@@ -235,17 +286,20 @@ Note: @code{ivy-mode} can be toggled on and off with @kbd{M-x} @code{ivy-mode}.
 @node Basic customization
 @section Basic customization
 
-Here are some basic settings particularly useful for new Ivy
-users:
+Here are some basic settings particularly useful for new Ivy users:
 
 @lisp
 (setq ivy-use-virtual-buffers t)
 (setq ivy-height 10)
-(setq ivy-display-style 'fancy)
 (setq ivy-count-format "(%d/%d) ")
 @end lisp
 
-For additional customizations, refer to @code{M-x describe-variable}
+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 @code{M-x describe-variable}
 documentation.
 
 @node Key bindings
@@ -259,50 +313,60 @@ documentation.
 @node Global key bindings
 @section Global key bindings
 
-Recommended key bindings are:
-@subsubheading Ivy-based interface to standard commands
+The recommended key bindings are:
 
+@subsubheading Ivy-based interface to standard commands
+@indentedblock
 @lisp
-(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-load-library)
-(global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
-(global-set-key (kbd "<f2> u") 'counsel-unicode-char)
+     (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-load-library)
+     (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
+     (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
 @end lisp
+@end indentedblock
 @subsubheading Ivy-based interface to shell and system tools
-
+@indentedblock
 @lisp
-(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)
+     (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)
 @end lisp
+@end indentedblock
 @subsubheading Ivy-resume and other commands
+@indentedblock
 @code{ivy-resume} resumes the last Ivy-based completion.
 
 @lisp
-(global-set-key (kbd "C-c C-r") 'ivy-resume)
+     (global-set-key (kbd "C-c C-r") 'ivy-resume)
 @end lisp
+@end indentedblock
 
 @node Minibuffer key bindings
 @section Minibuffer key bindings
 
+@vindex ivy-minibuffer-map
 Ivy includes several minibuffer bindings, which are defined in the
 @code{ivy-minibuffer-map} keymap variable. The most frequently used ones
 are described here.
 
-@code{swiper} or @code{counsel-M-x} add more through the @code{keymap} argument to
-@code{ivy-read}. These keys, also active in the minibuffer, are described
-under their respective commands.
+@code{swiper} or @code{counsel-M-x} add more key bindings through the @code{keymap}
+argument to @code{ivy-read}. These keys, also active in the minibuffer, are
+described under their respective commands.
+
+A key feature of @code{ivy-minibuffer-map} is its full editing capability
+where the familiar @kbd{C-a}, @kbd{C-f}, @kbd{M-d}, @kbd{M-DEL}, @kbd{M-b}, @kbd{M-w}, @kbd{C-k},
+@kbd{C-y} key bindings work the same as in @code{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 minibuffer input::
+* Key bindings that alter the minibuffer input::
 * Other key bindings::
 * Hydra in the minibuffer::
 * Saving the current completion session to a buffer::
@@ -326,17 +390,20 @@ under their respective commands.
 @kbd{M-v} (@code{ivy-scroll-down-command}) scrolls down by @code{ivy-height} lines
 @end itemize
 
+
 @defopt ivy-wrap
-This user option allows to get the wrap-around behavior for @kbd{C-n} and
-@kbd{C-p}.  When set to @code{t}, @code{ivy-next-line} and @code{ivy-previous-line} will
-cycle past the last and the first candidates respectively.
+Specifies the wrap-around behavior for @kbd{C-n} and @kbd{C-p}. When
+@code{ivy-wrap} is set to @code{t}, @code{ivy-next-line} and @code{ivy-previous-line}
+will cycle past the last and the first candidates respectively.
 
-This behavior is off by default.
+Warp-around behavior is off by default.
 @end defopt
 
 @defopt ivy-height
-Use this variable to adjust the minibuffer height, and therefore the
-scroll size for @kbd{C-v} and @kbd{M-v}.
+Use this option to adjust the minibuffer height, which also
+affects scroll size when using @kbd{C-v} and @kbd{M-v} key bindings.
+
+@code{ivy-height} is 10 lines by default.
 @end defopt
 
 @node Key bindings for single selection action then exit minibuffer
@@ -352,40 +419,67 @@ 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.
 
-@kbd{C-m} or @kbd{RET} (@code{ivy-done}) calls the default action and exits the
-minibuffer.
-
-@kbd{M-o} (@code{ivy-dispatching-done}) presents all available valid actions
-from which to choose. When there is only one action available, there
-is no difference between @kbd{M-o} and @kbd{C-m}.
-
-@kbd{C-j} (@code{ivy-alt-done}) calls the alternate action, such as completing
-a directory name in a file list whereas @kbd{C-m} will select that directory
-and exit the minibuffer.
-
-Exiting the minibuffer also closes the Ivy window (as specified by
-@code{ivy-height}). This closing and exiting sequence is conveniently off
-when applying multiple actions. Multiple actions and multiple
-selections as covered in the next section of this manual.
-
-@kbd{TAB} (@code{ivy-partial-or-done}) attempts partial completion, extending
-current input as much as possible.
-
-@kbd{TAB TAB} is the same as @kbd{C-j}.
+@subsubheading @kbd{C-m} or @kbd{RET} (@code{ivy-done})
+@vindex ivy-done
+@kindex C-m
+@kindex RET
+@indentedblock
+Calls the default action and then exits the minibuffer.
+@end indentedblock
+@subsubheading @kbd{M-o} (@code{ivy-dispatching-done})
+@vindex ivy-dispatching-done
+@kindex M-o
+@indentedblock
+Presents valid actions from which to choose. When only one action
+is available, there is no difference between @kbd{M-o} and @kbd{C-m}.
+@end indentedblock
+@subsubheading @kbd{C-j} (@code{ivy-alt-done})
+@vindex ivy-alt-done
+@kindex C-j
+@indentedblock
+When completing file names, selects the current directory
+candidate and starts a new completion session there. Otherwise,
+it is the same as @code{ivy-done}.
+@end indentedblock
+@subsubheading @kbd{TAB} (@code{ivy-partial-or-done})
+@vindex ivy-partial-or-done
+@kindex TAB
+@indentedblock
+Attempts partial completion, extending current input as much as
+possible. @kbd{TAB TAB} is the same as @kbd{C-j} (@code{ivy-alt-done}).
+
+Example ERT test:
 
-@kbd{C-M-j} (@code{ivy-immediate-done}) is useful when there is no match for
-the given input. Or there is an incorrect partial match. @kbd{C-M-j} with
-@code{find-file} lists ignores the partial match and instead takes the
-current input to create a new directory with @code{dired-create-directory}.
-
-@code{ivy-immediate-done} illustrates how Ivy distinguishes between calling
-an action on the @emph{currently selected} candidate and calling an action
-on the @emph{current input}.
-
-Invoking avy completion with @kbd{C-'} (@code{ivy-avy}).
-@kbd{C-`} uses avy's visible jump mechanism, which can further reduce
-Ivy's line-by-line scrolling that requires multiple @kbd{C-n} or @kbd{C-p}
-keystrokes.
+@lisp
+     (should
+      (equal (ivy-with
+              '(progn
+                (ivy-read "Test: " '("can do" "can't, sorry" "other"))
+                ivy-text)
+              "c <tab>")
+             "can"))
+@end lisp
+@end indentedblock
+@subsubheading @kbd{C-M-j} (@code{ivy-immediate-done})
+@vindex ivy-immediate-done
+@kindex C-M-j
+@indentedblock
+Exits with @emph{the current input} instead of @emph{the current candidate}
+(like other commands).
+
+This is useful e.g. when you call @code{find-file} to create a new
+file, but the desired name matches an existing file. In that
+case, using @kbd{C-j} would select that existing file, which isn't
+what you want - use this command instead.
+@end indentedblock
+@subsubheading @kbd{C-'} (@code{ivy-avy})
+@vindex ivy-avy
+@kindex C-'
+@indentedblock
+Uses avy to select one of the candidates on the current candidate
+page.  This can often be faster than multiple @kbd{C-n} or @kbd{C-p}
+keystrokes followed by @kbd{C-m}.
+@end indentedblock
 
 @node Key bindings for multiple selections and actions keep minibuffer open
 @subsection Key bindings for multiple selections and actions, keep minibuffer open
@@ -398,105 +492,317 @@ Adding an extra meta key to the normal key chord invokes the special
 version of the regular commands that enables applying multiple
 actions.
 
-@kbd{C-M-m} (@code{ivy-call}) is the non-exiting version of the default action,
-@kbd{C-m} (@code{ivy-done}). Instead of closing the minibuffer, @kbd{C-M-m} allows
-selecting another candidate or another action. For example, @kbd{C-M-m} on
-functions list invokes @code{describe-function}. When combined with @kbd{C-n},
-function descriptions can be invoked quickly in succession.
-
-@kbd{RET} exits the minibuffer.
-
-@code{ivy-resume} recalls the state of the completion session just before
-its last exit. Useful after an accidental @kbd{C-m} (@code{ivy-done}).
-
-@kbd{C-M-o} (@code{ivy-dispatching-call}) is a non-exiting version of @kbd{M-o}
-(@code{ivy-dispatching-done}) that can accumulate candidates into a queue.
-For example, for playback in @code{counsel-rhythmbox}, @kbd{C-M-o e} en-queues
-the selected candidate, and @kbd{C-n C-m} plays the next one in the queue.
-
-@kbd{C-M-n} (@code{ivy-next-line-and-call}) combines @kbd{C-n} and @kbd{C-M-m}. Applies
-an action and moves to next line. Comes in handy when opening multiple
-files from @code{counsel-find-file}, @code{counsel-git-grep}, @code{counsel-ag}, or
+@subsubheading @kbd{C-M-m} (@code{ivy-call})
+@vindex ivy-call
+@kindex C-M-m
+@indentedblock
+Is the non-exiting version of @kbd{C-m} (@code{ivy-done}).
+
+Instead of closing the minibuffer, @kbd{C-M-m} allows selecting
+another candidate or another action. For example, @kbd{C-M-m} on
+functions list invokes @code{describe-function}. When combined with
+@kbd{C-n}, function descriptions can be invoked quickly in
+succession.
+@end indentedblock
+@subsubheading @kbd{C-M-o} (@code{ivy-dispatching-call})
+@vindex ivy-dispatching-call
+@kindex C-M-o
+@indentedblock
+Is the non-exiting version of @kbd{M-o} (@code{ivy-dispatching-done}).
+
+For example, during the @code{counsel-rhythmbox} completion, press
+@kbd{C-M-o e} to en-queue the selected candidate, followed by @kbd{C-n
+     C-m} to play the next candidate - the current action reverts to
+the default one after @kbd{C-M-o}.
+@end indentedblock
+@subsubheading @kbd{C-M-n} (@code{ivy-next-line-and-call})
+@vindex ivy-next-line-and-call
+@kindex C-M-n
+@indentedblock
+Combines @kbd{C-n} and @kbd{C-M-m}. Applies an action and moves to next
+line.
+
+Comes in handy when opening multiple files from
+@code{counsel-find-file}, @code{counsel-git-grep}, @code{counsel-ag}, or
 @code{counsel-locate} lists. Just hold @kbd{C-M-n} for rapid-fire default
 action on each successive element of the list.
-
-@kbd{C-M-p} (@code{ivy-previous-line-and-call}) combines @kbd{C-p} and @kbd{C-M-m}. Is
-the same as above except that it moves through the list in the other
-direction.
-
-@node Key bindings that alter minibuffer input
-@subsection Key bindings that alter minibuffer input
-
-@kbd{M-n} (@code{ivy-next-history-element}) and @kbd{M-p}
-(@code{ivy-previous-history-element}) cycle through the Ivy command
-history. Ivy updates an internal history list after each action. When
-this history list is empty, @kbd{M-n} inserts symbol (or URL) at point
+@end indentedblock
+@subsubheading @kbd{C-M-p} (@code{ivy-previous-line-and-call})
+@vindex ivy-previous-line-and-call
+@kindex C-M-p
+@indentedblock
+Combines @kbd{C-p} and @kbd{C-M-m}.
+
+Similar to the above except it moves through the list in the
+other direction.
+@end indentedblock
+@subsubheading @code{ivy-resume}
+@vindex ivy-resume
+@indentedblock
+Recalls the state of the completion session just before its last
+exit.
+
+Useful after an accidental @kbd{C-m} (@code{ivy-done}).
+@end indentedblock
+
+@node Key bindings that alter the minibuffer input
+@subsection Key bindings that alter the minibuffer input
+
+@subsubheading @kbd{M-n} (@code{ivy-next-history-element})
+@vindex ivy-next-history-element
+@kindex M-n
+@indentedblock
+Cycles forward through the Ivy command history.
+
+Ivy updates an internal history list after each action. When this
+history list is empty, @kbd{M-n} inserts symbol (or URL) at point
 into the minibuffer.
-
-@kbd{M-i} (@code{ivy-insert-current}) inserts the current candidate into the
-minibuffer. Useful for copying and renaming files, for example: @kbd{M-i}
-to insert the original file name string, edit it, and then @kbd{C-m} to
+@end indentedblock
+@subsubheading @kbd{M-p} (@code{ivy-previous-history-element})
+@vindex ivy-previous-history-element
+@kindex M-p
+@indentedblock
+Cycles forward through the Ivy command history.
+@end indentedblock
+@subsubheading @kbd{M-i} (@code{ivy-insert-current})
+@vindex ivy-insert-current
+@kindex M-i
+@indentedblock
+Inserts the current candidate into the minibuffer.
+
+Useful for copying and renaming files, for example: @kbd{M-i} to
+insert the original file name string, edit it, and then @kbd{C-m} to
 complete the renaming.
-
-@kbd{M-j} (@code{ivy-yank-word}) inserts sub-word at point into minibuffer. This
-is similar to @kbd{C-s C-w} with @code{isearch}. Ivy reserves @kbd{C-w} for
-@code{kill-region}.
-
-@kbd{S-SPC} (@code{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.
-
-@kbd{C-r} (@code{ivy-reverse-i-search}) works just like @kbd{C-r} at bash command
-prompt, where the completion candidates are the history items. Upon
-completion, the selected candidate string is inserted into the
-minibuffer.
+@end indentedblock
+@subsubheading @kbd{M-j} (@code{ivy-yank-word})
+@vindex ivy-yank-word
+@kindex M-j
+@indentedblock
+Inserts the sub-word at point into the minibuffer.
+
+This is similar to @kbd{C-s C-w} with @code{isearch}. Ivy reserves @kbd{C-w}
+for @code{kill-region}.
+@end indentedblock
+@subsubheading @kbd{S-SPC} (@code{ivy-restrict-to-matches})
+@vindex ivy-restrict-to-matches
+@kindex S-SPC
+@indentedblock
+Deletes the current input, and resets the candidates list to the
+currently restricted matches.
+
+This is how Ivy provides narrowing in successive tiers.
+@end indentedblock
+@subsubheading @kbd{C-r} (@code{ivy-reverse-i-search})
+@vindex ivy-reverse-i-search
+@kindex C-r
+@indentedblock
+Starts a recursive completion session through the command's
+history.
+
+This works just like @kbd{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.
+@end indentedblock
 
 @node Other key bindings
 @subsection Other key bindings
 
-@kbd{M-w} (@code{ivy-kill-ring-save}) copies selected candidates to the kill
-ring; when the region is active, copies active region.
+@subsubheading @kbd{M-w} (@code{ivy-kill-ring-save})
+@vindex ivy-kill-ring-save
+@kindex M-w
+@indentedblock
+Copies selected candidates to the kill ring.
+
+Copies the region if the region is active.
+@end indentedblock
 
 @node Hydra in the minibuffer
 @subsection Hydra in the minibuffer
 
-@kbd{C-o} (@code{hydra-ivy/body}) invokes Hydra menus with key shortcuts.
-
-@kbd{C-o} or @kbd{i} resumes editing.
+@subsubheading @kbd{C-o} (@code{hydra-ivy/body})
+@kindex C-o
+@indentedblock
+Invokes the hydra menu with short key bindings.
+@end indentedblock
+
+When Hydra is active, minibuffer editing is disabled and menus
+display short aliases:
+
+@multitable {aaaaa} {aaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaa}
+@headitem Short
+@tab Normal
+@tab Command name
+@item @kbd{o}
+@tab @kbd{C-g}
+@tab @code{keyboard-escape-quit}
+@item @kbd{j}
+@tab @kbd{C-n}
+@tab @code{ivy-next-line}
+@item @kbd{k}
+@tab @kbd{C-p}
+@tab @code{ivy-previous-line}
+@item @kbd{h}
+@tab @kbd{M-<}
+@tab @code{ivy-beginning-of-buffer}
+@item @kbd{l}
+@tab @kbd{M->}
+@tab @code{ivy-end-of-buffer}
+@item @kbd{d}
+@tab @kbd{C-m}
+@tab @code{ivy-done}
+@item @kbd{f}
+@tab @kbd{C-j}
+@tab @code{ivy-alt-done}
+@item @kbd{g}
+@tab @kbd{C-M-m}
+@tab @code{ivy-call}
+@item @kbd{u}
+@tab @kbd{C-c C-o}
+@tab @code{ivy-occur}
+@end multitable
 
 Hydra reduces key strokes, for example: @kbd{C-n C-n C-n C-n} is @kbd{C-o
-jjjj} in Hydra. Hydra has other benefits besides certain shorter key
-bindings:
-@itemize
-@item
-@kbd{<} and @kbd{>} to adjust height of minibuffer,
-@item
-describes the current completion state, such as case folding and the
-current action.
-@end itemize
-
-Minibuffer editing is disabled when Hydra is active.
+jjjj} in Hydra.
+
+Hydra menu offers these additioanl bindings:
+
+@subsubheading @kbd{c} (@code{ivy-toggle-calling})
+@vindex ivy-toggle-calling
+@kindex c
+@indentedblock
+Toggle calling the action after each candidate change. It
+modifies @kbd{j} to @kbd{jg}, @kbd{k} to @kbd{kg} etc.
+@end indentedblock
+@subsubheading @kbd{m} (@code{ivy-toggle-fuzzy})
+@vindex ivy-toggle-fuzzy
+@kindex m
+@indentedblock
+Toggle the current regexp matcher.
+@end indentedblock
+@subsubheading @kbd{>} (@code{ivy-minibuffer-grow})
+@vindex ivy-minibuffer-grow
+@kindex >
+@indentedblock
+Increase @code{ivy-height} for the current minibuffer.
+@end indentedblock
+@subsubheading @kbd{<} (@code{ivy-minibuffer-shrink})
+@vindex ivy-minibuffer-shrink
+@kindex <
+@indentedblock
+Decrease @code{ivy-height} for the current minibuffer.
+@end indentedblock
+@subsubheading @kbd{w} (@code{ivy-prev-action})
+@vindex ivy-prev-action
+@kindex w
+@indentedblock
+Select the previous action.
+@end indentedblock
+@subsubheading @kbd{s} (@code{ivy-next-action})
+@vindex ivy-next-action
+@kindex s
+@indentedblock
+Select the next action.
+@end indentedblock
+@subsubheading @kbd{a} (@code{ivy-read-action})
+@vindex ivy-read-action
+@kindex a
+@indentedblock
+Use a menu to select an action.
+@end indentedblock
+@subsubheading @kbd{C} (@code{ivy-toggle-case-fold})
+@vindex ivy-toggle-case-fold
+@kindex C
+@indentedblock
+Toggle case folding (match both upper and lower case
+characters for lower case input).
+@end indentedblock
 
 @node Saving the current completion session to a buffer
 @subsection Saving the current completion session to a buffer
 
-@kbd{C-c C-o} (@code{ivy-occur}) saves the current candidates to a new buffer;
-the list is active in the new buffer.
+@subsubheading @kbd{C-c C-o} (@code{ivy-occur})
+@vindex ivy-occur
+@kindex C-c C-o
+@indentedblock
+Saves the current candidates to a new buffer and exits
+completion.
+@end indentedblock
+
+The new buffer is read-only and has a few useful bindings defined.
+
+@subsubheading @kbd{RET} or @kbd{j} (@code{ivy-occur-press})
+@vindex ivy-occur-press
+@kindex RET
+@kindex j
+@indentedblock
+Call the current action on the selected candidate.
+@end indentedblock
+@subsubheading @kbd{mouse-1} (@code{ivy-occur-click})
+@vindex ivy-occur-click
+@kindex mouse-1
+@indentedblock
+Call the current action on the selected candidate.
+@end indentedblock
+@subsubheading @kbd{j} (@code{next-line})
+@kindex j
+@indentedblock
+Move to next line.
+@end indentedblock
+@subsubheading @kbd{k} (@code{previous-line})
+@kindex k
+@indentedblock
+Move to previous line.
+@end indentedblock
+@subsubheading @kbd{a} (@code{ivy-occur-read-action})
+@vindex ivy-occur-read-action
+@kindex a
+@indentedblock
+Read an action and make it current for this buffer.
+@end indentedblock
+@subsubheading @kbd{o} (@code{ivy-occur-dispatch})
+@vindex ivy-occur-dispatch
+@kindex o
+@indentedblock
+Read an action and call it on the selected candidate.
+@end indentedblock
+@subsubheading @kbd{q} (@code{quit-window})
+@kindex q
+@indentedblock
+Bury the current buffer.
+@end indentedblock
 
-@kbd{RET} or @kbd{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: @code{*ivy-occur counsel-describe-variable
+Ivy takes care of naming buffers uniquely by constructing descriptive
+names. For example: @code{*ivy-occur counsel-describe-variable
 "function$*}.
 
-@node Completion styles
-@chapter Completion styles
+@node Completion Styles
+@chapter 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 @code{ivy-re-builders-alist}.
 
-Ivy's completion functions rely on the highly configurable regex
-builder.
+The keys of this alist are collection names, and the values are one of
+the following:
+@itemize
+@item
+@code{ivy--regex}
+@item
+@code{ivy--regex-plus}
+@item
+@code{ivy--regex-ignore-order}
+@item
+@code{ivy--regex-fuzzy}
+@item
+@code{regexp-quote}
+@end itemize
+
+A catch-all key, @code{t}, applies to all collections that don't have their
+own key.
 
 The default is:
 
@@ -505,9 +811,8 @@ The default is:
       '((t . ivy--regex-plus)))
 @end lisp
 
-The default @code{ivy--regex-plus} narrowing is always invoked unless
-specified otherwise. For example, file name completion may have a
-custom completion function:
+This example shows a custom regex builder assigned to file name
+completion:
 
 @lisp
 (setq ivy-re-builders-alist
@@ -515,10 +820,26 @@ custom completion function:
         (t . ivy--regex-plus)))
 @end lisp
 
-Ivy's flexibility extends to using different styles of completion
-mechanics (regex-builders) for different types of lists. Despite this
-flexibility, Ivy operates within a consistent and uniform interface.
-The main regex-builders currently in Ivy are:
+Here, @code{read-file-name-internal} is a function that is passed as the
+second argument to @code{completing-read} for file name completion.
+
+The regex builder resolves as follows (in order of priority):
+@enumerate
+@item
+@code{re-builder} argument passed to @code{ivy-read}.
+@item
+@code{collection} argument passed to @code{ivy-read} is a function and has an
+entry on @code{ivy-re-builders-alist}.
+@item
+@code{caller} argument passed to @code{ivy-read} has an entry on
+@code{ivy-re-builders-alist}.
+@item
+@code{this-command} has an entry on @code{ivy-re-builders-alist}.
+@item
+@code{t} has an entry on @code{ivy-re-builders-alist}.
+@item
+@code{ivy--regex}.
+@end enumerate
 @menu
 * ivy--regex-plus::
 * ivy--regex-ignore-order::
@@ -534,58 +855,818 @@ The main regex-builders currently in Ivy are:
 rebuilding it into a regex.
 
 As the search string is typed in Ivy's minibuffer, it is transformed
-into proper regex syntax. If the string is "for example", it is
+into valid regex syntax. If the string is @code{"for example"}, it is
 transformed into
 
-@verbatim
+@lisp
 "\\(for\\).*\\(example\\)"
-@end verbatim
+@end lisp
 
-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. For literal white space matching in Ivy, use an extra space:
-to match one space type two spaces, to match two spaces type three
-spaces, and so on.
+which in regex terminology matches @code{"for"} followed by a wild card and
+then @code{"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.
-
-@verbatim
-Standard regexp identifiers work:
-
-"^", "$", "\b" or "[a-z]"
-@end verbatim
+Ivy supports regexp negation with @code{"!"}.
+For example, @code{"define key ! ivy quit"} first selects everything
+matching @code{"define.*key"}, then removes everything matching @code{"ivy"},
+and finally removes everything matching @code{"quit"}. What remains is the
+final result set of the negation regexp.
 
-Since Ivy treats minibuffer input as a regexp, standard regexp
-identifiers work as usual. The exceptions are spaces, which
-translate to ".*", and "!" that signal the beginning of a negation
-group.
+Since Ivy treats minibuffer input as a regexp, the standard regexp
+identifiers work: @code{"^"}, @code{"$"}, @code{"\b"} or @code{"[a-z]"}. The exceptions
+are spaces, which translate to @code{".*"}, and @code{"!"} that signal the
+beginning of a negation group.
 
 @node ivy--regex-ignore-order
 @section ivy--regex-ignore-order
 
 @code{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". Otherwise @code{ivy--regex-plus}
-normal behavior is to honor the order of regexp tokens.
+searching for matching candidates. For instance, the input
+@code{"for example"} will match @code{"example test for"}.
 
 @node ivy--regex-fuzzy
 @section ivy--regex-fuzzy
 
 @code{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 @code{flx} package's scoring mechanism, if it's
+for @code{"for"} returns all @code{"f.*o.*r"} matches, resulting in a large
+number of hits.  Yet some searches need these extra hits. Ivy sorts
+such large lists using @code{flx} package's scoring mechanism, if it's
 installed.
 
+@kbd{C-o m} toggles the current regexp builder.
+
+@node Customization
+@chapter Customization
+
+@menu
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+@end menu
+
+@node Faces
+@section Faces
+
+@subsubheading @code{ivy-current-match}
+@vindex ivy-current-match
+@indentedblock
+Highlights the currently selected candidate.
+@end indentedblock
+@subsubheading @code{ivy-minibuffer-match-face-1}
+@vindex ivy-minibuffer-match-face-1
+@indentedblock
+Highlights the background of the match.
+@end indentedblock
+@subsubheading @code{ivy-minibuffer-match-face-2}
+@vindex ivy-minibuffer-match-face-2
+@indentedblock
+Highlights the first (modulo 3) matched group.
+@end indentedblock
+@subsubheading @code{ivy-minibuffer-match-face-3}
+@vindex ivy-minibuffer-match-face-3
+@indentedblock
+Highlights the second (modulo 3) matched group.
+@end indentedblock
+@subsubheading @code{ivy-minibuffer-match-face-4}
+@vindex ivy-minibuffer-match-face-4
+@indentedblock
+Highlights the third (modulo 3) matched group.
+@end indentedblock
+@subsubheading @code{ivy-confirm-face}
+@vindex ivy-confirm-face
+@indentedblock
+Highlights the "(confirm)" part of the prompt.
+
+When @code{confirm-nonexistent-file-or-buffer} set to @code{t}, then
+confirming non-existent files in @code{ivy-mode} requires an
+additional @kbd{RET}.
+
+The confirmation prompt will use this face.
+
+For example:
+
+@lisp
+     (setq confirm-nonexistent-file-or-buffer t)
+@end lisp
+
+Then call @code{find-file}, enter "eldorado" and press @kbd{RET} - the
+prompt will be appended with "(confirm)". Press @kbd{RET} once more
+to confirm, or any key to continue the completion.
+@end indentedblock
+@subsubheading @code{ivy-match-required-face}
+@vindex ivy-match-required-face
+@indentedblock
+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 @code{describe-variable}, enter "waldo" and press
+@kbd{RET} - "(match required)" is prompted.
+Press any key for the prompt to disappear.
+@end indentedblock
+@subsubheading @code{ivy-subdir}
+@vindex ivy-subdir
+@indentedblock
+Highlights directories when completing file names.
+@end indentedblock
+@subsubheading @code{ivy-remote}
+@vindex ivy-remote
+@indentedblock
+Highlights remote files when completing file names.
+@end indentedblock
+@subsubheading @code{ivy-virtual}
+@vindex ivy-virtual
+@indentedblock
+Highlights virtual buffers when completing buffer names.
+
+Virtual buffers correspond to bookmarks and recent files list,
+@code{recentf}.
+
+Enable virtual buffers with:
+
+@lisp
+     (setq ivy-use-virtual-buffers t)
+@end lisp
+@end indentedblock
+
+@node Defcustoms
+@section Defcustoms
+
+@defopt 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:
+
+@lisp
+     (setq ivy-count-format "")
+@end lisp
+
+To also display the current candidate:
+
+@lisp
+     (setq ivy-count-format "(%d/%d) ")
+@end lisp
+
+The @code{format}-style switches this variable uses are described
+in the @code{format} documentation.
+@end defopt
+
+@defopt ivy-display-style
+Specifies highlighting candidates in the minibuffer.
+
+The default setting is @code{'fancy} and valid only in Emacs versions
+24.5 or newer.
+
+Set @code{ivy-display-style} to @code{nil} for a plain minibuffer.
+@end defopt
+
+@defopt ivy-on-del-error-function
+Specify what when @kbd{DEL} (@code{ivy-backward-delete-char}) throws.
+
+The default behavior is to quit the completion after @kbd{DEL} -- a
+handy key to invoke after mistakenly triggering a completion.
+@end defopt
+
+@node Actions
+@section 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::
+@end menu
+
+@node What are actions?
+@subsection 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.
+
+@subsubheading Window context when calling an action
+@indentedblock
+Currently, the action is executed in the minibuffer window
+context. This means e.g. that if you call @code{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 @code{with-ivy-window} wrapper
+macro.
+
+@lisp
+     (defun ivy-insert-action (x)
+       (with-ivy-window
+         (insert x)))
+@end lisp
+@end indentedblock
+
+@node How can different actions be called?
+@subsection How can different actions be called?
+
+@itemize
+@item
+@kbd{C-m} (@code{ivy-done}) calls the current action.
+@item
+@kbd{M-o} (@code{ivy-dispatching-done}) presents available actions for
+selection, calls it after selection, and then exits.
+@item
+@kbd{C-M-o} (@code{ivy-dispatching-call}) presents available actions for
+selection, calls it after selection, and then does not exit.
+@end itemize
+
+@node How to modify the actions list?
+@subsection 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 @kbd{o} is
+designated for the default command. This way, @kbd{M-o o} should be always
+equivalent to @kbd{C-m}.
+
+@node Example - add two actions to each command
+@subsection Example - add two actions to each command
+
+The first action inserts the current candidate into the Ivy window -
+the window from which @code{ivy-read} was called.
+
+The second action copies the current candidate to the kill ring.
+
+@lisp
+(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")))
+@end lisp
+
+Then in any completion session, @kbd{M-o y} invokes @code{ivy-yank-action}, and
+@kbd{M-o i} invokes @code{ivy-copy-to-buffer-action}.
+@menu
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+@end menu
+
+@node How to undo adding the two actions
+@subsubsection How to undo adding the two actions
+
+Since @code{ivy-set-actions} modifies the internal dictionary with new
+data, set the extra actions list to @code{nil} by assigning @code{nil} value to
+the @code{t} key as follows:
+
+@lisp
+(ivy-set-actions t nil)
+@end lisp
+
+@node How to add actions to a specific command
+@subsubsection How to add actions to a specific command
+
+Use the command name as the key:
+
+@lisp
+(ivy-set-actions
+ 'swiper
+ '(("i" ivy-copy-to-buffer-action "insert")
+   ("y" ivy-yank-action "yank")))
+@end lisp
+
+@node Example - define a new command with several actions
+@subsection Example - define a new command with several actions
+
+@lisp
+(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"))))
+@end lisp
+
+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 @code{ivy-occur}::
+@end menu
+
+@node Test the above function with @code{ivy-occur}
+@subsubsection Test the above function with @code{ivy-occur}
+
+To examine each action with each candidate in a key-efficient way, try:
+
+@itemize
+@item
+Call @code{my-command-with-3-actions}
+@item
+Press @kbd{C-c C-o} to close the completion window and move to an
+ivy-occur buffer
+@item
+Press @kbd{kkk} to move to the first candidate, since the point is most
+likely at the end of the buffer
+@item
+Press @kbd{oo} to call the first action
+@item
+Press @kbd{oj} and @kbd{ok} to call the second and the third actions
+@item
+Press @kbd{j} to move to the next candidate
+@item
+Press @kbd{oo}, @kbd{oj}, @kbd{ok}
+@item
+Press @kbd{j} to move to the next candidate
+@item
+and so on@dots{}
+@end itemize
+
+@node Packages
+@section Packages
+
+@subsubheading @code{org-mode}
+@indentedblock
+@code{org-mode} versions 8.3.3 or later obey
+@code{completing-read-function} (which @code{ivy-mode} sets). Try refiling
+headings with similar names to appreciate @code{ivy-mode}.
+@end indentedblock
+@subsubheading @code{magit}
+@indentedblock
+Magit requries this setting for ivy completion:
+
+@lisp
+     (setq magit-completing-read-function 'ivy-completing-read)
+@end lisp
+@end indentedblock
+@subsubheading @code{find-file-in-project}
+@indentedblock
+It uses ivy by default if Ivy is installed.
+@end indentedblock
+@subsubheading @code{projectile}
+@indentedblock
+Projectile requires this seeting for ivy completion:
+
+@lisp
+     (setq projectile-completion-system 'ivy)
+@end lisp
+@end indentedblock
+@subsubheading @code{helm-make}
+@indentedblock
+Helm-make requires this seeting for ivy completion.
+
+@lisp
+     (setq helm-make-completion-method 'ivy)
+@end lisp
+@end indentedblock
+
+@node Commands
+@chapter Commands
+
+@menu
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+@end menu
+
+@node File Name Completion
+@section File Name Completion
+
+Since file name completion is ubiquitious, Ivy provides extra
+bindings that work here:
+
+
+@subsubheading @kbd{C-j} (@code{ivy-alt-done})
+@vindex ivy-alt-done
+@kindex C-j
+@indentedblock
+On a directory, restarts completion from that directory.
+
+On a file or @code{./}, exit completion with the selected candidate.
+@end indentedblock
+@subsubheading @kbd{DEL} (@code{ivy-backward-delete-char})
+@vindex ivy-backward-delete-char
+@kindex DEL
+@indentedblock
+Restart the completion in the parent directory if current input
+is empty.
+@end indentedblock
+@subsubheading @kbd{//} (@code{self-insert-command})
+@kindex //
+@indentedblock
+Switch to the root directory.
+@end indentedblock
+@subsubheading @kbd{~} (@code{self-insert-command})
+@kindex ~
+@indentedblock
+Switch to the home directory.
+@end indentedblock
+@subsubheading @kbd{/} (@code{self-insert-command})
+@kindex /
+@indentedblock
+If the current input matches an existing directory name exactly,
+switch the completion to that directory.
+@end indentedblock
+@subsubheading @kbd{M-q} (@code{ivy-toggle-regexp-quote})
+@vindex ivy-toggle-regexp-quote
+@kindex M-q
+@indentedblock
+Toggle between input as regexp or not.
+
+Switch to matching literally since file names include @code{.}, which
+is for matching any char in regexp mode.
+@end indentedblock
+@defopt ivy-extra-directories
+Decide if you want to see @code{../} and @code{./} during file name
+completion.
+
+Reason to remove: @code{../} is the same as @kbd{DEL}.
+
+Reason not to remove: navigate anywhere with only @kbd{C-n}, @kbd{C-p}
+and @kbd{C-j}.
+
+Likewise, @code{./} can be removed.
+@end defopt
+
+@subsubheading Using TRAMP
+@indentedblock
+From any directory, with the empty input, inputting @code{/ssh:} and
+pressing @kbd{C-j} (or @kbd{RET}, which is the same thing) completes for
+host and user names.
+
+For @code{/ssh:user@@} input, completes the domain name.
+
+@kbd{C-i} works in a similar way to the default completion.
+@end indentedblock
+@subsubheading History
+@indentedblock
+File history works the same with @kbd{M-p}, @kbd{M-n}, and @kbd{C-r}, but
+uses a custom code for file name completion that cycles through
+files previously opened. It also works with TRAMP files.
+@end indentedblock
+
+@node Buffer Name Completion
+@section Buffer Name Completion
+
+@defopt ivy-use-virtual-buffers
+When non-nil, add @code{recentf-mode} and bookmarks to
+@code{ivy-switch-buffer} completion candidates.
+
+Adding this to Emacs init file:
+
+@lisp
+     (setq ivy-use-virtual-buffers t)
+@end lisp
+will add additional virual buffers to the buffers list for recent
+files. Selecting such virtual buffers, which are highlighted with
+@code{ivy-virtual} face, will open the corresponding file.
+@end defopt
+
+@node Counsel commands
+@section Counsel commands
+
+The main advantages of @code{counsel-} functions over their basic
+equivalents in @code{ivy-mode} are:
+
+@enumerate
+@item
+Multi-actions and non-exiting actions work.
+@item
+@code{ivy-resume} can resume the last completion session.
+@item
+Customize @code{ivy-set-actions}, @code{ivy-re-builders-alist}.
+@item
+Customize individual keymaps, such as @code{counsel-describe-map},
+@code{counsel-git-grep-map}, or @code{counsel-find-file-map}, instead of
+customizing @code{ivy-minibuffer-map} that applies to all completion
+sessions.
+@end enumerate
+
+@node API
+@chapter API
+
+The main (and only) entry point is the @code{ivy-read} function. It takes
+two required arguments and many optional arguments that can be passed
+by a key. The optional @code{:action} argument is highly recommended for
+features such as multi-actions, non-exiting actions, @code{ivy-occur} and
+@code{ivy-resume}.
+@menu
+* Required arguments for @code{ivy-read}::
+* Optional arguments for @code{ivy-read}::
+* Example - @code{counsel-describe-function}::
+* Example - @code{counsel-locate}::
+@end menu
+
+@node Required arguments for @code{ivy-read}
+@section Required arguments for @code{ivy-read}
+
+@subsubheading @code{prompt}
+@indentedblock
+A format string normally ending in a colon and a space.
+
+@code{%d} anywhere in the string is replaced by the current number of
+matching candidates. To use a literal @code{%} character, escape it as
+@code{%%}. See also @code{ivy-count-format}.
+@end indentedblock
+@subsubheading @code{collection}
+@indentedblock
+Either a list of strings, a function, an alist or a hash table.
+
+If a function, then it has to be compatible with
+@code{all-completions}.
+@end indentedblock
+
+@node Optional arguments for @code{ivy-read}
+@section Optional arguments for @code{ivy-read}
+
+@subsubheading @code{predicate}
+@indentedblock
+Is a function to filter the initial collection. It has to be
+compatible with @code{all-completions}. Tip: most of the time, it's
+simpler to just apply this filter to the @code{collection} argument
+itself, e.g. @code{(cl-remove-if-not predicate collection)}.
+@end indentedblock
+@subsubheading @code{require-match}
+@indentedblock
+When set to a non-nil value, input must match one of the
+candidates. Custom input is not accepted.
+@end indentedblock
+@subsubheading @code{initial-input}
+@indentedblock
+This string argument is included for compatibility with
+@code{completing-read}, which inserts it into the minibuffer.
+
+It's recommended to use the @code{preselect} argument instead of this.
+@end indentedblock
+@subsubheading @code{history}
+@indentedblock
+Name of the symbol to store history. See @code{completing-read}.
+@end indentedblock
+@subsubheading @code{preselect}
+@indentedblock
+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
+@code{preselect} is selected.
+@end indentedblock
+@subsubheading @code{keymap}
+@indentedblock
+A keymap to be composed with @code{ivy-minibuffer-map}. This keymap
+has priority over @code{ivy-minibuffer-map} and can be modified at any
+later stage.
+@end indentedblock
+@subsubheading @code{update-fn}
+@indentedblock
+Is the function called each time the current candidate changes.
+This function takes no arguments and is called in the
+minibuffer's @code{post-command-hook}. See @code{swiper} for an example
+usage.
+@end indentedblock
+@subsubheading @code{sort}
+@indentedblock
+When non-nil, use @code{ivy-sort-functions-alist} to sort the
+collection as long as the collection is not larger than
+@code{ivy-sort-max-size}.
+@end indentedblock
+@subsubheading @code{action}
+@indentedblock
+Is the function to call after selection. It takes a string
+argument.
+@end indentedblock
+@subsubheading @code{unwind}
+@indentedblock
+Is the function to call before exiting completion. It takes no
+arguments. This function is called even if the completion is
+interrupted with @kbd{C-g}. See @code{swiper} for an example usage.
+@end indentedblock
+@subsubheading @code{re-builder}
+@indentedblock
+Is a function that takes a string and returns a valid regex. See
+@code{Completion Styles} for details.
+@end indentedblock
+@subsubheading @code{matcher}
+@indentedblock
+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 mathing
+functions can be used. See @code{counsel-find-file} for an example
+usage.
+@end indentedblock
+@subsubheading @code{dynamic-collection}
+@indentedblock
+When non-nil, @code{collection} will be used to dynamically generate
+the candidates each time the input changes, instead of being used
+once statically with @code{all-completions} to generate a list of
+strings. See @code{counsel-locate} for an example usage.
+@end indentedblock
+@subsubheading @code{caller}
+@indentedblock
+Is a symbol that uniquely identifies the function that called
+@code{ivy-read}, which may be useful for further customizations.
+@end indentedblock
+
+@node Example - @code{counsel-describe-function}
+@section Example - @code{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 @code{action}) are essential - the
+rest of the arguments are for fine-tuning, and could be omitted.
+
+The @code{action} argument could also be omitted - but then @code{ivy-read}
+would do nothing except returning the string result, which you could
+later use yourself. However, it's recommended that you use the
+@code{action} argument.
+
+@lisp
+(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))
+@end lisp
+
+Here are the interesting features of the above function, in the order that they appear:
+
+@itemize
+@item
+The @code{prompt} argument is a simple string ending in ": ".
+@item
+The @code{collection} argument evaluates to a (large) list of strings.
+@item
+The @code{keymap} argument is for a custom keymap to supplement @code{ivy-minibuffer-map}.
+@item
+The @code{preselect} is provided by @code{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 @kbd{RET} will suffice. No further user
+input is necessary.
+@item
+The @code{history} argument is for keeping the history of this command
+separate from the common history in @code{ivy-history}.
+@item
+The @code{require-match} is set to @code{t} since it doesn't make sense to
+call @code{describe-function} on an un-interned symbol.
+@item
+The @code{sort} argument is set to @code{t} so choosing between similar
+candidates becomes easier. Sometimes, the collection size will
+exceed @code{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.
+@item
+The @code{action} argument calls @code{describe-function} on the interned
+selected candidate.
+@item
+The @code{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 @code{ivy-read} to identify
+"who's calling" and to apply the appropriate customizations is to
+examine @code{this-command}. But @code{this-command} would be modified if
+another command called @code{counsel-describe-function}.
+@end itemize
+
+@node Example - @code{counsel-locate}
+@section Example - @code{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 @code{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.
+
+@lisp
+(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))
+@end lisp
+
+Here are the interesting features of the above functions, in the order
+that they appear:
+
+@itemize
+@item
+@code{counsel-locate-function} takes a string argument and returns a list
+of strings. Note that it's not compatible with @code{all-completions},
+but since we're not using that here, might as well use one argument
+instead of three.
+@item
+@code{counsel-more-chars} is a simple function that returns e.g.
+@code{'("2 chars more")} asking the user for more input.
+@item
+@code{counsel--async-command} is a very easy API simplification that
+takes a single string argument suitable for
+@code{shell-command-to-string}. So you could prototype your function as
+non-async using @code{shell-command-to-string} and @code{split-string} to
+produce a collection, then decide that you want async and simply swap in
+@code{counsel--async-command}.
+@item
+@code{counsel-locate} is an interactive function with an optional @code{initial-input}.
+@item
+@code{#'counsel-locate-function} is passed as the @code{collection} argument.
+@item
+@code{dynamic-collection} is set to t, since this is an async collection.
+@item
+@code{action} argument uses @code{with-ivy-window} wrapper, since we want to open the
+selected file in the same window from which @code{counsel-locate} was
+called.
+@item
+@code{unwind} argument is set to @code{#'counsel-delete-process}: when we press @kbd{C-g}
+we want to kill the running process created by
+@code{counsel--async-command}.
+@item
+@code{caller} argument identifies this command for easier customization.
+@end itemize
+
 @node Variable Index
-@chapter Variable Index
+@unnumbered Variable Index
 
 @printindex vr
 
+@node Keystroke Index
+@unnumbered Keystroke Index
+
+@printindex ky
+
 @bye
diff --git a/packages/ivy/doc/style.css b/packages/ivy/doc/style.css
deleted file mode 100644 (file)
index 547b4f0..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-body {
-    color: #333;
-    background-color: #ffffff;
-    margin-left: 1em;
-    margin-right: auto;
-    font-family: 'Ubuntu Mono', sans-serif;
-    max-width: 50em;
-}
-
-body a {
-    color: blue;
-}
-
-h2 {
-    font-weight: normal;
-    text-indent: 0;
-    border-radius: 15px;
-    background-color: #d6d8ec;
-    text-align: left;
-    padding: 3px 3px 3px 3px;
-}
-
-h2 a[id^="unnumbered"] {
-    background-color: #d6d8ec;
-}
-
-h2 a {
-    color: white;
-    background-color:#777777;
-    font-size:18px;
-    border-radius:3px;
-    padding: 0px 5px 0px 5px; 
-}
-
-kbd {
-    padding:0.1em 0.6em;
-    border:1px solid #ccc;
-    font-size:13px;
-    font-weight:bold;
-    font-family:monospace;
-    background-color:#d6d8ec;
-    color:#333;
-    -moz-box-shadow:0 1px 0px rgba(0, 0, 0, 0.2),0 0 0 2px #ffffff inset;
-    -webkit-box-shadow:0 1px 0px rgba(0, 0, 0, 0.2),0 0 0 2px #ffffff inset;
-    box-shadow:0 1px 0px rgba(0, 0, 0, 0.2),0 0 0 2px #ffffff inset;
-    -moz-border-radius:3px;
-    -webkit-border-radius:3px;
-    border-radius:3px;
-    display:inline-block;
-    margin:0 0.1em;
-    text-shadow:0 1px 0 #fff;
-    line-height:1.4;
-    white-space:nowrap;
-}
-
-body a code {
-    color: black;
-    border: 1px solid Blue;
-    border-radius:3px;
-}
-
-code {
-    font-size:13px;
-    border: 1px solid Silver;
-    background-color: #e3e4ec;
-}
-
-pre {
-    border: 1px solid Silver;
-    background-color: #eeeeee;
-    padding: 3px;
-    margin-left: 1em;
-}
-
-cursor {
-    color: #fff;
-    background-color: #000;
-    overflow: hidden;
-}
-
-h3 {
-    counter-reset: chapter;
-}
-
-h4 {
-    margin-left: auto;
-}
-
-table, td, th {
-    border: 0px;
-}
-
-th {
-    background-color:#d6d8ec;
-}
-
-tr:nth-child(odd) {
-    background-color:#fff;
-}
-tr:nth-child(even) {
-    background-color:#d6d8ec;
-}
-
-.region {
-    color: #ffffff;
-    background-color: #f9b593;
-}
index 63755da7cbf4c0a2be176b5dce13d38e95edaf59..44f87543f002a1a8d297095eab015abb422062e2 100644 (file)
 (defhydra hydra-ivy (:hint nil
                      :color pink)
   "
-^^^^^^          ^Yes^    ^^      ^No^     ^Maybe^            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Action^               ^
-^^^^^^^^^^^^^^^----------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------
-^ ^ _k_ ^ ^     _f_ollow occ_u_r _i_nsert _c_: calling %-5s(if ivy-calling \"on\" \"off\") _w_/_s_/_a_: %-14s(ivy-action-name)
-_h_ ^+^ _l_     _d_one      ^ ^  _o_ops   _m_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _C_ase-fold: %-10`ivy-case-fold-search
-^ ^ _j_ ^ ^     _g_o        ^ ^  ^ ^      _<_/_>_: shrink/grow^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _t_runcate: %-11`truncate-lines
+^ ^ ^ ^ ^ ^ | ^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)
@@ -83,7 +83,10 @@ _h_ ^+^ _l_     _d_one      ^ ^  _o_ops   _m_: matcher %-5s(ivy--matcher-desc)^^
   ("a" ivy-read-action)
   ("t" (setq truncate-lines (not truncate-lines)))
   ("C" ivy-toggle-case-fold)
-  ("u" ivy-occur :exit t))
+  ("u" ivy-occur :exit t)
+  ("D" (ivy-exit-with-action
+        (lambda (_) (find-function 'hydra-ivy/body)))
+       :exit t))
 
 (provide 'ivy-hydra)
 
index ec5857d8581b59bb549b45c701f1ba766963f3d5..40dae48286bb4254a290fc04585f31222ea8bd0e 100644 (file)
 ;; see <http://www.gnu.org/licenses/>.
 
 (require 'ert)
+
+;; useful for #'ivy-read-remap. It must arrive before (require 'ivy)
+(define-key global-map (kbd "<S-right>") #'end-of-buffer)
+
 (require 'ivy)
+(require 'counsel)
 
 (defvar ivy-expr nil
   "Holds a test expression to evaluate with `ivy-eval'.")
            (ivy-with '(ivy-read "test" '("aaab" "aaac"))
                      "a C-n <tab> C-m")
            "aaac"))
+  (should (equal
+           (ivy-with '(ivy-read "test" '(("foo" . "bar")))
+                     "asdf C-m")
+           "asdf"))
+  (should (equal
+           (ivy-with
+            '(with-output-to-string
+              (ivy-read "test" '(("foo" . "bar"))
+               :action (lambda (x) (prin1 x))))
+            "f C-m")
+           "\"bar\""))
+  (should (equal
+           (ivy-with
+            '(with-output-to-string
+              (ivy-read "test" '(("foo" . "bar"))
+               :action (lambda (x) (prin1 x))))
+            "asdf C-m")
+           "\"asdf\""))
   (should (equal
            (ivy-with '(ivy-read "pattern: " '("can do" "can" "can't do"))
                      "can C-m")
            "can")))
 
+(ert-deftest ivy-read-remap ()
+  (should (equal
+           (ivy-with '(ivy-read "pattern: " '("blue" "yellow" "red"))
+                  "<S-right> C-m")
+           "red")))
+
 (ert-deftest swiper--re-builder ()
   (setq swiper--width 4)
   (should (string= (swiper--re-builder "^")
                  '("Who are" "the Brittons?")))
   (should (equal (ivy--split "We're  all  Britons and   I   am your   king.")
                  '("We're all Britons"
-                  "and  I  am"
-                   "your  king."))))
+                   "and  I  am"
+                   "your  king.")))
+  (should (equal (ivy--split "^[^ ]") '("^[^ ]")))
+  (should (equal (ivy--split "^[^ ] bar") '("^[^ ]" "bar"))))
+
+(ert-deftest ivy--regex ()
+  (should (equal (ivy--regex
+                  "\\(?:interactive\\|swiper\\) \\(?:list\\|symbol\\)")
+                 "\\(\\(?:interactive\\|swiper\\)\\).*?\\(\\(?:list\\|symbol\\)\\)")))
 
 (ert-deftest ivy--regex-fuzzy ()
   (should (string= (ivy--regex-fuzzy "tmux")
   (should (string= (ivy--regex-fuzzy "$")
                    "$")))
 
+(ert-deftest ivy--regex-ignore-order ()
+  (should (equal (ivy--regex-ignore-order "tmux")
+                 '(("tmux" . t))))
+  (should (equal (ivy--regex-ignore-order "^tmux")
+                 '(("^tmux" . t))))
+  (should (equal (ivy--regex-ignore-order "^tmux$")
+                 '(("^tmux$" . t))))
+  (should (equal (ivy--regex-ignore-order "")
+                 ""))
+  (should (equal (ivy--regex-ignore-order "^")
+                 '(("^" . t))))
+  (should (equal (ivy--regex-ignore-order "$")
+                 '(("$" . t))))
+  (should (equal (ivy--regex-ignore-order "one two")
+                 '(("one" . t) ("two" . t))))
+  (should (equal (ivy--regex-ignore-order "one two !three")
+                 '(("one" . t) ("two" . t) ("three"))))
+  (should (equal (ivy--regex-ignore-order "one two !three four")
+                 '(("one" . t) ("two" . t) ("three") ("four"))))
+  (should (equal (ivy--regex-ignore-order "!three four")
+                 '(("" . t) (("three") ("four"))))))
+
 (ert-deftest ivy--format ()
   (should (string= (let ((ivy--index 10)
-                         (ivy-format-function (lambda (x) (mapconcat (lambda (y) (car y)) x "\n")))
+                         (ivy-format-function (lambda (x) (mapconcat #'identity x "\n")))
                          (cands '("NAME"
                                   "SYNOPSIS"
                                   "DESCRIPTION"
                  '("the" "The")))
   (should (equal (ivy--filter "The" '("foo" "the" "The"))
                  '("The"))))
+
+(ert-deftest counsel-unquote-regex-parens ()
+  (should (equal (counsel-unquote-regex-parens
+                  (ivy--regex "foo bar"))
+                 "(foo).*?(bar)"))
+  (should (equal (counsel-unquote-regex-parens
+                  (ivy--regex "(foo bar"))
+                 "(\\(foo).*?(bar)")))
index 5127582c909154070ce4fa0f6baf74f39d7a89a4..36fa7b347057d24efbdd571a48e0a41c0c77f0b4 100644 (file)
@@ -4,6 +4,7 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.8.0
 ;; Package-Requires: ((emacs "24.1"))
 ;; Keywords: matching
 
@@ -46,7 +47,8 @@
 
 (defgroup ivy-faces nil
   "Font-lock faces for `ivy'."
-  :group 'ivy)
+  :group 'ivy
+  :group 'faces)
 
 (defface ivy-current-match
   '((((class color) (background light))
      :background "#e99ce8" :weight bold)
     (((class color) (background dark))
      :background "#777777" :weight bold))
-  "Face for `ivy' minibuffer matches modulo 1.")
+  "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 modulo 2.")
+  "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 modulo 3.")
+  "Face for `ivy' minibuffer matches numbered 3 modulo 3.")
 
 (defface ivy-confirm-face
   '((t :foreground "ForestGreen" :inherit minibuffer-prompt))
   '((t :foreground "red" :inherit minibuffer-prompt))
   "Face used by Ivy for a match required prompt.")
 
-(setcdr (assoc load-file-name custom-current-group-alist) 'ivy)
-
 (defface ivy-subdir
-  '((t (:inherit 'dired-directory)))
+  '((t :inherit dired-directory))
   "Face used by Ivy for highlighting subdirs in the alternatives.")
 
 (defface ivy-modified-buffer
-  '((t :inherit 'default))
+  '((t :inherit default))
   "Face used by Ivy for highlighting modified file visiting buffers.")
 
 (defface ivy-remote
-  '((t (:foreground "#110099")))
+  '((t :foreground "#110099"))
   "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'.")
+
+(setcdr (assoc load-file-name custom-current-group-alist) 'ivy)
+
 (defcustom ivy-height 10
   "Number of lines for the minibuffer window."
   :type 'integer)
@@ -123,6 +129,10 @@ Set this to \"(%d/%d) \" to display both the index and the count."
           (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)
@@ -167,6 +177,48 @@ Only \"./\" and \"../\" apply here. They appear in reverse order."
   (setq ivy--actions-list
         (plist-put ivy--actions-list cmd actions)))
 
+(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)))
+
 ;;* Keymap
 (require 'delsel)
 (defvar ivy-minibuffer-map
@@ -176,25 +228,23 @@ Only \"./\" and \"../\" apply here. They appear in reverse order."
     (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 (kbd "C-n") 'ivy-next-line)
-    (define-key map (kbd "C-p") 'ivy-previous-line)
-    (define-key map (kbd "<down>") 'ivy-next-line)
-    (define-key map (kbd "<up>") 'ivy-previous-line)
+    (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 (kbd "DEL") 'ivy-backward-delete-char)
-    (define-key map (kbd "M-DEL") 'ivy-backward-kill-word)
-    (define-key map (kbd "C-d") 'ivy-delete-char)
-    (define-key map (kbd "C-f") 'ivy-forward-char)
-    (define-key map (kbd "M-d") 'ivy-kill-word)
-    (define-key map (kbd "M-<") 'ivy-beginning-of-buffer)
-    (define-key map (kbd "M->") 'ivy-end-of-buffer)
+    (define-key map [remap delete-backward-char] '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 (kbd "C-v") 'ivy-scroll-up-command)
-    (define-key map (kbd "M-v") 'ivy-scroll-down-command)
+    (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 "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-q") 'ivy-toggle-regexp-quote)
@@ -203,19 +253,24 @@ Only \"./\" and \"../\" apply here. They appear in reverse order."
     (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 (kbd "C-k") 'ivy-kill-line)
+    (define-key map [remap kill-line] 'ivy-kill-line)
     (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
-    (define-key map (kbd "M-w") 'ivy-kill-ring-save)
+    (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 [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]
+      'ivy-switch-buffer)
+    (define-key map [remap switch-to-buffer-other-window]
+      'ivy-switch-buffer-other-window)
     map)
   "Keymap for `ivy-mode'.")
 
@@ -236,9 +291,11 @@ Only \"./\" and \"../\" apply here. They appear in reverse order."
   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
   caller)
 
-(defvar ivy-last nil
+(defvar ivy-last (make-ivy-state)
   "The last parameters passed to `ivy-read'.
 
 This should eventually become a stack so that you could use
@@ -247,6 +304,22 @@ This should eventually become a stack so that you could use
 (defsubst ivy-set-action (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.
 
@@ -275,6 +348,30 @@ 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.")
 
@@ -308,6 +405,18 @@ When non-nil, it should contain at least one %d.")
 
 (defvar Info-current-file)
 
+(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
@@ -349,7 +458,10 @@ When non-nil, it should contain at least one %d.")
   "Exit the minibuffer with the selected candidate."
   (interactive)
   (delete-minibuffer-contents)
-  (cond ((> ivy--length 0)
+  (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--current))
         ((memq (ivy-state-collection ivy-last)
                '(read-file-name-internal internal-complete-buffer))
@@ -367,30 +479,48 @@ When non-nil, it should contain at least one %d.")
          (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--current)
+          (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."
+  "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)))
-    (unless (null (ivy--actionp actions))
-      (let* ((hint (concat ivy--current
-                           "\n"
-                           (mapconcat
-                            (lambda (x)
-                              (format "%s: %s"
-                                      (propertize
-                                       (car x)
-                                       'face 'font-lock-builtin-face)
-                                      (nth 2 x)))
-                            (cdr actions)
-                            "\n")
-                           "\n"))
+    (if (null (ivy--actionp actions))
+        t
+      (let* ((hint (funcall ivy-read-action-format-function (cdr actions)))
+             (resize-mini-windows 'grow-only)
              (key (string (read-key hint)))
              (action-idx (cl-position-if
                           (lambda (x) (equal (car x) key))
                           (cdr actions))))
-        (cond ((string= key "\a"))
+        (cond ((string= key "\a")
+               nil)
               ((null action-idx)
-               (error "%s is not bound" key))
+               (message "%s is not bound" key)
+               nil)
               (t
                (message "")
                (setcar actions (1+ action-idx))
@@ -399,8 +529,8 @@ When non-nil, it should contain at least one %d.")
 (defun ivy-dispatching-done ()
   "Select one of the available actions and call `ivy-done'."
   (interactive)
-  (ivy-read-action)
-  (ivy-done))
+  (when (ivy-read-action)
+    (ivy-done)))
 
 (defun ivy-dispatching-call ()
   "Select one of the available actions and call `ivy-call'."
@@ -432,8 +562,7 @@ When ARG is t, exit with current text, ignoring the candidates."
         (ivy--directory
          (ivy--directory-done))
         ((eq (ivy-state-collection ivy-last) 'Info-read-node-name-1)
-         (if (or (equal ivy--current "(./)")
-                 (equal ivy--current "(../)"))
+         (if (member ivy--current '("(./)" "(../)"))
              (ivy-quit-and-run
               (ivy-read "Go to file: " 'read-file-name-internal
                         :action (lambda (x)
@@ -452,23 +581,10 @@ When ARG is t, exit with current text, ignoring the candidates."
        (setq dir (concat ivy-text ivy--directory))
        (ivy--cd dir)
        (ivy--exhibit))
-      ((or
-        (and
-         (not (equal ivy-text ""))
-         (ignore-errors
-           (file-directory-p
-            (setq dir
-                  (file-name-as-directory
-                   (expand-file-name
-                    ivy-text ivy--directory))))))
-        (and
-         (not (string= ivy--current "./"))
-         (cl-plusp ivy--length)
-         (ignore-errors
-           (file-directory-p
-            (setq dir (file-name-as-directory
-                       (expand-file-name
-                        ivy--current ivy--directory)))))))
+      ((and
+        (> ivy--length 0)
+        (not (string= ivy--current "./"))
+        (setq dir (ivy-expand-file-if-directory ivy--current)))
        (ivy--cd dir)
        (ivy--exhibit))
       ((or (and (equal ivy--directory "/")
@@ -500,7 +616,7 @@ When ARG is t, exit with current text, ignoring the candidates."
          (setq res (cl-delete-duplicates res :test #'equal))
          (let* ((old-ivy-last ivy-last)
                 (enable-recursive-minibuffers t)
-                (host (ivy-read "Find File: "
+                (host (ivy-read "user@host: "
                                 (mapcar #'ivy-build-tramp-name res)
                                 :initial-input rest)))
            (setq ivy-last old-ivy-last)
@@ -510,6 +626,18 @@ When ARG is t, exit with current text, ignoring the candidates."
       (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)
@@ -522,13 +650,12 @@ If the text hasn't changed as a result, forward to `ivy-alt-done'."
            (or (and (equal ivy--directory "/")
                     (string-match "\\`[^/]+:.*\\'" ivy-text))
                (string-match "\\`/" ivy-text)))
-      (let ((default-directory ivy--directory))
+      (let ((default-directory ivy--directory)
+            dir)
         (minibuffer-complete)
         (setq ivy-text (ivy--input))
-        (when (file-directory-p
-               (expand-file-name ivy-text ivy--directory))
-          (ivy--cd (file-name-as-directory
-                    (expand-file-name ivy-text ivy--directory)))))
+        (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))
@@ -576,30 +703,32 @@ If the text hasn't changed as a result, forward to `ivy-alt-done'."
 (defun ivy-resume ()
   "Resume the last completion session."
   (interactive)
-  (when (eq (ivy-state-caller ivy-last) 'swiper)
-    (switch-to-buffer (ivy-state-buffer ivy-last)))
-  (with-current-buffer (ivy-state-buffer 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--current)
-     :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 ivy-calling nil
+  (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)
+      (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--current)
+       :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)
@@ -660,9 +789,9 @@ If the text hasn't changed as a result, forward to `ivy-alt-done'."
   "Move cursor vertically down ARG candidates.
 If the input is empty, select the previous history element instead."
   (interactive "p")
-  (when (string= ivy-text "")
-    (ivy-previous-history-element 1))
-  (ivy-next-line arg))
+  (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."
@@ -689,6 +818,16 @@ If the input is empty, select the previous history element instead."
   (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)))
@@ -699,12 +838,14 @@ If the input is empty, select the previous history element instead."
 
 (defun ivy--get-window (state)
   "Get the window from STATE."
-  (let ((window (ivy-state-window state)))
-    (if (window-live-p window)
-        window
-      (if (= (length (window-list)) 1)
-          (selected-window)
-        (next-window)))))
+  (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."
@@ -736,24 +877,36 @@ If the input is empty, select the previous history element instead."
                 (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-call ()
   "Call the current action without exiting completion."
   (interactive)
-  (let ((action (ivy--get-action ivy-last)))
-    (when action
-      (let* ((collection (ivy-state-collection ivy-last))
-             (x (if (and (consp collection)
-                         (consp (car collection)))
-                    (cdr (assoc ivy--current collection))
-                  (if (equal ivy--current "")
-                      ivy-text
-                    ivy--current))))
-        (prog1 (funcall action x)
-          (unless (or (eq ivy-exit 'done)
-                      (equal (selected-window)
-                             (active-minibuffer-window))
-                      (null (active-minibuffer-window)))
-            (select-window (active-minibuffer-window))))))))
+  (unless ivy-inhibit-action
+    (let ((action (ivy--get-action ivy-last)))
+      (when action
+        (let* ((collection (ivy-state-collection ivy-last))
+               (x (cond ((and (consp collection)
+                              (consp (car collection))
+                              (cdr (assoc ivy--current collection))))
+                        ((equal ivy--current "")
+                         ivy-text)
+                        (t
+                         ivy--current))))
+          (prog1 (funcall action x)
+            (unless (or (eq ivy-exit 'done)
+                        (equal (selected-window)
+                               (active-minibuffer-window))
+                        (null (active-minibuffer-window)))
+              (select-window (active-minibuffer-window)))))))))
 
 (defun ivy-next-line-and-call (&optional arg)
   "Move cursor vertically down ARG candidates.
@@ -782,18 +935,42 @@ Call the permanent action if possible."
 (defun ivy-next-history-element (arg)
   "Forward to `next-history-element' with ARG."
   (interactive "p")
-  (next-history-element arg)
+  (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 (ffap-url-p input))
+      (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)))
@@ -937,9 +1114,10 @@ On error (read-only), call `ivy-on-del-error-function'."
             (avy--process
              (nreverse candidates)
              (avy--style-fn avy-style)))))
-    (ivy-set-index (- (line-number-at-pos candidate) 2))
-    (ivy--exhibit)
-    (ivy-done)))
+    (when (numberp candidate)
+      (ivy-set-index (- (line-number-at-pos candidate) 2))
+      (ivy--exhibit)
+      (ivy-done))))
 
 (defun ivy-sort-file-function-default (x y)
   "Compare two files X and Y.
@@ -972,12 +1150,13 @@ See also `ivy-sort-max-size'."
   :type
   '(alist
     :key-type (choice
-               (const :tag "All other functions" t)
-               (symbol :tag "Function"))
+               (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)))
+                 (const :tag "Plain sort" string-lessp)
+                 (const :tag "File sort" ivy-sort-file-function-default)
+                 (const :tag "No sort" nil)
+                 (function :tag "Custom function")))
   :group 'ivy)
 
 (defvar ivy-index-functions-alist
@@ -994,11 +1173,18 @@ selected.")
 (defvar ivy-re-builders-alist
   '((t . ivy--regex-plus))
   "An alist of regex building functions for each collection function.
-Each function should take a string and return a valid regex or a
-regex sequence (see below).
 
-The entry associated with t is used for all fall-through cases.
-Possible choices: `ivy--regex', `regexp-quote', `ivy--regex-plus'.
+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\") ...).
@@ -1043,11 +1229,17 @@ Directories come first."
         (push dir seq))
       seq)))
 
+(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.")
+
 ;;** Entry Point
 (cl-defun ivy-read (prompt collection
-                           &key predicate require-match initial-input
-                           history preselect keymap update-fn sort
-                           action unwind re-builder matcher dynamic-collection caller)
+                    &key
+                      predicate require-match initial-input
+                      history preselect 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
@@ -1086,15 +1278,41 @@ 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 (plist-get ivy--actions-list this-command)))
+  (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
-            (if (functionp action)
-                `(1
-                  ("o" ,action "default")
-                  ,@extra-actions)
-              (delete-dups (append action extra-actions))))))
-  (let ((recursive-ivy-last (and (active-minibuffer-window) ivy-last)))
+            (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 ((recursive-ivy-last (and (active-minibuffer-window) ivy-last))
+        (transformer-fn
+         (plist-get ivy--display-transformers-list
+                    (or caller (and (functionp collection)
+                                    collection)))))
     (setq ivy-last
           (make-ivy-state
            :prompt prompt
@@ -1114,39 +1332,44 @@ customizations apply to the current completion session."
            :re-builder re-builder
            :matcher matcher
            :dynamic-collection dynamic-collection
+           :display-transformer-fn transformer-fn
            :caller caller))
     (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)))
-                     (res (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--current
-                                ivy-text)))
-                    (unless (equal item "")
-                      (set hist (cons (propertize item 'ivy-index ivy--index)
-                                      (delete item
-                                              (cdr (symbol-value hist)))))))
-                  res)))
+             (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))))
+                 (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--current
+                                 ivy-text)))
+                     (unless (equal item "")
+                       (set hist (cons (propertize item 'ivy-index ivy--index)
+                                       (delete item
+                                               (cdr (symbol-value hist))))))))
+                 ivy--current))
           (remove-hook 'post-command-hook #'ivy--exhibit)
           (when (setq unwind (ivy-state-unwind ivy-last))
-            (funcall unwind)))
+            (funcall unwind))
+          (unless (eq ivy-exit 'done)
+            (when recursive-ivy-last
+              (ivy--reset-state (setq ivy-last recursive-ivy-last)))))
       (ivy-call)
-      (when recursive-ivy-last
+      (when (and recursive-ivy-last
+                 ivy-recursive-restore)
         (ivy--reset-state (setq ivy-last recursive-ivy-last))))))
 
 (defun ivy--reset-state (state)
@@ -1174,6 +1397,7 @@ This is useful for recursive `ivy-read'."
                    (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)
@@ -1182,6 +1406,7 @@ This is useful for recursive `ivy-read'."
     (setq ivy--full-length nil)
     (setq ivy-text "")
     (setq ivy-calling nil)
+    (setq ivy-use-ignore ivy-use-ignore-default)
     (let (coll sort-fn)
       (cond ((eq collection 'Info-read-node-name-1)
              (if (equal Info-current-file "dir")
@@ -1192,7 +1417,11 @@ This is useful for recursive `ivy-read'."
                                 :test #'equal)))
                (setq coll (all-completions "" collection predicate))))
             ((eq collection 'read-file-name-internal)
-             (setq ivy--directory default-directory)
+             (if (and initial-input (file-directory-p initial-input))
+                 (progn
+                   (setq ivy--directory initial-input)
+                   (setq initial-input nil))
+               (setq ivy--directory default-directory))
              (require 'dired)
              (when preselect
                (let ((preselect-directory (file-name-directory preselect)))
@@ -1209,14 +1438,19 @@ This is useful for recursive `ivy-read'."
                            (equal initial-input default-directory)
                            (equal initial-input ""))
                  (setq coll (cons initial-input coll)))
-               (setq initial-input nil)))
+               (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)))
+             (setq coll (ivy--buffer-list "" ivy-use-virtual-buffers predicate)))
+            (dynamic-collection
+             (setq coll (funcall collection ivy-text)))
             ((or (functionp collection)
                  (byte-code-function-p collection)
                  (vectorp collection)
                  (and (consp collection) (listp (car collection)))
-                 (hash-table-p collection))
+                 (hash-table-p collection)
+                 (and (listp collection) (symbolp (car collection))))
              (setq coll (all-completions "" collection predicate)))
             (t
              (setq coll collection)))
@@ -1230,6 +1464,7 @@ This is useful for recursive `ivy-read'."
             (if (and (setq sort-fn (cdr (assoc t ivy-sort-functions-alist)))
                      (<= (length coll) ivy-sort-max-size))
                 (setq coll (cl-sort (copy-sequence coll) sort-fn))))))
+      (setq coll (ivy--set-candidates coll))
       (when preselect
         (unless (or (and require-match
                          (not (eq collection 'internal-complete-buffer)))
@@ -1260,10 +1495,12 @@ This is useful for recursive `ivy-read'."
                                   coll)))
                           0))))
     (setq ivy-exit nil)
-    (setq ivy--default (or
-                        (thing-at-point 'url)
-                        (thing-at-point 'symbol)
-                        ""))
+    (setq ivy--default
+          (if (region-active-p)
+              (buffer-substring
+               (region-beginning)
+               (region-end))
+            (ivy-thing-at-point)))
     (setq ivy--prompt
           (cond ((string-match "%.*d" prompt)
                  prompt)
@@ -1286,7 +1523,7 @@ This is useful for recursive `ivy-read'."
                 (ivy--directory
                  prompt)
                 (t
-                 nil)))
+                 prompt)))
     (setf (ivy-state-initial-input ivy-last) initial-input)))
 
 ;;;###autoload
@@ -1298,11 +1535,11 @@ This is useful for recursive `ivy-read'."
 This interface conforms to `completing-read' and can be used for
 `completing-read-function'.
 
-PROMPT is a string to prompt with; normally it ends in a colon and a space.
-COLLECTION can be a list of strings, an alist, an obarray or a hash table.
+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 specified with a boolean value.  See `completing-read'.
-INITIAL-INPUT is a string that can be inserted into the minibuffer initially.
+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."
@@ -1332,11 +1569,85 @@ INHERIT-INPUT-METHOD is currently ignored."
               :history history
               :keymap nil
               :sort
-              (let ((sort (assoc this-command ivy-sort-functions-alist)))
+              (let ((sort (or (assoc this-command ivy-sort-functions-alist)
+                              (assoc t ivy-sort-functions-alist))))
                 (if sort
                     (cdr sort)
                   t)))))
 
+(defvar ivy-completion-beg nil
+  "Completion bounds start.")
+
+(defvar ivy-completion-end nil
+  "Completion bounds end.")
+
+(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 (stringp str)
+    (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 str)
+      (setq ivy-completion-end
+            (move-marker (make-marker) (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)))
+    (while (and (<= pos len)
+                (let ((prop (get-text-property pos 'face str)))
+                  (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 str) len)
+      0)))
+
+(defun ivy-completion-in-region (start end collection &optional predicate)
+  "An Ivy function suitable for `completion-in-region-function'."
+  (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))))
+    (if (null comps)
+        (message "No matches")
+      (nconc comps nil)
+      (setq ivy-completion-beg (- end (ivy-completion-common-length (car comps))))
+      (setq ivy-completion-end end)
+      (if (null (cdr comps))
+          (if (string= str (car comps))
+              (message "Sole match")
+            (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
+                     :require-match t)
+           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.
@@ -1354,8 +1665,12 @@ Minibuffer bindings:
   :keymap ivy-mode-map
   :lighter " ivy"
   (if ivy-mode
-      (setq completing-read-function 'ivy-completing-read)
-    (setq completing-read-function 'completing-read-default)))
+      (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."
@@ -1363,7 +1678,7 @@ Minibuffer bindings:
          preselect)
         ((cl-position preselect candidates :test #'equal))
         ((stringp preselect)
-         (let ((re (regexp-quote preselect)))
+         (let ((re preselect))
            (cl-position-if
             (lambda (x)
               (string-match re x))
@@ -1386,19 +1701,27 @@ This allows to \"quote\" N spaces by inputting N+1 spaces."
         match-len)
     (while (and (string-match " +" str start1)
                 (< start1 len))
-      (setq match-len (- (match-end 0) (match-beginning 0)))
-      (if (= match-len 1)
+      (if (and (> (match-beginning 0) 2)
+               (string= "[^" (substring
+                              str
+                              (- (match-beginning 0) 2)
+                              (match-beginning 0))))
           (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)))))
+            (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))
@@ -1426,7 +1749,7 @@ When GREEDY is non-nil, join words in a greedy way."
                          (setq ivy--subexps (length subs))
                          (mapconcat
                           (lambda (x)
-                            (if (string-match "\\`\\\\(.*\\\\)\\'" x)
+                            (if (string-match "\\`\\\\([^?].*\\\\)\\'" x)
                                 x
                               (format "\\(%s\\)" x)))
                           subs
@@ -1435,32 +1758,36 @@ When GREEDY is non-nil, join words in a greedy way."
                             ".*?")))))
                     ivy--regex-hash)))))
 
-(defun ivy--regex-ignore-order (str)
+(defun ivy--regex-ignore-order--part (str &optional discard)
   "Re-build regex from STR by splitting at spaces.
-Ignore the order of each group.
-
-ATTENTION: This is just a proof of concept and may not work as
-expected. Besides ignoring the order of the tokens where 'foo'
-and 'bar', 'bar' and 'foo' are matched, it also matches multiple
-occurrences of 'foo' and 'bar'. To ignore the sort order and avoid
-multiple matches, use `ivy-restrict-to-matches' instead.
-"
+Ignore the order of each group."
   (let* ((subs (split-string str " +" t))
          (len (length subs)))
     (cl-case len
-      (1
-       (setq ivy--subexps 0)
-       (car subs))
+      (0
+       "")
       (t
-       (setq ivy--subexps len)
-       (let ((all (mapconcat #'identity subs "\\|")))
-         (mapconcat
-          (lambda (x)
-            (if (string-match "\\`\\\\(.*\\\\)\\'" x)
-                x
-              (format "\\(%s\\)" x)))
-          (make-list len all)
-          ".*?"))))))
+       (mapcar (lambda (x) (cons x (not discard)))
+               subs)))))
+
+(defun ivy--regex-ignore-order (str)
+  "Re-build regex from STR by splitting at spaces.
+Ignore the order of each group. 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)
+                 (ivy--regex-ignore-order--part (car parts) t))
+         (ivy--regex-ignore-order--part (car parts))))
+      (2
+       (append
+        (ivy--regex-ignore-order--part (car parts))
+        (ivy--regex-ignore-order--part (cadr parts) t)))
+      (t (error "Unexpected: use only one !")))))
 
 (defun ivy--regex-plus (str)
   "Build a regex sequence from STR.
@@ -1471,13 +1798,14 @@ match. Everything after \"!\" should not match."
       (0
        "")
       (1
-       (ivy--regex (car parts)))
+       (if (string= (substring str 0 1) "!")
+           (list (cons "" t)
+                 (list (ivy--regex (car parts))))
+         (ivy--regex (car parts))))
       (2
-       (let ((res
-              (mapcar #'list
-                      (split-string (cadr parts) " " t))))
-         (cons (cons (ivy--regex (car parts)) t)
-               res)))
+       (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)
@@ -1494,6 +1822,14 @@ Insert .* between each char."
         (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 at `ivy-height'. This effectively sets the minimum
+height at this level and tries to ensure that it does not change
+depending on the number of candidates."
+  :group 'ivy
+  :type 'boolean)
+
 ;;** Rest
 (defun ivy--minibuffer-setup ()
   "Setup ivy completion in the minibuffer."
@@ -1501,9 +1837,12 @@ Insert .* between each char."
   (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 t))
   (setq-local max-mini-window-height ivy-height)
+  (when ivy-fixed-height-minibuffer
+    (set-window-text-height (selected-window) ivy-height))
   (add-hook 'post-command-hook #'ivy--exhibit nil t)
   ;; show completions with empty input
   (ivy--exhibit))
@@ -1525,7 +1864,7 @@ Insert .* between each char."
   "Update the prompt according to `ivy--prompt'."
   (when ivy--prompt
     (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done
-                                          counsel-find-symbol))
+                                 counsel-find-symbol))
       (setq ivy--prompt-extra ""))
     (let (head tail)
       (if (string-match "\\(.*\\): \\'" ivy--prompt)
@@ -1566,6 +1905,8 @@ Insert .* between each char."
                  (window-width))
               (setq n-str (concat n-str "\n" d-str))
             (setq n-str (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))))
@@ -1608,6 +1949,28 @@ Insert .* between each char."
             (cl-sort (copy-sequence collection) sort-fn)
           collection)))))
 
+(defun ivy--magic-file-slash ()
+  (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 "[[:alpha:]]:/\\'" ivy-text)
+         (let ((drive-root (match-string 0 ivy-text)))
+           (when (file-exists-p drive-root)
+             (ivy--cd drive-root))))
+        ((and (or (> ivy--index 0)
+                  (= ivy--length 1)
+                  (not (string= ivy-text "/")))
+              (let ((default-directory ivy--directory))
+                (and
+                 (not (equal ivy--current ""))
+                 (file-directory-p ivy--current)
+                 (file-exists-p ivy--current))))
+         (ivy--cd (expand-file-name ivy--current ivy--directory)))))
+
 (defun ivy--exhibit ()
   "Insert Ivy completions display.
 Should be run via minibuffer `post-command-hook'."
@@ -1630,17 +1993,7 @@ Should be run via minibuffer `post-command-hook'."
              (ivy--format ivy--all-candidates))))
       (cond (ivy--directory
              (if (string-match "/\\'" ivy-text)
-                 (if (member ivy-text ivy--all-candidates)
-                     (ivy--cd (expand-file-name ivy-text ivy--directory))
-                   (when (string-match "//\\'" ivy-text)
-                     (if (and default-directory
-                              (string-match "\\`[[:alpha:]]:/" default-directory))
-                         (ivy--cd (match-string 0 default-directory))
-                       (ivy--cd "/")))
-                   (when (string-match "[[:alpha:]]:/$" ivy-text)
-                     (let ((drive-root (match-string 0 ivy-text)))
-                       (when (file-exists-p drive-root)
-                         (ivy--cd drive-root)))))
+                 (ivy--magic-file-slash)
                (if (string-match "\\`~\\'" ivy-text)
                    (ivy--cd (expand-file-name "~/")))))
             ((eq (ivy-state-collection ivy-last) 'internal-complete-buffer)
@@ -1681,16 +2034,20 @@ Should be run via minibuffer `post-command-hook'."
 
 (defun ivy--resize-minibuffer-to-fit ()
   "Resize the minibuffer window size to fit the text in the minibuffer."
-  (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)))
+  (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 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))))))
+            (window-resize nil (- text-height body-height) nil t)))))))
 
 (declare-function colir-blend-face-background "ext:colir")
 
@@ -1738,6 +2095,25 @@ You can toggle this to make `case-fold-search' nil regardless of input."
   ;; 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."
@@ -1752,15 +2128,15 @@ CANDIDATES are assumed to be static."
               (and ivy-case-fold-search
                    (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)
+                      (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)
@@ -1770,36 +2146,51 @@ CANDIDATES are assumed to be static."
                           (lambda (x) (string-match re x))
                           ivy--old-cands)))
                       (t
-                       (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)))))
+                       (ivy--re-filter re candidates)))))
         (ivy--recompute-index name re-str cands)
-        (setq ivy--old-re (if cands re-str ""))
+        (setq ivy--old-re
+              (if (eq ivy--regex-function 'ivy--regex-ignore-order)
+                  re
+                (if cands
+                    re-str
+                  "")))
         (setq ivy--old-cands (ivy--sort name 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))
-  "An alist of functions used to sort the matching candidates.
+  "An alist of functions for sorting matching candidates.
 
-This is different from `ivy-sort-functions-alist', which is used
-to sort the whole collection only once.  The functions taken from
-here are instead used on each input change, but they are used
-only on already matching candidates, not on all of them.
+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 a collection function or t to match previously
-not matched collection functions.
+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'.")
+`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-soft CANDIDATES according to file modification date."
@@ -1850,10 +2241,10 @@ Prefix matches to NAME are put ahead of the list."
     (unless (eq this-command 'ivy-resume)
       (setq ivy--index
             (or
-             (cl-position (if (and (> (length re-str) 0)
-                                   (eq ?^ (aref re-str 0)))
-                              (substring re-str 1)
-                            re-str) cands
+             (cl-position (if (and (> (length name) 0)
+                                   (eq ?^ (aref name 0)))
+                              (substring name 1)
+                            name) cands
                             :test #'equal)
              (and ivy--directory
                   (cl-position
@@ -1863,7 +2254,7 @@ Prefix matches to NAME are put ahead of the list."
                   (not (and (require 'flx nil 'noerror)
                             (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))))
@@ -1884,7 +2275,9 @@ Prefix matches to NAME are put ahead of the list."
           (while (and tail (null idx))
             ;; Compare with eq to handle equal duplicates in cands
             (setq idx (cl-position (pop tail) cands)))
-          (or idx 0))
+          (or
+           idx
+           (1- (length cands))))
       (if ivy--old-cands
           ivy--index
         ;; already in ivy-state-buffer
@@ -1898,25 +2291,55 @@ Prefix matches to NAME are put ahead of the list."
           res)))))
 
 (defun ivy-recompute-index-swiper-async (_re-str 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)))
+  (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)
   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-sort (name cands)
   "Sort according to closeness to string NAME the string list CANDS."
   (condition-case nil
       (if (and cands
-               (< (length cands) 200))
+               (< (length cands) ivy-flx-limit))
           (let* ((flx-name (if (string-match "^\\^" name)
                                (substring name 1)
                              name))
@@ -1924,15 +2347,28 @@ Prefix matches to NAME are put ahead of the list."
                   (delq nil
                         (mapcar
                          (lambda (x)
-                           (let ((score (car (flx-score x flx-name ivy--flx-cache))))
+                           (let ((score (flx-score x flx-name ivy--flx-cache)))
                              (and score
                                   (cons score x))))
                          cands))))
             (if cands-with-score
-                (mapcar #'cdr
+                (mapcar (lambda (x)
+                          (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))
                         (sort cands-with-score
                               (lambda (x y)
-                                (> (car x) (car y)))))
+                                (> (caar x) (caar y)))))
               cands))
         cands)
     (error
@@ -1953,91 +2389,107 @@ This string is inserted into the minibuffer."
                                     (- (length str) 3))) "...")
     str))
 
-(defun ivy--format-function-generic (selected-fn other-fn cand-pairs separator)
+(defun ivy--format-function-generic (selected-fn other-fn strs separator)
   "Transform CAND-PAIRS into a string for minibuffer.
-SELECTED-FN and OTHER-FN each take two string arguments.
+SELECTED-FN and OTHER-FN each take one string argument.
 SEPARATOR is used to join the candidates."
   (let ((i -1))
     (mapconcat
-     (lambda (pair)
-       (let ((str (car pair))
-             (extra (cdr pair))
-             (curr (eq (cl-incf i) ivy--index)))
+     (lambda (str)
+       (let ((curr (eq (cl-incf i) ivy--index)))
          (if curr
-             (funcall selected-fn str extra)
-           (funcall other-fn str extra))))
-     cand-pairs
+             (funcall selected-fn str)
+           (funcall other-fn str))))
+     strs
      separator)))
 
-(defun ivy-format-function-default (cand-pairs)
+(defun ivy-format-function-default (cands)
   "Transform CAND-PAIRS into a string for minibuffer."
   (ivy--format-function-generic
-   (lambda (str extra)
-     (concat (ivy--add-face str 'ivy-current-match) extra))
-   #'concat
-   cand-pairs
+   (lambda (str)
+     (ivy--add-face str 'ivy-current-match))
+   #'identity
+   cands
    "\n"))
 
-(defun ivy-format-function-arrow (cand-pairs)
+(defun ivy-format-function-arrow (cands)
   "Transform CAND-PAIRS into a string for minibuffer."
   (ivy--format-function-generic
-   (lambda (str extra)
-     (concat "> " (ivy--add-face str 'ivy-current-match) extra))
-   (lambda (str extra)
-     (concat "  " str extra))
-   cand-pairs
+   (lambda (str)
+     (concat "> " (ivy--add-face str 'ivy-current-match)))
+   (lambda (str)
+     (concat "  " str))
+   cands
    "\n"))
 
-(defun ivy-format-function-line (cand-pairs)
+(defun ivy-format-function-line (cands)
   "Transform CAND-PAIRS into a string for minibuffer."
   (ivy--format-function-generic
-   (lambda (str extra)
-     (ivy--add-face (concat str extra "\n") 'ivy-current-match))
-   (lambda (str extra)
-     (concat str extra "\n"))
-   cand-pairs
+   (lambda (str)
+     (ivy--add-face (concat str "\n") 'ivy-current-match))
+   (lambda (str)
+     (concat str "\n"))
+   cands
    ""))
 
-(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.")
+(defun ivy-add-face-text-property (start end face 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--format-minibuffer-line (str)
-  (let ((start 0)
+  (let ((start
+         (if (and (memq (ivy-state-caller ivy-last)
+                        '(counsel-git-grep counsel-ag counsel-pt))
+                  (string-match "^[^:]+:[^:]+:" str))
+             (match-end 0)
+           0))
         (str (copy-sequence str)))
-    (when (eq ivy-display-style 'fancy)
-      (unless ivy--old-re
-        (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
-      (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)))))
-              (if (fboundp 'add-face-text-property)
-                  (add-face-text-property
-                   (match-beginning i)
-                   (match-end i)
-                   face
-                   nil
-                   str)
-                (font-lock-append-text-property
-                 (match-beginning i)
-                 (match-end i)
-                 'face
-                 face
-                 str)))
-            (cl-incf i)))))
+    (cond ((eq ivy--regex-function 'ivy--regex-ignore-order)
+           (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)))))
+          ((and (eq ivy-display-style 'fancy)
+                (not (eq ivy--regex-function 'ivy--regex-fuzzy)))
+           (unless ivy--old-re
+             (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
+           (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))
+
+(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)
+  (if (string-match-p "/\\'" str)
+      (propertize str 'face 'ivy-subdir)
     str))
 
 (defun ivy--format (cands)
@@ -2053,28 +2505,17 @@ CANDS is a list of strings."
            (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)))
-      (cond (ivy--directory
-             (setq cands (mapcar (lambda (x)
-                                   (if (string-match-p "/\\'" x)
-                                       (propertize x 'face 'ivy-subdir)
-                                     x))
-                                 cands)))
-            ((eq (ivy-state-collection ivy-last) 'internal-complete-buffer)
-             (setq cands (mapcar (lambda (x)
-                                   (let ((b (get-buffer x)))
-                                     (if (and b
-                                              (buffer-file-name b)
-                                              (buffer-modified-p b))
-                                         (propertize x 'face 'ivy-modified-buffer)
-                                       x)))
-                                 cands))))
+           (index (- ivy--index start))
+           transformer-fn)
       (setq ivy--current (copy-sequence (nth index cands)))
+      (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+        (with-ivy-window
+          (setq cands (mapcar transformer-fn cands))))
       (let* ((ivy--index index)
-             (cand-pairs (mapcar
-                          (lambda (cand)
-                            (cons (ivy--format-minibuffer-line cand) nil)) cands))
-             (res (concat "\n" (funcall ivy-format-function cand-pairs))))
+             (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))))
 
@@ -2124,7 +2565,11 @@ CANDS is a list of strings."
       (setq ivy--virtual-buffers (nreverse virtual-buffers))
       (mapcar #'car ivy--virtual-buffers))))
 
-(defun ivy--buffer-list (str &optional virtual)
+(defcustom ivy-ignore-buffers '("\\` ")
+  "List of regexps or functions matching buffer names to ignore."
+  :type '(repeat (choice regexp function)))
+
+(defun ivy--buffer-list (str &optional virtual predicate)
   "Return the buffers that match STR.
 When VIRTUAL is non-nil, add virtual buffers."
   (delete-dups
@@ -2136,10 +2581,73 @@ When VIRTUAL is non-nil, add virtual buffers."
               (abbreviate-file-name default-directory)))
            (propertize x 'face 'ivy-remote)
          x))
-     (all-completions str 'internal-complete-buffer))
+     (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-source-views ()
+  (mapcar #'car ivy-views))
+
+(ivy-set-sources
+ 'ivy-switch-buffer
+ '((original-source)
+   (ivy-source-views)))
+
+(defun ivy-set-view-recur (view)
+  (cond ((eq (car view) 'vert)
+         (let ((wnd1 (selected-window))
+               (wnd2 (split-window-vertically)))
+           (with-selected-window wnd1
+             (ivy-set-view-recur (nth 1 view)))
+           (with-selected-window wnd2
+             (ivy-set-view-recur (nth 2 view)))))
+        ((eq (car view) 'horz)
+         (let ((wnd1 (selected-window))
+               (wnd2 (split-window-horizontally)))
+           (with-selected-window wnd1
+             (ivy-set-view-recur (nth 1 view)))
+           (with-selected-window wnd2
+             (ivy-set-view-recur (nth 2 view)))))
+        ((eq (car view) 'file)
+         (let* ((name (cadr 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)))))
+        ((eq (car view) 'buffer)
+         (switch-to-buffer (cadr view)))
+        ((eq (car view) 'sexp)
+         (eval (cadr view)))))
+
 (defun ivy--switch-buffer-action (buffer)
   "Switch to BUFFER.
 BUFFER may be a string or nil."
@@ -2147,12 +2655,17 @@ BUFFER may be a string or nil."
     (if (zerop (length buffer))
         (switch-to-buffer
          ivy-text nil 'force-same-window)
-      (let ((virtual (assoc buffer ivy--virtual-buffers)))
-        (if (and virtual
-                 (not (get-buffer buffer)))
-            (find-file (cdr virtual))
-          (switch-to-buffer
-           buffer 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)
+               (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.
@@ -2187,17 +2700,66 @@ BUFFER may be a string or nil."
     ivy--rename-buffer-action
     "rename")))
 
+(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-switch-buffer-transformer (str)
+  (let ((b (get-buffer str)))
+    (if (and b
+             (buffer-file-name b)
+             (buffer-modified-p b))
+        (propertize str 'face 'ivy-modified-buffer)
+      str)))
+
+(defun ivy-switch-buffer-occur ()
+  "Occur function for `ivy-switch-buffer' that uses `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)
-  (if (not ivy-mode)
-      (call-interactively 'switch-to-buffer)
-    (let ((this-command 'ivy-switch-buffer))
-      (ivy-read "Switch to buffer: " 'internal-complete-buffer
-                :preselect (buffer-name (other-buffer (current-buffer)))
-                :action #'ivy--switch-buffer-action
-                :keymap ivy-switch-buffer-map))))
+  (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-buffer-other-window ()
+  "Switch to another buffer in another window."
+  (interactive)
+  (ivy-read "Switch to buffer in other window: " 'internal-complete-buffer
+            :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))
 
 ;;;###autoload
 (defun ivy-recentf ()
@@ -2207,7 +2769,8 @@ BUFFER may be a string or nil."
             :action
             (lambda (f)
               (with-ivy-window
-                (find-file f)))))
+                (find-file f)))
+            :caller 'ivy-recentf))
 
 (defun ivy-yank-word ()
   "Pull next word from buffer into search string."
@@ -2259,7 +2822,8 @@ 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))
+        (old-last ivy-last)
+        (ivy-recursive-restore nil))
     (ivy-read "Reverse-i-search: "
               history
               :action (lambda (x)
@@ -2286,17 +2850,45 @@ buffer would modify `ivy-last'.")
   (let ((map (make-sparse-keymap)))
     (define-key map [mouse-1] 'ivy-occur-click)
     (define-key map (kbd "RET") 'ivy-occur-press)
-    (define-key map (kbd "j") 'next-line)
-    (define-key map (kbd "k") 'previous-line)
+    (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 "g") 'ivy-occur-press)
+    (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].
 
@@ -2313,7 +2905,26 @@ buffer would modify `ivy-last'.")
 
 \\{ivy-occur-grep-mode-map}")
 
-(defvar counsel-git-grep-cmd)
+(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)
+  (dolist (str cands)
+    (add-text-properties
+     0 (length str)
+     `(mouse-face
+       highlight
+       help-echo "mouse-1: call ivy-action")
+     str)
+    (insert str "\n")))
 
 (defun ivy-occur ()
   "Stop completion and put the current matches into a new buffer.
@@ -2325,49 +2936,57 @@ a mouse click will call the appropriate action for that candidate.
 
 There is no limit on the number of *ivy-occur* buffers."
   (interactive)
-  (let ((buffer
-         (generate-new-buffer
-          (format "*ivy-occur%s \"%s\"*"
-                  (let (caller)
-                    (if (setq caller (ivy-state-caller ivy-last))
-                        (concat " " (prin1-to-string caller))
-                      ""))
-                  ivy-text)))
-        (do-grep (eq (ivy-state-caller ivy-last) 'counsel-git-grep)))
-    (with-current-buffer buffer
-      (if do-grep
-          (progn
-            (setq ivy--old-cands
-                  (split-string
-                   (shell-command-to-string
-                    (format counsel-git-grep-cmd ivy--old-re))
-                   "\n"
-                   t))
-            (ivy-occur-grep-mode))
-        (ivy-occur-mode))
-      (setf (ivy-state-text ivy-last) ivy-text)
-      (setq ivy-occur-last ivy-last)
-      (setq-local ivy--directory ivy--directory)
-      (let ((inhibit-read-only t))
-        (erase-buffer)
-        (when do-grep
-          ;; 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--old-cands)))
-        (dolist (cand ivy--old-cands)
-          (let ((str (if do-grep
-                         (concat "./" cand)
-                       (concat "    " cand))))
-            (add-text-properties
-             0 (length str)
-             `(mouse-face
-               highlight
-               help-echo "mouse-1: call ivy-action")
-             str)
-            (insert str "\n")))))
-    (ivy-exit-with-action
-     `(lambda (_) (pop-to-buffer ,buffer)))))
+  (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)))
+            (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))))
+          ((memq caller '(counsel-git-grep counsel-grep counsel-ag))
+           (let ((inhibit-read-only t))
+             (erase-buffer)
+             (funcall (plist-get ivy--occurs-list caller)))))))
 
 (declare-function wgrep-change-to-wgrep-mode "ext:wgrep")
 
@@ -2407,13 +3026,27 @@ EVENT gives the mouse position."
       (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)
-  (require 'pulse)
   (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-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
@@ -2423,13 +3056,14 @@ EVENT gives the mouse position."
            (action (ivy--get-action ivy-last))
            (ivy-exit 'done))
       (with-ivy-window
+        (setq counsel-grep-last-line nil)
         (funcall action
                  (if (and (consp coll)
                           (consp (car coll)))
                      (cdr (assoc str coll))
                    str))
         (if (memq (ivy-state-caller ivy-last)
-                  '(swiper counsel-git-grep))
+                  '(swiper counsel-git-grep counsel-grep))
             (with-current-buffer (window-buffer (selected-window))
               (swiper--cleanup)
               (swiper--add-overlays
@@ -2437,8 +3071,37 @@ EVENT gives the mouse position."
                (line-beginning-position)
                (line-end-position)
                (selected-window))
-              (run-at-time 0.5 nil 'swiper--cleanup))
-          (pulse-momentary-highlight-one-line (point)))))))
+              (when (timerp ivy-occur-timer)
+                (cancel-timer ivy-occur-timer))
+              (setq ivy-occur-timer (run-at-time 1.0 nil 'swiper--cleanup))))))))
+
+(defvar 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)
 
index d9bf724cf16a5228564bf422d871e7775ec75cf6..7c99a13ab93554223da7725c056cc2913123911d 100644 (file)
@@ -4,8 +4,8 @@
 
 ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
 ;; URL: https://github.com/abo-abo/swiper
-;; Version: 0.7.0
-;; Package-Requires: ((emacs "24.1"))
+;; Version: 0.8.0
+;; Package-Requires: ((emacs "24.1") (ivy "0.8.0"))
 ;; Keywords: matching
 
 ;; This file is part of GNU Emacs.
   '((t (:inherit isearch-fail)))
   "Face for `swiper' matches modulo 3.")
 
-(define-obsolete-face-alias 'swiper-minibuffer-match-face-1
-    'ivy-minibuffer-match-face-1 "0.6.0")
-
-(define-obsolete-face-alias 'swiper-minibuffer-match-face-2
-    'ivy-minibuffer-match-face-2 "0.6.0")
-
-(define-obsolete-face-alias 'swiper-minibuffer-match-face-3
-    'ivy-minibuffer-match-face-3 "0.6.0")
-
-(define-obsolete-face-alias 'swiper-minibuffer-match-face-4
-    'ivy-minibuffer-match-face-4 "0.6.0")
-
 (defface swiper-line-face
   '((t (:inherit highlight)))
   "Face for current `swiper' line.")
@@ -81,7 +69,9 @@
                           swiper-match-face-2
                           swiper-match-face-3
                           swiper-match-face-4)
-  "List of `swiper' faces for group matches.")
+  "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."
       (user-error "Should only be called in the minibuffer through `swiper-map'")
     (let* ((enable-recursive-minibuffers t)
            (from (ivy--regex ivy-text))
-           (to (query-replace-read-to from "Query replace" t)))
+           (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 (_)
                                 (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))
+                           (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
 (declare-function mc/create-fake-cursor-at-point "ext:multiple-cursors-core")
 (declare-function multiple-cursors-mode "ext:multiple-cursors-core")
 
-;;;###autoload
 (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
   (with-ivy-window
     (recenter-top-bottom arg)))
 
+(defvar swiper-font-lock-exclude
+  '(package-menu-mode
+    gnus-summary-mode
+    gnus-article-mode
+    gnus-group-mode
+    emms-playlist-mode
+    emms-stream-mode
+    erc-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
+    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
+    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 (or (derived-mode-p 'magit-mode)
-              (bound-and-true-p magit-blame-mode)
-              (memq major-mode '(package-menu-mode
-                                 gnus-summary-mode
-                                 gnus-article-mode
-                                 gnus-group-mode
-                                 emms-playlist-mode
-                                 emms-stream-mode
-                                 erc-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
-                                 help-mode
-                                 debbugs-gnu-mode
-                                 occur-mode
-                                 occur-edit-mode
-                                 bongo-mode
-                                 eww-mode
-                                 twittering-mode
-                                 vc-dir-mode
-                                 w3m-mode)))
-    (unless (> (buffer-size) 100000)
+  (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))))))
   "Store the current candidates format spec.")
 
 (defvar swiper--width nil
-  "Store the amount of digits needed for the longest line nubmer.")
+  "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'.")
 (defun swiper--candidates (&optional numbers-width)
   "Return a list of this buffer lines.
 
-NUMBERS-WIDTH, when specified, is used for line numbers width
-spec, instead of calculating it as the log of the buffer line
-count."
+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))
@@ -293,8 +302,7 @@ count."
                            (buffer-substring
                             (point)
                             (line-end-position)))))))
-              (when (eq major-mode 'twittering-mode)
-                (remove-text-properties 0 (length str) '(field) str))
+              (remove-text-properties 0 (length str) '(field) str)
               (put-text-property 0 1 'display
                                  (format swiper--format-spec
                                          (cl-incf line-number))
@@ -311,35 +319,89 @@ count."
   "`isearch' with an overview.
 When non-nil, INITIAL-INPUT is the initial search pattern."
   (interactive)
-  (swiper--ivy initial-input))
+  (swiper--ivy (swiper--candidates) initial-input))
+
+(declare-function string-trim-right "subr-x")
+
+(defun swiper-occur (&optional revert)
+  "Generate a custom occur buffer for `swiper'.
+When REVERT is non-nil, regenerate the current *ivy-occur* buffer."
+  (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 'display 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))
+    (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-jumper--set-jump "ext:evil-jumper")
 
+(defvar swiper--current-line nil)
+(defvar swiper--current-match-start nil)
+
 (defun swiper--init ()
   "Perform initialization common to both completion methods."
+  (setq swiper--current-line nil)
+  (setq swiper--current-match-start nil)
   (setq swiper--opoint (point))
   (when (bound-and-true-p evil-jumper-mode)
     (evil-jumper--set-jump)))
 
 (defun swiper--re-builder (str)
   "Transform STR into a swiper regex.
-This is the regex used in the minibuffer, since the candidates
-there have line numbers. In the buffer, `ivy--regex' should be used."
-  (cond
-    ((equal str "")
-     "")
-    ((equal str "^")
-     (setq ivy--subexps 0)
-     ".")
-    ((string-match "^\\^" str)
-     (setq ivy--old-re "")
-     (let ((re (ivy--regex-plus (substring str 1))))
-       (if (zerop ivy--subexps)
-           (prog1 (format "^ ?\\(%s\\)" re)
-             (setq ivy--subexps 1))
-         (format "^ %s" re))))
-    (t
-     (ivy--regex-plus str))))
+This is the regex used in the minibuffer where candidates have
+line numbers. For the buffer, use `ivy--regex' instead."
+  (replace-regexp-in-string
+   "\t" "    "
+   (cond
+     ((equal str "")
+      "")
+     ((equal str "^")
+      (setq ivy--subexps 0)
+      ".")
+     ((string-match "^\\^" str)
+      (setq ivy--old-re "")
+      (let ((re (ivy--regex-plus (substring str 1))))
+        (if (zerop ivy--subexps)
+            (prog1 (format "^ ?\\(%s\\)" re)
+              (setq ivy--subexps 1))
+          (format "^ %s" re))))
+     (t
+      (ivy--regex-plus str)))))
 
 (defvar swiper-history nil
   "History for `swiper'.")
@@ -347,15 +409,14 @@ there have line numbers. In the buffer, `ivy--regex' should be used."
 (defvar swiper-invocation-face nil
   "The face at the point of invocation of `swiper'.")
 
-(defun swiper--ivy (&optional initial-input)
-  "`isearch' with an overview using `ivy'.
+(defun swiper--ivy (candidates &optional initial-input)
+  "Select one of CANDIDATES and move there.
 When non-nil, INITIAL-INPUT is the initial search pattern."
   (interactive)
   (swiper--init)
   (setq swiper-invocation-face
         (plist-get (text-properties-at (point)) 'face))
-  (let ((candidates (swiper--candidates))
-        (preselect
+  (let ((preselect
          (if swiper-use-visual-line
              (count-screen-lines
               (point-min)
@@ -364,20 +425,22 @@ When non-nil, INITIAL-INPUT is the initial search pattern."
         (minibuffer-allow-text-properties t)
         res)
     (unwind-protect
-         (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))
+         (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)))))
 
@@ -410,7 +473,7 @@ Matched candidates should have `swiper-invocation-face'."
 
 (defun swiper--ensure-visible ()
   "Remove overlays hiding point."
-  (let ((overlays (overlays-at (point)))
+  (let ((overlays (overlays-at (1- (point))))
         ov expose)
     (while (setq ov (pop overlays))
       (if (and (invisible-p (overlay-get ov 'invisible))
@@ -433,24 +496,33 @@ Matched candidates should have `swiper-invocation-face'."
   (with-ivy-window
     (swiper--cleanup)
     (when (> (length ivy--current) 0)
-      (let* ((re (funcall ivy--regex-function ivy-text))
+      (let* ((re (replace-regexp-in-string
+                  "    " "\t"
+                  (funcall ivy--regex-function ivy-text)))
              (re (if (stringp re) re (caar re)))
              (str (get-text-property 0 'display ivy--current))
              (num (if (string-match "^[0-9]+" str)
                       (string-to-number (match-string 0 str))
                     0)))
         (unless (eq this-command 'ivy-yank-word)
-          (goto-char (point-min))
           (when (cl-plusp num)
-            (goto-char (point-min))
-            (if swiper-use-visual-line
-                (line-move (1- num))
-              (forward-line (1- num)))
+            (unless (if swiper--current-line
+                        (eq swiper--current-line num)
+                      (eq (line-number-at-pos) num))
+              (goto-char (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)
-              (re-search-forward re (line-end-position) t))
+              (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))
@@ -511,25 +583,32 @@ WND, when specified is the window."
 
 (defun swiper--action (x)
   "Goto line X."
-  (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 (point-min))
-      (funcall (if swiper-use-visual-line
-                   #'line-move
-                 #'forward-line)
-               (1- (read (get-text-property 0 'display x))))
-      (re-search-forward
-       (ivy--regex ivy-text) (line-end-position) t)
-      (swiper--ensure-visible)
-      (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")))))))
+  (let ((ln (1- (read (or (get-text-property 0 'display 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 (point-min))
+        (funcall (if swiper-use-visual-line
+                     #'line-move
+                   #'forward-line)
+                 ln)
+        (re-search-forward re (line-end-position) t)
+        (swiper--ensure-visible)
+        (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)))))
 
 ;; (define-key isearch-mode-map (kbd "C-o") 'swiper-from-isearch)
 (defun swiper-from-isearch ()
@@ -573,6 +652,8 @@ Run `swiper' for those buffers."
                          (buffer-list)))
             :action 'swiper-multi-action-2
             :unwind #'swiper--cleanup
+            :update-fn (lambda ()
+                         (swiper-multi-action-2 ivy--current))
             :caller 'swiper-multi))
 
 (defun swiper--multi-candidates (buffers)
@@ -596,7 +677,8 @@ Run `swiper' for those buffers."
                      (1- len) len 'display
                      (concat
                       (make-string
-                       (- ww (string-width s) (length (buffer-name)) 3)
+                       (max 0
+                            (- ww (string-width s) (length (buffer-name)) 3))
                        ?\ )
                       (buffer-name))
                      s)