Skip to content

Releases: max-fluff/obsidian-code-linker

1.7.0

Choose a tag to compare

@github-actions github-actions released this 25 Aug 12:56

Added

  • The whole look of a link, a mark and a snippet (Style Settings). The links this plugin inserts carry a class of their own in both render modes now, so they can take a colour and an underline — both the theme's own until you change them. The stale and broken marks get their two colours, the underline's style and thickness, and an optional symbol beside the link, for themes where a thin underline is hard to see. A hover preview takes a width as well as a height, and a snippet a line height and a text size. The section is grouped into Links, Stale and broken links, Previews and embeds, Autocomplete and Side panel. Every option is a plain CSS variable or a class on body, so a snippet in .obsidian/snippets/ does as well — the readme lists them all.
  • The index panel's row density and text size (Indexing, Style Settings). Rows dense, normal or roomy, and the panel's base text size. The path column beside an autocomplete suggestion can be hidden.

Changed

  • The target line's highlight no longer buries the code (Preview, Embeds). The band is drawn behind the snippet, and a theme's selection colour at full strength left the line on top of it unreadable. It still follows that colour, taken down to where the code stays legible; Preview line highlight sets it outright, at whatever strength you choose.
  • A colour setting opens on the colour in use (Style Settings). Reading the variable is not enough to show it: Obsidian builds its accent from calc() and a chain of other variables, which a colour picker cannot parse, so the swatch came up empty. Each colour is settled through the browser into a plain rgb() and written again whenever the theme changes — so a picker shows what the theme is really using, and follows it until you choose otherwise.

Internal

  • The rows every plugin of a kind offers are written once in the shared repository and spliced into each plugin's Style Settings block at build time, so the two sigil linkers cannot drift apart, and a plugin takes only the fragments it can honour — a side-panel row in a plugin with no side panel is a setting that does nothing. The suites check both directions: a row nothing reads fails, and a variable no row offers fails.

1.6.1

Choose a tag to compare

@github-actions github-actions released this 23 Aug 16:36

Fixed

  • The Style Settings section did not appear until Obsidian was restarted, when this plugin was enabled after Style Settings itself.

Internal

  • The cross-plugin contract now carries the other meanings a linker has for one span, so a word claimed from two places is offered as two rows rather than one. No effect here — the code linker resolves an explicit @@ reference, which names one target — but the shared layer moves in step across the four plugins.

1.6.0

Choose a tag to compare

@github-actions github-actions released this 02 Aug 13:11

Added

  • The index panel (Indexing, Links). A pane in the right sidebar answering the two questions the pickers cannot: what the scan actually found, and which links no longer land. The top half is the index itself — every language with the number of entries under it, and the kinds inside each once you open one — with a search box that finds a symbol by name and offers to open its file or copy a link to it, without inserting anything into a note. Reachable from the ribbon or Open the code index panel; the ribbon icon can be turned off.
  • Vault-wide link health (Links). The panel's lower half reports, per note, how many of its code links drifted and how many are broken, and hands the drifted ones to the same preview the update commands use. It reads every note, so it runs only when you press Scan — and it is a dry run of exactly that rewrite: it reads and never writes. A link into a file the index has never heard of is left unjudged rather than reddened, so one mistyped code root cannot condemn every link at once.
  • sym: as an inline filter (Suggestions). @@sym:def asks for the symbol named def — the only way to reach a symbol whose own name is a language or kind token, which a bare query reads as a filter instead.

Internal

  • Filtering and pinning are one registry now. A way of addressing an entry is declared once as a projection from an entry to a value, and that one projection answers what a typed filter keeps, what the typed text is matched against, and what a link pins to — where the two sides were written separately and could drift. The anchors a link stores (sym:, kind:, line:) are unchanged on disk.
  • The community listing text is kept out of the repository.

1.5.0

Choose a tag to compare

@github-actions github-actions released this 01 Aug 20:50

Added

  • The code embed has a toolbar (Embeds). Drawn on the shared embed frame: wrap long lines, copy the snippet, Open, Refresh, and a menu holding everything that writes to the note.
  • Line numbers (Embeds). A snippet says which lines of the file it is showing, with the target line's number carrying its highlight. numbers: off drops the gutter for a snippet quoted for its wording rather than for where it sits.
  • Show more lines (Embeds). A strip above and below opens the snippet out ten lines at a time, and says how much is there: three lines from the top of the file it offers three, not ten. Opening it out is a way of reading, not an edit — the block keeps saying what it said, and Refresh puts it back.
  • Respect .gitignore (Indexing). Build output an ignore file excludes stays out of the index. The setting appears only where the scan actually meets a .gitignore.

Changed

  • The menu's note-editing items — Pin, Unpin and Fix — are offered only where the note is open in an editor. Reading view has no editor to undo a write in.

Fixed

  • An embed pinning or unpinning itself wrote its bind: line back in two steps, and could write it into whichever note was open rather than the block's own. The write is atomic now, and goes only to the note the block lives in.

Internal

  • Scan folders are watched through the shared watcher, which works on Linux too.

v1.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 17:46

Added

  • Both update commands now open a preview before anything is written. Every drifted link and embed is listed under its note with a checkbox, showing the line it would move from and to; links whose code is gone are listed separately as needing attention, so "nothing to update" is a verdict you can read rather than a notice that flashes past. Untick individual changes or a whole note, then apply. A note edited between opening the preview and applying is skipped instead of overwritten.
  • Pin unpinned code links and embeds in this note / … in the whole vault (previously links only) ask what to pin to first — symbol name, kind, exact line text, or a combination, with symbol plus line as the default. Anchors combine, so a bulk pin no longer silently attaches to a same-named declaration elsewhere in the file.
  • A drifted embed's right-click menu offers Update this code link, the fence-body counterpart of the item a drifted link already had.
  • Priority among linker plugins, first in Settings → Maintenance. It appears only when another linker plugin is installed, and decides which plugin claims a word or a link both recognise. Each plugin moves only itself, so an arrangement may need a move in more than one settings tab.

Changed

  • Rename or move a pinned file and the link follows it. The symbol is looked up in its new file, and if the match is unambiguous the link is marked fixable rather than broken; the update commands rewrite both the path and the line, and the preview tints a move so it can be looked over before applying.
  • New links write {code-root} where they used to write {root}, so a link says which linker owns it. Links already in notes are not touched and keep resolving: a bare {root} is still filled in when the link carries a code pin, when Code Linker is the only linker installed, or when the path resolves inside the code root. Editor templates in settings — presets and custom ones alike — are rewritten to {code-root} on load, and a migrated preset stays a recognised preset instead of being filed as "Custom".
  • With Reference Linker also installed, the two selection commands nest under a shared entry instead of appearing twice: one Find and open with Code inside it, one Find and convert to link likewise. Alone, the flat wording stays and says what it makes — Find and open code, Find and convert to code link.
  • Right-clicking a link that both linkers recognise now offers one set of actions. Ownership is settled by the pin the author wrote when there is one, and by the priority order otherwise.

Fixed

  • A link whose file the index doesn't know — outside the scan folders, not yet indexed, or moved — was underlined in the error colour as though its code were gone. Such a link is now judged silently: marked stale if its pin turns up elsewhere, otherwise left unmarked. Embeds behave the same way.
  • With Reference Linker installed, each plugin read the other's pins as its own, found no matching symbol, and marked those links broken. Pins are now checked for ownership before being judged.
  • Clicking a link with a {root} token was handled by whichever linker happened to load first, so the same link could open in the wrong target. Each plugin now claims only links it can show are its own.
  • The plugin published its API before finishing load, so a failed load could leave Reference Linker standing aside for a plugin that never came up. It is published last.

Internal

  • The hover popover, the inline suggester, the stale-link marking, the update preview, the interface strings and styles, the menu builder and the precedence control moved into the shared submodule, along with the interop layer that decides which linker owns a contested link.
  • Tests moved to the shared harness and stubs, and CI gates on the cross-version contract tests.

v1.3.5

Choose a tag to compare

@github-actions github-actions released this 17 Jul 17:31

Added

  • Link pinning: pin a link to what it should track, from its right-click submenu or the palette — the symbol on its line (sym:Player), the kind of thing there (kind:class), or the exact line (line:<hash>). Anchors are requirements and combine, so sym:Player kind:class tells the file Player.cs apart from the class Player in it.
  • The pin lives in the link's markdown title rather than its text, so [the player](…/Player.cs:4 "sym:Player") tracks. Link text no longer affects anything, and a title that isn't a pin is left alone.
  • Embeds pin the same way, with a bind: line in the block. A drifted embed marks its header and names the line the code moved to; the update commands fix its target, ranges included (the window keeps its length). Pin one from the block's right-click menu.
  • New commands: Insert code link to a line; Pin code link to its symbol / kind / exact line; Unpin code link; Pin unpinned code links in this note / the whole vault.

Changed

  • Tracking is opt-in: only a pinned link is marked or updated. Any link whose text happened to name a symbol used to be tracked, so a retitled link read as broken and the update commands could rewrite links you hadn't asked about. Existing notes stop being tracked until pinned — run "Pin unpinned code links in the whole vault" once.
  • A link or embed pointing at a whole file no longer carries a :1 it never meant; the line goes along with the punctuation that introduces it (: in the editor presets, #L in the permalinks).
  • Moving a link onto another line that still matches its pin isn't drift — a link pinned to sym:TakeDamage is fine on either one in the file.
  • The broken mark now means one thing: nothing in the file matches the pin any more, whether renamed, removed, or rewritten.

Fixed

  • The JetBrains preset tracked nothing at all. A path was only recognised after a /, so templates that introduce it with = — JetBrains' path={path}, or a custom preset's file={abs} — never resolved: no stale marks, no hover preview, and the update commands silently did nothing.
  • A link to a whole file resolved to a same-named declaration inside it and got "updated" to point at the class: [Player](…/Player.cs:1) became Player.cs:4.

Internal

  • Link bindings and the link/fence rewriting helpers moved into the shared submodule.
  • Bumped version once again to pass review

v1.3.2

Choose a tag to compare

@github-actions github-actions released this 16 Jul 22:00

Added

  • Link pinning: pin a link to what it should track, from its right-click submenu or the palette — the symbol on its line (sym:Player), the kind of thing there (kind:class), or the exact line (line:<hash>). Anchors are requirements and combine, so sym:Player kind:class tells the file Player.cs apart from the class Player in it.
  • The pin lives in the link's markdown title rather than its text, so [the player](…/Player.cs:4 "sym:Player") tracks. Link text no longer affects anything, and a title that isn't a pin is left alone.
  • Embeds pin the same way, with a bind: line in the block. A drifted embed marks its header and names the line the code moved to; the update commands fix its target, ranges included (the window keeps its length). Pin one from the block's right-click menu.
  • New commands: Insert code link to a line; Pin code link to its symbol / kind / exact line; Unpin code link; Pin unpinned code links in this note / the whole vault.

Changed

  • Tracking is opt-in: only a pinned link is marked or updated. Any link whose text happened to name a symbol used to be tracked, so a retitled link read as broken and the update commands could rewrite links you hadn't asked about. Existing notes stop being tracked until pinned — run "Pin unpinned code links in the whole vault" once.
  • A link or embed pointing at a whole file no longer carries a :1 it never meant; the line goes along with the punctuation that introduces it (: in the editor presets, #L in the permalinks).
  • Moving a link onto another line that still matches its pin isn't drift — a link pinned to sym:TakeDamage is fine on either one in the file.
  • The broken mark now means one thing: nothing in the file matches the pin any more, whether renamed, removed, or rewritten.

Fixed

  • The JetBrains preset tracked nothing at all. A path was only recognised after a /, so templates that introduce it with = — JetBrains' path={path}, or a custom preset's file={abs} — never resolved: no stale marks, no hover preview, and the update commands silently did nothing.
  • A link to a whole file resolved to a same-named declaration inside it and got "updated" to point at the class: [Player](…/Player.cs:1) became Player.cs:4.

Internal

  • Link bindings and the link/fence rewriting helpers moved into the shared submodule.
  • Bumped version to pass review

v1.2.0

Choose a tag to compare

@max-fluff max-fluff released this 14 Jul 10:42

Added

  • Git permalink presets (GitHub and GitLab): insert a web link pinned to the file's exact commit. The remote and commit sha are read straight from the file's .git (no git binary), walking up to the nearest repo so a vault spanning several repos links each file to its own. New placeholders {gitRemote}, {gitSha}, {gitBranch}. The presets are revealed in the pickers automatically on first run when a matching remote is found.
  • Suggestion filters: type lang:kind:Name after the trigger to narrow results — e.g. py:def:parse for a Python definition. A trailing .Container (bar.Foo) restricts to a same-file container; the first unrecognised prefix starts the name.
  • More symbols indexed: methods and functions in the C-like languages (C#, C/C++, Java), plus class methods and lambdas in JavaScript and TypeScript.
  • JetBrains support in custom editor presets, with a per-IDE product picker.
  • The editor picker now floats your most recently used presets to the top.

Changed

  • Settings reorganised; scan-root and skip-folder lists gained per-row path autocomplete.
  • The JetBrains placeholder was renamed {product} → {jetbrainsProduct}. Update any custom editor template that used the old name — {product} is no longer substituted.

Internal

  • Shared markdown / i18n helpers extracted into a git submodule (shared with Glossary Linker); CI now builds on every PR.

v1.1.0

Choose a tag to compare

@max-fluff max-fluff released this 11 Jul 15:47

Added

  • Hover preview — hover a code link to see a syntax-highlighted snippet of the file around the target line; the window size is configurable (Preview lines before / after, -1 = to file edge). Ctrl/Cmd to trigger it in Live Preview.
  • Inline code embeds — a ```code-link block renders a live, highlighted snippet (by symbol, declaration line, or line range, with optional context: padding and title:). Re-renders automatically when the index rebuilds. New Insert code embed command.
  • Stale / broken link marks — Mark stale links underlines links whose stored line has drifted (warning colour) or whose symbol was renamed/removed (error colour), in both reading view and Live Preview.
  • Update code links — new commands to re-resolve and fix drifted line numbers in the current note or the whole vault, plus a right-click Update this code link on a single drifted link.
  • Editor switcher — switch the active editor preset from the status bar or the Switch editor preset command without opening settings; Always ask picks the format per insert.
  • Copy code link on right-click of an existing link, with {root} resolved to an absolute path.
  • New built-in languages: Java, PHP, Rust — built-ins now cover C#, TypeScript, JavaScript, Python, Java, C/C++, PHP, Go and Rust (9 total).
  • New settings: Min characters (before suggestions appear) and Max results.

Changed

  • Syntax highlighting in hover/embeds now uses Obsidian's loadPrism(), so a language is highlighted reliably without first rendering a code block elsewhere.
  • Stale/broken underlines switched to a border-bottom (wavy/offset underlines rendered inconsistently across platforms); still restylable via Style Settings and CSS variables.
  • Settings reorganised (min/max/auto-refresh grouped with indexing).

Internal

  • Automated release workflow: builds and attaches attested main.js, manifest.json, styles.css on release publish; CONTRIBUTING.md and committed package-lock.json added.

v1.0.0

Choose a tag to compare

@max-fluff max-fluff released this 30 Jun 10:35

Initial release.

Added

  • Autocompletes references to your source code on a configurable trigger (default @@), with fuzzy / camelCase matching (hc finds HttpClient). Indexes file names and type declarations with their line numbers, and inserts a markdown link that opens the file at the exact line. Suppressed inside code, frontmatter and existing links; pipes inside a table cell are escaped.
  • Picker commands to insert, open, or copy a code link via a full-screen fuzzy picker.
  • Selection commands and right-click menu actions: convert a selected name or path into a link, or find and open the matching file. A single match acts directly; several open the picker.
  • Portable {root} links: the note keeps a relative path and the literal {root}, and the machine-specific code root is filled in only when the link is rendered or opened, so notes stay portable.
  • Editor targets as URI templates: file://, VS Code, JetBrains (per-IDE), plus your own named templates. Placeholders: {root}, {abs}, {path}, {line}, {name}, {project}, {product}.
  • Built-in languages for C#, TypeScript, JavaScript, Python, C/C++ and Go, with per-language and per-kind toggles. Add or override languages with a custom JSON languages file in your vault.
  • On-disk index cache for instant startup; the background rebuild re-reads only files whose modification time changed. Optional auto-refresh watches your code folders and rebuilds on change.
  • Read-only public API at app.plugins.plugins['code-linker'].api (entries, files, stats, languages, find, link/uri builders, change subscription) for other plugins and DataviewJS.
  • Interface in English and Russian, following Obsidian's language.

Requires Obsidian 1.4.0+, desktop only (it reads the filesystem).