2

I wrote a set of predicates to filter matches in my ìsearch-* and query-replace* routines. I also wrote a macro to bind the isearch-filter-predicate variable to multiple predicates:

(defmacro with-ifp-predicates (PREDICATES &rest body)
  (declare (indent 1))
  `(let ((isearch-filter-predicate isearch-filter-predicate))
     (mapcar (lambda (x)
               (add-function :before-while isearch-filter-predicate x))
             ,PREDICATES)
     ,@body))

I use it in my code in this way:

(with-ifp-predicates '(skip-maths skip-comments)
  (query-replace "foo" "bar" nil (point-min) (point-max)))

I tested it and it seems to work but if I enter recursive-edit (C-r) and look at the value (C-h v) of the isearch-filter-predicate variable, I get this:

enter image description here

Is it normal? Is it caused by the :before-while? I chose it because I need a match to be skipped if just one of the predicats is satisfied.

Drew
  • 75,699
  • 9
  • 109
  • 225
Gabriele Nicolardi
  • 1,199
  • 8
  • 17
  • Yes, it's normal. `add-function` generates those objects (which are byte-compiled-functions). In Emacs-26, you should see it displayed in a slightly more user-friendly way which would make it clear that it's an advice. – Stefan Mar 13 '19 at 21:13

1 Answers1

1

Yes, it's normal. The code is byte-compiled on the fly. See nadvice.el (advice-p, for example).

Because of this it can help to give a piece of advice a user-friendly name, which can kind of describe it.


FWIW, you might want to take a look at the dynamic Isearch filtering available with Isearch+. It gives you easy ways to add, combine, and remove Isearch filter predicates, either interactively or with code. I think it gives you a generalization of what you're doing now.

With respect to describing (at least naming) Isearch filter predicates:

  • You can name each predicate you activate (add) dynamically.
  • The names of the active predicates, and their order, can be shown in the Isearch prompt, so you can tell what filtering is being used.
  • You can also name the current suite of filter predicates, creating a named predicate that does the same thing. You can use that name to reuse the suite later or to easily remove it as the current predicate. See function isearch-defun-filter-predicate.

BTW - I'm glad to see someone taking an interest in using Isearch filtering, and in a flexible way. In vanilla Emacs it is so far used rarely, and only with hard-coded filters for a few particular contexts.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • Thank you for the suggestions. I will study them carefully. This tool is proving to be very powerful in my work as a LaTeX typesetter, eliminating false positives from my `query-replace` routines and saving me a lot of time and mental energy. – Gabriele Nicolardi Mar 13 '19 at 18:26
  • Cool. Really glad to see people using Isearch filtering. – Drew Mar 13 '19 at 20:00