zk icon indicating copy to clipboard operation
zk copied to clipboard

LSP autocompletion for heading IDs

Open mickael-menu opened this issue 2 years ago • 7 comments

Discussed in https://github.com/mickael-menu/zk-nvim/discussions/53

Originally posted by @dzintars June 3, 2022 Hi all. REALLY impressive tooling! :) I have a question about Heading ID autocompletion? Is it possible? I know that if many nested levels i a single note breaks the "atomicity rule", but still.. image There is an image of what i mean. That Tmux note contains few sections, i would like to link to. This is how it looks in Obsidian: Frame 1 I believe block references are Obsidian specific only so i don't care much about them. But Heading IDs would be helpful to have after typing #. Currently it returns list of tags.

mickael-menu avatar Jun 03 '22 06:06 mickael-menu

It's not high on my personal list as my notes are pretty small, but this should certainly be possible with zk.

It requires a few things:

  1. Indexing the HTML anchors in the database, and generate some for the headings.
  2. Adding a new LSP auto-completion type triggered with # inside a link, which will return the anchors for the linked note.
  3. Properly handle jumping to an anchor from an LSP link, instead of going to the top of the linked note.

Number 1 is not so easy. HTML anchors (<a id="my-header"></a>) are standardized, but not the generation of anchors from headings. Most implementations seem to use lowercased camel-case but there are variations and treatment of special characters is unclear.

If someone wants to help kickstart this feature without diving in the code, it would be helpful to find and list the various implementations used to generate heading anchors.

mickael-menu avatar Jun 03 '22 07:06 mickael-menu

Regarding anchor ID...

Why not just create a hash (sha256 or 512) of it? This way you don't need to worry about all these weird edge cases, the id will be standardized and consistent, and won't have to worry about formatting.

eric-hansen avatar Jun 03 '22 10:06 eric-hansen

It is definitely just a "nice to have" feature and not the deal breaker for me personally.

dzintars avatar Jun 03 '22 10:06 dzintars

@eric-hansen Inside zk we can handle it however we want. I'm mainly worried about interoperability: it should work in Obsidian, GitHub, Emanote/Neuron, etc.

An alternative could be to insert an HTML anchor manually when linking to a section, but this would look a bit ugly in the notes IMHO.

mickael-menu avatar Jun 03 '22 11:06 mickael-menu

Here are some good starting points for research:

  • https://talk.commonmark.org/t/feature-request-automatically-generated-ids-for-headers
  • https://talk.commonmark.org/t/anchors-in-markdown/247

mickael-menu avatar Jun 03 '22 11:06 mickael-menu

Maybe inserting a manual anchor is not so bad. Yes it's ugly, but it's guaranteed to work everywhere and it's also stable if you change the heading title or reorder the sections (assuming index-based generated IDs).

# My heading
<a id="e3f"/>

Content with [link](#e3f)

However this poses some challenging with LCP, I'm not sure we can modify the target document during completion.

mickael-menu avatar Jun 03 '22 12:06 mickael-menu

I'm also in favor of manual anchor because it is grep-able and can be given some meaningful name.

Personally, I really like Obsidian's block ID despite its incompatibility, because it looks clean in plain text and enables fine-grained references. I actually planned to implement it (currently only the parser is implemented), but I couldn't find time to work on it.

related: https://github.com/EmaApps/emanote/discussions/105

tomtomjhj avatar Jul 15 '22 11:07 tomtomjhj