From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Gabriele Nicolardi Newsgroups: gmane.emacs.bugs Subject: bug#69542: Feature request: making occur obey isearch-filter-predicate Date: Mon, 4 Mar 2024 12:44:48 +0100 Message-ID: <6071eb9a-fa15-45fb-9917-7a35c7556680@medialab.sissa.it> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="------------zrEEoRN1SeuqiwV3Q46w2Jya" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="20784"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla Thunderbird To: 69542@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Mar 04 12:45:48 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 1rh6lP-0005BC-K9 for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 04 Mar 2024 12:45:47 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rh6lD-0008Nw-4a; Mon, 04 Mar 2024 06:45:35 -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 1rh6lA-0008Le-MK for bug-gnu-emacs@gnu.org; Mon, 04 Mar 2024 06:45: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 1rh6lA-0006uY-DY for bug-gnu-emacs@gnu.org; Mon, 04 Mar 2024 06:45:32 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1rh6ld-0002hS-Tj for bug-gnu-emacs@gnu.org; Mon, 04 Mar 2024 06:46:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Gabriele Nicolardi Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 04 Mar 2024 11:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 69542 X-GNU-PR-Package: emacs X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.17095527376916 (code B ref -1); Mon, 04 Mar 2024 11:46:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 4 Mar 2024 11:45:37 +0000 Original-Received: from localhost ([127.0.0.1]:42196 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rh6lE-0001lf-On for submit@debbugs.gnu.org; Mon, 04 Mar 2024 06:45:37 -0500 Original-Received: from lists.gnu.org ([209.51.188.17]:50186) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1rh6lC-0001gI-Tu for submit@debbugs.gnu.org; Mon, 04 Mar 2024 06:45:35 -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 1rh6kf-000802-FL for bug-gnu-emacs@gnu.org; Mon, 04 Mar 2024 06:45:02 -0500 Original-Received: from smtp02.cbsolt.net ([185.97.217.41]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rh6kb-0006l7-9V for bug-gnu-emacs@gnu.org; Mon, 04 Mar 2024 06:45:01 -0500 Original-Received: from [10.0.2.15] (host-79-16-242-199.retail.telecomitalia.it [79.16.242.199]) by smtp02.cbsolt.net (Postfix) with ESMTPSA id 4TpH1G1H8zz3wbB for ; Mon, 4 Mar 2024 12:44:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cbsolt.net; s=201504-di4k2w; t=1709552691; bh=vLY9SZaq3M1s16W8tnjAfGutHaN9DH2VnOK/gluJjc0=; h=Date:To:From:Subject:From; b=URHBGVly+KQ+sbUhuiWLFRzmq97Fn3KRFxwljrbDkQdFQUl5Id/8iuwn9E9uQDEQf NeBVFaYvQNfayCL3rdW/t1mMBStoN7PvJhrc2KOf2r9mI80/mCYYHGpuM5i9z+S2hZ Thq93CMBaQrroc1jp7uur0xLKF7pJMP22sE2nObE= Content-Language: en-US Received-SPF: pass client-ip=185.97.217.41; envelope-from=gabriele@medialab.sissa.it; helo=smtp02.cbsolt.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action 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:280994 Archived-At: This is a multi-part message in MIME format. --------------zrEEoRN1SeuqiwV3Q46w2Jya Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi, 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) (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) | Best regards, Gabriele Nicolardi ​ --------------zrEEoRN1SeuqiwV3Q46w2Jya Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hi,

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)

(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)

Best regards,

Gabriele Nicolardi

--------------zrEEoRN1SeuqiwV3Q46w2Jya--