Advertisement
6clk4mW8KYjKb5Af

Org-roam helm reference switcher V3

Mar 8th, 2020
660
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 6.45 KB | None | 0 0
  1. (defun my/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.   (my//roam-helm-reference (buffer-file-name (or (buffer-base-buffer)
  8.                                                  (current-buffer)))))
  9.  
  10. ;; -- Helper functions -------------------------------------------------------
  11.  
  12. (defun my//roam-helm-reference (file-path)
  13.   "Switch to links and backlinks by completing-read."
  14.   (let* ((links-out (my//get-links-out file-path))
  15.          (backlinks (my//roam-file-backlink-info file-path))
  16.          (sources nil))
  17.  
  18.     ;; Back-references to current page
  19.     (when-let* ((filtered-backlinks (--filter
  20.                                      (not (f-same? file-path (plist-get it :file)))
  21.                                      backlinks))
  22.                 (candidites
  23.                  (--map (cons (format "%s\t%s"
  24.                                       (plist-get it :title)
  25.                                       (propertize (plist-get it :line)
  26.                                                   'face
  27.                                                   'helm-separator))
  28.                               it)
  29.                         filtered-backlinks)))
  30.       (push (helm-build-sync-source "Back-references"
  31.               :candidates candidites
  32.               :action my//ror-actions
  33.               :keymap my//ror-actions-keymap)
  34.             sources))
  35.  
  36.     ;; Walk through pages of outgoing links
  37.     (dolist (link-info links-out)
  38.       (let* ((link-title (plist-get link-info :title))
  39.              (link-file (plist-get link-info :file))
  40.              (link-links-out (my//get-links-out link-file))
  41.              (link-backlinks (my//roam-file-backlink-info link-file))
  42.              ;; First line is link to source
  43.              (candidites (list (cons (propertize link-title 'face 'org-roam-link)
  44.                                      link-info))))
  45.  
  46.         ;; Links from current page out
  47.         (when link-links-out
  48.           (dolist (info link-links-out)
  49.             (unless (or (equal file-path (plist-get info :file))
  50.                         (equal link-file (plist-get info :file)))
  51.               (push (cons (format "πŸ”— %s"
  52.                                   (propertize (plist-get info :title)
  53.                                               'face 'org-roam-link))
  54.                           info)
  55.                     candidites))))
  56.  
  57.  
  58.         ;; ;; Back-references to current page
  59.         (when link-backlinks
  60.           (dolist (info link-backlinks)
  61.             (unless (or (equal file-path (plist-get info :file))
  62.                         (equal link-file (plist-get info :file)))
  63.               (push (cons (format "← %s\t%s"
  64.                                   (propertize (plist-get info :title)
  65.                                               'face 'org-roam-link)
  66.                                   (propertize (plist-get info :line)
  67.                                               'face
  68.                                               'helm-separator))
  69.                           info)
  70.                     candidites))))
  71.  
  72.         ;; Build source for link
  73.         (push (helm-build-sync-source link-title
  74.                 :candidates (nreverse candidites)
  75.                 :action my//ror-actions
  76.                 :keymap my//ror-actions-keymap)
  77.               sources)))
  78.     (helm :sources (nreverse sources) :prompt "Pick reference: ")))
  79.  
  80. (defun my//roam-file-backlink-info (file-path &optional drop-to)
  81.   "Produce a list of info on backlink."
  82.   (when-let* ((backlinks (org-roam--get-backlinks file-path))
  83.               (grouped-backlinks (--group-by (nth 0 it) backlinks)))
  84.     (let (bl-info)
  85.       (dolist (group grouped-backlinks)
  86.         (let* ((file-from (car group)))
  87.           (unless (equal drop-to file-from)
  88.             (let* ((bls (cdr group))
  89.                    (title (org-roam--get-title-or-slug file-from)))
  90.               (dolist (backlink bls)
  91.                 (pcase-let ((`(,file-from ,file-to ,props) backlink))
  92.                   (let* ((file-point (plist-get props :point))
  93.                          (line (-> (plist-get props :content)
  94.                                    s-trim
  95.                                    org-link-display-format
  96.                                    substring-no-properties)))
  97.                     (push (list :file file-from
  98.                                 :title title
  99.                                 :line line
  100.                                 :file-point file-point)
  101.                           bl-info))))))))
  102.       bl-info)))
  103.  
  104. (defun my//get-links-out (file-path &optional ignore-to)
  105.   "Produce a list of info on link."
  106.   (-as-> (org-roam-sql [:select [file-to] :from file-links
  107.                                 :where (= file-from $s1)]
  108.                        file-path)
  109.          prev
  110.          (mapcar #'car prev)
  111.          (-remove-item ignore-to prev)
  112.          (-uniq prev)
  113.          (--map (list :title (org-roam--get-title-or-slug it)
  114.                       :file it) prev)
  115.          (--sort (string-lessp (plist-get it :title)
  116.                                (plist-get other :title))
  117.                  prev)))
  118.  
  119.  
  120. ;; -- Helm Actions -----------------------------------------------------------
  121.  
  122. (defun my//ror-open (candidite)
  123.   (find-file (plist-get candidite :file))
  124.  
  125.   (when-let ((pos (plist-get candidite :file-point)))
  126.     (goto-char pos)))
  127.  
  128. (defun my//ror-run-open ()
  129.   (interactive)
  130.   (with-helm-alive-p (helm-exit-and-execute-action 'my//ror-open)))
  131.  
  132. (defun my//ror-open-other-window (candidite)
  133.   (find-file-other-window (plist-get candidite :file))
  134.  
  135.   (when-let ((pos (plist-get candidite :file-point)))
  136.     (goto-char pos)))
  137.  
  138. (defun my//ror-follow (candidite)
  139.   (my//roam-helm-reference (plist-get candidite :file)))
  140.  
  141. (defun my//ror-run-follow ()
  142.   (interactive)
  143.   (with-helm-alive-p (helm-exit-and-execute-action 'my//ror-follow)))
  144.  
  145. ;; -- Helm Extra -------------------------------------------------------------
  146.  
  147. (setq my//ror-actions
  148.       `(("Open file other window" . ,#'my//ror-open-other-window)
  149.         ("Open file" . ,#'my//ror-open)
  150.         ("Follow" . ,#'my//ror-follow)))
  151.  
  152. (setq my//ror-actions-keymap
  153.       (let ((map (make-sparse-keymap)))
  154.         (set-keymap-parent map helm-map)
  155.         (define-key map (kbd "C-<return>") #'my//ror-run-open)
  156.         (define-key map (kbd "C-j") #'my//ror-run-follow)
  157.         map))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement