[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master ca84f24 269/348: Add highlighter function configuration to
From: |
Oleh Krehel |
Subject: |
[elpa] master ca84f24 269/348: Add highlighter function configuration to ivy |
Date: |
Sat, 8 Apr 2017 11:04:12 -0400 (EDT) |
branch: master
commit ca84f24521fac922d41ccfa8b42632b10acc9dd3
Author: Jean-Philippe Bernardy <address@hidden>
Commit: Oleh Krehel <address@hidden>
Add highlighter function configuration to ivy
Use an alist to figure out the highlight function.
Fixes #691
---
ivy.el | 141 +++++++++++++++++++++++++++++++++++++-------------------------
swiper.el | 11 +++++
2 files changed, 95 insertions(+), 57 deletions(-)
diff --git a/ivy.el b/ivy.el
index 8361b94..7c0400a 100644
--- a/ivy.el
+++ b/ivy.el
@@ -436,6 +436,9 @@ When non-nil, it should contain at least one %d.")
(defvar ivy--regex-function 'ivy--regex
"Current function for building a regex.")
+(defvar ivy--highlight-function 'ivy--highlight-default
+ "Current function for formatting the candidates.")
+
(defvar ivy--subexps 0
"Number of groups in the current `ivy--regex'.")
@@ -1298,6 +1301,20 @@ The matches will be filtered in a sequence, you can mix
the
regexps that should match and that should not match as you
like.")
+(defvar ivy-highlight-functions-alist
+ '((ivy--regex-ignore-order . ivy--highlight-ignore-order)
+ (ivy--regex-fuzzy . (:eval (if ivy--flx-featurep 'ivy--highlight-fuzzy
'ivy--highlight-default))))
+ "An alist of highlighting functions for each regex buidler function.
+
+Each value should be either:
+
+1. A function that takes two arguments, STR and START. The
+function should return a highlight STR from the index START, and
+return the result.
+
+2. A plist whose :eval entry is a form, which evaluates to a
+function as in point 1.")
+
(defvar ivy-initial-inputs-alist
'((org-refile . "^")
(org-agenda-refile . "^")
@@ -1537,6 +1554,7 @@ This is useful for recursive `ivy-read'."
(setq ivy-text "")
(setq ivy-calling nil)
(setq ivy-use-ignore ivy-use-ignore-default)
+ (setq ivy--highlight-function (ivy--highlight-function-for-regex-function
ivy--regex-function))
(let (coll sort-fn)
(cond ((eq collection 'Info-read-node-name-1)
(if (equal Info-current-file "dir")
@@ -2440,7 +2458,7 @@ CANDIDATES are assumed to be static."
(setq ivy--old-cands (ivy--sort name cands))
(ivy--recompute-index name re-str ivy--old-cands))
(setq ivy--old-re
- (if (eq ivy--regex-function 'ivy--regex-ignore-order)
+ (if (eq ivy--highlight-function 'ivy--highlight-ignore-order)
re
(if ivy--old-cands
re-str
@@ -2774,63 +2792,72 @@ SEPARATOR is used to join the candidates."
(font-lock-append-text-property
start end 'face face str)))
+(defun ivy--highlight-ignore-order (str _start)
+ "Highlight STR, starting from START, using the ignore-order method."
+ ;; (message "ivy--highlight-ignore-order: old-re = %s" ivy--old-re)
+ (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))))
+ str)
+
+(defun ivy--highlight-fuzzy (str _start)
+ "Highlight STR, starting from START, using the fuzzy method."
+ (let ((flx-name (if (string-match "^\\^" ivy-text)
+ (substring ivy-text 1)
+ ivy-text)))
+ (ivy--flx-propertize
+ (cons (flx-score str flx-name ivy--flx-cache) str))))
+
+(defun ivy--highlight-default (str start)
+ "Highlight STR, starting from START, using the default method."
+ (unless ivy--old-re
+ (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
+ (ignore-errors
+ (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--highlight-function-for-regex-function (regex-fn)
+ "Return a highlighting function which is appropriate for the regex builder
REGEX-FN."
+ (let ((res (cdr (or (assoc regex-fn ivy-highlight-functions-alist)
+ (cons t #'ivy--highlight-default)))))
+ ;; note: alist-get is only available in emacs 25 and above.
+ ;; (despite the documentation not mentioning this fact.)
+ (if (listp res)
+ (eval (plist-get res :eval))
+ res)))
+
(defun ivy--format-minibuffer-line (str)
- (let ((start
- (if (and (memq (ivy-state-caller ivy-last)
- '(counsel-git-grep counsel-ag counsel-rg counsel-pt))
- (string-match "^[^:]+:[^:]+:" str))
- (match-end 0)
- 0))
- (str (copy-sequence str)))
- (when (eq ivy-display-style 'fancy)
- (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
- ivy--flx-featurep
- (or (eq ivy--regex-function 'ivy--regex-fuzzy)
- (and (eq ivy--regex-function 'swiper--re-builder)
- (let ((caller (ivy-state-caller ivy-last)))
- (eq (or (and caller
- (cdr (assoc caller
ivy-re-builders-alist)))
- (cdr (assoc t ivy-re-builders-alist)))
- 'ivy--regex-fuzzy)))))
- (let ((flx-name (if (string-match "^\\^" ivy-text)
- (substring ivy-text 1)
- ivy-text)))
- (setq str
- (ivy--flx-propertize
- (cons (flx-score str flx-name ivy--flx-cache) str)))))
- (t
- (unless ivy--old-re
- (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
- (ignore-errors
- (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))
+ (when (eq ivy-display-style 'fancy)
+ (let ((start
+ (if (and (memq (ivy-state-caller ivy-last)
+ '(counsel-git-grep counsel-ag counsel-rg counsel-pt))
+ (string-match "^[^:]+:[^:]+:" str))
+ (match-end 0)
+ 0)))
+ (funcall ivy--highlight-function (copy-sequence str) start))))
(ivy-set-display-transformer
'counsel-find-file 'ivy-read-file-transformer)
diff --git a/swiper.el b/swiper.el
index 56e8d54..1d6aa8a 100644
--- a/swiper.el
+++ b/swiper.el
@@ -420,6 +420,17 @@ When REVERT is non-nil, regenerate the current *ivy-occur*
buffer."
(when (bound-and-true-p evil-mode)
(evil-set-jump)))
+(defun swiper--highlighter ()
+ "Return the correct highlighter for swiper."
+ (let ((re-builder
+ (or (cdr (assoc 'swiper ivy-re-builders-alist))
+ (cdr (assoc t ivy-re-builders-alist))))
+ (ivy-highlight-functions-alist
+ (assq-delete-all 'swiper--re-builder (copy-alist
ivy-highlight-functions-alist))))
+ (ivy--highlight-function-for-regex-function re-builder)))
+
+(push '(swiper--re-builder . (:eval (swiper--highlighter)))
ivy-highlight-functions-alist)
+
(defun swiper--re-builder (str)
"Transform STR into a swiper regex.
This is the regex used in the minibuffer where candidates have
- [elpa] master fc5c8fc 159/348: Fix ivy-occur-press for swiper, (continued)
- [elpa] master fc5c8fc 159/348: Fix ivy-occur-press for swiper, Oleh Krehel, 2017/04/08
- [elpa] master e98883f 162/348: Improve fuzzy swiper highlight, Oleh Krehel, 2017/04/08
- [elpa] master 9b28927 187/348: counsel.el (counsel-hydra-heads): Fixup, Oleh Krehel, 2017/04/08
- [elpa] master 00219da 181/348: Fix for older Emacs, Oleh Krehel, 2017/04/08
- [elpa] master 8f87f74 178/348: counsel.el (counsel-git-grep): Update for Windows, Oleh Krehel, 2017/04/08
- [elpa] master 79105a5 208/348: counsel.el (counsel-info-lookup-symbol): Add preselect, Oleh Krehel, 2017/04/08
- [elpa] master 222a5e6 217/348: ivy.el (ivy--virtual-buffers): Move to silence compiler, Oleh Krehel, 2017/04/08
- [elpa] master 35b5d29 230/348: New example to show how to associate values, Oleh Krehel, 2017/04/08
- [elpa] master e9c274a 236/348: Allow to customize ivy-display-function per caller, Oleh Krehel, 2017/04/08
- [elpa] master c14ceac 245/348: Add support for counsel-find-library, Oleh Krehel, 2017/04/08
- [elpa] master ca84f24 269/348: Add highlighter function configuration to ivy,
Oleh Krehel <=
- [elpa] master 5701444 314/348: ivy.el (ivy-occur-revert-buffer): Restore ivy-occur-last, Oleh Krehel, 2017/04/08
- [elpa] master 13def15 318/348: ivy.el (ivy-case-fold-search): Add additional value 'always, Oleh Krehel, 2017/04/08
- [elpa] master 54c5447 319/348: counsel.el (counsel-grep-function): Add shell-quote-argument, Oleh Krehel, 2017/04/08
- [elpa] master bf8dc5f 326/348: Make swiper-avy work with more regexp builders, Oleh Krehel, 2017/04/08
- [elpa] master 03f90af 324/348: ivy.el (ivy-rotate-sort): Guard against nil sort, Oleh Krehel, 2017/04/08
- [elpa] master ac944ea 325/348: ivy.el: Remove with-ivy-window, Oleh Krehel, 2017/04/08
- [elpa] master 18da759 320/348: ivy.el: Remove ivy--current, Oleh Krehel, 2017/04/08
- [elpa] master 20744aa 337/348: doc/Changelog.org: Prepare for 0.9.0, Oleh Krehel, 2017/04/08
- [elpa] master 13a3f2d 342/348: doc/Changelog.org: Sort stuff, Oleh Krehel, 2017/04/08
- [elpa] master 69dfed9 146/348: counsel.el (counsel-dpkg): Remove typo, Oleh Krehel, 2017/04/08