branch: elpa/anzu
commit ff4393fac5ed9bc4adaf723b15e119ebec1021c1
Author: Syohei YOSHIDA <[email protected]>
Commit: Syohei YOSHIDA <[email protected]>
Add feature that highlight replaced texts
---
anzu.el | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 60 insertions(+), 8 deletions(-)
diff --git a/anzu.el b/anzu.el
index fab96b0c5d..a20bac97dd 100644
--- a/anzu.el
+++ b/anzu.el
@@ -90,6 +90,11 @@
"face of anzu modeline"
:group 'anzu)
+(defface anzu-replace-highlight
+ '((t :inherit query-replace))
+ "highlight of replaced string"
+ :group 'anzu)
+
(defvar anzu--total-matched 0)
(defvar anzu--current-posion 0)
(defvar anzu--overflow-p nil)
@@ -100,6 +105,7 @@
(defvar anzu--cached-count 0)
(defvar anzu--replace-begin nil)
(defvar anzu--replace-end nil)
+(defvar anzu--window-height 0)
(defun anzu--validate-regexp (regexp)
(condition-case err
@@ -243,19 +249,56 @@
(query-replace-descr (cdr query-replace-defaults)))
prompt)))
+(defun anzu--add-overlay (beg end)
+ (let ((ov (make-overlay beg end)))
+ (overlay-put ov 'face 'anzu-replace-highlight)
+ (overlay-put ov 'anzu-replace t)))
+
+(defsubst anzu--case-fold-search (input)
+ (let ((case-fold-search nil))
+ (not (string-match-p "[A-Z]" input))))
+
(defun anzu--count-matched (buf str use-regexp)
(when (not use-regexp)
(setq str (regexp-quote str)))
(if (not (anzu--validate-regexp str))
anzu--cached-count
(with-current-buffer buf
- (setq anzu--cached-count
- (how-many str anzu--replace-begin anzu--replace-end)))))
+ (save-excursion
+ (let* ((overlay-beg anzu--replace-begin)
+ (overlay-end (min (save-excursion
+ (forward-line anzu--window-height)
+ (point))
+ anzu--replace-end)))
+ (goto-char anzu--replace-begin)
+ (let ((count 0)
+ (finish nil)
+ (case-fold-search (anzu--case-fold-search str)))
+ (while (and (not finish) (re-search-forward str anzu--replace-end
t))
+ (incf count)
+ (let ((beg (match-beginning 0))
+ (end (match-end 0)))
+ (if (= beg end)
+ (if (eobp)
+ (setq finish t)
+ (forward-char 1))
+ (when (and (>= beg overlay-beg) (<= end overlay-end))
+ (anzu--add-overlay beg end)))))
+ (setq anzu--cached-count count)))))))
(defun anzu--check-minibuffer-input (buf use-regexp)
- (let ((matched (anzu--count-matched buf (minibuffer-contents) use-regexp)))
- (setq anzu--total-matched matched)
- (force-mode-line-update)))
+ (let ((content (minibuffer-contents)))
+ (let ((matched (if (string= content "")
+ (setq anzu--cached-count 0)
+ (anzu--count-matched buf content use-regexp))))
+ (setq anzu--total-matched matched)
+ (force-mode-line-update))))
+
+(defun anzu--clear-overlays (buf beg end)
+ (with-current-buffer buf
+ (dolist (ov (overlays-in (or beg (point-min)) (or end (point-max))))
+ (when (overlay-get ov 'anzu-replace)
+ (delete-overlay ov)))))
(defun anzu--read-from-string (prompt use-regexp)
(let ((curbuf (current-buffer))
@@ -267,6 +310,7 @@
(max anzu-input-idle-delay 0.01)
'repeat
(lambda ()
+ (anzu--clear-overlays curbuf nil nil)
(with-selected-window (or
(active-minibuffer-window)
(minibuffer-window))
(anzu--check-minibuffer-input curbuf
use-regexp))))))
@@ -303,21 +347,29 @@
anzu--replace-end end))
(defun anzu--query-replace-common (use-regexp)
+ (setq anzu--window-height (window-height))
(anzu--cons-mode-line 'replace)
(let* ((use-region (use-region-p))
- (beg (and use-region (region-beginning)))
- (end (and use-region (region-end)))
+ (beg (if use-region (region-beginning) (point)))
+ (end (if use-region (region-end) (point-max)))
(prompt (anzu--query-prompt use-region use-regexp))
- (delimited current-prefix-arg))
+ (delimited current-prefix-arg)
+ (curbuf (current-buffer))
+ (clear-overlay nil))
+ (anzu--set-region-information beg end)
(unwind-protect
(let* ((from (anzu--query-from-string prompt use-regexp))
(to (if (consp from)
(prog1 (cdr from) (setq from (car from)))
(query-replace-read-to from prompt use-regexp))))
+ (anzu--clear-overlays curbuf beg end)
+ (setq clear-overlay t)
(if use-regexp
(perform-replace from to t t delimited nil nil beg end)
(query-replace from to delimited beg end)))
(progn
+ (unless clear-overlay
+ (anzu--clear-overlays curbuf beg end))
(anzu--reset-mode-line)
(force-mode-line-update)))))