From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#14563: Add prefix arg to more isearch commands Date: Sat, 15 Jun 2013 01:30:15 +0300 Organization: JURTA Message-ID: <87ppvocno8.fsf@mail.jurta.org> References: <87obbj699r.fsf@mail.jurta.org> <87ehcbkooo.fsf@mail.jurta.org> <87sj0logus.fsf@mail.jurta.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1371250573 20479 80.91.229.3 (14 Jun 2013 22:56:13 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 14 Jun 2013 22:56:13 +0000 (UTC) To: 14563@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jun 15 00:56:13 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Uncug-0004Fb-Vy for geb-bug-gnu-emacs@m.gmane.org; Sat, 15 Jun 2013 00:56:11 +0200 Original-Received: from localhost ([::1]:42901 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uncug-0006MZ-Di for geb-bug-gnu-emacs@m.gmane.org; Fri, 14 Jun 2013 18:56:10 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:43528) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uncuc-0006MS-2p for bug-gnu-emacs@gnu.org; Fri, 14 Jun 2013 18:56:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uncua-0002Vi-Ul for bug-gnu-emacs@gnu.org; Fri, 14 Jun 2013 18:56:06 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:60288) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uncua-0002Vd-S2 for bug-gnu-emacs@gnu.org; Fri, 14 Jun 2013 18:56:04 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1UncuZ-00033S-Cf for bug-gnu-emacs@gnu.org; Fri, 14 Jun 2013 18:56:04 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 14 Jun 2013 22:56:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 14563 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 14563-submit@debbugs.gnu.org id=B14563.137125054811695 (code B ref 14563); Fri, 14 Jun 2013 22:56:03 +0000 Original-Received: (at 14563) by debbugs.gnu.org; 14 Jun 2013 22:55:48 +0000 Original-Received: from localhost ([127.0.0.1]:44953 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1UncuJ-00032S-Kp for submit@debbugs.gnu.org; Fri, 14 Jun 2013 18:55:48 -0400 Original-Received: from ps18281.dreamhost.com ([69.163.218.105]:43511 helo=ps18281.dreamhostps.com) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1UncuF-00032B-E3 for 14563@debbugs.gnu.org; Fri, 14 Jun 2013 18:55:44 -0400 Original-Received: from localhost (ps18281.dreamhostps.com [69.163.218.105]) by ps18281.dreamhostps.com (Postfix) with ESMTP id 93857258B9E91C for <14563@debbugs.gnu.org>; Fri, 14 Jun 2013 15:55:41 -0700 (PDT) In-Reply-To: <87sj0logus.fsf@mail.jurta.org> (Juri Linkov's message of "Fri, 14 Jun 2013 00:12:11 +0300") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (x86_64-pc-linux-gnu) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:75129 Archived-At: 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."