branch: externals/denote commit 9d8748c3820d53661ac198b37a32e5020da7a97f Author: Protesilaos Stavrou <i...@protesilaos.com> Commit: Protesilaos Stavrou <i...@protesilaos.com>
Add proof-of-concept backlink (lots of TODO) --- denote.el | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/denote.el b/denote.el index 7bd2367277..1414082ffe 100644 --- a/denote.el +++ b/denote.el @@ -92,6 +92,14 @@ define." :type 'string :group 'denote) +(defcustom denote-link-insert-functions + (list #'denote-write-backlink) + "Functions that run after `denote-link'. +Each function accepts a TARGET-FILE and an ORIGIN-LINK argument. +Both are supplied by `denote-link'." + :type 'hook + :group 'denote) + ;;; Main variables ;; TODO 2022-06-04: Can we make the entire file name format a defcustom? @@ -386,6 +394,9 @@ sample template. We will eventually have a manual." (defvar denote--link-format "[[denote:%s][%s (%s)]]" "Format of Org link to note.") +(defvar denote--backlink-format "[[denote:%s][backlink: %s (%s)]]" + "Format of Org link to note.") + (defun denote--retrieve-value (note regexp) "Return REGEXP value from NOTE." (let ((default-directory (denote--directory))) @@ -399,15 +410,36 @@ sample template. We will eventually have a manual." nil t nil #'file-regular-p)) ;;;###autoload -(defun denote-link (note) - "Create Org link to NOTE in `denote-directory'." +(defun denote-link (target) + "Create Org link to TARGET note in `denote-directory'. +Run `denote-link-insert-functions' afterwards." (interactive (list (denote--read-file-prompt))) - (let ((identifier (cdr (denote--retrieve-value note denote--identifier-regexp))) - (filename (string-remove-prefix - (denote--directory) - (cdr (denote--retrieve-value note denote--filename-regexp)))) - (title (cdr (denote--retrieve-value note denote--title-regexp)))) - (insert (format denote--link-format filename title identifier)))) + (let* ((target-id (cdr (denote--retrieve-value target denote--identifier-regexp))) + (target-name (string-remove-prefix + (denote--directory) + (cdr (denote--retrieve-value target denote--filename-regexp)))) + (target-title (cdr (denote--retrieve-value target denote--title-regexp))) + (target-link (format denote--link-format target-name target-title target-id)) + (origin-note (buffer-file-name)) + (origin-id (cdr (denote--retrieve-value origin-note denote--identifier-regexp))) + (origin-name (string-remove-prefix + (denote--directory) + (cdr (denote--retrieve-value origin-note denote--filename-regexp)))) + (origin-title (cdr (denote--retrieve-value origin-note denote--title-regexp))) + (origin-link (format denote--backlink-format origin-name origin-title origin-id))) + (insert target-link) + (run-hook-with-args 'denote-link-insert-functions target origin-link))) + +;; NOTE 2022-06-05: A proof-of-concept. We need to: (i) have a +;; Backlinks headeding, (ii) delete duplicates, (iii) ensure one +;; backlink per line, (iv) have a `denote-unlink' command or a +;; `denote-clean-backlinks' for invalid links. +(defun denote-write-backlink (target-file origin-link) + "Insert ORIGIN-LINK to TARGET-FILE." + (let ((default-directory (denote--directory))) + (with-current-buffer (find-file-noselect target-file) + (goto-char (point-max)) + (insert origin-link)))) (provide 'denote) ;;; denote.el ends here