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

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

[elpa] master e54aa18 067/348: Add prefix arg for action functions


From: Oleh Krehel
Subject: [elpa] master e54aa18 067/348: Add prefix arg for action functions
Date: Sat, 8 Apr 2017 11:03:26 -0400 (EDT)

branch: master
commit e54aa1850077d22e8007edef86d4bb751c3b7794
Author: John Kitchin <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Add prefix arg for action functions
    
    This commit makes ivy store prefix args that can be used in action
    functions. The prefix arg is stored in `ivy-current-prefix-arg'.
    
    New tests are added to ivy-test.el.
    
    Fixes #552
    
    Single actions
    | C-m     | ivy-done             | store prefix |
    | M-o     | ivy-dispatching-done | store prefix |
    | C-j     | ivy-alt-done         | store prefix |
    | C-M-j   | ivy-immediate-done   | store prefix |
    | TAB TAB | ivy-partial-or-done  | unsupported  |
    | C-'     | ivy-avy              | unsupported  |
    
    Multiple actions
    | C-M-m | ivy-call                   | store prefix, type prefix again for 
next call |
    | C-M-o | ivy-dispatching-call       | store prefix, type prefix again for 
next call |
    | C-M-n | ivy-next-line-and-call     | store prefix, type prefix again for 
next call |
    | C-M-p | ivy-previous-line-and-call | store prefix, type prefix again for 
next call |
    
    ** An example application
    
    no prefix prints first number in a message-box
    one prefix prints last number in a message-box
    numeric prefix selects the index to print in a message-box
    
    (ivy-read "choose: " '(("a" 1 2 3)
                       ("b" 3 4 5))
          :action
          (lambda (x)
            (message-box "%s"
                         (cond
                          ((null ivy-current-prefix-arg)
                           (elt x 0))
                          ((equal '(4) ivy-current-prefix-arg)
                           (car (last x)))
                          (t
                           (elt x (prefix-numeric-value 
ivy-current-prefix-arg)))))))
---
 ivy-test.el | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ivy.el      |  21 ++++++-
 2 files changed, 209 insertions(+), 2 deletions(-)

diff --git a/ivy-test.el b/ivy-test.el
index dee8803..a0ccb9c 100644
--- a/ivy-test.el
+++ b/ivy-test.el
@@ -212,4 +212,194 @@
                    0.07058823529411765
                    0.20392156862745098))))
 
+
+;;* prefix arg tests
+;;** tests with no prefix
+(ert-deftest ivy-no-prefix-arg ()
+  "Tests with no prefix arg."
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-m")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-j")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-M-j")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-M-m")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-M-n")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-M-p")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "M-o o")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "TAB TAB")
+           nil)))
+
+;;** tests with one prefix
+(ert-deftest ivy-one-prefix-arg ()
+  "Tests with no prefix arg."
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u C-m")
+           '(4)))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u C-j")
+           '(4)))
+  ;; C-M-j does not pass a prefix on.
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u C-M-j")
+           nil))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u C-M-m")
+           '(4)))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u C-M-n")
+           '(4)))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u C-M-p")
+           '(4)))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "C-u M-o o")
+           '(4)))
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action
+               '(1 ("o" (lambda (x)
+                          (setq res ivy-current-prefix-arg)))
+                 ("p" (lambda (x)
+                        (setq res ivy-current-prefix-arg)))))
+              res)
+            "C-u M-o p")
+           '(4)))
+  ;; TAB TAB does not pass prefix arg
+  (should (equal
+           (ivy-with
+            '(let (res)
+              (ivy-read "pattern: " '("blue" "yellow")
+               :action (lambda (x)
+                         (setq res ivy-current-prefix-arg)))
+              res)
+            "TAB TAB")
+           nil)))
+
+
+(ert-deftest ivy-numeric-prefix-arg ()
+  (should (equal
+           (ivy-with
+            '(let (res)
+               (ivy-read "pattern: " '("blue" "yellow")
+                         :action (lambda (x)
+                                   (setq res ivy-current-prefix-arg)))
+               res)
+            "M-1 M-2 M-3 C-m")
+           123))
+  (should (equal
+           (ivy-with
+            '(let (res)
+               (ivy-read "pattern: " '("blue" "yellow")
+                         :action (lambda (x)
+                                   (setq res ivy-current-prefix-arg)))
+               res)
+            "C-u 123 C-m")
+           123)))
+
+
 (provide 'ivy-test)
diff --git a/ivy.el b/ivy.el
index 76d12fa..d882999 100644
--- a/ivy.el
+++ b/ivy.el
@@ -227,6 +227,11 @@ Example:
   (setq ivy--sources-list
         (plist-put ivy--sources-list cmd sources)))
 
+(defvar ivy-current-prefix-arg nil
+  "Prefix arg to pass to actions.
+This is a global variable that is set by ivy functions for use in
+action functions.")
+
 ;;* Keymap
 (require 'delsel)
 (defvar ivy-minibuffer-map
@@ -466,6 +471,7 @@ When non-nil, it should contain at least one %d.")
 (defun ivy-done ()
   "Exit the minibuffer with the selected candidate."
   (interactive)
+  (setq ivy-current-prefix-arg current-prefix-arg)
   (delete-minibuffer-contents)
   (cond ((or (> ivy--length 0)
              ;; the action from `ivy-dispatching-done' may not need a
@@ -544,10 +550,11 @@ selection, non-nil otherwise."
 (defun ivy-dispatching-call ()
   "Select one of the available actions and call `ivy-call'."
   (interactive)
+  (setq ivy-current-prefix-arg current-prefix-arg)
   (let ((actions (copy-sequence (ivy-state-action ivy-last))))
     (unwind-protect
-         (when (ivy-read-action)
-           (ivy-call))
+        (when (ivy-read-action)
+          (ivy-call))
       (ivy-set-action actions))))
 
 (defun ivy-build-tramp-name (x)
@@ -566,6 +573,7 @@ Is is a cons cell, related to 
`tramp-get-completion-function'."
   "Exit the minibuffer with the selected candidate.
 When ARG is t, exit with current text, ignoring the candidates."
   (interactive "P")
+  (setq ivy-current-prefix-arg current-prefix-arg)
   (cond (arg
          (ivy-immediate-done))
         (ivy--directory
@@ -909,6 +917,15 @@ Example use:
 (defun ivy-call ()
   "Call the current action without exiting completion."
   (interactive)
+  (unless
+      (or
+       ;; this is needed for testing in ivy-with which seems to call ivy-call
+       ;; again, and this-command is nil in that case.
+       (null this-command)
+       (memq this-command '(ivy-done
+                            ivy-alt-done
+                            ivy-dispatching-done)))
+    (setq ivy-current-prefix-arg current-prefix-arg))
   (unless ivy-inhibit-action
     (let ((action (ivy--get-action ivy-last)))
       (when action



reply via email to

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