[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)
- [elpa] master 0d410d3 047/272: ivy.el (ivy-flx-limit): Configure when flx is used, (continued)
- [elpa] master 0d410d3 047/272: ivy.el (ivy-flx-limit): Configure when flx is used, Oleh Krehel, 2016/04/25
- [elpa] master c210bf6 050/272: counsel.el (counsel-tmm): Fix tmm free variable, Oleh Krehel, 2016/04/25
- [elpa] master bcb81dd 049/272: Fix swiper "backward" search, Oleh Krehel, 2016/04/25
- [elpa] master a1e0063 018/272: ivy.el (ivy--reset-state): Don't null initial-input, Oleh Krehel, 2016/04/25
- [elpa] master fdb21f6 033/272: counsel.el (counsel--async-sentinel): Re-display when no cands, Oleh Krehel, 2016/04/25
- [elpa] master 1365b2b 031/272: Change tramp prompt from "Find File: " to "address@hidden: ", Oleh Krehel, 2016/04/25
- [elpa] master d1216eb 036/272: Add the '!' behavior into `ivy--regex-ignore-order', Oleh Krehel, 2016/04/25
- [elpa] master 66e00ed 034/272: counsel: Add counsel-up-directory to find-file-map, Oleh Krehel, 2016/04/25
- [elpa] master e23c175 039/272: Insert intermediate candidates during async completions, Oleh Krehel, 2016/04/25
- [elpa] master bc4d4a8 043/272: swiper.el (swiper-font-lock-exclude): Add sauron-mode, Oleh Krehel, 2016/04/25
- [elpa] master 93d1adc 026/272: Properly support matching ignoring order,
Oleh Krehel <=
- [elpa] master 9a6b5fd 042/272: Add rcirc-mode to swiper-font-lock-ensure-exclude, Oleh Krehel, 2016/04/25
- [elpa] master ec7da3f 075/272: ivy.el (ivy-help-file): Improve location, Oleh Krehel, 2016/04/25
- [elpa] master c76c005 045/272: Add feedback for sole ivy completion., Oleh Krehel, 2016/04/25
- [elpa] master 59c5f16 044/272: Special case empty ivy-count-format completion., Oleh Krehel, 2016/04/25
- [elpa] master 569c11e 017/272: ivy.el (ivy-completion-in-region): Use compact ivy-count-format, Oleh Krehel, 2016/04/25
- [elpa] master d996215 038/272: Add counsel-descbinds, Oleh Krehel, 2016/04/25
- [elpa] master 9ef344d 062/272: use imenu API to jump to position. required by org-mode, Oleh Krehel, 2016/04/25
- [elpa] master 0a9780b 046/272: ivy.el (ivy--recompute-index): Update cl-position logic, Oleh Krehel, 2016/04/25
- [elpa] master 407ce2c 051/272: counsel.el (counsel-list-processes): New command, Oleh Krehel, 2016/04/25
- [elpa] master e3e1f51 052/272: ivy.el (ivy-ffap-url-functions): Customize "C-x C-f M-n", Oleh Krehel, 2016/04/25