zetteldeft
zetteldeft copied to clipboard
Can I set it up to follow The Archive style links? [[202012290540]]
I am starting to use emacs in conjunction with the archive, and am trying to get emacs to have similar behavior to the archive in that it will pull up a matching file when clicking a link such as [[202012290540]]
. I'm using org and md files.
I read this and this, hoping they would point the way - but they seem to be doing something different.
Any ideas on how I can get emacs to follow those sorts of links? I would still want [[#internal]]
links to work.
Here's a config that worked - the missing piece was the zetteldeft-id-regex
to find candidates.
(setq zetteldeft-link-indicator "[[")
(setq zetteldeft-link-suffix "]]")
(setq zetteldeft-id-format "%Y%m%d%H%M")
(setq zetteldeft-id-regex "20[0-9]\\{10\\}")
Any idea how to hook zetteldeft-follow-link
into org-return
/ org-open-at-point
? That would be the final touch.
Here's a config that will try org-mode's search first, then fall back to zetteldeft-follow-link:
(setq org-return-follows-link t)
(setq org-link-search-must-match-exact-headline nil)
(defun zetteldeft-try-follow-link (orig-org-open-at-point &optional arg)
(condition-case nil
(apply orig-org-open-at-point arg)
(error (zetteldeft-follow-link))))
(advice-add 'org-open-at-point :around #'zetteldeft-try-follow-link)
I do notice some weird behavior where zetteldeft-follow-link changes the text and downcases a character, if it's in one of the first two characters, or there is no match:
It still doesn't work with the first two characters (I guess it has to do with the regex), but I managed to stop the weird behavior not running the avy file prompt:
(defun zetteldeft-follow-link ()
"Follows zetteldeft link to a file if point is on a link.
Prompts for a link to follow with `zetteldeft-avy-file-search' if it isn't."
(interactive)
(if (thing-at-point-looking-at (zetteldeft--link-regex))
(zetteldeft--search-filename
(zetteldeft--lift-id (zetteldeft--get-thing-at-point)))
(message "Not a zetteldeft link!")))
I've never tried integration with The Archive -- although I do hope to achieve some compatibility with Zetteldeft. I think the extra challenge that you have is that you mix .md
and .org
files, as the use of [[
]]
as Zetteldeft link delimiters overlaps with the markup Org uses for links. Anyway, glad you've found a way to combine the two -- that's a nice solution.
With regards to the zetteldeft-follow-link
hick-up, I think it indeed has to do with the zetteldeft-id-regex
you've set up. Not sure what the issue is exactly, though.
The easiest way to prevent all of this is to make a choice between .md
and .org
for your files, but that might not be a real option.
Also, you might not really need to call zetteldeft-follow-link
in your zetteldeft-try-follow-link
function, as that would involve the Avy-style functions where you really don't need them.
Maybe try:
(defun zetteldeft-try-follow-link (orig-org-open-at-point &optional arg)
(condition-case nil
(apply orig-org-open-at-point arg)
(error (zetteldeft--search-filename (zetteldeft--lift-id (zetteldeft--get-thing-at-point))))))
As a reference: over on forum.zettelkasten.de someone shared a configuration to make Zetteldeft work like The Archive, see https://forum.zettelkasten.de/discussion/1640/making-zetteldeft-work-like-the-archive
Thanks both @patmaddox and @EFLS, this thread helped me fix some things that I had been trying to figure out for a long time.
I would like to be greedy here and ask for the next step for me- how would I take the zetteldeft-try-follow-link
that @EFLS posted there and add a third fallback, so that if neither an org link nor a zetteldeft link worked, it would instead call zetteldeft-search-at-point
? I am trying, but my lisp is not up to the task.
I thank you for your potential indulgence.
Not really sure about that. You could look at zetteldeft--search-filename
and try to write a similar function that launches a search when there are no files found (i.e., replace the when
in that function with an if
).
(setq zetteldeft-link-indicator "[[") (setq zetteldeft-link-suffix "]]") (setq zetteldeft-id-format "%Y%m%d%H%M") (setq zetteldeft-id-regex "20[0-9]\\{10\\}")
Is this a viable formatting for links in zetteldeft that wouldn't clash with orgmode?
Have you tried it? My guess is it will clash with Org, as it also uses [[ ]]
style links.
Yes, just tried. I noticed some discussion around this topic. I suppose there is no way to have it then! :)
You need to be more clear about what you are trying to achieve if you want help. It is possible to use The Archive style links, but if you do that in .org
files, you run into trouble. So the best way to go is to not use .org
file extensions if you want to use The Archive links (but simply use .md
, as The Archive does AFAIK).
Thanks for this. I wanted to know whether I should open a new issue for this quick question, relevant here: How to customize the link format? AT the moment it looks like [[ID]]
. So whenever Izetteldeft-copy-ID-current-file
and paste it on another note, I just paste an ID, and would like to have [[ID]]: title of note
if it's possible. Thanks for your help!
To insert that, you should use zetteldeft-find-file-full-title-insert. Does that do what you want?
Thanks for this. I just tried and it prompts to find the file. The scenario I have in mind is the following:
- I work on a file and copy its ID with
zetteldeft-copy-ID-current-file
- I paste it on a different file.
If I use zetteldeft-find-file-full-title-insert I have to search for the current note I am on. It would feel like an extra step.
Maybe there could be a simple function (I wish I could code it myself) that just pastes an "extended" ID with full title, something like zetteldeft-paste-ID-with-full-title
(I'm not good with function naming) :)
Haven’t tested this, but try:
(defun zetteldeft-copy-id-title-current-file ()
"Copy current ID and title.
Add the id and title from the filename the buffer is currently visiting to the
kill ring."
(interactive)
(zetteldeft--check)
(let* ((ID (concat zetteldeft-link-indicator
(zetteldeft--lift-id (file-name-base (buffer-file-name)))
zetteldeft-link-suffix))
(title (zetteldeft--id-to-title ID)))
(kill-new (format “%s: %s” ID title))))
Thanks! It's not working, and giving me this error:
Debugger entered--Lisp error: (wrong-type-argument stringp nil)
It was a bit more complicated than I expected.
The functions zetteldeft--lift-file-title
and zetteldeft--id-to-title
return a title in the form "id title", so it's necessary to extract the actual title manually with the regexp. :/
Try this:
(defun zetteldeft-copy-id-title-current-file ()
"Copy current ID and title.
Add the id and title from the filename the buffer is currently visiting to the
kill ring."
(interactive)
(zetteldeft--check)
(let* ((file (buffer-file-name))
(id (zetteldeft--lift-id file))
(full-title (zetteldeft--lift-file-title file))
(title (progn
(string-match (concat "\\(?1:"
zetteldeft-id-regex
"\\).\\(?2:.*\\)")
full-title)
(match-string 2 full-title)))
(link (concat zetteldeft-link-indicator
id
zetteldeft-link-suffix))
(return (format "%s: %s" link title)))
(kill-new return)
(message return)))
Thanks. Now it won't spit out any error message. For some reason it's returning: [2022-03-03-1911-16]]: nil
That will be caused by the regex argument passed to string-match
in the function above. I guess it’s not general enough, but it could be changed to match the title portion of your own notes’ file names.
Thanks. So in the lines
concat "\\(?1:"
zetteldeft-id-regex
"\\).\\(?2:.*\\)")
I should replace \\).\\(?2:.*\\
) by my zetteldeft-id-regex
expression?
The functions zetteldeft--lift-file-title and zetteldeft--id-to-title return a title in the form "id title", so it's necessary to extract the actual title manually with the regexp. :/
Not sure what you mean? zetteldeft–id-to-title
should really just retunr the title.
Anyway, this is what I came up with. Does this work for you @AtomicNess123?
(defun efls/zd-copy-id-and-title ()
(interactive)
(zetteldeft--check)
(let* ((id (zetteldeft--lift-id (file-name-base (buffer-file-name))))
(link (concat zetteldeft-link-indicator
id
zetteldeft-link-suffix))
(title (zetteldeft--id-to-title id)))
(kill-new (concat link
" "
title))))
Sorry, I see my misunderstanding. I didn't realize that deft-parse-title
takes the title from the first line of the file itself, not from the file name. My mistake!
The functions zetteldeft--lift-file-title and zetteldeft--id-to-title return a title in the form "id title", so it's necessary to extract the actual title manually with the regexp. :/
Not sure what you mean?
zetteldeft–id-to-title
should really just retunr the title.Anyway, this is what I came up with. Does this work for you @AtomicNess123?
(defun efls/zd-copy-id-and-title () (interactive) (zetteldeft--check) (let* ((id (zetteldeft--lift-id (file-name-base (buffer-file-name)))) (link (concat zetteldeft-link-indicator id zetteldeft-link-suffix)) (title (zetteldeft--id-to-title id))) (kill-new (concat link " " title))))
Actually it doesn't. It returns this (I tried with several notes):
helm-M-x-execute-command: ID Error. Multiple zetteldeft files found with ID 2021-09-09-2119-26
Seems like you have multiple notes with the same ID. Make sure the IDs are unique. Open your notes folder, look for the note with that ID in the filename, and change it so it's unique.
Yes, I had a bak dirctory with some duplicates for some reason. After deleting them, it works:
[[2021-09-09-2119-26]]
title of the note
However, how to change the function to include the title of the note as part of the clickable link? Like this:
[[2022-04-21-1328-22][title of the note]]
This would look nicer on the note.
Not sure how that would work. Are you using Markdown or Org-mode? In Org, the [
formatting would interfere with Org-links. Unless you use some kind of custom link.
Thing is, I have a function that makes org try to follow link, and if it fails, then uses zetteldeft. I copied it from somewhere, and it works fine. So I would like to have the links with that formatting, as if I just have text beside a link, I may have to wrap it with brackets of something not to be confused with the text if inserted in a paragraph.
I copied it from somewhere, and it works fine.
Ah yes, I remember that discussion somewhere around here.
With such heavy customization, it might be worth it to learn some basic emacs lisp.
You could replace the (concat ...)
part in the previous function with something like this:
(concat "[["
id
"]["
title
"]]")
Thank you!
Hi, and coming back to this, this function is great to have orgmode
follow the links using zetteldeft
when using two brackets:
; from: https://github.com/localauthor/zk#using-org-mode-and-org-links
(defun zk-org-try-to-follow-link (fn &optional arg)
"When 'org-open-at-point' FN fails, try 'zk-follow-link-at-point'.
Optional ARG."
(let ((org-link-search-must-match-exact-headline t))
(condition-case nil
(apply fn arg)
(error (zetteldeft-follow-link)))))
(advice-add 'org-open-at-point :around #'zk-org-try-to-follow-link)
But in my case, it does not work when the follow link has the format:
[[2022-10-23-1720-41][2022-10-23-1720-41 title of the note]]
Any way to tweak the function to make this work? It would be nice to have the title inside the clickable link rather than only the numerical code (less informative).
This would be of use to many users.
Thanks!