Skip to content

feat: add ObsidianFindIncomingLinks and ObsidianFindOutgoingLinks commands - #930

Open
metalelf0 wants to merge 3 commits into
obsidian-nvim:mainfrom
metalelf0:feat/find-backlinks
Open

feat: add ObsidianFindIncomingLinks and ObsidianFindOutgoingLinks commands#930
metalelf0 wants to merge 3 commits into
obsidian-nvim:mainfrom
metalelf0:feat/find-backlinks

Conversation

@metalelf0

Copy link
Copy Markdown
Contributor

What does the PR do?

Adds two new note-context commands for surfacing and converting unlinked plain-text mentions:

  • :Obsidian incoming_links / :ObsidianFindIncomingLinks — scans all cached vault notes for plain-text mentions of the current note's title or aliases; opens a picker to select matches and convert them to links in the target files.
  • :Obsidian outgoing_links / :ObsidianFindOutgoingLinks — scans the current buffer for plain-text mentions of other vault notes (by title or alias); opens a picker to select and convert matches to links in-place.

Both commands support multi-select (<Tab> to toggle, <CR> to apply all selected).

Implementation notes

  • No new scan logic. Both commands wire through the existing note/link_suggestion module (symbols, find, find_in_line). All skip rules (existing links, code fences, inline code, frontmatter, tags, bare URLs) are inherited for free.
  • Incoming links iterates cache.notes.all(), applies a fast raw-string pre-filter before full note parse, then scans with find_in_line. On confirm it bufadd/bufloads the target file, applies nvim_buf_set_text, writes, and unloads if it was not previously open.
  • Outgoing links calls link_suggestion.find(note) on the current buffer and delegates conversion to the existing actions.link_suggestion.
  • Respects configured link.style / link.format.
  • Errors gracefully when cache is not enabled/warm.

Files changed

File Change
lua/obsidian/commands/incoming_links.lua New command
lua/obsidian/commands/outgoing_links.lua New command
lua/obsidian/commands/init.lua Registered both as note_action = true
lua/obsidian/commands/init-legacy.lua Added ObsidianFindIncomingLinks / ObsidianFindOutgoingLinks legacy aliases
tests/test_find_links.lua 7 new tests
CHANGELOG.md / README.md Updated

Screenshots

Picker UI is identical to :Obsidian backlinks — standard picker with preview, multi-select via <Tab>.

PR Checklist

  • The PR contains a description of the changes
  • I read the [CONTRIBUTING.md] file
  • The CHANGELOG.md is updated
  • The changes are documented in the README.md file
  • The code complies with make chores (for style, lint, types, and tests)

…mands

Two new note-context commands for surfacing unlinked plain-text mentions:

- `:Obsidian incoming_links` / `:ObsidianFindIncomingLinks`
  Scans all cached vault notes for plain-text mentions of the current
  note's title and aliases. Opens a picker; selecting entries (with
  multi-select via <Tab>) replaces the plain text with a proper link in
  the target file.

- `:Obsidian outgoing_links` / `:ObsidianFindOutgoingLinks`
  Scans the current buffer for plain-text mentions of other vault notes
  (by title or alias). Opens a picker; selecting entries converts the
  mentions to links in-place.

Both commands:
- Reuse the existing `note/link_suggestion` scan infrastructure
  (symbols, find, find_in_line) — no new skip logic introduced.
- Inherit all existing exclusions: already-linked text, code fences,
  inline code spans, frontmatter, tags, and bare URLs.
- Respect `link.style` / `link.format` config for the produced link.
- Require the cache to be enabled and warm; error gracefully otherwise.
- Support multi-select (<Tab> to toggle, <CR> to apply all).

Incoming-links fast pre-filter: raw string search on file content before
full note parse, keeping large-vault performance acceptable.

Tests: 7 new cases in tests/test_find_links.lua covering outgoing scan,
skip-link, skip-code-fence, skip-inline-code, incoming scan, alias
matching, and wikilink exclusion.
Refactor incoming_links.lua to use a scan_note() helper function
instead of goto/::continue:: labels. Refactor test_find_links.lua
similarly, extracting the shared incoming scan Lua snippet to a
module-level constant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant