README.org

January 8, 2026 · View on GitHub

#+TITLE: tagref.el #+AUTHOR: Vedang Manerikar #+OPTIONS: toc:2

Emacs integration for [[https://github.com/stepchowfun/tagref][tagref]], a tool for managing cross-references in code.

  • Overview

Tagref helps you maintain cross-references in your codebase using simple tags:

  • =[tag:name]= defines a tag
  • =[ref:name]= references a tag

This package provides Emacs support for working with these directives:

  • Completion for =[ref:]= and =[tag:]= with existing tag names
  • Navigation via =M-.= to jump from a reference to its tag definition, and =M-?= to find all references of a tag
  • Validation via =M-x tagref-check= with clickable error locations
  • Browsing via =M-x tagref-list-tags= to see all tags in the project

[[file:images/tagref.png]]

  • Installation

** Requirements

** Manual Installation

#+begin_src emacs-lisp (add-to-list 'load-path "/path/to/tagref.el") (require 'tagref) #+end_src

** use-package

#+begin_src emacs-lisp (use-package tagref :ensure t :hook (prog-mode . tagref-mode)) #+end_src

** straight.el

#+begin_src emacs-lisp (straight-use-package '(tagref :type git :host github :repo "vedang/tagref.el")) #+end_src

  • Usage

** Enabling the Mode

Enable =tagref-mode= in any buffer:

#+begin_example M-x tagref-mode #+end_example

=tagref-mode= understands projects as defined by =project.el= and will be turned on for all buffers of that project.

** Completion

When =tagref-mode= is active, type =[ref:= or =[tag:= and invoke completion:

| Key | Action | |-----------+---------------------------------| | =C-M-i= | Complete tag name | | =M-TAB= | Complete tag name (same) |

Completions show the tag name with its file location:

#+begin_example polynomial_nonzero src/math.rs:42 path_default src/main.rs:93 #+end_example

Smart conversion: When completing =[tag:= and you select an existing tag, the directive is automatically converted to =[ref:= to prevent duplicates.

** Navigation

Navigate between references and their definitions using standard xref keys:

| Key | Command | Action | |-------+--------------------------+-------------------------------| | =M-.= | =xref-find-definitions= | Jump to tag definition | | =M-,= | =xref-go-back= | Return to previous location | | =M-?= | =xref-find-references= | Find all references to tag |

Place your cursor inside a =[ref:name]= and press =M-.= to jump to where the tag is defined.

When on a =[tag:name]=, press =M-?= to find all references. The results include the tag definition as the first entry for context. If there are no references, a message is shown.

** Validation

Run tagref's validation to find broken references:

#+begin_example M-x tagref-check #+end_example

This opens a compilation buffer with any errors. Click on an error (or press =RET=) to jump to that location.

Standard compilation-mode keys work:

| Key | Action | |-----------+---------------------| | =RET= | Go to error | | =M-g M-n= | Next error | | =M-g M-p= | Previous error | | =g= | Re-run check | | =q= | Close buffer |

** Tag Browser

Browse all tags in the project:

#+begin_example M-x tagref-list-tags #+end_example

This shows a sortable table of all tags:

#+begin_example Tag File Line polynomial_nonzero src/math.rs 42 path_default src/main.rs 93 tag_sigil_default src/main.rs 103 #+end_example

| Key | Action | |-------+---------------------------| | =RET= | Jump to tag definition | | =g= | Refresh list | | =S= | Sort by column | | =q= | Close buffer |

  • Configuration

** Custom Variables

#+begin_src emacs-lisp ;; Path to tagref executable (default: "tagref") (setq tagref-executable "/path/to/tagref")

;; Additional arguments for tagref commands (setq tagref-arguments '("--config" "custom.toml")) #+end_src

** Customization Interface

#+begin_example M-x customize-group RET tagref RET #+end_example

  • Commands

| Command | Description | |---------------------+--------------------------------------------------| | =tagref-mode= | Toggle tagref minor mode for the current project | | =tagref-check= | Run tagref validation, show errors | | =tagref-list-tags= | Display all tags in a browsable buffer |

  • Development

** Running Tests

#+begin_src shell make test # Run Buttercup test suite make check # Run byte-compile, checkdoc, package-lint make all # Run everything #+end_src

** Project Structure

#+begin_example ├── Makefile # Build and test commands ├── README.org # This file ├── tagref.el # Main package └── test/ └── tagref-test.el # Buttercup tests #+end_example

  • Troubleshooting

** Completion not appearing

  1. Verify tagref-mode is active: Check for " Tagref" in the mode line.

  2. Verify tagref CLI works: Run =M-x tagref-list-tags= to see if tags are found. If this shows no tags, check that =tagref= is in your PATH.

  3. Check CAPF is registered: #+begin_src emacs-lisp (member 'tagref-completion-at-point completion-at-point-functions) #+end_src

  4. With Corfu/Company: Completion should trigger automatically when you type =​[ref:= or =​[tag:=. If not, manually invoke with =C-M-i= or =M-TAB=.

  5. Debug the CAPF: Evaluate this with point inside a =​[ref:= directive: #+begin_src emacs-lisp (tagref-completion-at-point) #+end_src It should return a list like =(START END CANDIDATES ...)=.

** tagref-check shows no clickable errors

The error regexp matches the format =@ path/to/file:42=. If your errors aren't clickable, check that tagref output matches this format.

** Performance with large projects

The package calls =tagref list-tags= on each completion. For very large projects, this may cause a delay. Consider:

  • Increasing =corfu-auto-delay= if using Corfu
  • Using =M-x tagref-list-tags= to browse tags instead
  • License

GPL-3.0-or-later. See the [[file:tagref.el][source file]] for details.