Skip to content

fix(links): unify resolution for Markdown and WikiLinks and fix LSP p…#677

Open
sfgartland wants to merge 3 commits into
zk-org:devfrom
sfgartland:markdown-links-bug
Open

fix(links): unify resolution for Markdown and WikiLinks and fix LSP p…#677
sfgartland wants to merge 3 commits into
zk-org:devfrom
sfgartland:markdown-links-bug

Conversation

@sfgartland

Copy link
Copy Markdown

…anic

Markdown and WikiLinks are now resolved using an identical three-step hierarchy:

  1. Exact match relative to the vault root.
  2. Match relative to the current file.
  3. Fallback to partial path matching.

This fixes the issue where Markdown links requiring extensions were not properly indexed, and ensures consistent link resolution across CLI and LSP functionalities.

Additionally, added a nil-pointer check to the LSP definition handler to prevent crashes when resolving definitions for editors that do not provide full TextDocument LinkSupport capabilities.

...

Fixes #676

@WhyNotHugo

Copy link
Copy Markdown
Contributor

The correct order is:

  • Match relative to the current file.
  • Exact match relative to the vault root.
  • Fallback to partial path matching.

If we always default to the root, then x/a.md becomes unreachable if a.md exists, and links would change their destination when creating the latter.

In general terms, markdown links are relative to the current file. The other two behaviours are fallbacks for unusual usages.

@sfgartland sfgartland marked this pull request as draft March 23, 2026 08:06
Includes tests for Wikilinks, Markdown links, relative paths, root-absolute paths, and resolution priority.
Verifies that the LSP definition handler handles nil or incomplete client capability objects without crashing.
…anic

Markdown and WikiLinks are now resolved using an identical three-step hierarchy:
1. Match relative to the current file.
2. Exact match relative to the vault root.
3. Fallback to partial path matching.

This priority ensures that relative links are not hijacked by root-level files with the same name.

This also fixes the issue where Markdown links requiring extensions were not properly indexed, and ensures consistent link resolution across CLI and LSP functionalities.

Additionally, added a nil-pointer check to the LSP definition handler to prevent crashes when resolving definitions for editors that do not provide full TextDocument LinkSupport capabilities.
@sfgartland

Copy link
Copy Markdown
Author

If we always default to the root, then x/a.md becomes unreachable if a.md exists, and links would change their destination when creating the latter.

I had not considered this issue. I have always defaulted to using the zettel root as a quasi-absolute path for the sake of making refractoring links on move easier, but I can see the other use-cases as well.

I've amended my commit to reflect the followin priority:

  1. Match relative to the current file.
  2. Exact match relative to the vault root.
  3. Fallback to partial path matching.

And also added relevant end-to-end and unit tests

@sfgartland sfgartland marked this pull request as ready for review March 23, 2026 11:33
@sfgartland sfgartland mentioned this pull request Mar 23, 2026
Comment on lines +328 to +333
linkSupport := false
if clientCapabilities.TextDocument != nil && clientCapabilities.TextDocument.Definition != nil {
linkSupport = isTrue(clientCapabilities.TextDocument.Definition.LinkSupport)
}

if linkSupport {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change required here?

Comment on lines +309 to +317
// 1. Prioritize exact match (either literal href or root-relative).
for _, h := range []string{href, rootHref} {
id, err := d.FindIDByPath(h)
if err != nil {
return nil, err
}
if id.IsValid() {
return []core.NoteID{id}, nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In x/a.md, a link b.md will prefer note b.md, but should prefer x/b.md.

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.

Broken Markdown-style link support

2 participants