From b4fac8b59ea3f7276740b19065b716fcab68f8c4 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Tue, 22 May 2018 22:53:56 -0600 Subject: [PATCH] Highlight multiple regexps correctly Fixes #654. Fixes #1550. Supersedes #1551. --- ivy.el | 44 +++++++++++++++-------------- swiper.el | 82 +++++++++++++++++++++++++++++-------------------------- 2 files changed, 67 insertions(+), 59 deletions(-) diff --git a/ivy.el b/ivy.el index f8aceb2a..1edfe6ea 100644 --- a/ivy.el +++ b/ivy.el @@ -3315,26 +3315,30 @@ FACE is the face to apply to STR." (string-match "^[^:]+:[^:]+:" str)) (match-end 0) 0)) - (re (ivy-generic-regex-to-str ivy--old-re))) - (ignore-errors - (while (and (string-match 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)))))) + (regexps + (if (listp ivy--old-re) + (mapcar #'car (cl-remove-if-not #'cdr ivy--old-re)) + (list ivy--old-re)))) + (dolist (re regexps) + (ignore-errors + (while (and (string-match 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-minibuffer-line (str) diff --git a/swiper.el b/swiper.el index 288682dc..8e72b63a 100644 --- a/swiper.el +++ b/swiper.el @@ -620,45 +620,49 @@ Matched candidates should have `swiper-invocation-face'." (with-ivy-window (swiper--cleanup) (when (> (length (ivy-state-current ivy-last)) 0) - (let* ((re (funcall ivy--regex-function ivy-text)) - (re (if (stringp re) re (caar re))) - (re (replace-regexp-in-string - " " "\t" - re)) - (str (get-text-property 0 'swiper-line-number (ivy-state-current ivy-last))) - (num (if (string-match "^[0-9]+" str) - (string-to-number (match-string 0 str)) - 0))) - (unless (memq this-command '(ivy-yank-word - scroll-other-window)) - (when (cl-plusp num) - (unless (if swiper--current-line - (eq swiper--current-line num) - (eq (line-number-at-pos) num)) - (goto-char swiper--point-min) - (if swiper-use-visual-line - (line-move (1- num)) - (forward-line (1- num)))) - (if (and (equal ivy-text "") - (>= swiper--opoint (line-beginning-position)) - (<= swiper--opoint (line-end-position))) - (goto-char swiper--opoint) - (if (eq swiper--current-line num) - (when swiper--current-match-start - (goto-char swiper--current-match-start)) - (setq swiper--current-line num)) - (when (re-search-forward re (line-end-position) t) - (setq swiper--current-match-start (match-beginning 0)))) - (isearch-range-invisible (line-beginning-position) - (line-end-position)) - (unless (and (>= (point) (window-start)) - (<= (point) (window-end (ivy-state-window ivy-last) t))) - (recenter)) - (setq swiper--current-window-start (window-start)))) - (swiper--add-overlays - re - (max (window-start) swiper--point-min) - (min (window-end (selected-window) t) swiper--point-max)))))) + (let* ((regexp-or-regexps (funcall ivy--regex-function ivy-text)) + (regexps + (if (listp regexp-or-regexps) + (mapcar #'car (cl-remove-if-not #'cdr regexp-or-regexps)) + (list regexp-or-regexps)))) + (dolist (re regexps) + (let* ((re (replace-regexp-in-string + " " "\t" + re)) + (str (get-text-property 0 'swiper-line-number (ivy-state-current ivy-last))) + (num (if (string-match "^[0-9]+" str) + (string-to-number (match-string 0 str)) + 0))) + (unless (memq this-command '(ivy-yank-word + scroll-other-window)) + (when (cl-plusp num) + (unless (if swiper--current-line + (eq swiper--current-line num) + (eq (line-number-at-pos) num)) + (goto-char swiper--point-min) + (if swiper-use-visual-line + (line-move (1- num)) + (forward-line (1- num)))) + (if (and (equal ivy-text "") + (>= swiper--opoint (line-beginning-position)) + (<= swiper--opoint (line-end-position))) + (goto-char swiper--opoint) + (if (eq swiper--current-line num) + (when swiper--current-match-start + (goto-char swiper--current-match-start)) + (setq swiper--current-line num)) + (when (re-search-forward re (line-end-position) t) + (setq swiper--current-match-start (match-beginning 0)))) + (isearch-range-invisible (line-beginning-position) + (line-end-position)) + (unless (and (>= (point) (window-start)) + (<= (point) (window-end (ivy-state-window ivy-last) t))) + (recenter)) + (setq swiper--current-window-start (window-start)))) + (swiper--add-overlays + re + (max (window-start) swiper--point-min) + (min (window-end (selected-window) t) swiper--point-max)))))))) (defun swiper--add-overlays (re &optional beg end wnd) "Add overlays for RE regexp in visible part of the current buffer.