EFLS / zetteldeft

A Zettelkasten system! Or rather, some functions on top of the emacs deft package.
https://efls.github.io/zetteldeft
GNU General Public License v3.0
393 stars 42 forks source link

Implementation of (custom type `zdlink:`) Org links in (or on top of?) Zetteldeft #79

Closed TRSx80 closed 3 years ago

TRSx80 commented 4 years ago

Hallo gang,

This is touched on in zd-tutorial/2020-03-25-0928 Integration with org-link.org, however I wanted to expand on the idea.

Scope

I am a heavy Orgmode user since years and In my view, I prefer to leverage all of that "already made" functionality in my Zettelkasten (and elsewhere).

However EFLS has also stated that he wants to keep Zetteldeft as generic as possible in order to suit many different people's needs and use-cases. In fact, if you look closely at the linked zd-tutorial (above) you can see that he even called the completion function efls/zd-complete-link (which is in his personal namespace and not in zetteldeft-* one, which might be a clue to his intentions; or perhaps I am simply reading too much into that).

At any rate, I wish to maintain compatibility with Zetteldeft, while giving myself the Orgmode features I want "on top" of that, in the same way that Zetteldeft should itself "apply cleanly" on top of Deft. Now this latter thing I think has not been explicitly stated, but it seems to me to be the policy, and at any rate is a good idea I think.

If I am wrong about any of that, please let me know EFLS. Of course we can put any of this directly into Zetteldeft, or not, as you prefer. If not, maybe eventually I make my own package at some point, call it zetteldeft-org-links or I don't even know what, but I am not worried about anything like that right now. Really it's just a few functions on top of Zetteldeft anyway. But that is how Zetteldeft itself even started out, amirite? :smile:

Implementation

OK, so what I have cobbled together is the following, so far:

  (org-link-set-parameters "zdlink"
               :complete  #'my-zetteldeft-org-complete-link
               :follow    #'my-zetteldeft-org-follow-link
               :help-echo #'my-zetteldeft-org-help-echo
               :store     #'my-zetteldeft-org-store-link)

For reference: Orgmode Manual: Appendix: Adding Hyperlink Types

Features

I will not publish the details of the functions, for the time being. And I am still working on them. But so far, this is what functionality I have working:

Roadmap

Some things I still want to do:

Discuss? :smile:

EFLS commented 4 years ago

he even called the completion function efls/zd-complete-link (which is in his personal namespace and not in zetteldeft-* one, which might be a clue to his intentions; or perhaps I am simply reading too much into that).

That's simply because I first experimented with these ideas in my personal setup, and then shared it in a Github Gist when someone was looking for such functionality. It is rather crude (for example no -store-link, as you noticed) because I didn't spend enough time investigating the Org codebase to do all of those things.

If you decide to write code that does these things, be sure to share it. A more complete implementation of the zdlink: could be part of vanilla Zetteldeft (rather than a sort of customization as it is now).

TRSx80 commented 4 years ago

It is rather crude (for example no -store-link, as you noticed) because I didn't spend enough time investigating the Org codebase to do all of those things.

If it makes you feel any better, when I was working on my implementation, I noticed the docs on that functionality seemed to be rather sparse. I think perhaps because it's relatively "new" functionality in Org, maybe they haven't had a chance to flesh out the docs yet. I did however find this YouTube video by John Kitchin about New link features in org-mode v9.0 (dated 2016-11-03) which was very helpful in figuring it out, as well as demonstrating several other quite neat and advanced functionalities.

With those hints, I was able to play around and get the following working. Feel free to add it to your Zettel about Org Links or whatever you like.

I did not implement the :export "method" (for lack of a better term) yet, and doubt I will now, with my attention now going towards other things.

And finally, I never improved the completion to include a description, only the link part. However it only needs a little bit more work. I think someone interested in that probably wants to look at org-link-make-string as my notes say that is where my research was leading at the time.

But I leave that all to you guys now. :smile:

Cheers! :beers:

P.S. I think maybe this closes the issue? But I leave it up to you.


  (defun my-zetteldeft-org-help-echo (window object position)
    "Mouse over tool tips for Org zdlink type links.

  When mouse over plain link (eg. 'zdlink:2020-08-29-1234') you
  will get the title of the note.

  When mouse over a full Org bracket link (with description, which
  collapses down to just description by default) you will see the
  plain zdlink."
    (save-excursion
      (goto-char position)
      (goto-char (org-element-property :begin (org-element-context)))
      (cond ((looking-at org-plain-link-re)
         (format "%s"
             (zetteldeft--lift-file-title
              (zetteldeft--id-to-full-path
               (zetteldeft--lift-id (match-string 0))))))
        ((looking-at org-bracket-link-regexp)
         (format "%s" (match-string 1)))
        (t
         "No match"))))

  (defun my-zetteldeft-org-complete-link ()
    "Link completion for Org zdlink type links"
    (let* ((file (completing-read "File to link to: "
          (deft-find-all-files-no-prefix)))
       (link (zetteldeft--lift-id file)))
       (unless link (user-error "No file selected"))
       (concat "zdlink:" link)))

  (defun my-zetteldeft-org-follow-link (str)
    "Function to be called by Org to follow a zdlink."
    (zetteldeft--search-filename (zetteldeft--lift-id str)))

  (defun my-zetteldeft-org-store-link ()
    "Function to be called by Org to store a zdlink."
    ;;(interactive)
    (when (equal major-mode 'deft-mode)
      (let ((link (concat "zdlink:" (zetteldeft--lift-id (deft-filename-at-point))))
        (title (zetteldeft--lift-file-title (deft-filename-at-point))))
    (org-store-link-props
     :type "zdlink"
     :link link
     :description title))))

  (org-link-set-parameters "zdlink"
               :complete  #'my-zetteldeft-org-complete-link
               :follow    #'my-zetteldeft-org-follow-link
               :help-echo #'my-zetteldeft-org-help-echo
               :store     #'my-zetteldeft-org-store-link)
EFLS commented 3 years ago

I'll close this issue for now, since you've moved on to other projects.

For people finding this later, there is a useful code snippet here already: https://www.eliasstorms.net/zd-tutorial/2020-03-25-0928%20Integration%20with%20org-link.html

If anyone wants to explore an :export setup for zdlink, feel free to comment and I'll be happy to reopen.