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

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

[elpa] master 93d1adc 026/272: Properly support matching ignoring order


From: Oleh Krehel
Subject: [elpa] master 93d1adc 026/272: Properly support matching ignoring order
Date: Mon, 25 Apr 2016 10:13:14 +0000

branch: master
commit 93d1adc57a698b70278b7c5e76a4a3a18e8ebaf5
Author: Oleh Krehel <address@hidden>
Commit: Oleh Krehel <address@hidden>

    Properly support matching ignoring order
    
    * ivy.el (ivy--regex-ignore-order): Return a list of regexps rather than
      a single regexp.
    (ivy--re-filter): New defun, extracted from `ivy--filter'.
    (ivy--filter): Update.
    (ivy--format-minibuffer-line): Add special highlighting for
    `ivy--regex-ignore-order'.
    
    * counsel.el (counsel--find-file-matcher): Use `ivy--re-filter'.
    
    Fixes #296
    Fixes #329
---
 counsel.el |    5 +--
 ivy.el     |  144 ++++++++++++++++++++++++++++++++----------------------------
 2 files changed, 77 insertions(+), 72 deletions(-)

diff --git a/counsel.el b/counsel.el
index 89d3107..b40d409 100644
--- a/counsel.el
+++ b/counsel.el
@@ -488,10 +488,7 @@ Possible value: \"\\(?:\\`[#.]\\)\\|\\(?:[#~]\\'\\)\"."
 (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)))
+  (let ((res (ivy--re-filter regexp candidates)))
     (if (or (null counsel-find-file-ignore-regexp)
             (string-match counsel-find-file-ignore-regexp ivy-text))
         res
diff --git a/ivy.el b/ivy.el
index 16b8d81..2728cb2 100644
--- a/ivy.el
+++ b/ivy.el
@@ -1499,30 +1499,15 @@ When GREEDY is non-nil, join words in a greedy way."
 
 (defun ivy--regex-ignore-order (str)
   "Re-build regex from STR by splitting at spaces.
-Ignore the order of each group.
-
-ATTENTION: This is just a proof of concept and may not work as
-expected. Besides ignoring the order of the tokens where 'foo'
-and 'bar', 'bar' and 'foo' are matched, it also matches multiple
-occurrences of 'foo' and 'bar'. To ignore the sort order and avoid
-multiple matches, use `ivy-restrict-to-matches' instead.
-"
+Ignore the order of each group."
   (let* ((subs (split-string str " +" t))
          (len (length subs)))
     (cl-case len
-      (1
-       (setq ivy--subexps 0)
-       (car subs))
+      (0
+       "")
       (t
-       (setq ivy--subexps len)
-       (let ((all (mapconcat #'identity subs "\\|")))
-         (mapconcat
-          (lambda (x)
-            (if (string-match "\\`\\\\(.*\\\\)\\'" x)
-                x
-              (format "\\(%s\\)" x)))
-          (make-list len all)
-          ".*?"))))))
+       (mapcar (lambda (x) (cons x t))
+               subs)))))
 
 (defun ivy--regex-plus (str)
   "Build a regex sequence from STR.
@@ -1534,10 +1519,10 @@ match. Everything after \"!\" should not match."
        "")
       (1
        (if (string-equal (substring str 0 1) "!")
-            (list
-             (cons "" t)
-             (list (ivy--regex (car parts))))
-           (ivy--regex (car parts))))
+           (list
+            (cons "" t)
+            (list (ivy--regex (car parts))))
+         (ivy--regex (car parts))))
       (2
        (let ((res
               (mapcar #'list
@@ -1807,6 +1792,25 @@ You can toggle this to make `case-fold-search' nil 
regardless of input."
   ;; reset cache so that the candidate list updates
   (setq ivy--old-re nil))
 
+(defun ivy--re-filter (re candidates)
+  "Return all RE matching CANDIDATES.
+RE is a list of cons cells, with a regexp car and a boolean cdr.
+When the cdr is t, the car must match.
+Otherwise, the car must not match."
+  (let ((re-list (if (stringp re) (list (cons re t)) re))
+        (res candidates))
+    (dolist (re re-list)
+      (setq res
+            (ignore-errors
+              (funcall
+               (if (cdr re)
+                   #'cl-remove-if-not
+                 #'cl-remove-if)
+               (let ((re-str (car re)))
+                 (lambda (x) (string-match re-str x)))
+               res))))
+    res))
+
 (defun ivy--filter (name candidates)
   "Return all items that match NAME in CANDIDATES.
 CANDIDATES are assumed to be static."
@@ -1821,15 +1825,15 @@ CANDIDATES are assumed to be static."
               (and ivy-case-fold-search
                    (string= name (downcase name))))
              (cands (cond
-                     (matcher
-                      (funcall matcher re candidates))
-                     ((and ivy--old-re
-                           (stringp re)
-                           (stringp ivy--old-re)
-                           (not (string-match "\\\\" ivy--old-re))
-                           (not (equal ivy--old-re ""))
-                           (memq (cl-search
-                                  (if (string-match "\\\\)\\'" ivy--old-re)
+                      (matcher
+                       (funcall matcher re candidates))
+                      ((and ivy--old-re
+                            (stringp re)
+                            (stringp ivy--old-re)
+                            (not (string-match "\\\\" ivy--old-re))
+                            (not (equal ivy--old-re ""))
+                            (memq (cl-search
+                                   (if (string-match "\\\\)\\'" ivy--old-re)
                                        (substring ivy--old-re 0 -2)
                                      ivy--old-re)
                                    re)
@@ -1839,21 +1843,14 @@ CANDIDATES are assumed to be static."
                           (lambda (x) (string-match re x))
                           ivy--old-cands)))
                       (t
-                       (let ((re-list (if (stringp re) (list (cons re t)) re))
-                             (res candidates))
-                         (dolist (re re-list)
-                           (setq res
-                                 (ignore-errors
-                                   (funcall
-                                    (if (cdr re)
-                                        #'cl-remove-if-not
-                                      #'cl-remove-if)
-                                    (let ((re-str (car re)))
-                                      (lambda (x) (string-match re-str x)))
-                                    res))))
-                         res)))))
+                       (ivy--re-filter re candidates)))))
         (ivy--recompute-index name re-str cands)
-        (setq ivy--old-re (if cands re-str ""))
+        (setq ivy--old-re
+              (if (eq ivy--regex-function 'ivy--regex-ignore-order)
+                  re
+                (if cands
+                    re-str
+                  "")))
         (setq ivy--old-cands (ivy--sort name cands))))))
 
 (defcustom ivy-sort-matches-functions-alist '((t . nil))
@@ -2097,27 +2094,38 @@ SEPARATOR is used to join the candidates."
 (defun ivy--format-minibuffer-line (str)
   (let ((start 0)
         (str (copy-sequence str)))
-    (when (and (eq ivy-display-style 'fancy)
-               (not (eq ivy--regex-function 'ivy--regex-fuzzy)))
-      (unless ivy--old-re
-        (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
-      (while (and (string-match ivy--old-re str start)
-                  (> (- (match-end 0) (match-beginning 0)) 0))
-        (setq start (match-end 0))
-        (let ((i 0))
-          (while (<= i ivy--subexps)
-            (let ((face
-                   (cond ((zerop ivy--subexps)
-                          (cadr ivy-minibuffer-faces))
-                         ((zerop i)
-                          (car ivy-minibuffer-faces))
-                         (t
-                          (nth (1+ (mod (+ i 2) (1- (length 
ivy-minibuffer-faces))))
-                               ivy-minibuffer-faces)))))
-              (ivy-add-face-text-property
-               (match-beginning i) (match-end i)
-               face str))
-            (cl-incf i)))))
+    (cond ((eq ivy--regex-function 'ivy--regex-ignore-order)
+           (when (consp ivy--old-re)
+             (let ((i 1))
+               (dolist (re ivy--old-re)
+                 (when (string-match (car re) str)
+                   (ivy-add-face-text-property
+                    (match-beginning 0) (match-end 0)
+                    (nth (1+ (mod (+ i 2) (1- (length ivy-minibuffer-faces))))
+                         ivy-minibuffer-faces)
+                    str))
+                 (cl-incf i)))))
+          ((and (eq ivy-display-style 'fancy)
+                (not (eq ivy--regex-function 'ivy--regex-fuzzy)))
+           (unless ivy--old-re
+             (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
+           (while (and (string-match ivy--old-re str start)
+                       (> (- (match-end 0) (match-beginning 0)) 0))
+             (setq start (match-end 0))
+             (let ((i 0))
+               (while (<= i ivy--subexps)
+                 (let ((face
+                        (cond ((zerop ivy--subexps)
+                               (cadr ivy-minibuffer-faces))
+                              ((zerop i)
+                               (car ivy-minibuffer-faces))
+                              (t
+                               (nth (1+ (mod (+ i 2) (1- (length 
ivy-minibuffer-faces))))
+                                    ivy-minibuffer-faces)))))
+                   (ivy-add-face-text-property
+                    (match-beginning i) (match-end i)
+                    face str))
+                 (cl-incf i))))))
     str))
 
 (defun ivy--format (cands)



reply via email to

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