Here are two use cases where I call isearch-forward with some filter predicate.

(let ((isearch-filter-predicate (lambda (a b) nil)))
  (funcall 'isearch-forward))

(let ((isearch-filter-predicate (lambda (a b) nil)))
  (call-interactively 'isearch-forward))

Why is it that only the first one works? Is there a way to have the call-interactively call take isearch-filter-predicate into account?

It seems I need call-interactively if I want commands that leave isearch (e.g., C-n) to be executed properly (that is, C-s C-n should go to the next line).

  • Why do you say that you need to use call-interactively for keys such as C-n to quit Isearch? What are you trying to do - are you trying to define a command? If so, add an interactive spec. If not, use isearch-mode.
    – Drew
    Commented Apr 19, 2018 at 19:17
  • C-n does quit isearch, but does not go to the next line when called using funcall. My ultimate goal is to have a command that read-key-sequences and executes the associated function with a specific isearch-filter-predicate.
    – Michaël
    Commented Apr 19, 2018 at 20:12
  • @Drew One advantage of using call-interactively is that the original interactive spec is used for the called command. One only needs (interactive) for the caller. Injection of (interactive-form 'old-command) makes debugging with edebug a pain.
    – Tobias
    Commented Jul 16, 2019 at 13:12

1 Answer 1


The answer is given in the doc string of isearch-forward:

If this function is called non-interactively with a nil NO-RECURSIVE-EDIT, it does not return to the calling function until the search is done. See the function isearch-mode for more information.

In your first form

(let ((isearch-filter-predicate (lambda (a b) nil)))
  (funcall 'isearch-forward))

you use a nil value for the optional argument no-recursive-edit of isearch-forward. In that case the incremental search runs in a recursive-edit call within isearch-forward and the control flow does not leave the local scope of your let-form while isearch-mode is active.

In the second form

(let ((isearch-filter-predicate (lambda (a b) nil)))
  (call-interactively 'isearch-forward))

you start the isearch with the interactive call of isearch-forward. The command isearch-forward just starts isearch-mode and exits. The control flow is not within the isearch-forward function form while the incremental search is running.

An alternative way to call isearch-forward with user-defined isearch-filter-predicate that uses call-interactively is given in the answer to the question about searching for bold text.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.