# Refs

> Open the files and lines referenced in a message in a new nvim tmux split, with global marks A..Z and a quickfix list preconfigured at each location. Use when the user asks to 'open these refs', 'jump to those files', 'open the referenced lines', 'pull those up in nvim', or invokes '/refs'.

- Skill: `collinthefarmer/refs` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add collinthefarmer/refs`
- Raw SKILL.md: https://api.skillmd.com/api/skills/collinthefarmer/refs/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: collinthefarmer (https://skillmd.com/u/collinthefarmer)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/collinthefarmer/refs

---


# Refs — Open Referenced File:Line Locations in nvim

Take the `file:line` references from a message, open them in a fresh nvim session in a tmux split, and preconfigure global marks (`'A`..`'Z`) and a quickfix list at each location so the user can jump straight to what was discussed.

You ARE the orchestrator. Three steps.

## Step 1: Collect the references

From the target message, collect every file:line reference. The target is the most recent message that contains such references (usually your own last substantive reply); if the user's argument names a different message ("the one about the parser"), use that one instead.

A reference is a path with an optional line (and column): `src/app.py:42`, `lib/util.ts:10:5`, or a bare `README.md`. Collect them **in the order they appear**, keeping duplicates out. Produce a space-separated list of the raw tokens.

If the message contains no file:line references, say so and stop — do not open a split.

## Step 2: Stage the session

Run the helper with the collected tokens:

```bash
bash ~/.claude/skills/refs/scripts/open-refs.sh <tok1> <tok2> ...
```

It validates each reference against the filesystem, writes the kept set to a JSON data file, and prints `REFS_JSON`, `REFSVIM`, `REQUEST_PATH`, `CWD`, `TS`, one `MARK` line per kept reference, `SKIP` lines for unresolved ones, and `COUNT`.

- If the script exits non-zero (no nvim, no tmux, not in a tmux session), relay its error and stop.
- If `COUNT` is `0`, tell the user none of the references resolved to real files (list the `SKIP`s) and stop.

## Step 3: Open the split

The split fires from a **Write-tool** write to the pane request (a bash write will not trigger the hook). Using the values the script printed, write this to `REQUEST_PATH` with the **Write** tool:

```json
{
  "name": "refs/<TS>",
  "direction": "h",
  "size": 50,
  "cmd": "CLAUDE_REFS_JSON='<REFS_JSON>' nvim -S '<REFSVIM>'",
  "cwd": "<CWD>"
}
```

Substitute `<TS>`, `<REFS_JSON>`, `<REFSVIM>`, and `<CWD>` with the printed values. The pane hook opens the split and runs nvim, which sources `refs.vim`: it lands on the first reference, opens the quickfix window, and sets marks `A`.. for the first 26 references.

Then report to the user:

- the mark map — which letter jumps to which `file:line` (from the `MARK` lines);
- navigation: `'A`, `'B`, … jump by mark; `:cnext` / `:cprev` (or the open quickfix window) walk all references in order;
- any skipped references, and — if more than 26 resolved — that marks cover the first 26 while the quickfix list holds them all.

## Error Recovery

| Situation | Response |
|-----------|----------|
| Message has no file:line references | Say so; do not open a split. |
| Not inside a tmux session / nvim or tmux missing | Relay the script's error; the split needs a tmux session and nvim. |
| Some references don't resolve to files | They are skipped and listed; open the rest. |
| No references resolve (`COUNT` 0) | List the skipped tokens; do not open a split. |
| More than 26 references | Marks cover the first 26; the quickfix list holds all. Say so. |
| A referenced line exceeds the file's length | nvim clamps to the last line; the mark still lands in the right file. |

