Skip to content

Releases: lucasgaldinos/obsidian-gfm-headers

1.4.0

Choose a tag to compare

@github-actions github-actions released this 29 Jul 18:31

What's Changed

New Contributors

Full Changelog: 1.3.8...1.4.0

1.3.8

Choose a tag to compare

@github-actions github-actions released this 21 Jul 17:04

Fixed

  • Community review: ESLint fatal error — minAppVersion was '1.12' (invalid semver). Fixed to '1.0.0'.
  • versions.json — added missing entries for 1.3.7 and 1.3.8.
  • Sentence case in settings UI — fixed 5 obsidianmd/ui/sentence-case warnings.
  • README overhaul — badges, before/after table, Settings section, docs links, removed stale GFM collision limitation.
  • .gitignore compliance — untracked .agents/ and .github/instructions/ files.

Added

  • ESLint config (eslint.config.mjs) with eslint-plugin-obsidianmd
  • npm run lint script — catch review failures before submitting
  • Pre-submission validation section in README

1.3.7

Choose a tag to compare

@github-actions github-actions released this 21 Jul 14:54

title: "Changelog"
tags: [changelog, gfm-heading-links, obsidian-plugin]
description: "Release history and notable changes for the GFM Heading Links Obsidian plugin"
date_created: 2026-07-02
date_changed: 2026-07-18
author: "Lucas Galdino"

Changelog

All notable changes to the GFM Heading Links plugin are documented in this file.

The format is based on Keep a Changelog, and this project adheres to
Semantic Versioning.

[1.3.1][] — 2026-07-20

Note: This release consolidates the original v1.3.1 release infrastructure work and all
subsequent community review compliance fixes (previously spread across v1.3.2–1.3.6).
Those intermediate releases have been deleted — this is the definitive v1.3.1.

Added

  • Release Infrastructure: LICENSE (MIT), GitHub Actions release workflow
    (.github/workflows/release.yml), branch strategy (main=production/DEBUG_ENABLED=false,
    dev=development/DEBUG_ENABLED=true).
  • CI Artifact Attestations (actions/attest@v4): Supply-chain provenance for release
    artifacts.
  • author and authorUrl populated in manifest.json.
  • .gitignore hardened: data.json, *.png exclusions, refined .github/ and .agents/
    patterns.
  • Typed Internal APIs (src/vault-config.ts): getVaultConfig() and isWikilinksEnabled()
    helpers replace inline (vault as any) casts.
  • Type-Safe Editor Suggest: SuggestionValue, EditorSuggestInstance,
    SuggestionDropdownItem interfaces and unwrapDropdownItem() type guard — all any
    types eliminated from the suggest pipeline.

Changed

  • package.json version aligned with manifest.json (both 1.3.1).
  • All documentation updated: docs/plan/*, docs/research/architectural-history.md,
    docs/architecture.md, README.md.
  • Release links in CHANGELOG.md fixed to point to lucasgaldinos/obsidian-gfm-headers.
  • Production console hygiene: console.logconsole.debug in gated debug system
    (src/debug.ts). console.debug is suppressed by default in browser DevTools at the
    default "Info" log level.
  • Arrow functions for all monkeypatch assignments: workspace.openLinkText,
    workspace.trigger, and suggest.selectSuggestion all use arrow functions with
    explicit .call(workspace, ...) rebinding.
  • .bind(workspace) at method capture: originalOpenLinkText and originalTrigger
    are bound at capture time via .bind(workspace), eliminating this-scoping warnings
    from Obsidian's review linter.
  • Safe array initialization: new Array<number>(n).fill(0) replaces new Array(n).fill(0)
    to avoid implicit any[] inference.
  • window.setTimeout / window.clearTimeout used instead of bare setTimeout /
    clearTimeout for browser global compliance.
  • loadData() cast as Partial<GfmSettings> instead of as any.
  • view.currentMode cast as typed interface instead of as any.
  • injectVirtualBlock and selectSuggestion use typed Pos and SuggestionValue params.

Removed

  • Accidentally committed image.png, image copy.png, and data.json.
  • All eslint-disable and @typescript-eslint/no-explicit-any directive comments.
  • Unused debugLog / DEBUG_ENABLED import from main.ts.
  • Non-existent styles.css from CI release assets.

Fixed

  • this: void linter warnings: Original methods captured from workspace are now
    bound via .bind(workspace) at capture time, preventing this-scoping errors when
    the method is called detached from its object.
  • Review linter compliance: Addressed all warnings reported by Obsidian's automated
    plugin review — no any types, no console.log in production builds, no directive
    suppressions, no function() without this: void.

[1.3.0][] — 2026-07-17

Added

  • Settings Tab: Configurable prefix and suffix characters for autocompleted links (e.g., §Heading¶). Dual-API support: uses declarative getSettingDefinitions() on Obsidian 1.13.0+, falls back to display() on older versions.
  • Wikilink Alias Auto-Injection: When Obsidian is using wikilinks ([[), selecting a heading from autocomplete now automatically appends |Original Heading — producing [[#gfm-slug|Original Heading]] instead of bare [[#gfm-slug]].
  • Link Affixes: User-configurable prefix/suffix applied to heading aliases during autocomplete.
  • isGfmSlug() shared guard predicate in gfm-slugify.ts.
  • transformSuggestion() pure pipeline extracting heading mutation logic from selectSuggestion god-function.
  • decodeGfmSlug() and resolveTargetFile() shared resolution helpers.
  • injectVirtualBlock() shared utility with cleanup callback and VIRTUAL_BLOCK_CLEANUP_MS constant.
  • normalizeSlug() in src/link-parse.ts.

Changed

  • patch-workspace.ts split by SRP into patch-link-click.ts (applyClickPatch, async) and patch-link-hover.ts (applyHoverPatch, sync).
  • buildDocumentIndex() replaced O(n²) nested loop with 2-pass O(n) stack-based algorithm.
  • link-target.ts renamed to types.ts — all 5 imports updated.
  • Variable renames for readability: datahoverEventPayload, valuesuggestionValue, mutateddidModifySubpath.
  • resolveGfmTarget() and resolveGfmTargetSync() unified to use shared decodeGfmSlug() + resolveTargetFile() helpers, reducing each from ~90 to ~15 lines.
  • Hover handler no longer uses require("./document-index") inlining — delegates to resolveGfmTargetSync().
  • Settings tab uses declarative getSettingDefinitions() API (Obsidian 1.13.0+) with display() fallback.
  • minAppVersion set to 1.12.7 for dual settings API support.
  • DEBUG_ENABLED = true on dev branch — set to false for production builds.

Fixed

  • Inverted guard bug: isGfmSlug() condition was inverted in resolve-target.ts, causing valid GFM slugs to pass through unresolved.
  • Settings tab broken on Obsidian <1.13.0: Declarative-only API caused empty settings pane. Fixed with dual-API support.
  • Affixes applied to wrong field: Affixes were appended to suggestionValue.subpath (the slug) instead of suggestionValue.heading (the alias).
  • Wikilink alias not injected: Multiple iterations required; finally resolved via plugin.app.workspace.activeEditor?.editor post-insertion modification.

[1.2.0][] — 2026-07-13

Added

  • Document Index Architecture: Lightweight background Map<gfmSlug, AnchorTarget> per file, separate from Obsidian's cache. Enables O(1) slug lookups with zero risk of cache contamination.
  • Virtual Block Injection: Temporarily injects #^gfm-click-{slug} blocks into cache.blocks to leverage Obsidian's native block-level scrolling and .is-flashing highlight — works correctly for duplicate headings.
  • Autocomplete GFM Slug Output (EditorSuggest.selectSuggestion): Selecting a heading from the [[ dropdown now outputs the GFM slug (e.g., [My Heading](file.md#my-heading)) while preserving the original heading text as the alias.
  • Duplicate Heading Resolution in Autocomplete: Advanced dropdown occurrence-index matching correctly resolves which Nth duplicate was selected, producing the correct collision suffix (-1, -2, etc.).
  • HTML Anchor Scanning (scanHtmlAnchors): Parses <a id="..."> and <a name="..."> tags for target identification (click navigation in Reading mode).
  • Structured Debug Logging (src/debug.ts): 15 event types with DEBUG_ENABLED toggle for development instrumentation.
  • Unit Tests (Vitest, 17 tests): gfmSlugify (basic, Unicode, edge cases), buildDocumentIndex (collision suffixes, endLine), resolveGfmTarget (guard logic).

Changed

  • Architectural Shift: Abandoned the speculative Heading#Heading subpath navigation. Replaced with Document Index + Virtual Block Injection across all three monkeypatches (openLinkText, trigger('hover-link'), EditorSuggest.selectSuggestion).
  • Same-file navigation: Bypassed native resolution for same-file links to eliminate jump-to-top flicker.
  • HTML in heading aliases: Autocomplete now strips HTML tags from heading text (e.g., ## Title <a id="x"></a> → alias Title).

Fixed

  • Hover Preview on duplicate headings: Corrected buildDocumentIndex(cache.headings)buildDocumentIndex(cache) — the former produced an empty index, causing all hover previews to fail.
  • Alias loss in autocomplete: Stopped mutating value.heading — only value.subpath is rewritten to the GFM slug.
  • .is-flashing on duplicates: Native block navigation handles section highlighting correctly, no longer highlights wrong heading.

Known Limitations

  • HTML anchor click navigation works only in Reading mode (Live Preview / Source mode under investigation — see Bug 10).
  • HTML anchor hover preview is not yet supported (hover interceptor only handles heading-type targets — see Bug 6).
  • GFM collision suffix uses last-write-wins (Map.set() overwrites). First-occurrence priority deferred to v2 (see Bug 8).
  • DEBUG_ENABLED = true on dev branch — set to false for production builds.

[1.1.0][] — 2026-07-03

Changed

  • Architectural Overhaul: Completely abandoned the fragile CodeMirror 6 ViewPlugin and DOM MutationObserver architecture. The plugin now globally monkeypatches Obsidian's core Workspace router (workspace.openLinkText and workspace.trigger('hover-link')).
  • Fixed Ctrl + Hover (Page Preview): Because the plugin now patches the event routing layer rather than aggressively swallowing DOM mouseover events, Obsidian's native modifier-key detection and delays work perfectly.
  • Fixed Cross-File Links: Addressed a critical bug where links pointing to other files (e.g., [Link](other-file.md#gfm-slug)) were ignored. The new router patch correctly separates the file path from the hash before attempting resolution.

Removed...

Read more

1.3.1

Choose a tag to compare

@github-actions github-actions released this 21 Jul 11:27

Full Changelog: v1.3.0...1.3.1