GNU bug report logs - #69542
Feature request: making occur obey isearch-filter-predicate

Previous Next

Package: emacs;

Reported by: Gabriele Nicolardi <gabriele <at> medialab.sissa.it>

Date: Mon, 4 Mar 2024 11:46:01 UTC

Severity: wishlist

Full log


View this message in rfc822 format

From: Gabriele Nicolardi <gabriele <at> medialab.sissa.it>
To: Juri Linkov <juri <at> linkov.net>
Cc: 69542 <at> debbugs.gnu.org
Subject: bug#69542: Feature request: making occur obey isearch-filter-predicate
Date: Tue, 5 Mar 2024 18:11:37 +0100
[Message part 1 (text/plain, inline)]
> I think duplicating the whole body of functions is not better
> than using advice.

Until yesterday, I had no idea how to advise a function.

Now I'm experimenting with this code to obtain modified versions of 
|occur| and |how-many| that are sensitive to |isearch-filter-predicate|.

I'm not a programmer, so my code may not be very rigorous:

;; I need a copy of `re-search-forward' because it will be temporary 
adviced in
;; `how-many-ifp' and `occur-ifp' functions:
(defalias 're-search-forward-copy
  (symbol-function 're-search-forward)
  "Copy of `re-search-forward'")

(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 (re-search-forward-copy 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 override-re-search-forward (orig-fun &rest args)
  "Temporary advice the `re-search-forward' function, overriding it with
`re-search-forward-ifp' to make it sensitive to `isearch-filter-predicate'"
  (unwind-protect
      (progn
        (advice-add 're-search-forward :override #'re-search-forward-ifp)
        (apply orig-fun args))
    (advice-remove 're-search-forward #'re-search-forward-ifp)))

(defalias 'how-many-ifp
  (symbol-function 'how-many)
  "Copy of the `how-many' function (to be) adviced to obey to
`isearch-filter-predicate'")
(defalias 'count-matches-ifp 'how-many-ifp)

(advice-add 'how-many-ifp :around #'override-re-search-forward)

(defalias 'occur-ifp
  (symbol-function 'occur)
  "Copy of the `occur' function (to be) adviced to obey to
 `isearch-filter-predicate'")

(advice-add 'occur-ifp :around #'override-re-search-forward)

The key is the `re-search-forward` function used in `how-many` and 
`occur` definition. If you make it sensible to 
`isearch-filter-predicate` also `how-many` and `occur` will be.

I don't know if advicing a function to advice a function inside it is a 
good idea but it seem to work (I need more tests).

Now I discovered how to build these functions I could be fine with my 
modified ones, but making this feature avaible (maybe not default) in 
the original functions could be a better idea.

>   An alternative would be to add a new variable
> 're-search-forward-function' and then to use it like
> '(funcall re-search-forward-function)'.

The idea of a new function seems good to me.

[Message part 2 (text/html, inline)]

This bug report was last modified 1 year and 103 days ago.

Previous Next


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