emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master f5dac47 63/63: Merge commit '09f86fca437f1b2e168093824e9d4


From: Oleh Krehel
Subject: [elpa] master f5dac47 63/63: Merge commit '09f86fca437f1b2e168093824e9d4ee0aea5130a' from swiper
Date: Fri, 21 Aug 2015 12:08:50 +0000

branch: master
commit f5dac473c5461c4834431feac50ea18b6948d4df
Merge: b0039dd 09f86fc
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Merge commit '09f86fca437f1b2e168093824e9d4ee0aea5130a' from swiper
---
 packages/swiper/counsel.el        |  379 ++++++++++++++++++++++++++++++-------
 packages/swiper/doc/Changelog.org |  296 +++++++++++++++++++++++++++++
 packages/swiper/ivy-hydra.el      |   15 +-
 packages/swiper/ivy-test.el       |    8 +
 packages/swiper/ivy.el            |  363 ++++++++++++++++++++++++++---------
 packages/swiper/swiper.el         |  117 ++++++------
 6 files changed, 961 insertions(+), 217 deletions(-)

diff --git a/packages/swiper/counsel.el b/packages/swiper/counsel.el
index 94c8608..63c9552 100644
--- a/packages/swiper/counsel.el
+++ b/packages/swiper/counsel.el
@@ -34,6 +34,12 @@
 
 (require 'swiper)
 
+(defvar counsel-completion-beg nil
+  "Completion bounds start.")
+
+(defvar counsel-completion-end nil
+  "Completion bounds end.")
+
 ;;;###autoload
 (defun counsel-el ()
   "Elisp completion at point."
@@ -75,12 +81,6 @@
               :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)
@@ -142,6 +142,16 @@
              (match-string 1 s)
            s))))
 
+(defun counsel-variable-list ()
+  "Return the list of all currently bound variables."
+  (let (cands)
+    (mapatoms
+     (lambda (vv)
+       (when (or (get vv 'variable-documentation)
+                 (and (boundp vv) (not (keywordp vv))))
+         (push (symbol-name vv) cands))))
+    cands))
+
 ;;;###autoload
 (defun counsel-describe-variable ()
   "Forward to `describe-variable'."
@@ -149,13 +159,7 @@
   (let ((enable-recursive-minibuffers t))
     (ivy-read
      "Describe variable: "
-     (let (cands)
-       (mapatoms
-        (lambda (vv)
-          (when (or (get vv 'variable-documentation)
-                    (and (boundp vv) (not (keywordp vv))))
-            (push (symbol-name vv) cands))))
-       cands)
+     (counsel-variable-list)
      :keymap counsel-describe-map
      :preselect (counsel-symbol-at-point)
      :history 'counsel-describe-symbol-history
@@ -165,6 +169,16 @@
                (describe-variable
                 (intern x))))))
 
+(ivy-set-actions
+ 'counsel-describe-variable
+ '(("i" counsel-info-lookup-symbol "info")
+   ("d" counsel--find-symbol "definition")))
+
+(ivy-set-actions
+ 'counsel-describe-function
+ '(("i" counsel-info-lookup-symbol "info")
+   ("d" counsel--find-symbol "definition")))
+
 ;;;###autoload
 (defun counsel-describe-function ()
   "Forward to `describe-function'."
@@ -262,24 +276,21 @@
 (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)))))
+
 (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))
-      (progn
-        (setq ivy--full-length counsel--git-grep-count)
-        (list ""
-              (format "%d chars more" (- 3 (length ivy-text)))))
+      (counsel-more-chars 3)
     (let* ((default-directory counsel--git-grep-dir)
            (cmd (format "git --no-pager grep --full-name -n --no-color -i -e 
%S"
-                        (ivy--regex string t)))
-           res)
+                        (ivy--regex string t))))
       (if (<= counsel--git-grep-count 20000)
-          (progn
-            (setq res (shell-command-to-string cmd))
-            (setq ivy--full-length nil)
-            (split-string res "\n" t))
-        (setq ivy--full-length -1)
+          (split-string (shell-command-to-string cmd) "\n" t)
         (counsel--gg-candidates (ivy--regex string))
         nil))))
 
@@ -290,40 +301,40 @@
 
 (defun counsel-git-grep-recenter ()
   (interactive)
-  (with-selected-window (ivy-state-window ivy-last)
+  (with-ivy-window
     (counsel-git-grep-action ivy--current)
     (recenter-top-bottom)))
 
 (defun counsel-git-grep-action (x)
   (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))))))
+    (with-ivy-window
+      (let ((file-name (match-string-no-properties 1 x))
+            (line-number (match-string-no-properties 2 x)))
+        (find-file (expand-file-name file-name counsel--git-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)
+          (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."
+  "Grep for a string in the current git repository.
+INITIAL-INPUT can be given as the initial minibuffer input."
   (interactive)
   (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 "pattern: " 'counsel-git-grep-function
+    (ivy-read "git grep: " 'counsel-git-grep-function
               :initial-input initial-input
               :matcher #'counsel-git-grep-matcher
-              :dynamic-collection (when (> counsel--git-grep-count 20000)
-                                    'counsel-git-grep-function)
+              :dynamic-collection (> counsel--git-grep-count 20000)
               :keymap counsel-git-grep-map
               :action #'counsel-git-grep-action
               :unwind #'swiper--cleanup
@@ -336,6 +347,8 @@
 
 (declare-function ffap-guesser "ffap")
 
+(defvar counsel-find-file-map (make-sparse-keymap))
+
 ;;;###autoload
 (defun counsel-find-file ()
   "Forward to `find-file'."
@@ -344,12 +357,14 @@
             :matcher #'counsel--find-file-matcher
             :action
             (lambda (x)
-              (find-file (expand-file-name x ivy--directory)))
+              (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))
+            :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'.
@@ -397,13 +412,6 @@ Skip some dotfiles unless `ivy-text' requires them."
                  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))))
-    (counsel--async-command
-     (concat "locate -i --regex " (ivy--regex str)))))
-
 (defun counsel--async-command (cmd)
   (let* ((counsel--process " *counsel*")
          (proc (get-process counsel--process))
@@ -424,20 +432,50 @@ Skip some dotfiles unless `ivy-text' requires them."
         (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)))
+        (ivy--exhibit))
     (if (string= event "exited abnormally with code 1\n")
-        (message "Error"))))
+        (progn
+          (setq ivy--all-candidates '("Error"))
+          (setq ivy--old-cands ivy--all-candidates)
+          (ivy--exhibit)))))
+
+(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 "xdg-open %s" (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'.")
+
+(ivy-set-actions
+ 'counsel-locate
+ '(("x" counsel-locate-action-extern "xdg-open")
+   ("d" counsel-locate-action-dired "dired")))
+
+(defun counsel-locate-function (str &rest _u)
+  (if (< (length str) 3)
+      (counsel-more-chars 3)
+    (counsel--async-command
+     (concat "locate -i --regex " (ivy--regex str)))
+    '("" "working...")))
 
 ;;;###autoload
 (defun counsel-locate ()
-  "Call locate."
+  "Call locate shell command."
   (interactive)
-  (ivy-read "pattern: " nil
-            :dynamic-collection #'counsel-locate-function
-            :action (lambda (val)
-                      (when val
-                        (find-file val)))))
+  (ivy-read "Locate: " #'counsel-locate-function
+            :dynamic-collection t
+            :history 'counsel-locate-history
+            :action (lambda (file)
+                      (when file
+                        (find-file file)))))
 
 (defun counsel--generic (completion-fn)
   "Complete thing at point with COMPLETION-FN."
@@ -517,8 +555,12 @@ The libraries are offered from `load-path'."
                          (get-text-property 0 'full-name x)))
               :keymap counsel-describe-map)))
 
+(defvar counsel-gg-state nil
+  "The current state of candidates / count sync.")
+
 (defun counsel--gg-candidates (regex)
   "Return git grep candidates for REGEX."
+  (setq counsel-gg-state -2)
   (counsel--gg-count regex)
   (let* ((default-directory counsel--git-grep-dir)
          (counsel-gg-process " *counsel-gg*")
@@ -543,11 +585,13 @@ The libraries are offered from `load-path'."
         (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))))
+        (when (= 0 (cl-incf counsel-gg-state))
+          (ivy--exhibit)))
     (if (string= event "exited abnormally with code 1\n")
-        (message "Error"))))
+        (progn
+          (setq ivy--all-candidates '("Error"))
+          (setq ivy--old-cands ivy--all-candidates)
+          (ivy--exhibit)))))
 
 (defun counsel--gg-count (regex &optional no-async)
   "Quickly and asynchronously count the amount of git grep REGEX matches.
@@ -574,8 +618,8 @@ When NO-ASYNC is non-nil, do it synchronously."
              (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)))))))))
+               (when (= 0 (cl-incf counsel-gg-state))
+                 (ivy--exhibit)))))))))
 
 (defun counsel--M-x-transformer (cmd)
   "Add a binding to CMD if it's bound in the current window.
@@ -608,7 +652,7 @@ Optional INITIAL-INPUT is the initial input in the 
minibuffer."
           (lambda (cands)
             (funcall
              store
-             (with-selected-window (ivy-state-window ivy-last)
+             (with-ivy-window
                (mapcar #'counsel--M-x-transformer cands)))))
          (cands obarray)
          (pred 'commandp)
@@ -660,6 +704,213 @@ Usable with `ivy-resume', `ivy-next-line-and-call' and
                     (custom-available-themes))
             :action #'counsel--load-theme-action))
 
+(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-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))))
+
+(defvar counsel-rhythmbox-history nil
+  "History for `counsel-rhythmbox'.")
+
+;;;###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 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"))))
+
+(defvar counsel-org-tags nil
+  "Store the current list of tags.")
+
+(defvar org-outline-regexp)
+(defvar org-indent-mode)
+(defvar org-indent-indentation-per-level)
+(defvar org-tags-column)
+(declare-function org-get-tags-string "org")
+(declare-function org-move-to-column "org")
+
+(defun counsel-org-change-tags (tags)
+  (let ((current (org-get-tags-string))
+        (col (current-column))
+        level)
+    ;; Insert new tags at the correct column
+    (beginning-of-line 1)
+    (setq level (or (and (looking-at org-outline-regexp)
+                         (- (match-end 0) (point) 1))
+                    1))
+    (cond
+      ((and (equal current "") (equal tags "")))
+      ((re-search-forward
+        (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$")
+        (point-at-eol) t)
+       (if (equal tags "")
+           (delete-region
+            (match-beginning 0)
+            (match-end 0))
+         (goto-char (match-beginning 0))
+         (let* ((c0 (current-column))
+                ;; compute offset for the case of org-indent-mode active
+                (di (if (bound-and-true-p org-indent-mode)
+                        (* (1- org-indent-indentation-per-level) (1- level))
+                      0))
+                (p0 (if (equal (char-before) ?*) (1+ (point)) (point)))
+                (tc (+ org-tags-column (if (> org-tags-column 0) (- di) di)))
+                (c1 (max (1+ c0) (if (> tc 0) tc (- (- tc) (string-width 
tags)))))
+                (rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags)))
+           (replace-match rpl t t)
+           (and c0 indent-tabs-mode (tabify p0 (point)))
+           tags)))
+      (t (error "Tags alignment failed")))
+    (org-move-to-column col)))
+
+(defun counsel-org-tag-action (x)
+  (if (member x counsel-org-tags)
+      (progn
+        (setq counsel-org-tags (delete x counsel-org-tags)))
+    (setq counsel-org-tags (append counsel-org-tags (list x)))
+    (unless (member x ivy--all-candidates)
+      (setq ivy--all-candidates (append ivy--all-candidates (list x)))))
+  (let ((prompt (counsel-org-tag-prompt)))
+    (setf (ivy-state-prompt ivy-last) prompt)
+    (setq ivy--prompt (concat "%-4d " prompt)))
+  (cond ((memq this-command '(ivy-done ivy-alt-done))
+         (counsel-org-change-tags
+          (if counsel-org-tags
+              (format ":%s:"
+                      (mapconcat #'identity counsel-org-tags ":"))
+            "")))
+        ((eq this-command 'ivy-call)
+         (delete-minibuffer-contents))))
+
+(defun counsel-org-tag-prompt ()
+  (format "Tags (%s): "
+          (mapconcat #'identity counsel-org-tags ", ")))
+
+(defvar org-setting-tags)
+(defvar org-last-tags-completion-table)
+(defvar org-tag-persistent-alist)
+(defvar org-tag-alist)
+(defvar org-complete-tags-always-offer-all-agenda-tags)
+
+(declare-function org-at-heading-p "org")
+(declare-function org-back-to-heading "org")
+(declare-function org-get-buffer-tags "org")
+(declare-function org-global-tags-completion-table "org")
+(declare-function org-agenda-files "org")
+(declare-function org-agenda-set-tags "org-agenda")
+
+;;;###autoload
+(defun counsel-org-tag ()
+  "Add or remove tags in org-mode."
+  (interactive)
+  (save-excursion
+    (unless (org-at-heading-p)
+      (org-back-to-heading t))
+    (setq counsel-org-tags (split-string (org-get-tags-string) ":" t))
+    (let ((org-setting-tags t)
+          (org-last-tags-completion-table
+           (append org-tag-persistent-alist
+                   (or org-tag-alist (org-get-buffer-tags))
+                   (and
+                    org-complete-tags-always-offer-all-agenda-tags
+                    (org-global-tags-completion-table
+                     (org-agenda-files))))))
+      (ivy-read (counsel-org-tag-prompt)
+                (lambda (str &rest _unused)
+                  (delete-dups
+                   (all-completions str 'org-tags-completion-function)))
+                :history 'org-tags-history
+                :action 'counsel-org-tag-action))))
+
+;;;###autoload
+(defun counsel-org-tag-agenda ()
+  "Set tags for the current agenda item."
+  (interactive)
+  (let ((store (symbol-function 'org-set-tags)))
+    (unwind-protect
+         (progn
+           (fset 'org-set-tags
+                 (symbol-function 'counsel-org-tag))
+           (org-agenda-set-tags nil nil))
+      (fset 'org-set-tags store))))
+
+(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 ((regex (replace-regexp-in-string
+                  "\\\\)" ")"
+                  (replace-regexp-in-string
+                   "\\\\(" "("
+                   (ivy--regex string)))))
+      (counsel--async-command
+       (format "ag --noheading --nocolor %S" regex))
+      nil)))
+
+(defun counsel-ag (&optional initial-input)
+  "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 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 #'swiper--cleanup))
+
+(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)))))))
 
 (provide 'counsel)
 
diff --git a/packages/swiper/doc/Changelog.org 
b/packages/swiper/doc/Changelog.org
new file mode 100644
index 0000000..0f5ac2c
--- /dev/null
+++ b/packages/swiper/doc/Changelog.org
@@ -0,0 +1,296 @@
+#+OPTIONS: toc:nil
+* 0.6.0
+** Fixes
+*** =swiper-avy= should use only the current window
+Not all windows. See [[https://github.com/abo-abo/swiper/issues/117][#117]].
+*** fix wrap-around for =ivy-next-line=
+See [[https://github.com/abo-abo/swiper/issues/118][#118]].
+*** =swiper-avy= should do nothing for empty input
+See [[https://github.com/abo-abo/avy/issues/50][#50]].
+*** =ivy-alt-done= should require TRAMP if necessary
+See [[https://github.com/abo-abo/swiper/pull/145][#145]].
+*** =swiper-query-replace= shouldn't miss the first occurrence
+See [[https://github.com/abo-abo/swiper/pull/144][#144]].
+*** =swiper= should not deactivate mark
+*** =ivy-mode= should not switch to TRAMP for certain input
+See [[https://github.com/abo-abo/swiper/pull/145][#145]].
+*** =counsel-find-file= should work better with TRAMP
+"/ssh:foo" should not be cut off
+See [[https://github.com/abo-abo/swiper/pull/145][#145]].
+*** =counsel-find-file= supports Windows drive letters
+See [[https://github.com/abo-abo/swiper/pull/155][#155]].
+*** =counsel-file-file= should work better with files that contain "~"
+See [[https://github.com/abo-abo/swiper/pull/157][#157]].
+*** =counsel-M-x= should respect =ivy-format-function=
+See [[https://github.com/abo-abo/swiper/pull/150][#150]].
+*** =counsel-git-grep= should position better on exit
+See [[https://github.com/abo-abo/swiper/pull/153][#153]].
+*** =ivy-mode= should re-scale text to minibuffer height
+See [[https://github.com/abo-abo/swiper/pull/151][#151]].
+*** =counsel-unicode-char= should use action-style call
+See [[https://github.com/abo-abo/swiper/pull/160][#160]].
+*** =ivy-read= should allow % in prompt string
+See [[https://github.com/abo-abo/swiper/pull/171][#171]].
+*** =ivy-call= should execute in proper window
+See [[https://github.com/abo-abo/swiper/pull/176][#176]].
+** New Features
+*** =ivy-mode=
+**** Open an Info file on the file system
+When in =Info-mode=, press ~g~ and select either "(./)" or "(../)" to
+switch to file name completion. That file will be opened with Info.
+**** Account for =minibuffer-depth-indication-mode=
+If you have =minibuffer-depth-indication-mode= on, the minibuffer
+prompt will indicate the current depth.
+See [[https://github.com/abo-abo/swiper/pull/134][#134]].
+**** Add fuzzy matching function
+To enable fuzzy matching, set your =ivy-re-builders-alist= accordingly:
+#+begin_src elisp
+(setq ivy-re-builders-alist
+      '((t . ivy--regex-fuzzy)))
+#+end_src
+See [[https://github.com/abo-abo/swiper/pull/136][#136]].
+
+See also [[https://github.com/abo-abo/swiper/pull/142][#142]] for toggling 
fuzzy matching with ~C-o m~.
+**** =case-fold-search= optimization
+Bind case-fold-search to t when the input is all lower-case:
+
+- input "the" matches both "the" and "The".
+- input "The" matches only "The".
+
+See [[https://github.com/abo-abo/swiper/pull/166][#166]].
+**** Allow to see the candidate index a la =anzu= via =ivy-count-format=
+To have this feature, use something like this:
+#+begin_src elisp
+(setq ivy-count-format "(%d/%d) ")
+#+end_src
+See [[https://github.com/abo-abo/swiper/pull/167][#167]].
+
+You can also set this to nil, if you don't want any count, see 
[[https://github.com/abo-abo/swiper/pull/188][#188]].
+**** Allow to add additional exit points for any command
+Example for =ivy-switch-to-buffer=:
+#+begin_src elisp
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("k"
+    (lambda (x)
+      (kill-buffer x)
+      (ivy--reset-state ivy-last))
+    "kill")
+   ("j"
+    ivy--switch-buffer-other-window-action
+    "other")))
+#+end_src
+
+After this:
+
+- use ~M-o k~ to kill a buffer
+- use ~M-o j~ to switch to a buffer in other window
+
+You can always use ~M-o o~ to access the default action. When there is
+only one action, ~M-o~ does the same as ~C-m~.
+
+See [[https://github.com/abo-abo/swiper/pull/164][#164]].
+
+
+
+
+
+
+
+
+*** =counsel-describe-function= and =counsel-decribe-variable=
+**** Add a binding to look up the symbol in info
+Press ~C-,~ to look up the symbol in info, instead of the default
+describe action.
+See [[https://github.com/abo-abo/swiper/pull/121][#121]].
+**** Handle symbol-at-point better in non-Elisp buffers
+See [[https://github.com/abo-abo/swiper/pull/126][#126]].
+*** =ivy-switch-buffer=
+**** New face =ivy-virtual=
+See [[https://github.com/abo-abo/swiper/pull/129][#129]].
+**** Deal better with invisible buffers
+See [[https://github.com/abo-abo/swiper/pull/135][#135]].
+**** Add custom keymap
+You can customize =ivy-switch-buffer-map=.
+
+See [[https://github.com/abo-abo/swiper/pull/164][#164]].
+**** Add extra actions
+Add a =kill-buffer= action, and =switch-to-buffer-other-window= action.
+*** =counsel-git-grep=
+**** Add Async
+Make it fully async: the process =git grep= will be killed and
+restarted on new input. This results in almost no keyboard delay.
+**** Own history variable
+*** =swiper=
+**** Own history variable
+Having own history variable allows to get more use of ~M-p~, ~M-n~ and ~C-r~.
+*** =counsel-el=
+**** Switch to action-style call
+This allows to make use of ~C-M-n~ and ~C-M-p~.
+*** =counsel-locate=
+**** Add Async
+**** Add extra actions
+In addition to the default action of opening a file add:
+
+- =xdg-open= action
+- =dired= action
+
+Press ~M-o~ or ~C-o~ to access these actions.
+**** Add own history
+
+*** API
+**** Add :matcher
+A matcher is a function that accepts a regexp and a list of candidates
+and returns the filtered list of candidates.
+
+The default matcher is basically =cl-remove-if-not= + =string-match=.
+If you'd like to customize this, pass your own matcher.
+
+See =counsel-git-grep-matcher= for an example.
+**** Allow to customize the initial input for all commands
+Customize =ivy-initial-inputs-alist= for this.
+See [[https://github.com/abo-abo/swiper/pull/140][#140]].
+**** =ivy-sort-functions-alist= should also examine =this-command=
+**** :dynamic-collection is now a boolean
+Pass the collection function as the second var instead.
+
+** New Commands
+*** =ivy-call=
+Execute the current action for the current candidate without exiting
+the minibuffer.  Bound to ~C-M-m~ or ~M-RET~ or ~C-o g~.
+
+
+*** =counsel-find-file=
+Forward to =find-file= with Ivy completion.
+
+=ivy-next-line-and-call= as well as =ivy-resume= should work for this command.
+
+The variable =counsel-find-file-ignore-regexp= allows to ignore
+certain files, like dot files.  Input a leading dot to see all files.
+
+The variable =counsel-find-file-at-point= allows to automatically use
+=ffap=.  You also can do it manually with ~M-n~ when the point is on a file 
name.
+
+The variable =counsel-find-file-map= allows to customize the
+minibuffer key bindings for this command.
+
+Recommended binding:
+
+#+begin_src elisp
+(global-set-key (kbd "C-x C-f") 'counsel-find-file)
+#+end_src
+
+You can peek at files with ~C-M-n~ and ~C-M-p~.
+
+See [[https://github.com/abo-abo/swiper/issues/122][#122]] and 
[[https://github.com/abo-abo/swiper/issues/123][#123]].
+
+See [[https://github.com/abo-abo/swiper/pull/152][#152]] about ~M-n~, ~M-p~ 
and ~M-i~ switching directories when necessary.
+
+*** =ivy-recentf=
+Find a file on =recentf-list=.
+
+Note that if your set =ivy-use-virtual-buffers=, =recentf-list= is
+merged into candidates list for =ivy-switch-buffer=. But if you want
+it separately, you can use this command.
+
+See [[https://github.com/abo-abo/swiper/issues/124][#124]].
+*** =ivy-yank-word=
+Add word at point to minibuffer input.
+
+This is similar to what ~C-w~ does for =isearch=.  However it's bound
+to ~M-j~ instead of ~C-w~, since ~C-w~ is bound to =kill-region= - a
+useful command.
+
+See [[https://github.com/abo-abo/swiper/issues/125][#125]].
+*** =counsel-M-x=
+Forward to =execute-extended-command= with Ivy completion.
+The candidate list will also display the key binding for each bound command.
+
+This command will piggyback on =smex= for sorting, if =smex= is installed.
+
+Use =counsel-M-x-initial-input= to customize the initial input for
+this command.  By default, it's "^" - the regex character that
+indicates beginning of string.  This results in much faster matching,
+since you usually type the command name from the start.
+
+See [[https://github.com/abo-abo/swiper/pull/136][#136]] and 
[[https://github.com/abo-abo/swiper/pull/138][#138]].
+
+*** =hydra-ivy=
+Press ~C-o~ to toggle the Hydra for Ivy.
+It gives access to shorter bindings and many customizable options.
+
+Use ~C-o >~ to grow the minibuffer.
+Use ~C-o <~ to shrink the minibuffer.
+
+See [[https://github.com/abo-abo/swiper/pull/151][#151]].
+
+*** =ivy-toggle-calling=
+Toggle executing the current action each time a new candidate is selected.
+
+This command is bound to ~C-o c~.
+
+To explain how this is useful: ~C-M-m C-M-f C-M-f C-M-f~  is equivalent to 
~C-o cjjj~.
+
+*** =ivy-insert-current=
+Inserts the current candidate into the minibuffer.
+
+Press ~M-i~ if you want something close to the current candidate. You
+can follow up with an edit and select.
+
+I find this very useful when creating new files with a similar name to
+the existing file: ~C-x C-f M-i~ + a bit of editing is very fast.
+
+See [[https://github.com/abo-abo/swiper/pull/141][#141]].
+
+*** =counsel-load-theme=
+Forward to =load-theme= with Ivy completion. Allows to rapidly try themes 
(e.g. with ~C-M-n~).
+
+*** =ivy-reverse-i-search=
+Allow to recursively match history with ~C-r~.
+
+I like this command from bash shell. The usual way to search through
+history is with ~M-p~ and ~M-n~.  Using =ivy-reverse-i-search= will
+open a recursive completion session with the current history as the
+candidates.
+*** =counsel-rhythmbox=
+[[http://oremacs.com/2015/07/09/counsel-rhythmbox/][Control Rhythmbox from 
Emacs.]]
+*** =ivy-dispatching-done=
+Select an action for the current candidate and execute it. Bound to ~M-o~.
+
+Some commands that support ~M-o~:
+
+- =counsel-rhythmbox=
+- =counsel-describe-function=
+- =counsel-describe-variable=
+- =ivy-switch-buffer=
+- =counsel-locate=
+
+*** =counsel-org-tag=
+Forward to =org-set-tags= with Ivy completion.
+
+Selecting any tag each time will toggle it on/off.
+The current list of selected tags will be displayed in the prompt.
+
+See [[https://github.com/abo-abo/swiper/pull/177][#177]] and 
[[https://github.com/abo-abo/swiper/pull/91][#91]].
+
+*** =counsel-org-tag-agenda=
+Forward to =org-agenda-set-tags= with Ivy completion.
+See [[https://github.com/abo-abo/swiper/pull/177][#177]].
+
+*** =counsel-ag=
+Interactively =ag= using Ivy completion.
+
+*** =counsel-recoll=
+Use =recoll= with Ivy completion.
+See [[http://oremacs.com/2015/07/27/counsel-recoll/][Using Recoll desktop 
search database with Emacs]].
+
+Install recoll with =sudo apt-get install recoll=.
+
+*** =swiper-from-isearch=
+Start =swiper= from the current =isearch= input.
+
+*** =ivy-immediate-done=
+Use this command to exit the minibuffer choosing not the current
+candidate, but the current text.  Bound to ~C-M-j~ or ~C-u C-j~.
+
+See [[https://github.com/abo-abo/swiper/pull/183][#183]].
diff --git a/packages/swiper/ivy-hydra.el b/packages/swiper/ivy-hydra.el
index 03e4d20..6ab1f9a 100644
--- a/packages/swiper/ivy-hydra.el
+++ b/packages/swiper/ivy-hydra.el
@@ -30,7 +30,7 @@
 (require 'ivy)
 
 (eval-when-compile
-  (unless (package-installed-p 'hydra)
+  (unless (or (featurep 'hydra) (package-installed-p 'hydra))
     (defmacro defhydra (name &rest _)
       "This is a stub for the uninstalled `hydra' package."
       `(defun ,(intern (format "%S/body" name)) ()
@@ -47,11 +47,11 @@
 (defhydra hydra-ivy (:hint nil
                      :color pink)
   "
-^^^^^^          ^Yes^     ^No^     ^Maybe^
-^^^^^^^^^^^^^^---------------------------------------
-^ ^ _k_ ^ ^     _f_ollow  _i_nsert _c_: calling %s(if ivy-calling \"on\" 
\"off\")
+^^^^^^          ^Yes^     ^No^     ^Maybe^           ^Action^
+^^^^^^^^^^^^^^---------------------------------------------------
+^ ^ _k_ ^ ^     _f_ollow  _i_nsert _c_: calling %s(if ivy-calling \"on\" 
\"off\")  _w_/_s_: %s(ivy-action-name)
 _h_ ^+^ _l_     _d_one    _o_ops   _m_: matcher %s(if (eq ivy--regex-function 
'ivy--regex-fuzzy) \"fuzzy\" \"ivy\")
-^ ^ _j_ ^ ^     ^ ^       ^ ^      _<_/_>_: shrink/grow window
+^ ^ _j_ ^ ^     _g_o      ^ ^      _<_/_>_: shrink/grow window
 "
   ;; arrows
   ("h" ivy-beginning-of-buffer)
@@ -66,11 +66,14 @@ _h_ ^+^ _l_     _d_one    _o_ops   _m_: matcher %s(if (eq 
ivy--regex-function 'i
   ("f" ivy-alt-done :exit nil)
   ("C-j" ivy-alt-done :exit nil)
   ("d" ivy-done :exit t)
+  ("g" ivy-call)
   ("C-m" ivy-done :exit t)
   ("c" ivy-toggle-calling)
   ("m" ivy-toggle-fuzzy)
   (">" ivy-minibuffer-grow)
-  ("<" ivy-minibuffer-shrink))
+  ("<" ivy-minibuffer-shrink)
+  ("w" ivy-prev-action)
+  ("s" ivy-next-action))
 
 (provide 'ivy-hydra)
 
diff --git a/packages/swiper/ivy-test.el b/packages/swiper/ivy-test.el
index af0fc60..10dd8f9 100644
--- a/packages/swiper/ivy-test.el
+++ b/packages/swiper/ivy-test.el
@@ -114,3 +114,11 @@
                    #("\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)))))
+
+(ert-deftest ivy--filter ()
+  (setq ivy-last (make-ivy-state))
+  (should (equal (ivy--filter "the" '("foo" "the" "The"))
+                 '("the" "The")))
+  (should (equal (ivy--filter "The" '("foo" "the" "The"))
+                 '("The"))))
+
diff --git a/packages/swiper/ivy.el b/packages/swiper/ivy.el
index f64782c..21197c3 100644
--- a/packages/swiper/ivy.el
+++ b/packages/swiper/ivy.el
@@ -69,8 +69,10 @@
 
 (defcustom ivy-count-format "%-4d "
   "The style of showing the current candidate count for `ivy-read'.
-Set this to nil if you don't want the count."
-  :type 'string)
+Set this to nil if you don't want the count.  You can also set it
+to e.g. \"(%d/%d) \" if you want to see both the candidate index
+and the candidate count."
+  :type '(choice (const :tag "Count disabled" nil) string))
 
 (defcustom ivy-wrap nil
   "Whether to wrap around after the first and last candidate."
@@ -90,12 +92,22 @@ Only \"./\" and \"../\" apply here. They appear in reverse 
order."
   "When non-nil, add `recentf-mode' and bookmarks to the list of buffers."
   :type 'boolean)
 
+(defvar ivy--actions-list nil
+  "A list of extra actions per command.")
+
+(defun ivy-set-actions (cmd actions)
+  "Set CMD extra exit points to ACTIONS."
+  (setq ivy--actions-list
+        (plist-put ivy--actions-list cmd actions)))
+
 ;;* Keymap
 (require 'delsel)
 (defvar ivy-minibuffer-map
   (let ((map (make-sparse-keymap)))
     (define-key map (kbd "C-m") 'ivy-done)
+    (define-key map (kbd "C-M-m") 'ivy-call)
     (define-key map (kbd "C-j") 'ivy-alt-done)
+    (define-key map (kbd "C-M-j") 'ivy-immediate-done)
     (define-key map (kbd "TAB") 'ivy-partial-or-done)
     (define-key map (kbd "C-n") 'ivy-next-line)
     (define-key map (kbd "C-p") 'ivy-previous-line)
@@ -124,7 +136,9 @@ Only \"./\" and \"../\" apply here. They appear in reverse 
order."
     (define-key map (kbd "M-j") 'ivy-yank-word)
     (define-key map (kbd "M-i") 'ivy-insert-current)
     (define-key map (kbd "C-o") 'hydra-ivy/body)
+    (define-key map (kbd "M-o") 'ivy-dispatching-done)
     (define-key map (kbd "C-k") 'ivy-kill-line)
+    (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
     map)
   "Keymap used in the minibuffer.")
 (autoload 'hydra-ivy/body "ivy-hydra" "" t)
@@ -223,6 +237,13 @@ When non-nil, it should contain one %d.")
                     ,@body))
      (minibuffer-keyboard-quit)))
 
+(defmacro with-ivy-window (&rest body)
+  "Execute BODY in the window from which `ivy-read' was called."
+  (declare (indent 0)
+           (debug t))
+  `(with-selected-window (ivy-state-window ivy-last)
+     ,@body))
+
 (defun ivy--done (text)
   "Insert TEXT and exit minibuffer."
   (if (and ivy--directory
@@ -256,6 +277,34 @@ When non-nil, it should contain one %d.")
          (insert ivy-text)
          (ivy--exhibit))))
 
+(defun ivy-dispatching-done ()
+  "Select one of the available actions and call `ivy-done'."
+  (interactive)
+  (let ((actions (ivy-state-action ivy-last)))
+    (if (null (ivy--actionp actions))
+        (ivy-done)
+      (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"))
+             (key (string (read-key hint)))
+             (action (assoc key (cdr actions))))
+        (cond ((string= key ""))
+              ((null action)
+               (error "%s is not bound" key))
+              (t
+               (message "")
+               (ivy-set-action (nth 1 action))
+               (ivy-done)))))))
+
 (defun ivy-build-tramp-name (x)
   "Reconstruct X into a path.
 Is is a cons cell, related to `tramp-get-completion-function'."
@@ -433,7 +482,7 @@ If the text hasn't changed as a result, forward to 
`ivy-alt-done'."
   (ivy-set-index (max (- ivy--index ivy-height)
                       0)))
 (defun ivy-minibuffer-grow ()
-  "Grow the minibuffer window by 1 line"
+  "Grow the minibuffer window by 1 line."
   (interactive)
   (setq-local max-mini-window-height
               (cl-incf ivy-height)))
@@ -485,16 +534,62 @@ If the input is empty, select the previous history 
element instead."
   (ivy-previous-line arg))
 
 (defun ivy-toggle-calling ()
-  "Flip `ivy-calling'"
+  "Flip `ivy-calling'."
   (interactive)
   (when (setq ivy-calling (not ivy-calling))
     (ivy-call)))
 
+(defun ivy--get-action (state)
+  "Get the action function from STATE."
+  (let ((action (ivy-state-action state)))
+    (when action
+      (if (functionp action)
+          action
+        (cadr (nth (car action) action))))))
+
+(defun ivy--actionp (x)
+  "Return non-nil when X is a list of actions."
+  (and x (listp x) (not (eq (car x) 'closure))))
+
+(defun ivy-next-action ()
+  "When the current action is a list, scroll it forwards."
+  (interactive)
+  (let ((action (ivy-state-action ivy-last)))
+    (when (ivy--actionp action)
+      (unless (>= (car action) (1- (length action)))
+        (cl-incf (car action))))))
+
+(defun ivy-prev-action ()
+  "When the current action is a list, scroll it backwards."
+  (interactive)
+  (let ((action (ivy-state-action ivy-last)))
+    (when (ivy--actionp action)
+      (unless (<= (car action) 1)
+        (cl-decf (car action))))))
+
+(defun ivy-action-name ()
+  "Return the name associated with the current action."
+  (let ((action (ivy-state-action ivy-last)))
+    (if (ivy--actionp action)
+        (format "[%d/%d] %s"
+                (car action)
+                (1- (length action))
+                (nth 2 (nth (car action) action)))
+      "[1/1] default")))
+
 (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))))
+  (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))))
+        (funcall action x)))))
 
 (defun ivy-next-line-and-call (&optional arg)
   "Move cursor vertically down ARG candidates.
@@ -617,7 +712,9 @@ On error (read-only), call `ivy-on-del-error-function'."
                     ivy--directory))))
         (ivy--exhibit))
     (ignore-errors
-      (backward-kill-word 1))))
+      (let ((pt (point)))
+        (forward-word -1)
+        (delete-region (point) pt)))))
 
 (defvar ivy--regexp-quote 'regexp-quote
   "Store the regexp quoting state.")
@@ -649,7 +746,7 @@ Prioritize directories."
   "An alist of sorting functions for each collection function.
 Interactive functions that call completion fit in here as well.
 
-For each entry, nil means no sorting. It's very useful to turn
+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'.
 
@@ -716,7 +813,8 @@ Directories come first."
 
 PROMPT is a string to prompt with; normally it ends in a colon
 and a space.  When PROMPT contains %d, it will be updated with
-the current number of matching candidates.
+the current number of matching candidates.  If % appears elsewhere
+in the PROMPT it should be quoted as %%.
 See also `ivy-count-format'.
 
 COLLECTION is a list of strings.
@@ -743,6 +841,14 @@ MATCHER can completely override matching.
 
 DYNAMIC-COLLECTION is a function to call to update the list of
 candidates with each input."
+  (let ((extra-actions (plist-get ivy--actions-list this-command)))
+    (when extra-actions
+      (setq action
+            (if (functionp action)
+                `(1
+                  ("o" ,action "default")
+                  ,@extra-actions)
+              (delete-dups (append action extra-actions))))))
   (setq ivy-last
         (make-ivy-state
          :prompt prompt
@@ -779,15 +885,15 @@ candidates with each input."
                  (let ((item (if ivy--directory
                                  ivy--current
                                ivy-text)))
-                   (set hist (cons (propertize item 'ivy-index ivy--index)
-                                   (delete item
-                                           (cdr (symbol-value hist))))))
+                   (unless (equal item "")
+                     (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))))
+    (ivy-call)))
 
 (defun ivy--reset-state (state)
   "Reset the ivy to STATE.
@@ -801,7 +907,8 @@ This is useful for recursive `ivy-read'."
         (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)))
+        (require-match (ivy-state-require-match state))
+        (matcher (ivy-state-matcher state)))
     (unless initial-input
       (setq initial-input (cdr (assoc this-command
                                       ivy-initial-inputs-alist))))
@@ -830,8 +937,14 @@ This is useful for recursive `ivy-read'."
             ((eq collection 'read-file-name-internal)
              (setq ivy--directory default-directory)
              (require 'dired)
-             (setq coll
-                   (ivy--sorted-files default-directory))
+             (when preselect
+               (let ((preselect-directory (file-name-directory preselect)))
+                 (unless (or (null preselect-directory)
+                             (string= preselect-directory
+                                      default-directory))
+                   (setq ivy--directory preselect-directory))
+                 (setq preselect (file-name-nondirectory preselect))))
+             (setq coll (ivy--sorted-files ivy--directory))
              (when initial-input
                (unless (or require-match
                            (equal initial-input default-directory)
@@ -870,7 +983,7 @@ This is useful for recursive `ivy-read'."
                              ivy--index)
                         (and preselect
                              (ivy--preselect-index
-                              coll initial-input preselect))
+                              coll initial-input preselect matcher))
                         0))
       (setq ivy--old-re nil)
       (setq ivy--old-cands nil)
@@ -880,6 +993,19 @@ This is useful for recursive `ivy-read'."
     (setq ivy--prompt
           (cond ((string-match "%.*d" prompt)
                  prompt)
+                ((null ivy-count-format)
+                 nil)
+                ((string-match "%d.*%d" ivy-count-format)
+                 (let ((w (length (number-to-string
+                                   (length ivy--all-candidates))))
+                       (s (copy-sequence ivy-count-format)))
+                   (string-match "%d" s)
+                   (match-end 0)
+                   (string-match "%d" s (match-end 0))
+                   (setq s (replace-match (format "%%-%dd" w) nil nil s))
+                   (string-match "%d" s)
+                   (concat (replace-match (format "%%%dd" w) nil nil s)
+                           prompt)))
                 ((string-match "%.*d" ivy-count-format)
                  (concat ivy-count-format prompt))
                 (ivy--directory
@@ -906,7 +1032,8 @@ DEF is the default value.
 _INHERIT-INPUT-METHOD is ignored for now.
 
 The history, defaults and input-method arguments are ignored for now."
-  (ivy-read prompt collection
+  (ivy-read (replace-regexp-in-string "%" "%%" prompt)
+            collection
             :predicate predicate
             :require-match require-match
             :initial-input (if (consp initial-input)
@@ -941,15 +1068,21 @@ Minibuffer bindings:
       (setq completing-read-function 'ivy-completing-read)
     (setq completing-read-function 'completing-read-default)))
 
-(defun ivy--preselect-index (candidates initial-input preselect)
-  "Return the index in CANDIDATES filtered by INITIAL-INPUT for PRESELECT."
-  (when initial-input
-    (setq initial-input (ivy--regex-plus initial-input))
-    (setq candidates
-          (cl-remove-if-not
-           (lambda (x)
-             (string-match initial-input x))
-           candidates)))
+(defun ivy--preselect-index (candidates initial-input preselect matcher)
+  "Return the index in CANDIDATES filtered by INITIAL-INPUT for PRESELECT.
+When MATCHER is non-nil it's used instead of `cl-remove-if-not'."
+  (if initial-input
+      (progn
+        (setq initial-input (ivy--regex-plus initial-input))
+        (setq candidates
+              (if matcher
+                  (funcall matcher initial-input candidates)
+                (cl-remove-if-not
+                 (lambda (x)
+                   (string-match initial-input x))
+                 candidates))))
+    (when matcher
+      (setq candidates (funcall matcher "" candidates))))
   (or (cl-position preselect candidates :test #'equal)
       (cl-position-if
        (lambda (x)
@@ -1001,6 +1134,8 @@ When GREEDY is non-nil, join words in a greedy way."
     (if hashed
         (prog1 (cdr hashed)
           (setq ivy--subexps (car hashed)))
+      (when (string-match "\\([^\\]\\|^\\)\\\\$" str)
+        (setq str (substring str 0 -1)))
       (cdr (puthash str
                     (let ((subs (ivy--split str)))
                       (if (= (length subs) 1)
@@ -1108,21 +1243,27 @@ Insert .* between each char."
       (let ((inhibit-read-only t)
             (std-props '(front-sticky t rear-nonsticky t field t read-only t))
             (n-str
-             (format
+             (concat
+              (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
+                       (> (minibuffer-depth) 1))
+                  (format "[%d] " (minibuffer-depth))
+                "")
               (concat
-               (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
-                        (> (minibuffer-depth) 1))
-                   (format "[%d] " (minibuffer-depth))
-                 "")
-               head
+               (if (string-match "%d.*%d" ivy-count-format)
+                   (format head
+                           (1+ ivy--index)
+                           (or (and (ivy-state-dynamic-collection ivy-last)
+                                    ivy--full-length)
+                               ivy--length))
+                 (format head
+                         (or (and (ivy-state-dynamic-collection ivy-last)
+                                  ivy--full-length)
+                             ivy--length)))
                ivy--prompt-extra
-               tail
-               (if ivy--directory
-                   (abbreviate-file-name ivy--directory)
-                 ""))
-              (or (and (ivy-state-dynamic-collection ivy-last)
-                       ivy--full-length)
-                  ivy--length))))
+               tail)
+              (if ivy--directory
+                  (abbreviate-file-name ivy--directory)
+                ""))))
         (save-excursion
           (goto-char (point-min))
           (delete-region (point-min) (minibuffer-prompt-end))
@@ -1151,50 +1292,51 @@ Insert .* between each char."
 (defun ivy--exhibit ()
   "Insert Ivy completions display.
 Should be run via minibuffer `post-command-hook'."
-  (setq ivy-text (ivy--input))
-  (if (ivy-state-dynamic-collection ivy-last)
-      ;; while-no-input would cause annoying
-      ;; "Waiting for process to die...done" message interruptions
-      (let ((inhibit-message t))
-        (unless (equal ivy--old-text ivy-text)
-          (while-no-input
-            ;; 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)
-                  (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)
-                          (not (string-match "\\` " ivy--old-text)))
-                     (and (string-match "\\` " ivy--old-text)
-                          (not (string-match "\\` " ivy-text))))
-             (setq ivy--all-candidates
-                   (if (and (> (length ivy-text) 0)
-                            (eq (aref ivy-text 0)
-                                ?\ ))
-                       (ivy--buffer-list " ")
-                     (ivy--buffer-list "" ivy-use-virtual-buffers)))
-             (setq ivy--old-re nil))))
-    (ivy--insert-minibuffer
-     (ivy--format
-      (ivy--filter ivy-text ivy--all-candidates)))
-    (setq ivy--old-text ivy-text)))
+  (when (memq 'ivy--exhibit post-command-hook)
+    (setq ivy-text (ivy--input))
+    (if (ivy-state-dynamic-collection ivy-last)
+        ;; while-no-input would cause annoying
+        ;; "Waiting for process to die...done" message interruptions
+        (let ((inhibit-message t))
+          (unless (equal ivy--old-text ivy-text)
+            (while-no-input
+              (setq ivy--all-candidates
+                    (funcall (ivy-state-collection ivy-last) ivy-text))
+              (setq ivy--old-text ivy-text)))
+          (when ivy--all-candidates
+            (ivy--insert-minibuffer
+             (ivy--format ivy--all-candidates))))
+      (cond (ivy--directory
+             (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)))))
+               (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)
+                            (not (string-match "\\` " ivy--old-text)))
+                       (and (string-match "\\` " ivy--old-text)
+                            (not (string-match "\\` " ivy-text))))
+               (setq ivy--all-candidates
+                     (if (and (> (length ivy-text) 0)
+                              (eq (aref ivy-text 0)
+                                  ?\ ))
+                         (ivy--buffer-list " ")
+                       (ivy--buffer-list "" ivy-use-virtual-buffers)))
+               (setq ivy--old-re nil))))
+      (ivy--insert-minibuffer
+       (ivy--format
+        (ivy--filter ivy-text ivy--all-candidates)))
+      (setq ivy--old-text ivy-text))))
 
 (defun ivy--insert-minibuffer (text)
   "Insert TEXT into minibuffer with appropriate cleanup."
@@ -1231,6 +1373,7 @@ Should be run via minibuffer `post-command-hook'."
 CANDIDATES are assumed to be static."
   (let* ((re (funcall ivy--regex-function name))
          (matcher (ivy-state-matcher ivy-last))
+         (case-fold-search (string= name (downcase name)))
          (cands (cond
                   (matcher
                    (funcall matcher re candidates))
@@ -1272,8 +1415,11 @@ CANDIDATES are assumed to be static."
       (unless (and (not (equal re ivy--old-re))
                    (or (setq ivy--index
                              (or
-                              (cl-position re cands
-                                           :test #'equal)
+                              (cl-position (if (and (> (length re) 0)
+                                                    (eq ?^ (aref re 0)))
+                                               (substring re 1)
+                                             re) cands
+                                             :test #'equal)
                               (and ivy--directory
                                    (cl-position
                                     (concat re "/") cands
@@ -1420,14 +1566,40 @@ BUFFER may be a string or nil."
         (switch-to-buffer
          buffer nil 'force-same-window)))))
 
+(defun ivy--switch-buffer-other-window-action (buffer)
+  "Switch to BUFFER in other window.
+BUFFER may be a string or nil."
+  (if (zerop (length buffer))
+      (switch-to-buffer-other-window ivy-text)
+    (let ((virtual (assoc buffer ivy--virtual-buffers)))
+      (if (and virtual
+               (not (get-buffer buffer)))
+          (find-file-other-window (cdr virtual))
+        (switch-to-buffer-other-window buffer)))))
+
+(defvar ivy-switch-buffer-map (make-sparse-keymap))
+
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("k"
+    (lambda (x)
+      (kill-buffer x)
+      (ivy--reset-state ivy-last))
+    "kill")
+   ("j"
+    ivy--switch-buffer-other-window-action
+    "other")))
+
 (defun ivy-switch-buffer ()
   "Switch to another buffer."
   (interactive)
   (if (not ivy-mode)
       (call-interactively 'switch-to-buffer)
-    (ivy-read "Switch to buffer: " 'internal-complete-buffer
-              :preselect (buffer-name (other-buffer (current-buffer)))
-              :action #'ivy--switch-buffer-action)))
+    (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))))
 
 (defun ivy-recentf ()
   "Find a file on `recentf-list'."
@@ -1439,7 +1611,7 @@ BUFFER may be a string or nil."
   "Pull next word from buffer into search string."
   (interactive)
   (let (amend)
-    (with-selected-window (ivy-state-window ivy-last)
+    (with-ivy-window
       (let ((pt (point))
             (le (line-end-position)))
         (forward-word 1)
@@ -1483,6 +1655,13 @@ The selected history element will be inserted into the 
minibufer."
                         (insert (substring-no-properties x))
                         (ivy--cd-maybe)))))
 
+(defun ivy-restrict-to-matches ()
+  "Restrict candidates to current matches and erase input."
+  (interactive)
+  (delete-minibuffer-contents)
+  (setq ivy--all-candidates
+        (ivy--filter ivy-text ivy--all-candidates)))
+
 (provide 'ivy)
 
 ;;; ivy.el ends here
diff --git a/packages/swiper/swiper.el b/packages/swiper/swiper.el
index 1975ae2..1032f04 100644
--- a/packages/swiper/swiper.el
+++ b/packages/swiper/swiper.el
@@ -83,9 +83,6 @@
     map)
   "Keymap for swiper.")
 
-(defvar swiper--window nil
-  "Store the current window.")
-
 (defun swiper-query-replace ()
   "Start `query-replace' with string to replace from last search string."
   (interactive)
@@ -96,7 +93,7 @@
            (to (query-replace-read-to from "Query replace" t)))
       (delete-minibuffer-contents)
       (ivy-set-action (lambda (_)
-                        (with-selected-window swiper--window
+                        (with-ivy-window
                           (move-beginning-of-line 1)
                           (perform-replace from to
                                            t t nil))))
@@ -108,14 +105,14 @@
 (declare-function avy--regex-candidates "ext:avy")
 (declare-function avy--process "ext:avy")
 (declare-function avy--overlay-post "ext:avy")
-(declare-function avy--goto "ext:avy")
+(declare-function avy-action-goto "ext:avy")
 
 ;;;###autoload
 (defun swiper-avy ()
   "Jump to one of the current swiper candidates."
   (interactive)
   (unless (string= ivy-text "")
-    (with-selected-window (ivy-state-window ivy-last)
+    (with-ivy-window
       (let* ((avy-all-windows nil)
              (candidates
               (avy--regex-candidates
@@ -124,12 +121,12 @@
              (candidate
               (avy--process candidates #'avy--overlay-post)))
         (ivy-quit-and-run
-         (avy--goto candidate))))))
+         (avy-action-goto candidate))))))
 
 (defun swiper-recenter-top-bottom (&optional arg)
-  "Call (`recenter-top-bottom' ARG) in `swiper--window'."
+  "Call (`recenter-top-bottom' ARG)."
   (interactive "P")
-  (with-selected-window swiper--window
+  (with-ivy-window
     (recenter-top-bottom arg)))
 
 (defun swiper-font-lock-ensure ()
@@ -145,7 +142,9 @@
                                  dired-mode
                                  jabber-chat-mode
                                  elfeed-search-mode
-                                 fundamental-mode)))
+                                 fundamental-mode
+                                 Man-mode
+                                 woman-mode)))
     (unless (> (buffer-size) 100000)
       (if (fboundp 'font-lock-ensure)
           (font-lock-ensure)
@@ -199,8 +198,7 @@ When non-nil, INITIAL-INPUT is the initial search pattern."
   "Perform initialization common to both completion methods."
   (setq swiper--opoint (point))
   (setq swiper--len 0)
-  (setq swiper--anchor (line-number-at-pos))
-  (setq swiper--window (selected-window)))
+  (setq swiper--anchor (line-number-at-pos)))
 
 (defun swiper--re-builder (str)
   "Transform STR into a swiper regex.
@@ -244,8 +242,7 @@ Please remove it and update the \"swiper\" package."))
         res)
     (unwind-protect
          (setq res (ivy-read
-                    (replace-regexp-in-string
-                     "%s" "pattern: " swiper--format-spec)
+                    "Swiper: "
                     candidates
                     :initial-input initial-input
                     :keymap swiper-map
@@ -281,13 +278,13 @@ Please remove it and update the \"swiper\" package."))
 
 (defun swiper--update-input-ivy ()
   "Called when `ivy' input is updated."
-  (swiper--cleanup)
-  (let* ((re (ivy--regex ivy-text))
-         (str ivy--current)
-         (num (if (string-match "^[0-9]+" str)
-                  (string-to-number (match-string 0 str))
-                0)))
-    (with-selected-window swiper--window
+  (with-ivy-window
+    (swiper--cleanup)
+    (let* ((re (ivy--regex ivy-text))
+           (str ivy--current)
+           (num (if (string-match "^[0-9]+" str)
+                    (string-to-number (match-string 0 str))
+                  0)))
       (goto-char (point-min))
       (when (cl-plusp num)
         (goto-char (point-min))
@@ -300,7 +297,7 @@ Please remove it and update the \"swiper\" package."))
         (isearch-range-invisible (line-beginning-position)
                                  (line-end-position))
         (unless (and (>= (point) (window-start))
-                     (<= (point) (window-end swiper--window t)))
+                     (<= (point) (window-end (ivy-state-window ivy-last) t)))
           (recenter)))
       (swiper--add-overlays re))))
 
@@ -311,39 +308,39 @@ BEG and END, when specified, are the point bounds."
              (line-beginning-position)
              (1+ (line-end-position)))))
     (overlay-put ov 'face 'swiper-line-face)
-    (overlay-put ov 'window swiper--window)
-    (push ov swiper--overlays))
-  (let* ((wh (window-height))
-         (beg (or beg (save-excursion
-                        (forward-line (- wh))
-                        (point))))
-         (end (or end (save-excursion
-                        (forward-line wh)
-                        (point)))))
-    (when (>= (length re) swiper-min-highlight)
-      (save-excursion
-        (goto-char beg)
-        ;; RE can become an invalid regexp
-        (while (and (ignore-errors (re-search-forward re end t))
-                    (> (- (match-end 0) (match-beginning 0)) 0))
-          (let ((i 0))
-            (while (<= i ivy--subexps)
-              (when (match-beginning i)
-                (let ((overlay (make-overlay (match-beginning i)
-                                             (match-end i)))
-                      (face
-                       (cond ((zerop ivy--subexps)
-                              (cadr swiper-faces))
-                             ((zerop i)
-                              (car swiper-faces))
-                             (t
-                              (nth (1+ (mod (+ i 2) (1- (length 
swiper-faces))))
-                                   swiper-faces)))))
-                  (push overlay swiper--overlays)
-                  (overlay-put overlay 'face face)
-                  (overlay-put overlay 'window swiper--window)
-                  (overlay-put overlay 'priority i)))
-              (cl-incf i))))))))
+    (overlay-put ov 'window (ivy-state-window ivy-last))
+    (push ov swiper--overlays)
+    (let* ((wh (window-height))
+           (beg (or beg (save-excursion
+                          (forward-line (- wh))
+                          (point))))
+           (end (or end (save-excursion
+                          (forward-line wh)
+                          (point)))))
+      (when (>= (length re) swiper-min-highlight)
+        (save-excursion
+          (goto-char beg)
+          ;; RE can become an invalid regexp
+          (while (and (ignore-errors (re-search-forward re end t))
+                      (> (- (match-end 0) (match-beginning 0)) 0))
+            (let ((i 0))
+              (while (<= i ivy--subexps)
+                (when (match-beginning i)
+                  (let ((overlay (make-overlay (match-beginning i)
+                                               (match-end i)))
+                        (face
+                         (cond ((zerop ivy--subexps)
+                                (cadr swiper-faces))
+                               ((zerop i)
+                                (car swiper-faces))
+                               (t
+                                (nth (1+ (mod (+ i 2) (1- (length 
swiper-faces))))
+                                     swiper-faces)))))
+                    (push overlay swiper--overlays)
+                    (overlay-put overlay 'face face)
+                    (overlay-put overlay 'window (ivy-state-window ivy-last))
+                    (overlay-put overlay 'priority i)))
+                (cl-incf i)))))))))
 
 (defun swiper--action (x input)
   "Goto line X and search for INPUT."
@@ -359,6 +356,16 @@ BEG and END, when specified, are the point bounds."
         (push-mark swiper--opoint t)
         (message "Mark saved where search started")))))
 
+;; (define-key isearch-mode-map (kbd "C-o") 'swiper-from-isearch)
+(defun swiper-from-isearch ()
+  "Invoke `swiper' from isearch."
+  (interactive)
+  (let ((query (if isearch-regexp
+                   isearch-string
+                 (regexp-quote isearch-string))))
+    (isearch-exit)
+    (swiper query)))
+
 (provide 'swiper)
 
 ;;; swiper.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]