diff --git a/org-roam.el b/org-roam.el index 8a2305a..ef1ef25 100644 --- a/org-roam.el +++ b/org-roam.el @@ -6,6 +6,7 @@ ;;; Code: (require 'deft) (require 'async) +(require 'subr-x) (defgroup org-roam nil "Roam Research replica in Org-mode." @@ -108,38 +109,47 @@ Valid states are 'visible, 'exists and 'none." (require 'org) (require 'org-element) ,(async-inject-variables "org-roam-") - (let ((backlinks (make-hash-table :test #'equal)) - (org-roam-parse-content (lambda (file) - (with-temp-buffer - (insert-file-contents file) - (with-current-buffer (current-buffer) - (org-element-map (org-element-parse-buffer) 'link - (lambda (link) - (let ((type (org-element-property :type link)) - (path (org-element-property :path link))) - (when (and (string= type "file") - (string= (file-name-extension path) "org")) - path))))))))) + (let ((backlinks (make-hash-table :test #'equal))) (mapcar (lambda (file) - (let (paths (org-roam-parse-content file)) - (mapcar (lambda (link) - (let* ((item (gethash link backlinks)) - (updated (if item - (if (member (file-name-nondirectory - file) item) - item - (cons (file-name-nondirectory - file) item)) - (list (file-name-nondirectory - file))))) - (puthash link updated backlinks))) - paths))) + (let ((items (with-temp-buffer + (insert-file-contents file) + (with-current-buffer (current-buffer) + (org-element-map (org-element-parse-buffer) 'link + (lambda (link) + (let ((type (org-element-property :type link)) + (path (org-element-property :path link)) + (start (org-element-property :begin link))) + (when (and (string= type "file") + (string= (file-name-extension path) "org")) + (goto-char start) + (let* ((element (org-element-at-point)) + (content (buffer-substring + (or (org-element-property :content-begin element) + (org-element-property :begin element)) + (or (org-element-property :content-end element) + (org-element-property :end element))))) + (list path (string-trim content))))))))))) + (mapcar (lambda (item) + (let* ((path (car item)) + (content (cdr item)) + (relative-file (file-name-nondirectory file)) + (contents-hash (gethash path backlinks))) + (if contents-hash + (if-let ((contents-list (gethash relative-file contents-hash))) + (let ((updated (cons content contents-list))) + (puthash relative-file updated contents-hash) + (puthash path contents-hash backlinks)) + (puthash relative-file (list content) contents-hash) + (puthash path contents-hash backlinks)) + (let ((contents-hash (make-hash-table :test #'equal))) + (puthash relative-file (list content) contents-hash) + (puthash path contents-hash backlinks))))) + items))) org-roam-files) (prin1-to-string backlinks))) (lambda (backlinks) (setq org-roam-hash-backlinks (car (read-from-string - backlinks))) - (message "Org-roam backlinks built!")))) + backlinks)))))) (defun org-roam-new-file-named (slug) "Create a new file named `SLUG'. @@ -168,9 +178,12 @@ Valid states are 'visible, 'exists and 'none." (make-local-variable 'org-return-follows-link) (setq org-return-follows-link t) (insert (format "Backlinks for %s:\n\n" file)) - (mapcar (lambda (link) - (insert (format "- [[file:%s][%s]]\n" (expand-file-name link org-roam-directory) link)) - ) backlinks) + (when backlinks + (maphash (lambda (link contents) + (insert (format "* [[file:%s][%s]]\n" (expand-file-name link org-roam-directory) link)) + (dolist (content contents) + (insert (format "\n\n%s\n\n" content)))) + backlinks)) (read-only-mode +1)))) (setq org-roam-current-file file)) @@ -209,12 +222,10 @@ This needs to be quick/infrequent, because this is run at that are amongst deft files, and `org-roam' not already displaying information for the correct file." (interactive) - (while-no-input - (redisplay) - (when (and (eq major-mode 'org-mode) - (not (string= org-roam-current-file (buffer-file-name (current-buffer)))) - (member (buffer-file-name (current-buffer)) (deft-find-all-files))) - (org-roam-update (file-name-nondirectory (buffer-file-name (current-buffer))))))) + (when (and (eq major-mode 'org-mode) + (not (string= org-roam-current-file (buffer-file-name (current-buffer)))) + (member (buffer-file-name (current-buffer)) (deft-find-all-files))) + (org-roam-update (file-name-nondirectory (buffer-file-name (current-buffer)))))) (provide 'org-roam)