Automatic Linker

approved

by kdnk

automatically converts plain text file references into wiki links

ā˜… 40 stars↓ 14,890 downloadsUpdated 12d agoApache-2.0

šŸŖ„ Automatic Linker šŸ”®

Automatically convert plain text file references into Obsidian wiki links as you write. Keep your knowledge graph connected without manual linking.

Overview

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.

Installation

From Obsidian Community Plugins

  1. Open Settings → Community plugins
  2. Disable Safe mode
  3. Browse for "Automatic Linker"
  4. Click Install, then Enable

Manual Installation

  1. Download the latest release from GitHub Releases
  2. Extract main.js, manifest.json, and styles.css to your vault's .obsidian/plugins/automatic-linker/ directory
  3. Reload Obsidian and enable the plugin in Settings → Community plugins

Key Features

Automatic Link Conversion

The plugin automatically detects file names in your text and converts them to wiki links. It works seamlessly with:

  • Format on Save: Automatically convert links when saving files
  • Selected Text: Convert only highlighted body text via command palette; frontmatter, code, and existing links stay protected even when only part of them is selected
  • Entire Vault: Batch process files in your vault while respecting each note's automatic-linker-off setting
  • CJK Support: Full support for Japanese, Chinese, Korean, and other CJK languages
  • Case Sensitivity: Optional case-insensitive matching

Smart Namespace Management

Organize large vaults with sophisticated namespace handling:

  • Base Directory: Use Obsidian's "Folder to create new notes in" setting as the base directory where folder prefixes are omitted from links
  • Proximity-based Linking: Automatically resolve shorthand links to their full namespaced paths
  • Namespace Scope: Use automatic-linker-scoped: true in frontmatter to restrict linking to files within the same namespace
  • Closest Match Selection: When multiple candidates exist, the plugin selects the file closest to your current note

URL Formatting

Transform raw URLs into readable Markdown links automatically:

  • GitHub URLs: Convert https://github.com/user/repo/issues/123 to [user/repo#123](URL)
  • GitHub Enterprise: Configure custom GitHub Enterprise domains
  • Jira URLs: Format Jira issue links with custom domain support
  • Linear URLs: Format Linear issue links
  • Page Titles: Fetch and replace bare URLs with [Page Title](URL) format (cached to minimize requests)

Advanced Link Control

Fine-tune linking behavior to match your workflow:

  • Alias Support: Reference files by any of their frontmatter aliases
  • Prevent Linking: Add automatic-linker-exclude: true to frontmatter to exclude files from auto-linking
  • Prevent Self-Linking: Avoid creating links from a file to itself
  • Remove Aliases: Automatically strip aliases in specified directories
  • Month Note Handling: Ignore single/double digit references (1, 01, 12) unless namespaced
  • Date Format Ignoring: Skip date-formatted text (e.g., 2025-02-10) for compatibility with Obsidian Tasks

Quality of Life Features

  • Exclude Directories: Prevent auto-linking in specified folders
  • Preserve Existing Links: Never reformats already-linked text
  • Copy Without Links: Copy note content with wiki links converted back to plain text
  • Copy Selection Without Links: Copy selected lines with minimal indentation and wiki links removed (supports path-style links like [[path/to/file]])
  • Debug Mode: Detailed logging for troubleshooting
  • Load Notices: Optional notifications when files are processed

Commands

Access these commands via the Command Palette (Cmd/Ctrl + P):

CommandDescription
Automatic Linker: Format fileConvert text to links in the current file
Automatic Linker: Format selectionConvert only selected text to links
Automatic Linker: Format vaultBatch process all files in your vault
Automatic Linker: Copy file without linksCopy current file content with links as plain text
Automatic Linker: Copy selection without linksCopy selected lines with minimal indent and links removed
Automatic Linker: Rebuild indexRebuild the file index for link candidates

Configuration

Formatting Workflow

  • Format on save: Automatically format links when saving files.
  • Format delay (ms): Delay formatting stages by the configured number of milliseconds. This is not a completion timeout: each formatter's completion is awaited separately.
  • Run Prettier after formatting: Run Prettier after link formatting, and wait for it to finish before starting Linter.
  • Run Obsidian Linter after formatting: Run Obsidian Linter after link formatting and Prettier have completed.

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.

Link Behavior

  • Respect 'Folder to create new notes in' setting: Use Obsidian's new-note folder as the base directory when omitting folder prefixes from links.
  • Proximity-based linking: Resolve shorthand links to the candidate with the most path segments in common with the current file.
  • Include aliases: Include frontmatter aliases when matching text.
  • Remove aliases in directories: Remove displayed link aliases for links targeting the configured directories.
  • Ignore case: Match links without requiring the same letter case.
  • Match sentence case: When Ignore case is disabled, match text capitalized only because it starts a sentence.

Exclusions

  • Prevent self-linking: Do not link text to the current file.
  • Ignore date formats: Skip date-formatted text such as 2025-02-10.
  • Ignore headings: Do not add links inside Markdown headings.
  • Ignore Markdown tables: Do not add links inside Markdown table rows.
  • Exclude directories from automatic linking: Skip files in the configured directories when building automatic links.

URL Formatting

  • Format GitHub URLs on save: Convert GitHub URLs to readable issue and pull-request links.
  • GitHub Enterprise URLs: Add custom GitHub Enterprise domains.
  • Format JIRA URLs on save: Convert JIRA issue URLs to readable links.
  • JIRA URLs: Add custom JIRA domains.
  • Format Linear URLs on save: Convert Linear issue URLs to readable links.
  • Replace URL with title: Replace bare URLs with Markdown links using fetched page titles.
  • Ignore domains: Exclude configured domains and their subdomains from URL title replacement, including URLs whose titles have already been cached.

Diagnostics

  • Show load notice: Display a notice after the plugin loads Markdown files into its index.
  • Debug mode: Log debug information to the developer console.

Usage Examples

Example 1: Basic Linking

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.

Example 2: Proximity-based Linking

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]]

Example 3: Namespace Scope

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 āŒ

Example 4: URL Formatting

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)

Example 5: Copy Selection Without Links

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:

  • Removes minimal indentation from selected lines
  • Converts path-style links: [[path/to/file]] → file
  • Preserves relative indentation structure
  • Gets full lines even if partially selected

Integration with Obsidian Linter

To avoid conflicts when using both plugins:

  1. Disable "Lint on Save" in Obsidian Linter settings
  2. Enable "Format on Save" in Automatic Linker settings
  3. Enable "Run Obsidian Linter after formatting" in Automatic Linker settings

This ensures Automatic Linker runs first, followed by Linter.

Frontmatter Options

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]
---

Development

Prerequisites

  • Node.js 16+
  • pnpm (or npm)

Setup

# 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

Available Commands

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

Running Specific Tests

# Run a specific test file
npx vitest run src/path/to/test.ts

# Run tests matching a pattern
npx vitest run -t "test description"

Project Structure

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

Troubleshooting

Links aren't being created:

  • Ensure "Format on Save" is enabled or manually trigger the command
  • Verify the file isn't in an excluded directory

Proximity-based Linking not working:

  • Ensure "Proximity-based Linking" is enabled in settings
  • Check that files are within Obsidian's configured "Folder to create new notes in" directory if the "Respect 'Folder to create new notes in' setting" option is enabled

Conflicts with Obsidian Linter:

  • Follow the integration guide above to run plugins in sequence

Performance issues:

  • Disable debug mode if enabled
  • Consider excluding large directories from auto-linking
  • Increase format delay if formatting happens too frequently

Credits

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Author

Kodai Nakamura

Support


If you find this plugin useful, consider starring the repository on GitHub!

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.