Call a function interactively from another function in Emacs


The Silver surfer (ag) Linux tool is the fastest way to find where a word or phrase appears in the files on a directory.

I've been using ag in two ways from inside Emacs.

  1. The ag-mode package, that asks me to input a search term and the root directory where I want it to search and then it performs the search.
  2. Via projectile, that allows me to search on a whole project without the extra step of inserting the root dir.

Both of them are topic for another article. I had bound the H-g keybinding to the ag command and projectile defines C-c p s s to projectile-ag.

This is nice, but I wanted to assign a single keybinding and let Emacs choose the best option according to the situation at hand. But to do that, I'd need to find a way to invoke an interactive command from within an interactive command. Here's the solution I found: use the call-interactively function.

It works like this:

  (call-interactively #'interactive-function-name)

So here's the command I wrote in order to accomplish my goal:

It first finds out if the current buffer is visiting a file under a project recognized by projectile. We do so by calling projectile-project-p.

Then, if we are, we call (call-interactively #'projectile-ag) to search using projectile.

If we're not in a project, we just invoke (call-interactively #'ag).

  (defun fdx/ag-or-projectile-ag (&optional a b)
    (interactive)
    (if (projectile-project-p)
        (call-interactively #'projectile-ag)
      (call-interactively #'ag)))

Now I have fdx/ag-or-projectile-ag bound to H-g and I moved the plain ag call to H-G for special cases when I want my filter to be more specific even inside a project.

Use it at will.

Saluti.