[Top][All Lists]

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

[elpa] master 6817381 068/272: Allow to compose static collections with

From: Oleh Krehel
Subject: [elpa] master 6817381 068/272: Allow to compose static collections with `counsel--async-command'
Date: Mon, 25 Apr 2016 10:13:17 +0000

branch: master
commit 681738104cf709ffb1eb3209135713eea900552b
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Allow to compose static collections with `counsel--async-command'
    * ivy.el (ivy--sources-list): New defvar.
    (ivy-set-sources): New defun that sets `ivy--sources-list'
    (ivy--extra-candidates): New defvar.
    (ivy-read): Use `ivy--sources-list' to set `ivy--extra-candidates' - a
    list that composes itself with `ivy--all-candidates'.
    (ivy--set-candidates): New defun.
    Example - stack `recentf' on top of `counsel-locate':
        (defun small-test ()
          (cl-subseq recentf-list 0 10))
    Here, (original-source) represents the async candidates of
    `counsel-locate'. All extra sources are static - each function is called
    once to generate a list of strings, which will be filtered later.
    The order matters, so you can have e.g.:
    Fixes #373
 counsel.el |   13 ++++++------
 ivy.el     |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/counsel.el b/counsel.el
index 682e238..d80b5fb 100644
--- a/counsel.el
+++ b/counsel.el
@@ -598,9 +598,9 @@ Or the time of the last minibuffer update.")
   (if (string= event "finished\n")
         (with-current-buffer (process-buffer process)
-          (setq ivy--all-candidates
-                (ivy--sort-maybe
-                 (split-string (buffer-string) "\n" t)))
+          (ivy--set-candidates
+           (ivy--sort-maybe
+            (split-string (buffer-string) "\n" t)))
           (if (null ivy--old-cands)
               (setq ivy--index
                     (or (ivy--preselect-index
@@ -636,8 +636,8 @@ Update the minibuffer with the amount of lines collected 
       (with-current-buffer (process-buffer process)
         (goto-char (point-min))
         (setq size (- (buffer-size) (forward-line (buffer-size))))
-        (setq ivy--all-candidates
-              (split-string (buffer-string) "\n" t)))
+        (ivy--set-candidates
+         (split-string (buffer-string) "\n" t)))
       (let ((ivy--prompt (format
                           (concat "%d++ " (ivy-state-prompt ivy-last))
@@ -711,7 +711,8 @@ INITIAL-INPUT can be given as the initial minibuffer input."
                         (when file
                           (find-file file))))
-            :unwind #'counsel-delete-process))
+            :unwind #'counsel-delete-process
+            :caller 'counsel-locate))
 (defun counsel--generic (completion-fn)
   "Complete thing at point with COMPLETION-FN."
diff --git a/ivy.el b/ivy.el
index f44dbdf..08719f3 100644
--- a/ivy.el
+++ b/ivy.el
@@ -167,6 +167,33 @@ Only \"./\" and \"../\" apply here. They appear in reverse 
   (setq ivy--actions-list
         (plist-put ivy--actions-list cmd actions)))
+(defvar ivy--sources-list nil
+  "A list of extra sources per command.")
+(defun ivy-set-sources (cmd sources)
+  "Attach to CMD a list of extra SOURCES.
+Each static source is a function that takes no argument and
+returns a list of strings.
+The '(original-source) determines the position of the original
+dynamic source.
+Extra dynamic sources aren't supported yet.
+    (defun small-recentf ()
+      (cl-subseq recentf-list 0 20))
+    (ivy-set-sources
+     'counsel-locate
+     '((small-recentf)
+       (original-source)))
+  (setq ivy--sources-list
+        (plist-put ivy--sources-list cmd sources)))
 ;;* Keymap
 (require 'delsel)
 (defvar ivy-minibuffer-map
@@ -278,6 +305,18 @@ Otherwise, store nil.")
 (defvar ivy--all-candidates nil
   "Store the candidates passed to `ivy-read'.")
+(defvar ivy--extra-candidates '((original-source))
+  "Store candidates added by the extra sources.
+This is an internal-use alist. Each key is a function name, or
+original-source (which represents where the current dynamic
+candidates should go).
+Each value is an evaluation of the function, in case of static
+sources. These values will subsequently be filtered on `ivy-text'.
+This variable is set by `ivy-read' and used by `ivy--set-candidates'.")
 (defvar ivy--default nil
   "Default initial input.")
@@ -1138,6 +1177,20 @@ customizations apply to the current completion session."
                    (cons 1 extra-actions))
                    (delete-dups (append action extra-actions)))))))
+  (let ((extra-sources (plist-get ivy--sources-list caller)))
+    (if extra-sources
+        (progn
+          (setq ivy--extra-candidates nil)
+          (dolist (source extra-sources)
+            (cond ((equal source '(original-source))
+                   (setq ivy--extra-candidates
+                         (cons source ivy--extra-candidates)))
+                  ((null (cdr source))
+                   (setq ivy--extra-candidates
+                         (cons
+                          (list (car source) (funcall (car source)))
+                          ivy--extra-candidates))))))
+      (setq ivy--extra-candidates '((original-source)))))
   (let ((recursive-ivy-last (and (active-minibuffer-window) ivy-last)))
     (setq ivy-last
@@ -1941,6 +1994,20 @@ CANDIDATES are assumed to be static."
         (setq ivy--old-cands (ivy--sort name cands))))))
+(defun ivy--set-candidates (x)
+  "Update `ivy--all-candidates' with X."
+  (let (res)
+    (dolist (source ivy--extra-candidates)
+      (if (equal source '(original-source))
+          (if (null res)
+              (setq res x)
+            (setq res (append x res)))
+        (setq ivy--old-re nil)
+        (setq res (append
+                   (ivy--filter ivy-text (cadr source))
+                   res))))
+    (setq ivy--all-candidates res)))
 (defcustom ivy-sort-matches-functions-alist '((t . nil))
   "An alist of functions used to sort the matching candidates.

reply via email to

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