bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#29321: Isearch hit count


From: Juri Linkov
Subject: bug#29321: Isearch hit count
Date: Sat, 27 Oct 2018 23:55:56 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu)

> Isearch could show in the mode line how many matches follow or precede 
> the currently highlighted one (or we could write "3 of 4 matches", as, 
> e.g., Firefox does).  For big files, it could be helpful to calculate 
> this information either lazily or in another thread.

Thanks to Drew, now we have the full-buffer lazy-highlighting
loop that can be reused for Isearch hit count.

Here is a minimal patch that implements this feature:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 580b3ac40a..8c264ab3ed 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -316,6 +316,13 @@ isearch-lazy-highlight
   :group 'lazy-highlight
   :group 'isearch)
 
+(defcustom isearch-lazy-count nil
+  "Counts matches in the full buffer.
+When non-nil, all matches in the full buffer are counted."
+  :type 'boolean
+  :group 'isearch
+  :version "27.1")
+
 ;;; Lazy highlight customization.
 
 (defgroup lazy-highlight nil
@@ -2794,7 +2801,15 @@ isearch-message-prefix
                        (concat " [" current-input-method-title "]: "))
                     ": ")
                   )))
-    (propertize (concat (upcase (substring m 0 1)) (substring m 1))
+    (propertize (concat (if (and isearch-lazy-count isearch-lazy-count-current)
+                            (format "%d/%d " (if isearch-forward
+                                                 isearch-lazy-count-current
+                                               (- isearch-lazy-count-total
+                                                  isearch-lazy-count-current
+                                                  -1))
+                                    (or isearch-lazy-count-total "?"))
+                          "")
+                        (upcase (substring m 0 1)) (substring m 1))
                'face 'minibuffer-prompt)))
 
 (defun isearch-message-suffix (&optional c-q-hack)
@@ -3212,6 +3227,10 @@ 'isearch-lazy-highlight-word
 (defvar isearch-lazy-highlight-regexp-function nil)
 (defvar isearch-lazy-highlight-forward nil)
 (defvar isearch-lazy-highlight-error nil)
+(defvar isearch-lazy-count-current nil)
+(defvar isearch-lazy-count-total nil)
+(defvar isearch-lazy-count-start nil)
+(defvar isearch-lazy-count-hash (make-hash-table))
 
 (defun lazy-highlight-cleanup (&optional force procrastinate)
   "Stop lazy highlighting and remove extra highlighting from current buffer.
@@ -3235,8 +3254,7 @@ isearch-lazy-highlight-new-loop
 This is called when `isearch-update' is invoked (which can cause the
 search string to change or the window to scroll).  It is also used
 by other Emacs features."
-  (when (and (null executing-kbd-macro)
-             (sit-for 0)         ;make sure (window-start) is credible
+  (setq isearch-lazy-count-start
         (or (not (equal isearch-string
                         isearch-lazy-highlight-last-string))
             (not (memq (selected-window)
@@ -3251,17 +3269,20 @@ isearch-lazy-highlight-new-loop
                     isearch-lax-whitespace))
            (not (eq isearch-lazy-highlight-regexp-lax-whitespace
                     isearch-regexp-lax-whitespace))
-                (not (or lazy-highlight-buffer
-                         (= (window-group-start)
-                            isearch-lazy-highlight-window-start)))
-                (not (or lazy-highlight-buffer
-                         (= (window-group-end) ; Window may have been 
split/joined.
-                            isearch-lazy-highlight-window-end)))
            (not (eq isearch-forward
                     isearch-lazy-highlight-forward))
            ;; In case we are recovering from an error.
            (not (equal isearch-error
                        isearch-lazy-highlight-error))))
+  (when (and (null executing-kbd-macro)
+             (sit-for 0)         ;make sure (window-start) is credible
+             (or isearch-lazy-count-start
+                 (not (or lazy-highlight-buffer
+                         (= (window-group-start)
+                            isearch-lazy-highlight-window-start)))
+                (not (or lazy-highlight-buffer
+                         (= (window-group-end) ; Window may have been 
split/joined.
+                            isearch-lazy-highlight-window-end)))))
     ;; something important did indeed change
     (lazy-highlight-cleanup t (not (equal isearch-string ""))) ;stop old timer
     (setq isearch-lazy-highlight-error isearch-error)
@@ -3303,9 +3324,18 @@ isearch-lazy-highlight-new-loop
                    (1- (length isearch-lazy-highlight-last-string)))
                 (point-min))))
     (unless (equal isearch-string "")
+      (when (and isearch-lazy-count isearch-mode)
+        (when isearch-lazy-count-start
+          (clrhash isearch-lazy-count-hash)
+          (setq isearch-lazy-count-current nil
+                isearch-lazy-count-total nil)))
       (setq isearch-lazy-highlight-timer
             (run-with-idle-timer lazy-highlight-initial-delay nil
-                                 'isearch-lazy-highlight-start)))))
+                                 'isearch-lazy-highlight-start))))
+  (when (and isearch-lazy-count isearch-mode)
+    (setq isearch-lazy-count-current
+          (gethash isearch-other-end isearch-lazy-count-hash))
+    (funcall (or isearch-message-function #'isearch-message) nil t)))
 
 (defun isearch-lazy-highlight-search (string bound)
   "Search ahead for the next or previous match, for lazy highlighting.
@@ -3426,7 +3456,8 @@ isearch-lazy-highlight-update
                        (goto-char (min (or isearch-lazy-highlight-end-limit 
(point-max))
                                        window-end)))))))
            (if nomore
-               (when isearch-lazy-highlight-buffer
+                (when (or isearch-lazy-highlight-buffer
+                          isearch-lazy-count-start)
                  (if isearch-lazy-highlight-forward
                      (setq isearch-lazy-highlight-end (point-min))
                    (setq isearch-lazy-highlight-start (point-max)))
@@ -3475,8 +3506,13 @@ isearch-lazy-highlight-buffer-update
                            (if (= mb (point-min))
                                (setq found nil)
                              (forward-char -1)))
+                        (setq isearch-lazy-count-total (1+ (or 
isearch-lazy-count-total 0)))
+                        (puthash (if isearch-lazy-highlight-forward mb me)
+                                 isearch-lazy-count-total
+                                 isearch-lazy-count-hash)
                        ;; Already highlighted by isearch-lazy-highlight-update
-                       (unless (and (>= mb window-start) (<= me window-end))
+                        (unless (or (and (>= mb window-start) (<= me 
window-end))
+                                    (not isearch-lazy-highlight-buffer))
                          ;; non-zero-length match
                          (isearch-lazy-highlight-match mb me)))
                      ;; Remember the current position of point for
@@ -3491,6 +3527,10 @@ isearch-lazy-highlight-buffer-update
                    (setq looping nil
                          nomore  t))))
            (unless nomore
+             (when (and isearch-lazy-count isearch-mode)
+                (setq isearch-lazy-count-current
+                      (gethash isearch-other-end isearch-lazy-count-hash))
+                (funcall (or isearch-message-function #'isearch-message) nil 
t))
              (setq isearch-lazy-highlight-timer
                    (run-at-time lazy-highlight-interval nil
                                 'isearch-lazy-highlight-buffer-update)))))))))

reply via email to

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