emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 166f627: Add prefix arg to isearch-repeat-forward/b


From: Juri Linkov
Subject: [Emacs-diffs] master 166f627: Add prefix arg to isearch-repeat-forward/backward (bug#14563, bug#29321)
Date: Tue, 20 Nov 2018 18:43:32 -0500 (EST)

branch: master
commit 166f6274b4118344612e60fba831e223728f3e89
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    Add prefix arg to isearch-repeat-forward/backward (bug#14563, bug#29321)
    
    * lisp/isearch.el (isearch-repeat): Add optional arg COUNT.
    Add a while-loop that calls `isearch-search' COUNT times.
    (isearch-repeat-forward, isearch-repeat-backward):
    Add optional prefix ARG passed down to `isearch-repeat'.
    Handle reversed directions.
---
 etc/NEWS        |  5 ++++
 lisp/isearch.el | 81 +++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 63 insertions(+), 23 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 1382b4d..4ed312c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -640,6 +640,11 @@ can now be searched via 'C-s'.
 
 ** Search and Replace
 
+*** Isearch supports a prefix argument for 'C-s' ('isearch-repeat-forward')
+and 'C-r' ('isearch-repeat-backward').  With a prefix argument, these
+commands repeat the search for the specified occurrence of the search string.
+A negative argument repeats the search in the opposite direction.
+
 *** '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
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 87f4d49..6d94ef6 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -1555,8 +1555,8 @@ Use `isearch-exit' to quit without signaling."
       (isearch-pop-state))
     (isearch-update)))
 
-(defun isearch-repeat (direction)
-  ;; Utility for isearch-repeat-forward and -backward.
+(defun isearch-repeat (direction &optional count)
+  ;; Utility for isearch-repeat-forward and isearch-repeat-backward.
   (if (eq isearch-forward (eq direction 'forward))
       ;; C-s in forward or C-r in reverse.
       (if (equal isearch-string "")
@@ -1587,32 +1587,67 @@ Use `isearch-exit' to quit without signaling."
 
   (if (equal isearch-string "")
       (setq isearch-success t)
-    (if (and isearch-success
-            (equal (point) isearch-other-end)
-            (not isearch-just-started))
-       ;; If repeating a search that found
-       ;; an empty string, ensure we advance.
-       (if (if isearch-forward (eobp) (bobp))
-           ;; If there's nowhere to advance to, fail (and wrap next time).
-           (progn
-             (setq isearch-success nil)
-             (ding))
-         (forward-char (if isearch-forward 1 -1))
+    ;; For the case when count > 1, don't keep intermediate states
+    ;; added to isearch-cmds by isearch-push-state in this loop.
+    (let ((isearch-cmds isearch-cmds))
+      (while (<= 0 (setq count (1- (or count 1))))
+       (if (and isearch-success
+                (equal (point) isearch-other-end)
+                (not isearch-just-started))
+           ;; If repeating a search that found
+           ;; an empty string, ensure we advance.
+           (if (if isearch-forward (eobp) (bobp))
+               ;; If there's nowhere to advance to, fail (and wrap next time).
+               (progn
+                 (setq isearch-success nil)
+                 (ding))
+             (forward-char (if isearch-forward 1 -1))
+             (isearch-search))
          (isearch-search))
-      (isearch-search)))
+       (when (> count 0)
+         ;; Update isearch-cmds, so if isearch-search fails later,
+         ;; it can restore old successful state from isearch-cmds.
+         (isearch-push-state))
+       ;; Stop looping on failure.
+       (when (or (not isearch-success) isearch-error)
+         (setq count 0)))))
 
   (isearch-push-state)
   (isearch-update))
 
-(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 the search ARG times.
+A negative argument searches backwards."
+  (interactive "P")
+  (if arg
+      (let ((count (prefix-numeric-value arg)))
+        (cond ((< count 0)
+               (isearch-repeat-backward (abs count))
+               ;; Reverse the direction back
+               (isearch-repeat 'forward))
+              (t
+               ;; Take into account one iteration to reverse direction
+               (when (not isearch-forward) (setq count (1+ count)))
+               (isearch-repeat 'forward count))))
+    (isearch-repeat 'forward)))
+
+(defun isearch-repeat-backward (&optional arg)
+  "Repeat incremental search backwards.
+With a prefix argument, repeat the search ARG times.
+A negative argument searches forwards."
+  (interactive "P")
+  (if arg
+      (let ((count (prefix-numeric-value arg)))
+        (cond ((< count 0)
+               (isearch-repeat-forward (abs count))
+               ;; Reverse the direction back
+               (isearch-repeat 'backward))
+              (t
+               ;; Take into account one iteration to reverse direction
+               (when isearch-forward (setq count (1+ count)))
+               (isearch-repeat 'backward count))))
+    (isearch-repeat 'backward)))
 
 
 ;;; Toggles for `isearch-regexp-function' and `search-default-mode'.



reply via email to

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