]> code.delx.au - gnu-emacs-elpa/commitdiff
Merge commit 'e9530990914c1d81889269b4a8365b8003625557' from swiper
authorOleh Krehel <ohwoeowho@gmail.com>
Tue, 30 Jun 2015 07:18:10 +0000 (09:18 +0200)
committerOleh Krehel <ohwoeowho@gmail.com>
Tue, 30 Jun 2015 07:18:10 +0000 (09:18 +0200)
1  2 
packages/swiper/colir.el
packages/swiper/counsel.el
packages/swiper/ivy-hydra.el
packages/swiper/ivy-test.el
packages/swiper/ivy.el
packages/swiper/swiper.el

diff --combined packages/swiper/colir.el
index f5ce0aef8ac31248a2979b66a85960134b9a29a1,7eacbbd12b5f8a913eb486ff414a7abbd60b7af3..7eacbbd12b5f8a913eb486ff414a7abbd60b7af3
@@@ -76,6 -76,8 +76,8 @@@ See also `font-lock-append-text-propert
      (while (/= start end)
        (setq next (next-single-property-change start 'face object end)
              prev (get-text-property start 'face object))
+       (when (listp prev)
+         (setq prev (cl-find-if #'atom prev)))
        (if prev
            (let ((background-prev (face-background prev)))
              (progn
index c0581e5fdc8056016525ea818d60576c63b4f33d,94c8608eee308daa3b2e87bb1a7e53f1c7815607..94c8608eee308daa3b2e87bb1a7e53f1c7815607
  
  (require 'swiper)
  
+ ;;;###autoload
  (defun counsel-el ()
    "Elisp completion at point."
    (interactive)
-   (counsel--generic
-    (lambda (str) (all-completions str obarray))))
+   (let* ((bnd (unless (and (looking-at ")")
+                            (eq (char-before) ?\())
+                 (bounds-of-thing-at-point
+                  'symbol)))
+          (str (if bnd
+                   (buffer-substring-no-properties
+                    (car bnd)
+                    (cdr bnd))
+                 ""))
+          (ivy-height 7)
+          (funp (eq (char-before (car bnd)) ?\())
+          symbol-names)
+     (if bnd
+         (progn
+           (setq counsel-completion-beg
+                 (move-marker (make-marker) (car bnd)))
+           (setq counsel-completion-end
+                 (move-marker (make-marker) (cdr bnd))))
+       (setq counsel-completion-beg nil)
+       (setq counsel-completion-end nil))
+     (if (string= str "")
+         (mapatoms
+          (lambda (x)
+            (when (symbolp x)
+              (push (symbol-name x) symbol-names))))
+       (setq symbol-names
+             (all-completions str obarray
+                              (and funp
+                                   (lambda (x)
+                                     (or (functionp x)
+                                         (macrop x)
+                                         (special-form-p x)))))))
+     (ivy-read "Symbol name: " symbol-names
+               :predicate (and funp #'functionp)
+               :initial-input str
+               :action #'counsel--el-action)))
+ (defvar counsel-completion-beg nil
+   "Completion bounds start.")
+ (defvar counsel-completion-end nil
+   "Completion bounds end.")
+ (defun counsel--el-action (symbol)
+   "Insert SYMBOL, erasing the previous one."
+   (when (stringp symbol)
+     (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)))))
  
  (defvar counsel-describe-map
    (let ((map (make-sparse-keymap)))
-     (define-key map (kbd "C-.") 'counsel-find-symbol)
+     (define-key map (kbd "C-.") #'counsel-find-symbol)
+     (define-key map (kbd "C-,") #'counsel--info-lookup-symbol)
      map))
  
  (defun counsel-find-symbol ()
    "Jump to the definition of the current symbol."
    (interactive)
-   (ivy-set-action 'counsel--find-symbol)
+   (ivy-set-action #'counsel--find-symbol)
+   (ivy-done))
+ (defun counsel--info-lookup-symbol ()
+   "Lookup the current symbol in the info docs."
+   (interactive)
+   (ivy-set-action #'counsel-info-lookup-symbol)
    (ivy-done))
  
  (defun counsel--find-symbol (x)
  (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))))
+ ;;;###autoload
  (defun counsel-describe-variable ()
    "Forward to `describe-variable'."
    (interactive)
              (push (symbol-name vv) cands))))
         cands)
       :keymap counsel-describe-map
-      :preselect (thing-at-point 'symbol)
+      :preselect (counsel-symbol-at-point)
       :history 'counsel-describe-symbol-history
       :require-match t
       :sort t
                 (describe-variable
                  (intern x))))))
  
+ ;;;###autoload
  (defun counsel-describe-function ()
    "Forward to `describe-function'."
    (interactive)
                       (push (symbol-name x) cands))))
                  cands)
                :keymap counsel-describe-map
-               :preselect (thing-at-point 'symbol)
+               :preselect (counsel-symbol-at-point)
                :history 'counsel-describe-symbol-history
                :require-match t
                :sort t
  (declare-function info-lookup-change-mode "info-look")
  (declare-function info-lookup "info-look")
  
+ ;;;###autoload
  (defun counsel-info-lookup-symbol (symbol &optional mode)
    "Forward to (`info-describe-symbol' SYMBOL MODE) with ivy completion."
    (interactive
                      (mapcar #'car completions)
                      :sort t)))
         (list value info-lookup-mode))))
+   (require 'info-look)
    (info-lookup 'symbol symbol mode))
  
+ ;;;###autoload
  (defun counsel-unicode-char ()
    "Insert a Unicode character at point."
    (interactive)
-   (let* ((minibuffer-allow-text-properties t)
-          (char (ivy-read "Unicode name: "
-                          (mapcar (lambda (x)
-                                    (propertize
-                                     (format "% -60s%c" (car x) (cdr x))
-                                     'result (cdr x)))
-                                  (ucs-names)))))
-     (insert-char (get-text-property 0 'result char))))
+   (let ((minibuffer-allow-text-properties t))
+     (ivy-read "Unicode name: "
+               (mapcar (lambda (x)
+                         (propertize
+                          (format "% -60s%c" (car x) (cdr x))
+                          'result (cdr x)))
+                       (ucs-names))
+               :action (lambda (char)
+                         (insert-char (get-text-property 0 'result char))))))
  
  (declare-function cider-sync-request:complete "ext:cider-client")
+ ;;;###autoload
  (defun counsel-clj ()
    "Clojure completion at point."
    (interactive)
        #'cl-caddr
        (cider-sync-request:complete str ":same")))))
  
+ ;;;###autoload
  (defun counsel-git ()
    "Find file in the current Git repository."
    (interactive)
  (defvar counsel--git-grep-dir nil
    "Store the base git directory.")
  
- (defun counsel-git-grep-count (str)
-   "Quickly count the amount of git grep STR matches."
-   (let* ((default-directory counsel--git-grep-dir)
-          (out (shell-command-to-string
-                (format "git grep -i -c '%s' | sed 's/.*:\\(.*\\)/\\1/g' | awk '{s+=$1} END {print s}'"
-                        (ivy--regex str)))))
-     (string-to-number out)))
  (defvar counsel--git-grep-count nil
    "Store the line count in current repository.")
  
          (list ""
                (format "%d chars more" (- 3 (length ivy-text)))))
      (let* ((default-directory counsel--git-grep-dir)
-            (cmd (format "git --no-pager grep --full-name -n --no-color -i -e \"%s\""
+            (cmd (format "git --no-pager grep --full-name -n --no-color -i -e %S"
                          (ivy--regex string t)))
             res)
        (if (<= counsel--git-grep-count 20000)
            (progn
              (setq res (shell-command-to-string cmd))
-             (setq ivy--full-length nil))
-         (setq res (shell-command-to-string (concat cmd " | head -n 2000")))
-         (setq ivy--full-length (counsel-git-grep-count ivy-text)))
-       (split-string res "\n" t))))
+             (setq ivy--full-length nil)
+             (split-string res "\n" t))
+         (setq ivy--full-length -1)
+         (counsel--gg-candidates (ivy--regex string))
+         nil))))
  
  (defvar counsel-git-grep-map
    (let ((map (make-sparse-keymap)))
  (defun counsel-git-grep-recenter ()
    (interactive)
    (with-selected-window (ivy-state-window ivy-last)
-     (counsel-git-grep-action)
+     (counsel-git-grep-action ivy--current)
      (recenter-top-bottom)))
  
  (defun counsel-git-grep-action (x)
-   (let ((lst (split-string x ":")))
-     (find-file (expand-file-name (car lst) counsel--git-grep-dir))
-     (goto-char (point-min))
-     (forward-line (1- (string-to-number (cadr lst))))
-     (unless (eq ivy-exit 'done)
-       (setq swiper--window (selected-window))
-       (swiper--cleanup)
-       (swiper--add-overlays (ivy--regex ivy-text)))))
+   (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" x)
+     (let ((file-name (match-string-no-properties 1 x))
+           (line-number (match-string-no-properties 2 x)))
+       (find-file (expand-file-name file-name counsel--git-grep-dir))
+       (goto-char (point-min))
+       (forward-line (1- (string-to-number line-number)))
+       (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
+       (unless (eq ivy-exit 'done)
+         (setq swiper--window (selected-window))
+         (swiper--cleanup)
+         (swiper--add-overlays (ivy--regex ivy-text))))))
+ (defvar counsel-git-grep-history nil
+   "History for `counsel-git-grep'.")
+ ;;;###autoload
  (defun counsel-git-grep (&optional initial-input)
    "Grep for a string in the current git repository."
    (interactive)
          (locate-dominating-file default-directory ".git"))
    (if (null counsel--git-grep-dir)
        (error "Not in a git repository")
-     (setq counsel--git-grep-count (counsel-git-grep-count ""))
+     (setq counsel--git-grep-count (counsel--gg-count "" t))
      (ivy-read "pattern: " 'counsel-git-grep-function
                :initial-input initial-input
                :matcher #'counsel-git-grep-matcher
                                      'counsel-git-grep-function)
                :keymap counsel-git-grep-map
                :action #'counsel-git-grep-action
-               :unwind #'swiper--cleanup)))
- (defun counsel-git-grep-matcher (x)
-   (ignore-errors
-     (when (string-match "^[^:]+:[^:]+:" x)
-       (setq x (substring x (match-end 0)))
-       (if (stringp ivy--old-re)
-           (string-match ivy--old-re x)
-         (let ((res t))
-           (dolist (re ivy--old-re)
-             (setq res
-                   (and res
-                        (ignore-errors
-                          (if (cdr re)
-                              (string-match (car re) x)
-                            (not (string-match (car re) x)))))))
-           res)))))
+               :unwind #'swiper--cleanup
+               :history 'counsel-git-grep-history)))
+ (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")
+ ;;;###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)
+               (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))
+ (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)
+       (prog1
+           (setq ivy--old-cands
+                 (cl-remove-if-not
+                  (lambda (x)
+                    (ignore-errors
+                      (when (string-match "^[^:]+:[^:]+:" x)
+                        (setq x (substring x (match-end 0)))
+                        (if (stringp regexp)
+                            (string-match regexp x)
+                          (let ((res t))
+                            (dolist (re regexp)
+                              (setq res
+                                    (and res
+                                         (ignore-errors
+                                           (if (cdr re)
+                                               (string-match (car re) x)
+                                             (not (string-match (car re) x)))))))
+                            res)))))
+                  candidates))
+         (setq ivy--old-re regexp))))
  
  (defun counsel-locate-function (str &rest _u)
    (if (< (length str) 3)
        (list ""
              (format "%d chars more" (- 3 (length ivy-text))))
-     (split-string
-      (shell-command-to-string (concat "locate -i -l 20 --regex " (ivy--regex str))) "\n" t)))
+     (counsel--async-command
+      (concat "locate -i --regex " (ivy--regex str)))))
+ (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))
+     (set-process-sentinel proc #'counsel--async-sentinel)))
+ (defun counsel--async-sentinel (process event)
+   (if (string= event "finished\n")
+       (progn
+         (with-current-buffer (process-buffer process)
+           (setq ivy--all-candidates (split-string (buffer-string) "\n" t))
+           (setq ivy--old-cands ivy--all-candidates))
+         (ivy--insert-minibuffer
+          (ivy--format ivy--all-candidates)))
+     (if (string= event "exited abnormally with code 1\n")
+         (message "Error"))))
+ ;;;###autoload
  (defun counsel-locate ()
    "Call locate."
    (interactive)
-   (let* ((ivy--dynamic-function 'counsel-locate-function)
-          (val (ivy-read "pattern: " 'counsel-locate-function)))
-     (when val
-       (find-file val))))
+   (ivy-read "pattern: " nil
+             :dynamic-collection #'counsel-locate-function
+             :action (lambda (val)
+                       (when val
+                         (find-file val)))))
  
  (defun counsel--generic (completion-fn)
    "Complete thing at point with COMPLETION-FN."
       str)
      str))
  
+ ;;;###autoload
  (defun counsel-load-library ()
    "Load a selected the Emacs Lisp library.
  The libraries are offered from `load-path'."
                           (get-text-property 0 'full-name x)))
                :keymap counsel-describe-map)))
  
+ (defun counsel--gg-candidates (regex)
+   "Return git grep candidates for REGEX."
+   (counsel--gg-count regex)
+   (let* ((default-directory counsel--git-grep-dir)
+          (counsel-gg-process " *counsel-gg*")
+          (proc (get-process counsel-gg-process))
+          (buff (get-buffer counsel-gg-process)))
+     (when proc
+       (delete-process proc))
+     (when buff
+       (kill-buffer buff))
+     (setq proc (start-process-shell-command
+                 counsel-gg-process
+                 counsel-gg-process
+                 (format "git --no-pager grep --full-name -n --no-color -i -e %S | head -n 200"
+                         regex)))
+     (set-process-sentinel
+      proc
+      #'counsel--gg-sentinel)))
+ (defun counsel--gg-sentinel (process event)
+   (if (string= event "finished\n")
+       (progn
+         (with-current-buffer (process-buffer process)
+           (setq ivy--all-candidates (split-string (buffer-string) "\n" t))
+           (setq ivy--old-cands ivy--all-candidates))
+         (unless (eq ivy--full-length -1)
+           (ivy--insert-minibuffer
+            (ivy--format ivy--all-candidates))))
+     (if (string= event "exited abnormally with code 1\n")
+         (message "Error"))))
+ (defun counsel--gg-count (regex &optional no-async)
+   "Quickly and asynchronously count the amount of git grep REGEX matches.
+ When NO-ASYNC is non-nil, do it synchronously."
+   (let ((default-directory counsel--git-grep-dir)
+         (cmd (format "git grep -i -c '%s' | sed 's/.*:\\(.*\\)/\\1/g' | awk '{s+=$1} END {print s}'"
+                      regex))
+         (counsel-ggc-process " *counsel-gg-count*"))
+     (if no-async
+         (string-to-number (shell-command-to-string cmd))
+       (let ((proc (get-process counsel-ggc-process))
+             (buff (get-buffer counsel-ggc-process)))
+         (when proc
+           (delete-process proc))
+         (when buff
+           (kill-buffer buff))
+         (setq proc (start-process-shell-command
+                     counsel-ggc-process
+                     counsel-ggc-process
+                     cmd))
+         (set-process-sentinel
+          proc
+          #'(lambda (process event)
+              (when (string= event "finished\n")
+                (with-current-buffer (process-buffer process)
+                  (setq ivy--full-length (string-to-number (buffer-string))))
+                (ivy--insert-minibuffer
+                 (ivy--format ivy--all-candidates)))))))))
+ (defun counsel--M-x-transformer (cmd)
+   "Add a binding to CMD if it's bound in the current window.
+ CMD is a command name."
+   (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")
+ (declare-function package-installed-p "package")
+ ;;;###autoload
+ (defun counsel-M-x (&optional initial-input)
+   "Ivy version of `execute-extended-command'.
+ Optional INITIAL-INPUT is the initial input in the minibuffer."
+   (interactive)
+   (unless initial-input
+     (setq initial-input (cdr (assoc this-command
+                                     ivy-initial-inputs-alist))))
+   (let* ((store ivy-format-function)
+          (ivy-format-function
+           (lambda (cands)
+             (funcall
+              store
+              (with-selected-window (ivy-state-window ivy-last)
+                (mapcar #'counsel--M-x-transformer cands)))))
+          (cands obarray)
+          (pred 'commandp)
+          (sort t))
+     (when (or (featurep 'smex)
+               (package-installed-p 'smex))
+       (require 'smex)
+       (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 "M-x " 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))
+                   (command-execute (intern cmd) 'record)))
+               :sort sort
+               :keymap counsel-describe-map
+               :initial-input initial-input)))
+ (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))
  (provide 'counsel)
  
  ;;; counsel.el ends here
index 0000000000000000000000000000000000000000,03e4d208204a7de9a158e93a66718c3931c7aecc..03e4d208204a7de9a158e93a66718c3931c7aecc
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,77 +1,77 @@@
+ ;;; ivy-hydra.el --- Additional key bindings for Ivy  -*- lexical-binding: t -*-
+ ;; 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/>.
+ ;;; Commentary:
+ ;;
+ ;; This package provides the `hydra-ivy/body' command, which is a
+ ;; quasi-prefix map, with many useful bindings.  These bindings are
+ ;; shorter than usual, using mostly unprefixed keys.
+ ;;; Code:
+ (require 'hydra nil t)
+ (require 'ivy)
+ (eval-when-compile
+   (unless (package-installed-p 'hydra)
+     (defmacro defhydra (name &rest _)
+       "This is a stub for the uninstalled `hydra' package."
+       `(defun ,(intern (format "%S/body" name)) ()
+          (interactive)
+          (let ((enable-recursive-minibuffers t))
+            (if (yes-or-no-p "Package `hydra' not installed. Install?")
+                (progn
+                  (package-install 'hydra)
+                  (save-window-excursion
+                    (find-library "ivy-hydra")
+                    (byte-compile-file (buffer-file-name) t)))
+              (error "Please install `hydra' and recompile/reinstall `ivy-hydra'")))))))
+ (defhydra hydra-ivy (:hint nil
+                      :color pink)
+   "
+ ^^^^^^          ^Yes^     ^No^     ^Maybe^
+ ^^^^^^^^^^^^^^---------------------------------------
+ ^ ^ _k_ ^ ^     _f_ollow  _i_nsert _c_: calling %s(if ivy-calling \"on\" \"off\")
+ _h_ ^+^ _l_     _d_one    _o_ops   _m_: matcher %s(if (eq ivy--regex-function 'ivy--regex-fuzzy) \"fuzzy\" \"ivy\")
+ ^ ^ _j_ ^ ^     ^ ^       ^ ^      _<_/_>_: shrink/grow window
+ "
+   ;; arrows
+   ("h" ivy-beginning-of-buffer)
+   ("j" ivy-next-line)
+   ("k" ivy-previous-line)
+   ("l" ivy-end-of-buffer)
+   ;; actions
+   ("o" keyboard-escape-quit :exit t)
+   ("C-g" keyboard-escape-quit :exit t)
+   ("i" nil)
+   ("C-o" nil)
+   ("f" ivy-alt-done :exit nil)
+   ("C-j" ivy-alt-done :exit nil)
+   ("d" ivy-done :exit t)
+   ("C-m" ivy-done :exit t)
+   ("c" ivy-toggle-calling)
+   ("m" ivy-toggle-fuzzy)
+   (">" ivy-minibuffer-grow)
+   ("<" ivy-minibuffer-shrink))
+ (provide 'ivy-hydra)
+ ;;; ivy-hydra.el ends here
index 91e0dc35d962cbc820cacfd8cbc804849dc0d74b,af0fc60b95fba572227fccbf66123cb183f19d6f..af0fc60b95fba572227fccbf66123cb183f19d6f
                   '("We're all Britons"
                    "and  I  am"
                     "your  king."))))
+ (ert-deftest ivy--regex-fuzzy ()
+   (should (string= (ivy--regex-fuzzy "tmux")
+                    "t.*m.*u.*x"))
+   (should (string= (ivy--regex-fuzzy "^tmux")
+                    "^t.*m.*u.*x"))
+   (should (string= (ivy--regex-fuzzy "^tmux$")
+                    "^t.*m.*u.*x$"))
+   (should (string= (ivy--regex-fuzzy "")
+                    ""))
+   (should (string= (ivy--regex-fuzzy "^")
+                    "^"))
+   (should (string= (ivy--regex-fuzzy "$")
+                    "$")))
+ (ert-deftest ivy--format ()
+   (should (string= (let ((ivy--index 10)
+                          (ivy-format-function (lambda (x) (mapconcat #'identity x "\n")))
+                          (cands '("NAME"
+                                   "SYNOPSIS"
+                                   "DESCRIPTION"
+                                   "FUNCTION LETTERS"
+                                   "SWITCHES"
+                                   "DIAGNOSTICS"
+                                   "EXAMPLE 1"
+                                   "EXAMPLE 2"
+                                   "EXAMPLE 3"
+                                   "SEE ALSO"
+                                   "AUTHOR")))
+                      (ivy--format cands))
+                    #("\nDESCRIPTION\nFUNCTION LETTERS\nSWITCHES\nDIAGNOSTICS\nEXAMPLE 1\nEXAMPLE 2\nEXAMPLE 3\nSEE ALSO\nAUTHOR"
+                      0 90 (read-only nil)
+                      90 96 (face ivy-current-match read-only nil)))))
diff --combined packages/swiper/ivy.el
index dd79848add8f8b7ad4f1a74b2308730acdbce887,f64782cb940acf76ac32332e21f8e9784c22dca2..f64782cb940acf76ac32332e21f8e9784c22dca2
--- 2/ivy.el
@@@ -102,7 -102,7 +102,7 @@@ Only \"./\" and \"../\" apply here. The
      (define-key map (kbd "<down>") 'ivy-next-line)
      (define-key map (kbd "<up>") 'ivy-previous-line)
      (define-key map (kbd "C-s") 'ivy-next-line-or-history)
-     (define-key map (kbd "C-r") 'ivy-previous-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-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)
+     (define-key map (kbd "M-j") 'ivy-yank-word)
+     (define-key map (kbd "M-i") 'ivy-insert-current)
+     (define-key map (kbd "C-o") 'hydra-ivy/body)
+     (define-key map (kbd "C-k") 'ivy-kill-line)
      map)
    "Keymap used in the minibuffer.")
+ (autoload 'hydra-ivy/body "ivy-hydra" "" t)
  
  (defvar ivy-mode-map
    (let ((map (make-sparse-keymap)))
@@@ -222,9 -227,9 +227,9 @@@ When non-nil, it should contain one %d.
    "Insert TEXT and exit minibuffer."
    (if (and ivy--directory
             (not (eq (ivy-state-history ivy-last) 'grep-files-history)))
-       (insert (expand-file-name
-                  text ivy--directory))
-     (insert text))
+       (insert (setq ivy--current (expand-file-name
+                                   text ivy--directory)))
+     (insert (setq ivy--current text)))
    (setq ivy-exit 'done)
    (exit-minibuffer))
  
@@@ -261,42 -266,65 +266,65 @@@ Is is a cons cell, related to `tramp-ge
        domain)))
  
  (declare-function tramp-get-completion-function "tramp")
+ (declare-function Info-find-node "info")
  
  (defun ivy-alt-done (&optional arg)
    "Exit the minibuffer with the selected candidate.
  When ARG is t, exit with current text, ignoring the candidates."
    (interactive "P")
-   (if arg
-       (ivy-immediate-done)
-     (let (dir)
-       (cond ((and ivy--directory
-                   (or
-                    (and
-                     (not (string= ivy--current "./"))
-                     (cl-plusp ivy--length)
-                     (file-directory-p
-                      (setq dir (expand-file-name
-                                 ivy--current ivy--directory))))))
-              (ivy--cd dir)
-              (ivy--exhibit))
-             ((string-match "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?" ivy-text)
-              (let ((method (match-string 1 ivy-text))
-                    (user (match-string 2 ivy-text))
-                    res)
-                (dolist (x (tramp-get-completion-function method))
-                  (setq res (append res (funcall (car x) (cadr x)))))
-                (setq res (delq nil res))
-                (when user
-                  (dolist (x res)
-                    (setcar x user)))
-                (setq res (cl-delete-duplicates res :test #'equal))
-                (let ((host (ivy-read "Find File: "
-                                      (mapcar #'ivy-build-tramp-name res))))
-                  (when host
-                    (setq ivy--directory "/")
-                    (ivy--cd (concat "/" method ":" host ":"))))))
-             (t
-              (ivy-done))))))
+   (let (dir)
+     (cond (arg
+            (ivy-immediate-done))
+           ((and ivy--directory
+                 (or
+                  (and
+                   (not (string= ivy--current "./"))
+                   (cl-plusp ivy--length)
+                   (file-directory-p
+                    (setq dir (expand-file-name
+                               ivy--current ivy--directory))))))
+            (ivy--cd dir)
+            (ivy--exhibit))
+           ((eq (ivy-state-collection ivy-last) 'Info-read-node-name-1)
+            (if (or (equal ivy--current "(./)")
+                    (equal ivy--current "(../)"))
+                (ivy-quit-and-run
+                 (ivy-read "Go to file: " 'read-file-name-internal
+                           :action (lambda (x)
+                                     (Info-find-node
+                                      (expand-file-name x ivy--directory)
+                                      "Top"))))
+              (ivy-done)))
+           ((and ivy--directory
+                 (string-match "\\`/[^/]+:.*:.*\\'" ivy-text))
+            (ivy-done))
+           ((and ivy--directory
+                 (string-match
+                  "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+                  ivy-text))
+            (let ((method (match-string 1 ivy-text))
+                  (user (match-string 2 ivy-text))
+                  (rest (match-string 3 ivy-text))
+                  res)
+              (require 'tramp)
+              (dolist (x (tramp-get-completion-function method))
+                (setq res (append res (funcall (car x) (cadr x)))))
+              (setq res (delq nil res))
+              (when user
+                (dolist (x res)
+                  (setcar x user)))
+              (setq res (cl-delete-duplicates res :test #'equal))
+              (let* ((old-ivy-last ivy-last)
+                     (enable-recursive-minibuffers t)
+                     (host (ivy-read "Find File: "
+                                     (mapcar #'ivy-build-tramp-name res)
+                                     :initial-input rest)))
+                (setq ivy-last old-ivy-last)
+                (when host
+                  (setq ivy--directory "/")
+                  (ivy--cd (concat "/" method ":" host ":"))))))
+           (t
+            (ivy-done)))))
  
  (defcustom ivy-tab-space nil
    "When non-nil, `ivy-partial-or-done' should insert a space."
@@@ -325,14 -353,20 +353,20 @@@ If the text hasn't changed as a result
    (let* ((parts (or (split-string ivy-text " " t) (list "")))
           (postfix (car (last parts)))
           (completion-ignore-case t)
-          (new (try-completion postfix
+          (startp (string-match "^\\^" postfix))
+          (new (try-completion (if startp
+                                   (substring postfix 1)
+                                 postfix)
                                (mapcar (lambda (str) (substring str (string-match postfix str)))
                                        ivy--old-cands))))
      (cond ((eq new t) nil)
            ((string= new ivy-text) nil)
            (new
             (delete-region (minibuffer-prompt-end) (point-max))
-            (setcar (last parts) new)
+            (setcar (last parts)
+                    (if startp
+                        (concat "^" new)
+                      new))
             (insert (mapconcat #'identity parts " ")
                     (if ivy-tab-space " " ""))
             t))))
     :require-match (ivy-state-require-match ivy-last)
     :initial-input ivy-text
     :history (ivy-state-history ivy-last)
-    :preselect (regexp-quote ivy--current)
+    :preselect (unless (eq (ivy-state-collection ivy-last)
+                           'read-file-name-internal)
+                 (regexp-quote ivy--current))
     :keymap (ivy-state-keymap ivy-last)
     :update-fn (ivy-state-update-fn ivy-last)
     :sort (ivy-state-sort ivy-last)
     :matcher (ivy-state-matcher ivy-last)
     :dynamic-collection (ivy-state-dynamic-collection ivy-last)))
  
+ (defvar ivy-calling nil
+   "When non-nil, call the current action when `ivy--index' changes.")
+ (defun ivy-set-index (index)
+   "Set `ivy--index' to INDEX."
+   (setq ivy--index index)
+   (when ivy-calling
+     (ivy--exhibit)
+     (ivy-call)))
  (defun ivy-beginning-of-buffer ()
    "Select the first completion candidate."
    (interactive)
-   (setq ivy--index 0))
+   (ivy-set-index 0))
  
  (defun ivy-end-of-buffer ()
    "Select the last completion candidate."
    (interactive)
-   (setq ivy--index (1- ivy--length)))
+   (ivy-set-index (1- ivy--length)))
  
  (defun ivy-scroll-up-command ()
    "Scroll the candidates upward by the minibuffer height."
    (interactive)
-   (setq ivy--index (min (+ ivy--index ivy-height)
-                         (1- ivy--length))))
+   (ivy-set-index (min (+ ivy--index ivy-height)
+                       (1- ivy--length))))
  
  (defun ivy-scroll-down-command ()
    "Scroll the candidates downward by the minibuffer height."
    (interactive)
-   (setq ivy--index (max (- ivy--index ivy-height)
-                         0)))
+   (ivy-set-index (max (- ivy--index ivy-height)
+                       0)))
+ (defun ivy-minibuffer-grow ()
+   "Grow the minibuffer window by 1 line"
+   (interactive)
+   (setq-local max-mini-window-height
+               (cl-incf ivy-height)))
+ (defun ivy-minibuffer-shrink ()
+   "Shrink the minibuffer window by 1 line."
+   (interactive)
+   (unless (<= ivy-height 2)
+     (setq-local max-mini-window-height
+                 (cl-decf ivy-height))
+     (window-resize (selected-window) -1)))
  
  (defun ivy-next-line (&optional arg)
    "Move cursor vertically down ARG candidates."
    (interactive "p")
    (setq arg (or arg 1))
-   (cl-incf ivy--index arg)
-   (when (>= ivy--index (1- ivy--length))
-     (if ivy-wrap
-         (ivy-beginning-of-buffer)
-       (setq ivy--index (1- ivy--length)))))
+   (let ((index (+ ivy--index arg)))
+     (if (> index (1- ivy--length))
+         (if ivy-wrap
+             (ivy-beginning-of-buffer)
+           (ivy-set-index (1- ivy--length)))
+       (ivy-set-index index))))
  
  (defun ivy-next-line-or-history (&optional arg)
    "Move cursor vertically down ARG candidates.
@@@ -409,11 -469,12 +469,12 @@@ If the input is empty, select the previ
    "Move cursor vertically up ARG candidates."
    (interactive "p")
    (setq arg (or arg 1))
-   (cl-decf ivy--index arg)
-   (when (< ivy--index 0)
-     (if ivy-wrap
-         (ivy-end-of-buffer)
-       (setq ivy--index 0))))
+   (let ((index (- ivy--index arg)))
+     (if (< index 0)
+         (if ivy-wrap
+             (ivy-end-of-buffer)
+           (ivy-set-index 0))
+       (ivy-set-index index))))
  
  (defun ivy-previous-line-or-history (arg)
    "Move cursor vertically up ARG candidates.
@@@ -423,15 -484,25 +484,25 @@@ If the input is empty, select the previ
      (ivy-previous-history-element 1))
    (ivy-previous-line arg))
  
+ (defun ivy-toggle-calling ()
+   "Flip `ivy-calling'"
+   (interactive)
+   (when (setq ivy-calling (not ivy-calling))
+     (ivy-call)))
+ (defun ivy-call ()
+   "Call the current action without exiting completion."
+   (when (ivy-state-action ivy-last)
+     (with-selected-window (ivy-state-window ivy-last)
+       (funcall (ivy-state-action ivy-last) ivy--current))))
  (defun ivy-next-line-and-call (&optional arg)
    "Move cursor vertically down ARG candidates.
  Call the permanent action if possible."
    (interactive "p")
    (ivy-next-line arg)
    (ivy--exhibit)
-   (when (ivy-state-action ivy-last)
-     (with-selected-window (ivy-state-window ivy-last)
-       (funcall (ivy-state-action ivy-last) ivy--current))))
+   (ivy-call))
  
  (defun ivy-previous-line-and-call (&optional arg)
    "Move cursor vertically down ARG candidates.
@@@ -439,14 -510,13 +510,13 @@@ Call the permanent action if possible.
    (interactive "p")
    (ivy-previous-line arg)
    (ivy--exhibit)
-   (when (ivy-state-action ivy-last)
-     (with-selected-window (ivy-state-window ivy-last)
-       (funcall (ivy-state-action ivy-last) ivy--current))))
+   (ivy-call))
  
  (defun ivy-previous-history-element (arg)
    "Forward to `previous-history-element' with ARG."
    (interactive "p")
    (previous-history-element arg)
+   (ivy--cd-maybe)
    (move-end-of-line 1)
    (ivy--maybe-scroll-history))
  
    "Forward to `next-history-element' with ARG."
    (interactive "p")
    (next-history-element arg)
+   (ivy--cd-maybe)
    (move-end-of-line 1)
    (ivy--maybe-scroll-history))
  
+ (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 (expand-file-name (ivy--input)))
+            (file (file-name-nondirectory input))
+            (dir (expand-file-name (file-name-directory input))))
+       (if (string= dir ivy--directory)
+           (progn
+             (delete-minibuffer-contents)
+             (insert file))
+         (ivy--cd dir)
+         (insert file)))))
  (defun ivy--maybe-scroll-history ()
    "If the selected history element has an index, scroll there."
    (let ((idx (ignore-errors
@@@ -514,6 -599,13 +599,13 @@@ On error (read-only), call `ivy-on-del-
    (unless (= (point) (line-end-position))
      (kill-word arg)))
  
+ (defun ivy-kill-line ()
+   "Forward to `kill-line'."
+   (interactive)
+   (if (eolp)
+       (kill-region (minibuffer-prompt-end) (point))
+     (kill-line)))
  (defun ivy-backward-kill-word ()
    "Forward to `backward-kill-word'."
    (interactive)
@@@ -551,9 -643,16 +643,16 @@@ Prioritize directories.
    '((read-file-name-internal . ivy-sort-file-function-default)
      (internal-complete-buffer . nil)
      (counsel-git-grep-function . nil)
+     (Man-goto-section . nil)
+     (org-refile . nil)
      (t . string-lessp))
    "An alist of sorting functions for each collection function.
- For each entry, nil means no sorting.
+ Interactive functions that call completion fit in here as well.
+ For each entry, nil means no sorting. It's very useful to turn
+ off the sorting for functions that have candidates in the natural
+ buffer order, like `org-refile' or `Man-goto-section'.
  The entry associated to t is used for all fall-through cases.")
  
  (defvar ivy-re-builders-alist
@@@ -572,6 -671,17 +671,17 @@@ The matches will be filtered in a seque
  regexps that should match and that should not match as you
  like.")
  
+ (defvar ivy-initial-inputs-alist
+   '((org-refile . "^")
+     (org-agenda-refile . "^")
+     (org-capture-refile . "^")
+     (counsel-M-x . "^")
+     (counsel-describe-function . "^")
+     (counsel-describe-variable . "^")
+     (man . "^")
+     (woman . "^"))
+   "Command to initial input table.")
  (defcustom ivy-sort-max-size 30000
    "Sorting won't be done for collections larger than this."
    :type 'integer)
@@@ -651,72 -761,120 +761,120 @@@ candidates with each input.
           :re-builder re-builder
           :matcher matcher
           :dynamic-collection dynamic-collection))
-   (setq ivy--directory nil)
-   (setq ivy--regex-function
-         (or re-builder
-             (and (functionp collection)
-                  (cdr (assoc collection ivy-re-builders-alist)))
-             (cdr (assoc t ivy-re-builders-alist))
-             'ivy--regex))
-   (setq ivy--subexps 0)
-   (setq ivy--regexp-quote 'regexp-quote)
-   (setq ivy--old-text "")
-   (setq ivy-text "")
-   (let (coll sort-fn)
-     (cond ((eq collection 'Info-read-node-name-1)
-            (if (equal Info-current-file "dir")
-                (setq coll
-                      (mapcar (lambda (x) (format "(%s)" x))
-                              (cl-delete-duplicates
-                               (all-completions "(" collection predicate)
-                               :test #'equal)))
-              (setq coll (all-completions "" collection predicate))))
-           ((eq collection 'read-file-name-internal)
-            (setq ivy--directory default-directory)
-            (require 'dired)
-            (setq coll
-                  (ivy--sorted-files default-directory))
-            (when initial-input
-              (unless (or require-match
-                          (equal initial-input default-directory))
-                (setq coll (cons initial-input coll)))
-              (setq initial-input nil)))
-           ((eq collection 'internal-complete-buffer)
-            (setq coll (ivy--buffer-list "" ivy-use-virtual-buffers)))
-           ((or (functionp collection)
-                (vectorp collection)
-                (listp (car collection)))
-            (setq coll (all-completions "" collection predicate)))
-           ((hash-table-p collection)
-            (error "Hash table as a collection unsupported"))
-           (t
-            (setq coll collection)))
-     (when sort
-       (if (and (functionp collection)
-                (setq sort-fn (assoc collection ivy-sort-functions-alist)))
-           (when (and (setq sort-fn (cdr sort-fn))
-                      (not (eq collection 'read-file-name-internal)))
-             (setq coll (cl-sort coll sort-fn)))
-         (unless (eq history 'org-refile-history)
-           (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))))))
-     (when preselect
-       (unless (or require-match
-                   (let ((re (format "\\`%s" preselect)))
-                     (cl-find-if (lambda (x) (string-match re x))
-                                 coll)))
-         (setq coll (cons preselect coll))))
-     (setq ivy--index (or
-                       (and dynamic-collection
-                            ivy--index)
-                       (and preselect
-                            (ivy--preselect-index
-                             coll initial-input preselect))
-                       0))
-     (setq ivy--old-re nil)
-     (setq ivy--old-cands nil)
-     (setq ivy--all-candidates coll)
+   (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)
+                     (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)))
+                    (set hist (cons (propertize item 'ivy-index ivy--index)
+                                    (delete item
+                                            (cdr (symbol-value hist))))))
+                  res)))
+         (remove-hook 'post-command-hook #'ivy--exhibit)
+         (when (setq unwind (ivy-state-unwind ivy-last))
+           (funcall unwind)))
+     (when (setq action (ivy-state-action ivy-last))
+       (funcall action ivy--current))))
+ (defun ivy--reset-state (state)
+   "Reset the ivy to STATE.
+ This is useful for recursive `ivy-read'."
+   (let ((prompt (ivy-state-prompt state))
+         (collection (ivy-state-collection state))
+         (predicate (ivy-state-predicate state))
+         (history (ivy-state-history state))
+         (preselect (ivy-state-preselect state))
+         (sort (ivy-state-sort state))
+         (re-builder (ivy-state-re-builder state))
+         (dynamic-collection (ivy-state-dynamic-collection state))
+         (initial-input (ivy-state-initial-input state))
+         (require-match (ivy-state-require-match state)))
+     (unless initial-input
+       (setq initial-input (cdr (assoc this-command
+                                       ivy-initial-inputs-alist))))
+     (setq ivy--directory nil)
+     (setq ivy--regex-function
+           (or re-builder
+               (and (functionp collection)
+                    (cdr (assoc collection ivy-re-builders-alist)))
+               (cdr (assoc t ivy-re-builders-alist))
+               'ivy--regex))
+     (setq ivy--subexps 0)
+     (setq ivy--regexp-quote 'regexp-quote)
+     (setq ivy--old-text "")
+     (setq ivy--full-length nil)
+     (setq ivy-text "")
+     (setq ivy-calling nil)
+     (let (coll sort-fn)
+       (cond ((eq collection 'Info-read-node-name-1)
+              (if (equal Info-current-file "dir")
+                  (setq coll
+                        (mapcar (lambda (x) (format "(%s)" x))
+                                (cl-delete-duplicates
+                                 (all-completions "(" collection predicate)
+                                 :test #'equal)))
+                (setq coll (all-completions "" collection predicate))))
+             ((eq collection 'read-file-name-internal)
+              (setq ivy--directory default-directory)
+              (require 'dired)
+              (setq coll
+                    (ivy--sorted-files default-directory))
+              (when initial-input
+                (unless (or require-match
+                            (equal initial-input default-directory)
+                            (equal initial-input ""))
+                  (setq coll (cons initial-input coll)))
+                (setq initial-input nil)))
+             ((eq collection 'internal-complete-buffer)
+              (setq coll (ivy--buffer-list "" ivy-use-virtual-buffers)))
+             ((or (functionp collection)
+                  (vectorp collection)
+                  (listp (car collection)))
+              (setq coll (all-completions "" collection predicate)))
+             ((hash-table-p collection)
+              (error "Hash table as a collection unsupported"))
+             (t
+              (setq coll collection)))
+       (when sort
+         (if (and (functionp collection)
+                  (setq sort-fn (assoc collection ivy-sort-functions-alist)))
+             (when (and (setq sort-fn (cdr sort-fn))
+                        (not (eq collection 'read-file-name-internal)))
+               (setq coll (cl-sort coll sort-fn)))
+           (unless (eq history 'org-refile-history)
+             (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))))))
+       (when preselect
+         (unless (or (and require-match
+                          (not (eq collection 'internal-complete-buffer)))
+                     (let ((re (format "\\`%s" (regexp-quote preselect))))
+                       (cl-find-if (lambda (x) (string-match re x))
+                                   coll)))
+           (setq coll (cons preselect coll))))
+       (setq ivy--index (or
+                         (and dynamic-collection
+                              ivy--index)
+                         (and preselect
+                              (ivy--preselect-index
+                               coll initial-input preselect))
+                         0))
+       (setq ivy--old-re nil)
+       (setq ivy--old-cands nil)
+       (setq ivy--all-candidates coll))
      (setq ivy-exit nil)
      (setq ivy--default (or (thing-at-point 'symbol) ""))
      (setq ivy--prompt
                   prompt)
                  (t
                   nil)))
-     (prog1
-         (unwind-protect
-              (minibuffer-with-setup-hook
-                  #'ivy--minibuffer-setup
-                (let* ((hist (or history 'ivy-history))
-                       (minibuffer-completion-table collection)
-                       (minibuffer-completion-predicate predicate)
-                       (res (read-from-minibuffer
-                             prompt
-                             initial-input
-                             (make-composed-keymap keymap ivy-minibuffer-map)
-                             nil
-                             hist)))
-                  (when (eq ivy-exit 'done)
-                    (set hist (cons (propertize ivy-text 'ivy-index ivy--index)
-                                    (delete ivy-text
-                                            (cdr (symbol-value hist)))))
-                    res)))
-           (remove-hook 'post-command-hook #'ivy--exhibit)
-           (when (setq unwind (ivy-state-unwind ivy-last))
-             (funcall unwind)))
-       (when (setq action (ivy-state-action ivy-last))
-         (funcall action ivy--current)))))
+     (setf (ivy-state-initial-input ivy-last) initial-input)))
  
  (defun ivy-completing-read (prompt collection
                              &optional predicate require-match initial-input
@@@ -779,7 -915,11 +915,11 @@@ The history, defaults and input-method 
              :preselect (if (listp def) (car def) def)
              :history history
              :keymap nil
-             :sort t))
+             :sort
+             (let ((sort (assoc this-command ivy-sort-functions-alist)))
+               (if sort
+                   (cdr sort)
+                 t))))
  
  ;;;###autoload
  (define-minor-mode ivy-mode
@@@ -918,6 -1058,15 +1058,15 @@@ Everything after \"!\" should not match
                 res)))
        (t (error "Unexpected: use only one !")))))
  
+ (defun ivy--regex-fuzzy (str)
+   "Build a regex sequence from STR.
+ Insert .* between each char."
+   (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str)
+       (concat (match-string 1 str)
+               (mapconcat #'string (string-to-list (match-string 2 str)) ".*")
+               (match-string 3 str))
+     str))
  ;;** Rest
  (defun ivy--minibuffer-setup ()
    "Setup ivy completion in the minibuffer."
    "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)
              (std-props '(front-sticky t rear-nonsticky t field t read-only t))
              (n-str
               (format
-               (concat head
-                       ivy--prompt-extra
-                       tail
-                       (if ivy--directory
-                           (abbreviate-file-name ivy--directory)
-                         ""))
+               (concat
+                (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
+                         (> (minibuffer-depth) 1))
+                    (format "[%d] " (minibuffer-depth))
+                  "")
+                head
+                ivy--prompt-extra
+                tail
+                (if ivy--directory
+                    (abbreviate-file-name ivy--directory)
+                  ""))
                (or (and (ivy-state-dynamic-collection ivy-last)
                         ivy--full-length)
                    ivy--length))))
@@@ -1002,19 -1156,28 +1156,28 @@@ Should be run via minibuffer `post-comm
        ;; while-no-input would cause annoying
        ;; "Waiting for process to die...done" message interruptions
        (let ((inhibit-message t))
-         (while-no-input
-           (unless (equal ivy--old-text ivy-text)
-             (cl-letf ((store (ivy-state-dynamic-collection ivy-last))
-                       ((ivy-state-dynamic-collection ivy-last) nil))
-               (setq ivy--all-candidates (funcall store ivy-text))))
-           (ivy--insert-minibuffer (ivy--format ivy--all-candidates))))
+         (unless (equal ivy--old-text ivy-text)
+           (while-no-input
+             ;; dynamic collection should take care of everything
+             (funcall (ivy-state-dynamic-collection ivy-last) ivy-text)
+             (setq ivy--old-text ivy-text)))
+         (unless (eq ivy--full-length -1)
+           (ivy--insert-minibuffer
+            (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)
-                    (ivy--cd "/")))
-              (if (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)))))
+              (if (string-match "\\`~\\'" ivy-text)
                   (ivy--cd (expand-file-name "~/")))))
            ((eq (ivy-state-collection ivy-last) 'internal-complete-buffer)
             (when (or (and (string-match "\\` " ivy-text)
               (setq ivy--old-re nil))))
      (ivy--insert-minibuffer
       (ivy--format
-       (ivy--filter ivy-text ivy--all-candidates))))
-   (setq ivy--old-text ivy-text))
+       (ivy--filter ivy-text ivy--all-candidates)))
+     (setq ivy--old-text ivy-text)))
  
  (defun ivy--insert-minibuffer (text)
    "Insert TEXT into minibuffer with appropriate cleanup."
    (let ((resize-mini-windows nil)
-         (buffer-undo-list t)
          (update-fn (ivy-state-update-fn ivy-last))
          deactivate-mark)
      (ivy--cleanup)
      (ivy--insert-prompt)
      ;; Do nothing if while-no-input was aborted.
      (when (stringp text)
-       (save-excursion
-         (forward-line 1)
-         (insert text)))))
+       (let ((buffer-undo-list t))
+         (save-excursion
+           (forward-line 1)
+           (insert text))))))
  
  (declare-function colir-blend-face-background "ext:colir")
  
@@@ -1070,8 -1233,7 +1233,7 @@@ CANDIDATES are assumed to be static.
           (matcher (ivy-state-matcher ivy-last))
           (cands (cond
                    (matcher
-                    (let ((ivy--old-re re))
-                      (cl-remove-if-not matcher candidates)))
+                    (funcall matcher re candidates))
                    ((and (equal re ivy--old-re)
                          ivy--old-cands)
                     ivy--old-cands)
                       res))))
           (tail (nthcdr ivy--index ivy--old-cands))
           idx)
-     (when (and tail ivy--old-cands)
+     (when (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
        (unless (and (not (equal re ivy--old-re))
                     (or (setq ivy--index
                               (or
@@@ -1148,8 -1310,8 +1310,8 @@@ This string will be inserted into the m
      (mapconcat
       (lambda (s)
         (concat (if (eq (cl-incf i) ivy--index)
-                    "==> "
-                  "    ")
+                    "> "
+                  "  ")
                 s))
       cands "\n")))
  
@@@ -1164,8 -1326,9 +1326,9 @@@ CANDS is a list of strings.
      (let* ((half-height (/ ivy-height 2))
             (start (max 0 (- ivy--index half-height)))
             (end (min (+ start (1- ivy-height)) ivy--length))
+            (start (max 0 (min start (- end (1- ivy-height)))))
             (cands (cl-subseq cands start end))
-            (index (min ivy--index half-height (1- (length cands)))))
+            (index (- ivy--index start)))
        (when ivy--directory
          (setq cands (mapcar (lambda (x)
                                (if (string-match-p "/\\'" x)
        (setq ivy--current (copy-sequence (nth index cands)))
        (setf (nth index cands)
              (ivy--add-face ivy--current 'ivy-current-match))
+       (setq cands (mapcar
+                    (lambda (s)
+                      (let ((s (copy-sequence s)))
+                        (when (fboundp 'add-face-text-property)
+                          (add-face-text-property
+                           0 (length s)
+                           `(:height ,(face-attribute 'default :height)
+                                     :overline nil) nil s))
+                        s))
+                    cands))
        (let* ((ivy--index index)
               (res (concat "\n" (funcall ivy-format-function cands))))
          (put-text-property 0 (length res) 'read-only nil res)
    "Store the virtual buffers alist.")
  
  (defvar recentf-list)
- (defvar ido-use-faces)
+ (defface ivy-virtual '((t :inherit font-lock-builtin-face))
+   "Face used by Ivy for matching virtual buffer names.")
  
  (defun ivy--virtual-buffers ()
    "Adapted from `ido-add-virtual-buffers-to-list'."
             (not (assoc name virtual-buffers))
             (push (cons name head) virtual-buffers)))
      (when virtual-buffers
-       (if ido-use-faces
-           (dolist (comp virtual-buffers)
-             (put-text-property 0 (length (car comp))
-                                'face 'ido-virtual
-                                (car comp))))
+       (dolist (comp virtual-buffers)
+         (put-text-property 0 (length (car comp))
+                            'face 'ivy-virtual
+                            (car comp)))
        (setq ivy--virtual-buffers (nreverse virtual-buffers))
        (mapcar #'car ivy--virtual-buffers))))
  
@@@ -1240,7 -1414,8 +1414,8 @@@ BUFFER may be a string or nil.
        (switch-to-buffer
         ivy-text nil 'force-same-window)
      (let ((virtual (assoc buffer ivy--virtual-buffers)))
-       (if virtual
+       (if (and virtual
+                (not (get-buffer buffer)))
            (find-file (cdr virtual))
          (switch-to-buffer
           buffer nil 'force-same-window)))))
                :preselect (buffer-name (other-buffer (current-buffer)))
                :action #'ivy--switch-buffer-action)))
  
+ (defun ivy-recentf ()
+   "Find a file on `recentf-list'."
+   (interactive)
+   (ivy-read "Recentf: " recentf-list
+             :action #'find-file))
+ (defun ivy-yank-word ()
+   "Pull next word from buffer into search string."
+   (interactive)
+   (let (amend)
+     (with-selected-window (ivy-state-window ivy-last)
+       (let ((pt (point))
+             (le (line-end-position)))
+         (forward-word 1)
+         (if (> (point) le)
+             (goto-char pt)
+           (setq amend (buffer-substring-no-properties pt (point))))))
+     (when amend
+       (insert amend))))
+ (defun ivy-insert-current ()
+   "Make the current candidate into current input.
+ Don't finish completion."
+   (interactive)
+   (delete-minibuffer-contents)
+   (if (and ivy--directory
+            (string-match "/$" ivy--current))
+       (insert (substring ivy--current 0 -1))
+     (insert ivy--current)))
+ (defun ivy-toggle-fuzzy ()
+   "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'."
+   (interactive)
+   (setq ivy--old-re nil)
+   (if (eq ivy--regex-function 'ivy--regex-fuzzy)
+       (setq ivy--regex-function 'ivy--regex-plus)
+     (setq ivy--regex-function 'ivy--regex-fuzzy)))
+ (defun ivy-reverse-i-search ()
+   "Enter a recursive `ivy-read' session using the current history.
+ The selected history element will be inserted into the minibufer."
+   (interactive)
+   (let ((enable-recursive-minibuffers t)
+         (history (symbol-value (ivy-state-history ivy-last)))
+         (old-last ivy-last))
+     (ivy-read "Reverse-i-search: "
+               history
+               :action (lambda (x)
+                         (ivy--reset-state
+                          (setq ivy-last old-last))
+                         (delete-minibuffer-contents)
+                         (insert (substring-no-properties x))
+                         (ivy--cd-maybe)))))
  (provide 'ivy)
  
  ;;; ivy.el ends here
index 2f95a312c43cd7dc629be2579dd08425a813c4c8,1975ae2d0aad873887fb64057d8df873d9c6f800..1975ae2d0aad873887fb64057d8df873d9c6f800
@@@ -4,7 -4,7 +4,7 @@@
  
  ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
  ;; URL: https://github.com/abo-abo/swiper
- ;; Version: 0.4.1
+ ;; Version: 0.5.1
  ;; Package-Requires: ((emacs "24.1"))
  ;; Keywords: matching
  
        (delete-minibuffer-contents)
        (ivy-set-action (lambda (_)
                          (with-selected-window swiper--window
+                           (move-beginning-of-line 1)
                            (perform-replace from to
                                             t t nil))))
        (swiper--cleanup)
        (exit-minibuffer))))
  
  (defvar avy-background)
+ (defvar avy-all-windows)
  (declare-function avy--regex-candidates "ext:avy")
  (declare-function avy--process "ext:avy")
  (declare-function avy--overlay-post "ext:avy")
  (defun swiper-avy ()
    "Jump to one of the current swiper candidates."
    (interactive)
-   (with-selected-window (ivy-state-window ivy-last)
-     (let* ((candidates
-             (avy--regex-candidates
-              (ivy--regex ivy-text)))
-            (avy-background nil)
-            (candidate
-             (avy--process candidates #'avy--overlay-post)))
-       (ivy-quit-and-run
-        (avy--goto candidate)))))
+   (unless (string= ivy-text "")
+     (with-selected-window (ivy-state-window ivy-last)
+       (let* ((avy-all-windows nil)
+              (candidates
+               (avy--regex-candidates
+                (ivy--regex ivy-text)))
+              (avy-background nil)
+              (candidate
+               (avy--process candidates #'avy--overlay-post)))
+         (ivy-quit-and-run
+          (avy--goto candidate))))))
  
  (defun swiper-recenter-top-bottom (&optional arg)
    "Call (`recenter-top-bottom' ARG) in `swiper--window'."
  (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
@@@ -192,7 -197,6 +197,6 @@@ When non-nil, INITIAL-INPUT is the init
  
  (defun swiper--init ()
    "Perform initialization common to both completion methods."
-   (deactivate-mark)
    (setq swiper--opoint (point))
    (setq swiper--len 0)
    (setq swiper--anchor (line-number-at-pos))
@@@ -219,6 -223,9 +223,9 @@@ there have line numbers. In the buffer
      (t
       (ivy--regex-plus str))))
  
+ (defvar swiper-history nil
+   "History for `swiper'.")
  (defun swiper--ivy (&optional initial-input)
    "`isearch' with an overview using `ivy'.
  When non-nil, INITIAL-INPUT is the initial search pattern."
@@@ -231,10 -238,9 +238,9 @@@ Please remove it and update the \"swipe
          (preselect (format
                      swiper--format-spec
                      (line-number-at-pos)
-                     (regexp-quote
-                      (buffer-substring-no-properties
-                       (line-beginning-position)
-                       (line-end-position)))))
+                     (buffer-substring-no-properties
+                      (line-beginning-position)
+                      (line-end-position))))
          res)
      (unwind-protect
           (setq res (ivy-read
                      :require-match t
                      :update-fn #'swiper--update-input-ivy
                      :unwind #'swiper--cleanup
-                     :re-builder #'swiper--re-builder))
+                     :re-builder #'swiper--re-builder
+                     :history 'swiper-history))
        (if (null ivy-exit)
            (goto-char swiper--opoint)
          (swiper--action res ivy-text)))))
        (when (cl-plusp num)
          (goto-char (point-min))
          (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))
          (isearch-range-invisible (line-beginning-position)
                                   (line-end-position))
          (unless (and (>= (point) (window-start))