GNU bug report logs - #14563
Add prefix arg to more isearch commands

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> jurta.org>

Date: Thu, 6 Jun 2013 06:40:03 UTC

Severity: wishlist

Tags: patch

Done: Juri Linkov <juri <at> jurta.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 14563 in the body.
You can then email your comments to 14563 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#14563; Package emacs. (Thu, 06 Jun 2013 06:40:09 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> jurta.org>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 06 Jun 2013 06:40:12 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: bug-gnu-emacs <at> gnu.org
Subject: Add prefix arg to more isearch commands
Date: Thu, 06 Jun 2013 09:30:40 +0300
Severity: wishlist
Tags: patch

Since bug#9706 to allow a prefix arg pass to isearch commands
is done now more isearch commands can support prefix args.

bug#10614 and bug#10638 deals with adding a prefix arg to
`isearch-repeat-forward' and `isearch-repeat-backward'.

And the following patch adds a prefix arg to
`isearch-quote-char' (to use the same args as in `quoted-insert'),
`isearch-printing-char' (to use the same args as in `insert-char'),
`isearch-process-search-char' and
`isearch-process-search-multibyte-characters':

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-06-05 20:57:09 +0000
+++ lisp/isearch.el	2013-06-06 06:28:07 +0000
@@ -2381,9 +2585,11 @@ (defun isearch-other-meta-char (&optiona
           (t;; otherwise nil
 	   (isearch-process-search-string key key)))))
 
-(defun isearch-quote-char ()
-  "Quote special characters for incremental search."
-  (interactive)
+(defun isearch-quote-char (&optional count)
+  "Quote special characters for incremental search.
+With argument, add COUNT copies of the character."
+  (interactive "p")
   (let ((char (read-quoted-char (isearch-message t))))
     ;; Assume character codes 0200 - 0377 stand for characters in some
     ;; single-byte character set, and convert them to Emacs
@@ -2391,24 +2597,27 @@ (defun isearch-quote-char ()
     (if (and isearch-regexp isearch-regexp-lax-whitespace (= char ?\s))
 	(if (subregexp-context-p isearch-string (length isearch-string))
 	    (isearch-process-search-string "[ ]" " ")
-	  (isearch-process-search-char char))
+	  (isearch-process-search-char char count))
       (and enable-multibyte-characters
 	   (>= char ?\200)
 	   (<= char ?\377)
 	   (setq char (unibyte-char-to-multibyte char)))
-      (isearch-process-search-char char))))
+      (isearch-process-search-char char count))))
 
-(defun isearch-printing-char ()
-  "Add this ordinary printing character to the search string and search."
-  (interactive)
-  (let ((char last-command-event))
+(defun isearch-printing-char (&optional char count)
+  "Add this ordinary printing CHAR to the search string and search.
+With argument, add COUNT copies of the character."
+  (interactive (list last-command-event
+		     (prefix-numeric-value current-prefix-arg)))
+  (let ((char (or char last-command-event)))
     (if (= char ?\S-\ )
 	(setq char ?\s))
     (if current-input-method
-	(isearch-process-search-multibyte-characters char)
-      (isearch-process-search-char char))))
+	(isearch-process-search-multibyte-characters char count)
+      (isearch-process-search-char char count))))
 
-(defun isearch-process-search-char (char)
+(defun isearch-process-search-char (char &optional count)
   ;; * and ? are special in regexps when not preceded by \.
   ;; } and | are special in regexps when preceded by \.
   ;; Nothing special for + because it matches at least once.
@@ -2417,12 +2627,15 @@ (defun isearch-process-search-char (char
    ((eq   char ?\})      (isearch-fallback t t))
    ((eq   char ?|)       (isearch-fallback t nil t)))
 
-  ;; Append the char to the search string, update the message and re-search.
-  (isearch-process-search-string
-   (char-to-string char)
-   (if (>= char ?\200)
-       (char-to-string char)
-     (isearch-text-char-description char))))
+  ;; Append the char(s) to the search string,
+  ;; update the message and re-search.
+  (let* ((string (if (and (integerp count) (> count 1))
+		     (make-string count char)
+		   (char-to-string char)))
+	 (message (if (>= char ?\200)
+		      string
+		    (mapconcat 'isearch-text-char-description string ""))))
+    (isearch-process-search-string string message)))
 
 (defun isearch-process-search-string (string message)
   (setq isearch-string (concat isearch-string string)

=== modified file 'lisp/international/isearch-x.el'
--- lisp/international/isearch-x.el	2013-01-01 09:11:05 +0000
+++ lisp/international/isearch-x.el	2013-06-06 06:29:51 +0000
@@ -94,7 +94,7 @@ (defun isearch-with-input-method ()
     (exit-minibuffer)))
 
 ;;;###autoload
-(defun isearch-process-search-multibyte-characters (last-char)
+(defun isearch-process-search-multibyte-characters (last-char &optional count)
   (if (eq this-command 'isearch-printing-char)
       (let ((overriding-terminal-local-map nil)
 	    (prompt (isearch-message-prefix))
@@ -136,8 +136,11 @@ (defun isearch-process-search-multibyte-
 
 	(if (and str (> (length str) 0))
 	    (let ((unread-command-events nil))
-	      (isearch-process-search-string str str))
+	      (if (and (integerp count) (> count 1))
+		  (let ((strs (mapconcat 'identity (make-list count str) "")))
+		    (isearch-process-search-string strs strs))
+		(isearch-process-search-string str str)))
 	  (isearch-update)))
-    (isearch-process-search-char last-char)))
+    (isearch-process-search-char last-char count)))
 
 ;;; isearch-x.el ends here




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14563; Package emacs. (Sun, 09 Jun 2013 20:40:02 GMT) Full text and rfc822 format available.

Message #8 received at 14563 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: 14563 <at> debbugs.gnu.org
Subject: Re: bug#14563: Add prefix arg to more isearch commands
Date: Sun, 09 Jun 2013 23:35:19 +0300
> bug#10614 and bug#10638 deals with adding a prefix arg to
> `isearch-repeat-forward' and `isearch-repeat-backward'.
>
> And the following patch adds a prefix arg to
> `isearch-quote-char' (to use the same args as in `quoted-insert'),
> `isearch-printing-char' (to use the same args as in `insert-char'),
> `isearch-process-search-char' and
> `isearch-process-search-multibyte-characters':

I have no intention to add a prefix arg to all isearch commands
because for some commands a prefix arg doesn't make sense.
For instance, it makes no sense to add a prefix arg to
`isearch-delete-char' since after every DEL it requires
examination to visually confirm that the current search match
is what the user wants (because the search stack is invisible
to the user and it's difficult to keep it in mind and count items
in the stack).

Also a prefix arg for `isearch-yank-word-or-char' is useless too,
because it is too unpredictable in the exact number of characters
it will move forward (depends on the word syntax in the buffer),
so it's difficult for the user to give such a prefix arg that would
move forward the specified amount of unit (characters or words)
and stop at the exact position.

As for `isearch-yank-word' and `isearch-yank-line' it makes sense
to add a prefix arg to them only when a new feature `isearch-allow-move'
(intended to replace these commands) is not going to be added to isearch.el.
In this case a prefix arg for these commands can be added by this patch:

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-06-06 06:23:19 +0000
+++ lisp/isearch.el	2013-06-09 20:34:11 +0000
@@ -1919,29 +2082,33 @@ (defun isearch-yank-word-or-char ()
 	   (forward-word 1))
        (forward-char 1)) (point))))
 
-(defun isearch-yank-word ()
+(defun isearch-yank-word (&optional arg)
   "Pull next word from buffer into search string."
-  (interactive)
-  (isearch-yank-internal (lambda () (forward-word 1) (point))))
+  (interactive "p")
+  (isearch-yank-internal (lambda () (forward-word arg) (point))))
 
-(defun isearch-yank-line ()
+(defun isearch-yank-line (&optional arg)
   "Pull rest of line from buffer into search string."
-  (interactive)
+  (interactive "p")
   (isearch-yank-internal
    (lambda () (let ((inhibit-field-text-motion t))
-		(line-end-position (if (eolp) 2 1))))))
+		(line-end-position (if (eolp) (1+ arg) arg))))))
 
(defun isearch-char-by-name ()
   "Read a character by its Unicode name and add it to the search string.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14563; Package emacs. (Thu, 13 Jun 2013 21:14:01 GMT) Full text and rfc822 format available.

Message #11 received at 14563 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: 14563 <at> debbugs.gnu.org
Subject: Re: bug#14563: Add prefix arg to more isearch commands
Date: Fri, 14 Jun 2013 00:12:11 +0300
Additionally, I also fixed the existing arg of `isearch-del-char'
for the case where it failed when its arg is larger than the length
of the search string.  The test case is `C-s C-M-y C-u 2 C-M-w'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#14563; Package emacs. (Fri, 14 Jun 2013 22:56:03 GMT) Full text and rfc822 format available.

Message #14 received at 14563 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: 14563 <at> debbugs.gnu.org
Subject: Re: bug#14563: Add prefix arg to more isearch commands
Date: Sat, 15 Jun 2013 01:30:15 +0300
The remaining command that could benefit from a prefix arg is
`isearch-repeat-forward'.  There are 4 places on the call stack
that can process the count argument: `isearch-repeat-forward',
`isearch-repeat', `isearch-search', `isearch-search-string'.

`isearch-repeat-forward' is too high-level, so repeating
the call to the more low-level `isearch-repeat' COUNT times
has such bad effects as pushing to the search stack all
intermediate positions (because `isearch-repeat' calls
`isearch-push-state' on every invocation), so e.g.
`C-s str C-u 42 C-s DEL DEL DEL ...' requires 42 DELs
to return to the first match instead of just 1 `DEL',
And it also flickers because `isearch-update' quickly
highlights all visited matches.

OTOH, `isearch-search-string' is too low-level because passing
the COUNT argument to search functions like `search-forward'
doesn't skip invisible matches and other additional processing
in `isearch-search'.

So the most appropriate place to implement a prefix arg
is `isearch-repeat':

=== modified file 'lisp/isearch.el'
--- lisp/isearch.el	2013-06-13 22:08:45 +0000
+++ lisp/isearch.el	2013-06-14 22:28:27 +0000
@@ -1393,8 +1462,10 @@ (defun isearch-abort ()
       (isearch-pop-state))
     (isearch-update)))
 
-(defun isearch-repeat (direction)
+(defun isearch-repeat (direction &optional arg)
   ;; Utility for isearch-repeat-forward and -backward.
+  (unless arg (setq arg 1))
+
   (if (eq isearch-forward (eq direction 'forward))
       ;; C-s in forward or C-r in reverse.
       (if (equal isearch-string "")
@@ -1410,21 +1481,25 @@ (defun isearch-repeat (direction)
 	  isearch-success t))
 
   (setq isearch-barrier (point)) ; For subsequent \| if regexp.
+  (if (< arg 0) (setq arg (abs arg) isearch-forward (not isearch-forward)))
 
   (if (equal isearch-string "")
       (setq isearch-success t)
+    (let ((count arg)
+	  ;; Don't remember intermediate states in global `isearch-cmds'.
+	  (isearch-cmds isearch-cmds))
+      (while (> count 0)
     (if (and isearch-success
 	     (equal (point) isearch-other-end)
 	     (not isearch-just-started))
@@ -1437,20 +1512,33 @@ (defun isearch-repeat (direction)
 	      (ding))
 	  (forward-char (if isearch-forward 1 -1))
 	  (isearch-search))
-      (isearch-search)))
+	  (isearch-search))
+	(when (> count 1)
+	  ;; For the next iteration, add the current state to `isearch-cmds',
+	  ;; so that next failed `isearch-search' could restore old position.
+	  (isearch-push-state)
+	  (unless isearch-success
+	    ;; Wrap the search with code like above.
+	    (setq isearch-wrapped t)
+	    (if isearch-wrap-function
+		(funcall isearch-wrap-function)
+	      (goto-char (if isearch-forward (point-min) (point-max))))))
+	(setq count (1- count)))))
 
   (isearch-push-state)
   (isearch-update))
 
-(defun isearch-repeat-forward ()
-  "Repeat incremental search forwards."
-  (interactive)
-  (isearch-repeat 'forward))
+(defun isearch-repeat-forward (&optional arg)
+  "Repeat incremental search forwards.
+With argument, repeat search ARG times."
+  (interactive "p")
+  (isearch-repeat 'forward arg))
 
-(defun isearch-repeat-backward ()
-  "Repeat incremental search backwards."
-  (interactive)
-  (isearch-repeat 'backward))
+(defun isearch-repeat-backward (&optional arg)
+  "Repeat incremental search backwards.
+With argument, repeat search ARG times."
+  (interactive "p")
+  (isearch-repeat 'backward arg))
 
 (defun isearch-toggle-regexp ()
   "Toggle regexp searching on or off."




Reply sent to Juri Linkov <juri <at> jurta.org>:
You have taken responsibility. (Tue, 20 Nov 2018 23:47:02 GMT) Full text and rfc822 format available.

Notification sent to Juri Linkov <juri <at> jurta.org>:
bug acknowledged by developer. (Tue, 20 Nov 2018 23:47:02 GMT) Full text and rfc822 format available.

Message #19 received at 14563-done <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> jurta.org>
To: 14563-done <at> debbugs.gnu.org
Subject: Re: bug#14563: Add prefix arg to more isearch commands
Date: Wed, 21 Nov 2018 01:45:23 +0200
> The remaining command that could benefit from a prefix arg is
> `isearch-repeat-forward'.

Implemented in bug#29321 and closed.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 19 Dec 2018 12:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 5 years and 155 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.