Advertisement
6clk4mW8KYjKb5Af

Org-roam helm reference switcher

Mar 3rd, 2020
421
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 5.41 KB | None | 0 0
  1. (defun my/roam-helm-open-reference ()
  2.   "Use helm to open links, backlinks, link links and link backlinks quickly."
  3.   (interactive)
  4.   (unless (buffer-file-name (or (buffer-base-buffer)
  5.                                 (current-buffer)))
  6.     (error "Not visiting a file."))
  7.   (flet ((info-to-src (src-title info)
  8.                       (helm-build-sync-source src-title
  9.                         :candidates info
  10.                         :keymap (let ((map (make-sparse-keymap)))
  11.                                   (set-keymap-parent map helm-map)
  12.                                   (define-key map (kbd "C-<return>")
  13.                                     'my/roam-open-backlink-run-open-file)
  14.                                   map)
  15.                         :action
  16.                         '(("Open file other window" .
  17.                            (lambda (data)
  18.                              (find-file-other-window (car data))
  19.                              (goto-char (cadr data))))
  20.                           ("Open file" . my/roam-open-backlink-open-file))))
  21.          (get-links-out (file-path &optional ignore-to)
  22.                         (-as-> (org-roam-sql
  23.                                 [:select [file-to] :from file-links
  24.                                          :where (= file-from $s1)]
  25.                                 file-path) prev
  26.                                 (mapcar #'car prev)
  27.                                 (-remove-item ignore-to prev)
  28.                                 (-uniq prev)
  29.                                 (--map (cons (org-roam--get-title-or-slug it) it) prev)
  30.                                 (--sort (string-lessp (car it) (car other)) prev)))
  31.          (make-links-out-src (name links-out)
  32.                              (helm-build-sync-source name
  33.                                :candidates links-out
  34.                                :keymap (let ((map (make-sparse-keymap)))
  35.                                          (set-keymap-parent map helm-map)
  36.                                          (define-key map (kbd "C-<return>")
  37.                                            'my/roam-open-link-run-open-file)
  38.                                          map)
  39.                                :action
  40.                                '(("Open file other window" . find-file-other-window)
  41.                                  ("Open file" . find-file)))))
  42.     (let* ((file-path (buffer-file-name (or (buffer-base-buffer)
  43.                                             (current-buffer))))
  44.            (links-out (get-links-out file-path))
  45.            (backlinks (my/roam-file-backlink-info file-path))
  46.            (sources nil))
  47.  
  48.       ;; Links from current page out
  49.       (when-let* ((links-out-src (and links-out
  50.                                       (make-links-out-src "Links" links-out))))
  51.         (push links-out-src sources))
  52.  
  53.       ;; Back-references to current page
  54.       (when-let ((top-info-src (info-to-src "Backlinks" backlinks)))
  55.         (push top-info-src sources))
  56.  
  57.       ;; Walk through pages of outgoing links
  58.       (dolist (link links-out)
  59.         ;; Show their links
  60.         (when-let* ((links-out (get-links-out (cdr link) file-path))
  61.                     (links-out-src (make-links-out-src
  62.                                     (format "Links (%s)" (car link))
  63.                                     links-out)))
  64.           (push links-out-src sources))
  65.  
  66.         ;; Show their back-references
  67.         (when-let ((backlinks-src (info-to-src (format "Backlinks (%s)" (car link))
  68.                                                (my/roam-file-backlink-info
  69.                                                 (cdr link) file-path))))
  70.           (push backlinks-src sources)))
  71.       (unless sources
  72.         (user-error "No references available."))
  73.       (helm :sources (nreverse sources) :prompt "Pick reference: "))))
  74.  
  75. ;; -- Helper functions ---------------------------------------------------------
  76.  
  77. (defun my/roam-open-backlink-run-open-file ()
  78.   (interactive)
  79.   (with-helm-alive-p (helm-exit-and-execute-action
  80.                       'my/roam-open-backlink-open-file)))
  81.  
  82. (defun my/roam-open-backlink-open-file (data)
  83.   (find-file (car data))
  84.   (goto-char (cadr data)))
  85.  
  86. (defun my/roam-open-link-run-open-file ()
  87.   (interactive)
  88.   (with-helm-alive-p (helm-exit-and-execute-action 'find-file)))
  89.  
  90. (defun my/roam-file-backlink-info (file-path &optional drop-to)
  91.   "Produce a list of lists where
  92. 0: Description: Title and line
  93. 1: Link target path
  94. 2: Line start point"
  95.   (when-let* ((backlinks (org-roam--get-backlinks file-path))
  96.               (grouped-backlinks (--group-by (nth 0 it) backlinks)))
  97.     (let (bl-info)
  98.       (dolist (group grouped-backlinks)
  99.         (let* ((file-from (car group)))
  100.           (unless (equal drop-to file-from)
  101.             (let* ((bls (cdr group))
  102.                    (title (org-roam--get-title-or-slug file-from)))
  103.               (dolist (backlink bls)
  104.                 (pcase-let ((`(,file-from ,file-to ,props) backlink))
  105.                   (let* ((file-point (plist-get props :point))
  106.                          (line (-> (plist-get props :content)
  107.                                    s-trim
  108.                                    org-link-display-format
  109.                                    substring-no-properties))
  110.                          (desc (format "%s: %s" title line)))
  111.                     (push (list desc file-from file-point) bl-info))))))))
  112.       (--sort (string-lessp (car it) (car other)) bl-info))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement