Advertisement
6clk4mW8KYjKb5Af

Org-roam completing-read reference switcher

Mar 5th, 2020
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.41 KB | None | 0 0
  1. (defun test/roam-open-reference ()
  2.   "Switch to links and backlinks by completing-read."
  3.   (interactive)
  4.   (unless (buffer-file-name (or (buffer-base-buffer)
  5.                                 (current-buffer)))
  6.     (error "Not visiting a file."))
  7.   (let* ((file-path (buffer-file-name (or (buffer-base-buffer)
  8.                                           (current-buffer))))
  9.          (links-out (test/get-links-out file-path))
  10.          (backlinks (test/roam-file-backlink-info file-path))
  11.          (sources nil))
  12.  
  13.     ;; Back-references to current page
  14.     (when backlinks
  15.       (dolist (info backlinks)
  16.         (unless (equal file-path (plist-get info :file))
  17.           (push (cons (format "<- [%s] %s"
  18.                               (plist-get info :title)
  19.                               (plist-get info :line))
  20.                       info)
  21.                 sources))))
  22.  
  23.     ;; Walk through pages of outgoing links
  24.     (dolist (link-info links-out)
  25.  
  26.       ;; Links from current page out
  27.       (unless (equal file-path (plist-get link-info :file))
  28.         (push (cons (format "-> [%s]" (plist-get link-info :title))
  29.                     link-info)
  30.               sources))
  31.  
  32.       (let* ((link-title (plist-get link-info :title))
  33.              (link-file (plist-get link-info :file))
  34.              (link-links-out (test/get-links-out link-file))
  35.              (link-backlinks (test/roam-file-backlink-info link-file)))
  36.  
  37.         ;; Links from current page out
  38.         (when link-links-out
  39.           (dolist (info link-links-out)
  40.             (unless (equal file-path (plist-get info :file))
  41.               (push (cons (format "%s -> [%s]"
  42.                                   link-title
  43.                                   (plist-get info :title))
  44.                           info)
  45.                     sources))))
  46.  
  47.         ;; Back-references to current page
  48.         (when link-backlinks
  49.           (dolist (info link-backlinks)
  50.             (unless (equal file-path (plist-get info :file))
  51.               (push (cons (format "%s <- [%s] %s"
  52.                                   link-title
  53.                                   (plist-get info :title)
  54.                                   (plist-get info :line))
  55.                           info)
  56.                     sources))))))
  57.  
  58.     (setq sources (nreverse sources))
  59.     (when-let* ((selection (completing-read "Select reference: "
  60.                                             sources nil t))
  61.                 (info (cdr (assoc selection sources)))
  62.                 )
  63.       (find-file (plist-get info :file))
  64.       (when-let ((file-point (plist-get info :file-point)))
  65.         (goto-char file-point)))))
  66.  
  67. ;; -- Helper functions ---------------------------------------------------------
  68.  
  69. (defun test/roam-file-backlink-info (file-path &optional drop-to)
  70.   "Produce a list of info on backlink."
  71.   (when-let* ((backlinks (org-roam--get-backlinks file-path))
  72.               (grouped-backlinks (--group-by (nth 0 it) backlinks)))
  73.     (let (bl-info)
  74.       (dolist (group grouped-backlinks)
  75.         (let* ((file-from (car group)))
  76.           (unless (equal drop-to file-from)
  77.             (let* ((bls (cdr group))
  78.                    (title (org-roam--get-title-or-slug file-from)))
  79.               (dolist (backlink bls)
  80.                 (pcase-let ((`(,file-from ,file-to ,props) backlink))
  81.                   (let* ((file-point (plist-get props :point))
  82.                          (line (-> (plist-get props :content)
  83.                                    s-trim
  84.                                    org-link-display-format
  85.                                    substring-no-properties)))
  86.                     (push (list :file file-from
  87.                                 :title title
  88.                                 :line line
  89.                                 :file-point file-point)
  90.                           bl-info))))))))
  91.       bl-info)))
  92.  
  93. (defun test/get-links-out (file-path &optional ignore-to)
  94.   "Produce a list of info on link."
  95.   (-as-> (org-roam-sql [:select [file-to] :from file-links
  96.                                 :where (= file-from $s1)]
  97.                        file-path)
  98.          prev
  99.          (mapcar #'car prev)
  100.          (-remove-item ignore-to prev)
  101.          (-uniq prev)
  102.          (--map (list :title (org-roam--get-title-or-slug it)
  103.                       :file it) prev)
  104.          (--sort (string-lessp (plist-get it :title)
  105.                                (plist-get other :title))
  106.                  prev)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement