emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 35a88c8: Isearch hit count. (Bug#29321)


From: Juri Linkov
Subject: [Emacs-diffs] master 35a88c8: Isearch hit count. (Bug#29321)
Date: Wed, 14 Nov 2018 17:23:56 -0500 (EST)

branch: master
commit 35a88c809e9eb5a32dd8d7f0dae960021f4cd707
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    Isearch hit count.  (Bug#29321)
    
    * lisp/isearch.el (isearch-lazy-count): New defcustom.
    (lazy-count): New defgroup.
    (lazy-count-prefix-format, lazy-count-suffix-format): New defcustom.
    (isearch-lazy-count-format): New function.
    (isearch-message-prefix, isearch-message-suffix): Use it.
    (isearch-lazy-highlight-window-start-changed)
    (isearch-lazy-highlight-window-end-changed)
    (isearch-lazy-count-current, isearch-lazy-count-total)
    (isearch-lazy-count-hash): New variables.
    (isearch-lazy-highlight-new-loop): Reset isearch-lazy-count-total
    and update isearch-lazy-count-current for isearch-message.
    (isearch-lazy-highlight-update): Run full-buffer loop for
    isearch-lazy-count.
    (isearch-lazy-highlight-buffer-update): Count isearch-lazy-count-total.
    Set isearch-lazy-count-current at the end.
---
 etc/NEWS        |   6 +++
 lisp/isearch.el | 147 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 136 insertions(+), 17 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index dff7c5d..76531f2 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -621,6 +621,12 @@ can now be searched via 'C-s'.
 
 ** Search and Replace
 
+*** isearch-lazy-count shows the current match number and total number
+of matches in the Isearch prompt.  Customizable variables
+lazy-count-prefix-format and lazy-count-suffix-format define the
+format of the current and the total number of matches in the prompt's
+prefix and suffix respectively.
+
 *** lazy-highlight-buffer highlights matches in the full buffer.
 It is useful in combination with lazy-highlight-cleanup customized to nil
 to leave matches highlighted in the whole buffer after exiting isearch.
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 42b3aa4..035ff69 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -316,6 +316,16 @@ this variable is set to the symbol `all-windows'."
   :group 'lazy-highlight
   :group 'isearch)
 
+(defcustom isearch-lazy-count nil
+  "Show match numbers in the search prompt.
+When both this option and `isearch-lazy-highlight' are non-nil,
+show the current match number and the total number of matches
+in the buffer (or its restriction)."
+  :type 'boolean
+  :group 'lazy-count
+  :group 'isearch
+  :version "27.1")
+
 ;;; Lazy highlight customization.
 
 (defgroup lazy-highlight nil
@@ -386,6 +396,29 @@ and doesn't remove full-buffer highlighting after a 
search."
   :group 'lazy-highlight
   :group 'basic-faces)
 
+;;; Lazy count customization.
+
+(defgroup lazy-count nil
+  "Lazy counting feature for reporting the number of matches."
+  :prefix "lazy-count-"
+  :version "27.1"
+  :group 'isearch
+  :group 'matching)
+
+(defcustom lazy-count-prefix-format "%s/%s "
+  "Format of the current/total number of matches for the prompt prefix."
+  :type '(choice (const :tag "No prefix" nil)
+                 (string :tag "Prefix format string" "%s/%s "))
+  :group 'lazy-count
+  :version "27.1")
+
+(defcustom lazy-count-suffix-format nil
+  "Format of the current/total number of matches for the prompt suffix."
+  :type '(choice (const :tag "No suffix" nil)
+                 (string :tag "Suffix format string" " [%s of %s]"))
+  :group 'lazy-count
+  :version "27.1")
+
 
 ;; Define isearch help map.
 
@@ -2794,7 +2827,8 @@ the word mode."
                        (concat " [" current-input-method-title "]: "))
                     ": ")
                   )))
-    (propertize (concat (upcase (substring m 0 1)) (substring m 1))
+    (propertize (concat (isearch-lazy-count-format)
+                        (upcase (substring m 0 1)) (substring m 1))
                'face 'minibuffer-prompt)))
 
 (defun isearch-message-suffix (&optional c-q-hack)
@@ -2802,9 +2836,33 @@ the word mode."
                      (if isearch-error
                          (concat " [" isearch-error "]")
                        "")
+                      (isearch-lazy-count-format 'suffix)
                      (or isearch-message-suffix-add ""))
               'face 'minibuffer-prompt))
 
+(defun isearch-lazy-count-format (&optional suffix-p)
+  "Format the current match number and the total number of matches.
+When SUFFIX-P is non-nil, the returned string is indended for
+isearch-message-suffix prompt.  Otherwise, for isearch-message-prefix."
+  (let ((format-string (if suffix-p
+                           lazy-count-suffix-format
+                         lazy-count-prefix-format)))
+    (if (and format-string
+             isearch-lazy-count
+             isearch-lazy-count-current
+             (not isearch-error)
+             (not isearch-suspended))
+        (format format-string
+                (if isearch-forward
+                    isearch-lazy-count-current
+                  (if (eq isearch-lazy-count-current 0)
+                      0
+                    (- isearch-lazy-count-total
+                       isearch-lazy-count-current
+                       -1)))
+                (or isearch-lazy-count-total "?"))
+      "")))
+
 
 ;; Searching
 
@@ -3202,6 +3260,8 @@ since they have special meaning in a regexp."
 (defvar isearch-lazy-highlight-window-group nil)
 (defvar isearch-lazy-highlight-window-start nil)
 (defvar isearch-lazy-highlight-window-end nil)
+(defvar isearch-lazy-highlight-window-start-changed nil)
+(defvar isearch-lazy-highlight-window-end-changed nil)
 (defvar isearch-lazy-highlight-point-min nil)
 (defvar isearch-lazy-highlight-point-max nil)
 (defvar isearch-lazy-highlight-buffer nil)
@@ -3214,6 +3274,9 @@ since they have special meaning in a regexp."
 (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-hash (make-hash-table))
 
 (defun lazy-highlight-cleanup (&optional force procrastinate)
   "Stop lazy highlighting and remove extra highlighting from current buffer.
@@ -3258,18 +3321,41 @@ by other Emacs features."
                 ;; In case we are recovering from an error.
                 (not (equal isearch-error
                             isearch-lazy-highlight-error))
-                (not (if lazy-highlight-buffer
-                         (= (point-min)
-                            isearch-lazy-highlight-point-min)
-                       (= (window-group-start)
-                          isearch-lazy-highlight-window-start)))
-                (not (if lazy-highlight-buffer
-                         (= (point-max)
-                            isearch-lazy-highlight-point-max)
-                       (= (window-group-end) ; Window may have been 
split/joined.
-                          isearch-lazy-highlight-window-end)))))
+                (if lazy-highlight-buffer
+                    (not (= (point-min)
+                            isearch-lazy-highlight-point-min))
+                  (setq isearch-lazy-highlight-window-start-changed
+                        (not (= (window-group-start)
+                                isearch-lazy-highlight-window-start))))
+                (if lazy-highlight-buffer
+                    (not (= (point-max)
+                            isearch-lazy-highlight-point-max))
+                  (setq isearch-lazy-highlight-window-end-changed
+                        (not (= (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
+    (when isearch-lazy-count
+      (when (or (equal isearch-string "")
+                ;; Check if this place was reached by a condition above
+                ;; other than changed window boundaries (that shouldn't
+                ;; reset the counter)
+                (and (not isearch-lazy-highlight-window-start-changed)
+                     (not isearch-lazy-highlight-window-end-changed))
+                ;; Also check for changes in buffer boundaries in
+                ;; a possibly narrowed buffer in case lazy-highlight-buffer
+                ;; is nil, thus the same check was not performed above
+                (not (= (point-min)
+                        isearch-lazy-highlight-point-min))
+                (not (= (point-max)
+                        isearch-lazy-highlight-point-max)))
+        ;; Reset old counter before going to count new numbers
+        (clrhash isearch-lazy-count-hash)
+        (setq isearch-lazy-count-current nil
+              isearch-lazy-count-total nil)
+        (funcall (or isearch-message-function #'isearch-message))))
+    (setq isearch-lazy-highlight-window-start-changed nil)
+    (setq isearch-lazy-highlight-window-end-changed nil)
     (setq isearch-lazy-highlight-error isearch-error)
     ;; It used to check for `(not isearch-error)' here, but actually
     ;; lazy-highlighting might find matches to highlight even when
@@ -3313,7 +3399,16 @@ by other Emacs features."
     (unless (equal isearch-string "")
       (setq isearch-lazy-highlight-timer
             (run-with-idle-timer lazy-highlight-initial-delay nil
-                                 'isearch-lazy-highlight-start)))))
+                                 'isearch-lazy-highlight-start))))
+  ;; Update the current match number only in isearch-mode and
+  ;; unless isearch-mode is used specially with isearch-message-function
+  (when (and isearch-lazy-count isearch-mode (null isearch-message-function))
+    ;; Update isearch-lazy-count-current only when it was already set
+    ;; at the end of isearch-lazy-highlight-buffer-update
+    (when isearch-lazy-count-current
+      (setq isearch-lazy-count-current
+            (gethash (point) isearch-lazy-count-hash 0))
+      (isearch-message nil t))))
 
 (defun isearch-lazy-highlight-search (string bound)
   "Search ahead for the next or previous match, for lazy highlighting.
@@ -3434,7 +3529,8 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                        (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
+                         (and isearch-lazy-count (null 
isearch-lazy-count-current)))
                  (if isearch-lazy-highlight-forward
                      (setq isearch-lazy-highlight-end (point-min))
                    (setq isearch-lazy-highlight-start (point-max)))
@@ -3448,7 +3544,8 @@ Attempt to do the search exactly the way the pending 
Isearch would."
   "Update highlighting of other matches in the full buffer."
   (let ((max lazy-highlight-buffer-max-at-a-time)
         (looping t)
-        nomore window-start window-end)
+        nomore window-start window-end
+        (opoint (point)))
     (with-local-quit
       (save-selected-window
        (if (and (window-live-p isearch-lazy-highlight-window)
@@ -3483,8 +3580,18 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                            (if (= mb (point-min))
                                (setq found nil)
                              (forward-char -1)))
-                       ;; Already highlighted by isearch-lazy-highlight-update
-                       (unless (and (>= mb window-start) (<= me window-end))
+                       (when isearch-lazy-count
+                         (setq isearch-lazy-count-total
+                               (1+ (or isearch-lazy-count-total 0)))
+                         (puthash (if isearch-lazy-highlight-forward me mb)
+                                  isearch-lazy-count-total
+                                  isearch-lazy-count-hash))
+                       ;; Don't highlight the match when this loop is used
+                       ;; only to count matches or when matches were already
+                       ;; highlighted within the current window boundaries
+                       ;; by isearch-lazy-highlight-update
+                       (unless (or (not isearch-lazy-highlight-buffer)
+                                   (and (>= mb window-start) (<= me 
window-end)))
                          ;; non-zero-length match
                          (isearch-lazy-highlight-match mb me)))
                      ;; Remember the current position of point for
@@ -3498,7 +3605,13 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                (if (not found)
                    (setq looping nil
                          nomore  t))))
-           (unless nomore
+           (if nomore
+               (when (and isearch-lazy-count isearch-mode (null 
isearch-message-function))
+                 (unless isearch-lazy-count-total
+                   (setq isearch-lazy-count-total 0))
+                 (setq isearch-lazy-count-current
+                       (gethash opoint isearch-lazy-count-hash 0))
+                 (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]