Custom Roam-style link

@santi-younger,
For what it’s worth, I have been using my own personal plug-in / extension to enable markdown files to work with Org-roam (I call it “Md-roam”). It supports [[file-name-without-extension]] wiki-link syntax, and it can co-exists with Org files, as it respects Org Mode syntax when the buffer is an Org file. I didn’t have vimwiki in mind when I started it (I have just learned about it from you), so the wiki-link syntax may not be exactly the same. It’s been working well for me. It’s a personal project, so it might feel rough around edges (and far less ambitious than the feature suggested here), but used by some others, too. I suppose it might be something you could consider in your transition period.

Thanks for that @nobiot I really appreciate the help. I’ll definitely get around to move my vim .md notes to emacs with Md-roam! Thank you for your hard work.

Here’s a preview of what’s coming up in the PR, let me know what you think!

4 Likes

I like the idea. But does override the standard org-mode internal like, which also has the [[]] syntax?

@jethro’s implementation only changes the way you input the link: when you save, the links are resolved to their actual targets, either becoming a file:-link or id:-link. Technically, it overrides Org-mode’s default behaviour for [[foo]] links, but the same can be achieved with by typing [[*foo]] which will 1) create an ID for the headline foo if it doesn’t exist, and replace [[*foo]] with [[id:…][foo]].

Looks brilliant!

Yes it does, but only within Org-roam files.

Hope this is the right place to chime in. I’d love to try any of these new link styles, but none of that works. I have org roam version 1.2.1 installed. If I disable company-org-roam, I lose all autocompletion. company-capf is one of the company backends, but there is no autocompletion. I can force completion with M-x complete. And even here, what is inserted is a file link. What am I making wrong?

So it looks like you add the double-brackets, and then do a backspace to initiate the pop-up auto-completion. Is that correct?

Or is that just an artifact of the particular screen-cast?

It would be ideal if the auto-complete could pop-up immediately after entering the double-brackets.

This is now merged in master.

Nope, I’m calling company-complete manually here, I don’t have my company auto-show suggestions.

You can do this already, if you configure company this way:

(setq company-idle-delay 0
      company-minimum-prefix-length 0)
(push 'company-capf company-backends)

EDIT: the navigation in the gif is to the heading that was outside the screen recording

3 Likes

Make sure you are on the latest commit, this came a while after 1.2.1.

Great, that works now!

Now I am actually working on a small “zettelbrowser”, which gathers some useful entry points and navigation for the zettelkasten. Currently, I can look at the 10 most linked files, the last modified files, etc. In particulat, for each zettel, I can look at the list of backlinks and “tolinks” (is this the word?), so I can kind of browse my notes. Internally, I use an SQL query which, among others, checks for links with the type “file”.

I will publish the project soon on github, but I am reluctant because of the amazing speed of development. And I wanted to integrate the fuzzy links. I see in the database, that the new link has its own type, “fuzzy”. There is no filename associated with it, just the title or the title with an asterisk and the heading. No file name. I would, of course, like to integrate this new link type into my zettelkasten tool. So I guess my questions are:

  • Is it planned to keep this links plain “symbolic”, that is, that they are just names and the program has to look app the associated file by itself?

  • If the links are supposed to be kept symbolic, is there an easy way to resolve them within SQL? Everything else seems to me very costly for “bulk” operations. I toyed around a bit, and for me, the difficulty is to split the symbol at the asterisk. We have to transform the column content (name)*_ to name within the query. Up to now, my SQL queries just checked for equal file names to find links. Maybe it would make sense to save a copy of the link in new column in a normalized form (only the title, no asterisk); that would allow for an easy JOIN SQL query.

  • Looking at the database, I also see that other, not-related links are also recognized as “fuzzy” and inserted in the database. In my case, I find an old zotxt link (“zotero://select/items…”) and internal org links ("[[*Heading]]"). Maybe the mechanism which identifies the links before saving them should be more strict.

Yes. But the plan is to have them be fuzzy links only for a short while, there will be mechanisms in place to replace the fuzzy links with full links (file/id).

I don’t see a problem having extra things in the db. It’s also impossible to tell apart internal org links from Org-roam fuzzy links, since Org-roam replaces that behaviour entirely.

Don’t worry too much about the fuzzy links for now, until things settle.

Thanks for the answer!

It’s just that I don’t want my zettelkasten browser to break. Currently, I use one big query which gathers all informations I want per page (mtime, title, tags, etc.), it works surprisingly well and fast, and the system is built around this query. So introducing further joins and lookups might break that system.

This is just amazing, thank you so much for your hard work!

This is great! I originally wanted fuzzy links but I couldn’t figure out how to adequately manipulate the default behavior of org :upside_down_face:

I haven’t dug into the code or db for managing headline id links yet. Is it necessary to resolve the fuzzy file+headline links into proper id: links in order for it to save the link to the db? Leaving a file-only link fuzzy works just fine, and the fuzzy file+headline can otherwise navigate correctly – I just don’t see the headline version in the backlinks. I expected the behavior to be the creation of an ID property under the headline upon file save, and the backlinks buffer to populate the same as if I had a proper id: link. Since it can auto-complete headlines in fuzzy form and navigate correctly without id: resolution, it seems like it would be trivial to create an ID property and update the db without requiring resolution from fuzzy to id:. The implementation of a fuzzy-upon-edit behavior probably supersedes this issue – do you think the editing functionality will be simple to do?

Replacing roam: with the fuzzy links also breaks the demo implementation of Add Link-tags feature, so I need to come up with an alternative! Would something like link-tags be related to the implementation of link types? Except I don’t really want to define a new link type – simply annotate existing org-roam links. It wouldn’t be difficult to parse an implementation of link-tags out of the link-description section in any of fuzzy, file, or id types, but I would rather refactor with the most “correct” design :wink:

This is the default behaviour now.

The db is only a cache of the current contents in the Org files, so this would be really strange.

Not sure, but doesn’t sound terribly hard.

For this, we need to extend the spec of the fuzzy links with additional separators. If we were to go with org’s link types, that restricts us to only 1 link tag per link. The tags will need to be kept in the link description upon resolution. We can come up with a simple proposal, like

[[Title*Headline::tag1::tag2]]

Then we can consider implementing this, but I’m wondering how much interest there is in this feature.

It is the default behavior with (setq org-roam-auto-replace-fuzzy-links t), but when nil org-roam does not create an ID and save a backlink. If the fuzzy link is only for a file (no headline), then a backlink is created like normal even without resolving the link to a full file: link.

Perhaps I am not clear. Fuzzy file+headline links work as you would expect without needing replacement by true id: links, except that no backlink is saved. Fuzzy file links work, and save a backlink even without replacement by true file: links. Since all of the machinery is already in place to resolve id from fuzzy, I was wondering if it possible to save backlinks while leaving file+headline fuzzy.

It is just about preference and ease of editing. Making a fuzzy-on-edit behavior solves the issue entirely, but without having looked into the updated code at all I didn’t know if it would be simpler to save backlinks for fuzzy file+headline the same way as fuzzy file-only links.

Yes, the most straightforward solution is to handle tags in the description section. This is an important personal use case for me – I’m going to do it one way or another :laughing: I’m happy to share the end result, but I don’t think this has the same level of interest that would warrant inclusion in core org-roam at all. I am only wondering what your opinions are for implementing something with this kind of custom functionality now that a lot more development has been done around links (if there is a more or less “correct” way to maintain tighter integration with core development so that I don’t end up with conflicts).

It sounds like simply parsing link descriptions will be the way to go. Or else I don’t think it would be very difficult to come up with some post-link parsing scheme like [[link]]::tag:: and hooks/advice that would potentially have minimal need to integrate with the rest of org-roam.

Headline backlinks work via an ID, in the to column of the links table, so saving these file+headline links aren’t so easy. It’s possible to do this lookup on the fly, but that would make cache builds much more expensive. Hopefully the fuzzy-on-edit behaviour alleviates the bulk of the issue, although I’m wondering how often you edit your links. I don’t do this at all.

I’m fine pulling this into Org-roam’s core, it sounds useful, and this will require an additional column in the links table anyway. I just don’t want to overload the link description with too many things, so this might be the last of it.

It would indeed eliminate the issue entirely. In practice I edit them significantly less than my nagging on this issue implies :smile: It is just a nicety. I typically go through a write/save/edit/extend/summarize process multiple times with some academic notes. For some reason deleting a link entirely and entering a new one bothers me while writing, even though it’s likely objectively simpler/better. I haven’t gotten to really use the new fuzzy links + headlines and nested captures, so my link-breaking edits may be even less now. Since I don’t have any plans to move away from org-roam, the automatic conversion from fuzzy to file: or id: feels incongruent. I would just prefer to leave them all fuzzy, but this is strictly a personal issue.

Sounds good! I agree that I would prefer not to overload the description – the benefit of a custom link was that tags could live in the path and be hidden if desired. Any opinion on post-bracket parsing? Other than a design/style decision about potentially multi-word tags, I don’t think it would be very difficult or cumbersome. It would be link-type agnostic, and leave the link description parsing untouched.

I’ll start putting something together in the next week or two.