From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#69542: Feature request: making occur obey isearch-filter-predicate Date: Tue, 05 Mar 2024 18:30:20 +0200 Organization: LINKOV.NET Message-ID: <86msrdnjdn.fsf@mail.linkov.net> References: <6071eb9a-fa15-45fb-9917-7a35c7556680@medialab.sissa.it> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="10234"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/30.0.50 (x86_64-pc-linux-gnu) Cc: 69542@debbugs.gnu.org To: Gabriele Nicolardi Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Mar 05 17:36:57 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rhXmi-0002Os-MH for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 05 Mar 2024 17:36:57 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rhXmZ-0006jt-SK; Tue, 05 Mar 2024 11:36:49 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rhXmK-0006ik-68 for bug-gnu-emacs@gnu.org; Tue, 05 Mar 2024 11:36:32 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rhXmJ-00081T-UD for bug-gnu-emacs@gnu.org; Tue, 05 Mar 2024 11:36:31 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rhXmo-0000m4-2H for bug-gnu-emacs@gnu.org; Tue, 05 Mar 2024 11:37:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 05 Mar 2024 16:37:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 69542 X-GNU-PR-Package: emacs Original-Received: via spool by 69542-submit@debbugs.gnu.org id=B69542.17096565722911 (code B ref 69542); Tue, 05 Mar 2024 16:37:02 +0000 Original-Received: (at 69542) by debbugs.gnu.org; 5 Mar 2024 16:36:12 +0000 Original-Received: from localhost ([127.0.0.1]:48782 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rhXly-0000kr-DT for submit@debbugs.gnu.org; Tue, 05 Mar 2024 11:36:11 -0500 Original-Received: from relay6-d.mail.gandi.net ([217.70.183.198]:41295) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rhXlv-0000k7-El for 69542@debbugs.gnu.org; Tue, 05 Mar 2024 11:36:09 -0500 Original-Received: by mail.gandi.net (Postfix) with ESMTPSA id 124F5C0007; Tue, 5 Mar 2024 16:35:09 +0000 (UTC) In-Reply-To: <6071eb9a-fa15-45fb-9917-7a35c7556680@medialab.sissa.it> (Gabriele Nicolardi's message of "Mon, 4 Mar 2024 12:44:48 +0100") X-GND-Sasl: juri@linkov.net X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list 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-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:281060 Archived-At: > I’d like occur to obey to isearch-filter-predicate like query-replace* and > isearch* commands. > > This is an example of what I do: > > (defmacro with-ifp-predicates (PREDICATES &rest body) > "Allows assigning a list of predicates to the > variable `isearch-filter-predicate'. > > Below is an example of usage: > > (with-ifp-predicates '(skip-maths skip-comments) > (query-replace \"foo\" \"bar\" nil (point-min) (point-max)))" > (declare (indent 1)) > `(let ((isearch-filter-predicate isearch-filter-predicate)) > (mapc (lambda (predicate) > (add-function :before-while isearch-filter-predicate predicate)) > ,PREDICATES) > ,@body)) > > (I always use let-binding for operations that involve > isearch-filter-predicate.) > > In some cases, I would like to have something like this: > > (with-ifp-predicates '(predicate1 predicate2) > (save-window-excursion > (occur "foo") > (query-replace \"foo\" \"bar\" nil (point-min) (point-max)))) > > with occur showing me only the strings that match the active predicates. > > I wrote a mail to emacs-devel@gnu.org and I have verified that others also > believe that this solution would be helpful and consistent with the > functioning of some other functions defined in replace.el. > > I’d also like to add this feature to the how-many function. > > I already wrote this modified version (Emacs 29.2): > > (defun re-search-forward-ifp (REGEXP &optional BOUND NOERROR COUNT) > "Modified version of `search-forward-regexp' that > filters (skips) matches according to `isearch-filter-predicate'." > > (let ((POINT (point))) > (catch 'filtered > (while (search-forward-regexp REGEXP BOUND NOERROR COUNT) > (let ((B (match-beginning 0)) > (E (match-end 0))) > (when (funcall isearch-filter-predicate B E) > (throw 'filtered (point))))) > (goto-char POINT) > nil))) > (defalias 'search-forward-regexp-ifp 're-search-forward-ifp) So you rewrote the loop from isearch-search: (while retry (setq isearch-success (isearch-search-string isearch-string nil t)) (if (or (not isearch-success) (funcall isearch-filter-predicate (match-beginning 0) (match-end 0))) (setq retry nil) But this doesn't answer the question whether and how this could affect re-search-forward in a non-hackish way. Adding an option? Not sure. > (defun how-many-ifp (regexp &optional rstart rend interactive) > "Modified version of `how-many' that filters (skips) matches > according to `isearch-filter-predicate'." > > (interactive > (keep-lines-read-args "How many matches for regexp")) > (save-excursion > (if rstart > (if rend > (progn > (goto-char (min rstart rend)) > (setq rend (max rstart rend))) > (goto-char rstart) > (setq rend (point-max))) > (if (and interactive (use-region-p)) > (setq rstart (region-beginning) > rend (region-end)) > (setq rstart (point) > rend (point-max))) > (goto-char rstart)) > (let ((count 0) > (case-fold-search > (if (and case-fold-search search-upper-case) > (isearch-no-upper-case-p regexp t) > case-fold-search))) > (while (and (< (point) rend) > (re-search-forward-ifp regexp rend t)) > ;; Ensure forward progress on zero-length matches like "^$". > (when (and (= (match-beginning 0) (match-end 0)) > (not (eobp))) > (forward-char 1)) > (setq count (1+ count))) > (when interactive (message (ngettext "%d occurrence" > "%d occurrences" > count) > count)) > count))) > (defalias 'count-matches-ifp 'how-many-ifp) I think duplicating the whole body of functions is not better than using advice. An alternative would be to add a new variable 're-search-forward-function' and then to use it like '(funcall re-search-forward-function)'.