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)))))))))