kdnk14k downloadsautomatically converts plain text file references into wiki links
Automatically convert plain text file references into Obsidian wiki links as you write. Keep your knowledge graph connected without manual linking.
Automatic Linker scans your notes and intelligently converts text that matches file names in your vault into wiki links ([[...]]). Whether you're writing quick notes or maintaining a complex knowledge base, this plugin ensures your notes stay interconnected without interrupting your flow.
main.js, manifest.json, and styles.css to your vault's .obsidian/plugins/automatic-linker/ directoryThe plugin automatically detects file names in your text and converts them to wiki links. It works seamlessly with:
automatic-linker-off settingOrganize large vaults with sophisticated namespace handling:
automatic-linker-scoped: true in frontmatter to restrict linking to files within the same namespaceTransform raw URLs into readable Markdown links automatically:
https://github.com/user/repo/issues/123 to [user/repo#123](URL)[Page Title](URL) format (cached to minimize requests)Fine-tune linking behavior to match your workflow:
automatic-linker-exclude: true to frontmatter to exclude files from auto-linking2025-02-10) for compatibility with Obsidian Tasks[[path/to/file]])Access these commands via the Command Palette (Cmd/Ctrl + P):
| Command | Description |
|---|---|
| Automatic Linker: Format file | Convert text to links in the current file |
| Automatic Linker: Format selection | Convert only selected text to links |
| Automatic Linker: Format vault | Batch process all files in your vault |
| Automatic Linker: Copy file without links | Copy current file content with links as plain text |
| Automatic Linker: Copy selection without links | Copy selected lines with minimal indent and links removed |
| Automatic Linker: Rebuild index | Rebuild the file index for link candidates |
Formatting preserves frontmatter exactly. If you switch to another note or editor while formatting waits for page titles or integrations, the pending operation stops before applying further changes. Text you add to the same editor while titles are fetched is preserved.
List indentation is owned by the formatter, not Automatic Linker. The former Normalize list indentation to tabs setting has been removed; saved values are ignored. Use the kdnk Prettier fork's indentation repair when available. Install and verify that formatter before upgrading from a configuration that relies on Automatic Linker's old cleanup option.
When Automatic Linker handles formatting on save, disable Format on save in Prettier and Lint on save in Linter, while leaving the desired integrations enabled here. Otherwise those plugins also run independently and can overlap with this workflow. Automatic Linker warns about this configuration but never changes another plugin's settings.
Formatting requests are serialized. Repeated requests during a run are combined into one trailing run against the latest requested target. An error aborts that batch, including queued requests; a later request can retry. Unloading Automatic Linker discards queued work and prevents further stages; it cannot cancel an external formatter that is already running. It also cannot serialize a formatter started independently by another plugin or command.
The integration uses guarded completion-returning plugin methods, verified with prettier-format 0.2.0 and Obsidian Linter 1.32.0. Missing or incompatible methods stop the chain with a notice; there is no fire-and-forget command fallback. Linter's completion covers its editor formatting, not subsequent metadata-triggered custom commands. The plugins retain their own formatting rules: this coordination does not fix how Prettier interprets mixed indentation, or change tabs/spaces settings.
2025-02-10.You have files: Python.md, JavaScript.md, pages/TypeScript.md
When you type:
I'm learning Python and JavaScript for web development.
It becomes:
I'm learning [[Python]] and [[JavaScript]] for web development.
With Obsidian's "Folder to create new notes in" set to pages/ and "Respect 'Folder to create new notes in' setting" enabled, along with Proximity-based Linking enabled:
File structure:
pages/
languages/
Python.md
TypeScript.md
frameworks/
React.md
Current file: pages/frameworks/React.md
When you type: React uses TypeScript
It becomes: [[frameworks/React]] uses [[languages/TypeScript]]
File pages/team-a/internal.md has frontmatter:
---
automatic-linker-scoped: true
---
Current file: pages/team-a/notes.md
Typing internal creates [[team-a/internal]] ✅
From pages/team-b/notes.md, typing internal won't link ❌
Before:
Check out https://github.com/obsidianmd/obsidian-releases/issues/1234
After:
Check out [obsidianmd/obsidian-releases#1234](https://github.com/obsidianmd/obsidian-releases/issues/1234)
When you select part of a nested list:
Selection in editor:
- Priority about [[PBI]]
- High priority for near deadline
- Chapter [[PBI]]
- Up to 30% [[story point]] in sprint backlog
After running "Copy selection without links", clipboard contains:
- Priority about PBI
- High priority for near deadline
- Chapter PBI
- Up to 30% story point in sprint backlog
Features:
[[path/to/file]] → fileTo avoid conflicts when using both plugins:
This ensures Automatic Linker runs first, followed by Linter.
Add these to individual note frontmatter:
---
# Disable formatting and URL title fetching in this file (including vault and selection commands)
automatic-linker-off: true
# Exclude this file from being automatically linked from other files
automatic-linker-exclude: true
# Restrict linking to same namespace only
automatic-linker-scoped: true
# Disable URL title fetching and replacement in this file
automatic-linker-disable-url-title: true
# Define aliases for this file (standard Obsidian feature)
aliases: [shortname, alternative-name]
---
# Clone the repository
git clone https://github.com/kdnk/obsidian-automatic-linker.git
cd obsidian-automatic-linker
# Install dependencies
pnpm install
# Start development mode
pnpm dev
pnpm build # Build for production
pnpm dev # Development mode with watch
pnpm test # Run all tests
pnpm test:watch # Run tests in watch mode
pnpm tsc:watch # TypeScript type checking in watch mode
# Run a specific test file
npx vitest run src/path/to/test.ts
# Run tests matching a pattern
npx vitest run -t "test description"
src/
├── main.ts # Main plugin entry point
├── settings/ # Settings UI and types
├── replace-links/ # Core link replacement logic
├── replace-urls/ # URL formatting (GitHub, Jira, Linear)
├── replace-url-with-title/ # Bare URL to titled link conversion
├── exclude-links/ # Link exclusion logic
├── remove-minimal-indent/ # Remove minimal indentation from text
├── trie.ts # Trie data structure for efficient matching
└── update-editor.ts # Editor update utilities
Links aren't being created:
Proximity-based Linking not working:
Conflicts with Obsidian Linter:
Performance issues:
updateEditor function adapted from obsidian-linterThis project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Kodai Nakamura
If you find this plugin useful, consider starring the repository on GitHub!