pathnav.nvim is a supercharged gf for paths embedded in prose.
It detects paths under the cursor and opens, highlights, or jumps to the referenced location. It is especially useful for LLM-generated output, documentation, logs, and markdown, where file references often appear inline and wrapped in surrounding punctuation.
The plugin understands multiple path formats, such as:
- Absolute / relative paths
- Markdown embedded paths
path:linelocationspath:line-lineranges- GitHub-style
#Lline fragments - GitHub blob permalinks
- Paths wrapped in surrounding prose or punctuation
It is also git-aware and warns you if you try to open a path that does not match your current checked-out commit.
---@param opts? pathnav.ConfigOptions
require("pathnav").setup(opts)Initializes and configures the plugin. See Configuration.
---@param opts? pathnav.OpenOptions
---@return boolean
require("pathnav").open(opts)Opens the path under the cursor. Returns false if no readable path could be
resolved; true otherwise (including when the user cancels window selection).
| Option | Type | Default | Description |
|---|---|---|---|
jump |
boolean |
true |
Move the cursor to the referenced location and switch focus to the target window. |
highlight |
boolean |
true |
Highlight the referenced line or range. |
target_window |
pathnav.ConfigOptions.TargetWindow |
— | Override target window selection for this call. Same shape as the target_window section in setup(). |
Neovim 0.9.0 or newer
{
"tummetott/pathnav.nvim",
lazy = true,
---@type pathnav.ConfigOptions
opts = {
-- Optional config overrides
},
keys = {
{
"gf",
function()
require("pathnav").open()
end,
desc = "Jump to file under cursor",
},
{
"<leader>h",
function()
require("pathnav").open({
jump = false,
highlight = true,
})
end,
desc = "Highlight path location",
},
},
}---@type pathnav.ConfigOptions
{
-- Highlight options for referenced lines.
highlight = {
-- Highlight group used for the referenced line or range.
hlgroup = "PathnavReferenceText",
-- Events that clear the active reference highlight.
clear_events = { "CursorMoved" },
},
-- Target window selection options.
target_window = {
-- Exclude windows from target selection.
exclude = {
-- Exclude the current window.
current = true,
-- Exclude buffers with these filetypes.
filetypes = {},
-- Exclude buffers with these buftypes.
buftypes = {
"help",
"nofile",
"prompt",
"quickfix",
"terminal",
},
-- Callback that receives a window id and returns `true` when that
-- window is excluded from target selection.
condition = nil,
},
-- Prefer candidate windows that match these conditions.
prefer = {
-- Prefer a window that already shows the referenced file.
matching_file = true,
-- Prefer the window selected by the previous pathnav jump.
last_target = false,
},
-- Split behavior when a new target window is created.
split = {
-- Direction in which the new split opens.
direction = vim.o.splitright and "right" or "left",
-- Always open in a new split instead of reusing candidates.
force = false,
},
},
-- Window picker appearance.
picker = {
-- Characters used as picker labels.
charset = "jklasdfhguiopqwert",
-- Highlight group used for picker labels.
hlgroup = "PathnavPickerLabel",
}
}When opening a path, pathnav.nvim selects a target window from the current tabpage.
Floating windows are ignored. The remaining windows are filtered by
target_window.exclude.
Selection rules:
- If
target_window.split.forceis enabled or there is no candidate window, open a new split. - If there is one candidate window, use it.
- If the configured preferences identify one preferred candidate window, use it.
- Otherwise, use the picker.
Picker controls:
- press the displayed label to select a window
<Esc>or invalid input cancels the operation
To get navigable file references in LLM output, instruct your agent to use the
following format. Add this to your AGENTS.md, system prompt, or equivalent:
Always reference files using paths relative to the most appropriate base:
- **Inside cwd**: relative to cwd — `src/server/api.ts`
- **Inside home**: relative to `~` — `~/other-project/src/lib.rs`
- **Anything else**: absolute — `/etc/nginx/nginx.conf`
Allowed formats:
- Whole file: `<path>`
- Single line: `<path>:<line>`
- Line range (inclusive): `<path>:<start>-<end>`pathnav.nvim understands all of these formats and will jump directly to the
referenced line or range.
require("pathnav").open() cannot be used from within an expr mapping.
open() changes windows, opens buffers, moves the cursor, and adds highlights.
These operations are not allowed while an expr mapping is being evaluated.
Deferring the call would fix this, but introduces other edge cases with highlight
clearing.
Use vim.api.nvim_feedkeys(vim.keycode('<key>'), <mode>, false) to fall back to
the original key behavior instead.
❤️ Tummetott
