I use xref-find-definition to look up the definition of a symbol name. When I call xref-find-definition, I want to Emacs to automatically find and load an appropriately named etags file. For this purpose, I have a function, open-tags-file:

(defadvice xref-find-definitions (before before-xref-find-definitions activate)

(defun open-tags-file ()
  (if (booleanp tags-file-name)
    (when (file-exists-p "my_tag_file")
      (visit-tags-table "my_tag_file"))))

This works fine when I run xref-find-definitions with the cursor already over an existing symbol name. It also works if I do not have the cursor over a symbol name -- Emacs will prompt me to enter a symbol name, such as "CreateFood". Either way, The tags file is automatically loaded, and then the symbol is looked up.

However, when Emacs prompts me to enter a symbol name, I want to be able to type a partial symbol name, such as "Cre", and then press Tab and have "CreateFood" be auto-completed. If I do that, Emacs will prompt me to load the tag file, and it will expect it to have the name TAGS. This means that my defadvice xref-find-definitions is not being run before Emacs prompts me to enter the symbol name, it is only run after that symbol name is entered.

Is there a way to run open-tags-file before the symbol name is entered, so that I can auto-complete "Cre" into "CreateFood" when entering the symbol name to find the definition of?

  1. You should use the new advice system `nadvice` instead of the old one.
  2. xref-find-definitions prompts the user already in its `interactive-form`. So you need to run `open-tags-file` in the interactive-form of your advice for the case that xref-find-definitions is called interactively.
  3. I use the interactive specification of xref-find-definitions of emacs 25.3.1 in my-xref-find-definitions-interactive-spec. It may be that you need to adapt that to your emacs version. See the comment in the code. A variant would be to query the interactive form of xref-find-definitions with the help of function interactive-form. But that would complicate the code.
  4. The code is untested. Please test it for yourself and comment whether it is working for you or not.
  5. You usage of tags-file-name looks a bit strange. I think your test should be (unless (stringp tags-file-name) ...). That would be more descriptive.

    (require 'xref)
    (defun open-tags-file ()
      "Use \"my_tag_file\" as tag file for xref."
      (unless (stringp tags-file-name)
          (when (file-exists-p "my_tag_file")
            (visit-tags-table "my_tag_file"))))
    (defun my-xref-find-definitions-interactive-spec ()
      "Interactive form for `open-tags-file'."
      ;; The following is the interactive specification of `xref-find-definitions' in emacs 25.3.1.
      ;; It may be that you need to adapt it to your emacs version.
      (list (xref--read-identifier "Find definitions of: ")))
    (defun my-xref-find-definitions-before-ad (&rest _args)
      "Advice for `xref-find-definitions' that handles the \"my_tag_file\"."
      (interactive (my-xref-find-definitions-interactive-spec))
    (advice-add 'xref-find-definitions :before #'my-xref-find-definitions-before-ad)
  • How would I, as you put it, "query the interactive form of xref-find-definitions with the help of function interactive-form"? I would prefer doing this to creating my own interactive prompt, as I would like this to be compatible with different versions of Emacs. (Also, I would like to replicate the same tab completion functionality for other functions, such as xref-find-references and find-tag, when xref isn't available. That's more reason to call the default versions of interactive functions rather than having per-function customizations everywhere.)
    – std_answ
    May 1 '18 at 19:59
  • @std_answ For re-using interactive-form of some command see emacs.stackexchange.com/questions/28518/…. Especially interesting for you is phils' answer there.
    – Tobias
    May 1 '18 at 23:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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