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
- Emacs 28.1 or later
- [[https://github.com/stepchowfun/tagref][tagref]] CLI installed and available in your =PATH=
** 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
-
Verify tagref-mode is active: Check for " Tagref" in the mode line.
-
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.
-
Check CAPF is registered: #+begin_src emacs-lisp (member 'tagref-completion-at-point completion-at-point-functions) #+end_src
-
With Corfu/Company: Completion should trigger automatically when you type =[ref:= or =[tag:=. If not, manually invoke with =C-M-i= or =M-TAB=.
-
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.