[Top][All Lists]

[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: Thu, 15 Nov 2018 00:36:37 +0200
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.

Lazy-counting is now pushed to master.

> If we had this, it would also be convenient to say "go forward n
> matches", so that typing "M-3 C-s" during a search would be the
> equivalent of typing C-s three times.  To do this we could add numeric
> prefix arg handling to C-s/C-r/C-M-s/C-M-r, if that isn't already
> taken for some other behavior.

Adding a numeric prefix arg to C-s/C-r is implemented in

But this implementation causes flicker because it updates
isearch highlighting on every search hit while traversing
all found matches COUNT times until it reaches COUNT-th match.

Attached is a better approach that adds the COUNT arg to
isearch functions down to the lowest-level isearch function,
thus making it compatible with the COUNT arg of re-search-forward:

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 035ff69327..3e6e696a74 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1547,7 +1547,7 @@ isearch-abort
-(defun isearch-repeat (direction)
+(defun isearch-repeat (direction &optional count)
   ;; Utility for isearch-repeat-forward and -backward.
   (if (eq isearch-forward (eq direction 'forward))
       ;; C-s in forward or C-r in reverse.
@@ -1590,21 +1590,29 @@ isearch-repeat
              (setq isearch-success nil)
          (forward-char (if isearch-forward 1 -1))
-         (isearch-search))
-      (isearch-search)))
+         (isearch-search count))
+      (isearch-search count)))
-(defun isearch-repeat-forward ()
-  "Repeat incremental search forwards."
-  (interactive)
-  (isearch-repeat 'forward))
-(defun isearch-repeat-backward ()
-  "Repeat incremental search backwards."
-  (interactive)
-  (isearch-repeat 'backward))
+(defun isearch-repeat-forward (&optional arg)
+  "Repeat incremental search forwards.
+With a prefix argument, repeat a search ARG times."
+  (interactive "P")
+  (let ((count (and arg (abs (prefix-numeric-value arg)))))
+    ;; Take into account one search iteration to reverse direction.
+    (when (and count (not isearch-forward)) (setq count (1+ count)))
+    (isearch-repeat 'forward count)))
+(defun isearch-repeat-backward (&optional arg)
+  "Repeat incremental search backwards.
+With a prefix argument, repeat a search ARG times."
+  (interactive "P")
+  (let ((count (and arg (abs (prefix-numeric-value arg)))))
+    ;; Take into account one search iteration to reverse direction.
+    (when (and count isearch-forward) (setq count (1+ count)))
+    (isearch-repeat 'backward count)))
 ;;; Toggles for `isearch-regexp-function' and `search-default-mode'.
@@ -2910,7 +2918,7 @@ isearch-search-fun-default
              (t (regexp-quote string)))
        bound noerror count))))
-(defun isearch-search-string (string bound noerror)
+(defun isearch-search-string (string bound noerror &optional count)
   "Search for the first occurrence of STRING or its translation.
 STRING's characters are translated using `translation-table-for-input'
 if that is non-nil.
@@ -2921,7 +2929,10 @@ isearch-search-string
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil."
   (let* ((func (isearch-search-fun))
-         (pos1 (save-excursion (funcall func string bound noerror)))
+         (pos1 (save-excursion (if count
+                                   (funcall func string bound noerror count)
+                                 ;; Backward-compatibility for functions that 
don't support count arg
+                                 (funcall func string bound noerror))))
     (when (and
           ;; Avoid "obsolete" warnings for translation-table-for-input.
@@ -2960,7 +2971,7 @@ isearch-search-string
       (goto-char pos1)
-(defun isearch-search ()
+(defun isearch-search (&optional count)
   ;; Do the search with the current search string.
   (if (and (eq isearch-case-fold-search t) search-upper-case)
       (setq isearch-case-fold-search
@@ -2974,7 +2985,7 @@ isearch-search
        (setq isearch-error nil)
        (while retry
          (setq isearch-success
-               (isearch-search-string isearch-string nil t))
+               (isearch-search-string isearch-string nil t count))
          ;; Clear RETRY unless the search predicate says
          ;; to skip this search hit.
          (if (or (not isearch-success)

reply via email to

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