Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defun my/roam-helm-open-reference ()
- "Use helm to open links, backlinks, link links and link backlinks quickly."
- (interactive)
- (unless (buffer-file-name (or (buffer-base-buffer)
- (current-buffer)))
- (error "Not visiting a file."))
- (flet ((info-to-src (src-title info)
- (helm-build-sync-source src-title
- :candidates info
- :keymap (let ((map (make-sparse-keymap)))
- (set-keymap-parent map helm-map)
- (define-key map (kbd "C-<return>")
- 'my/roam-open-backlink-run-open-file)
- map)
- :action
- '(("Open file other window" .
- (lambda (data)
- (find-file-other-window (car data))
- (goto-char (cadr data))))
- ("Open file" . my/roam-open-backlink-open-file))))
- (get-links-out (file-path &optional ignore-to)
- (-as-> (org-roam-sql
- [:select [file-to] :from file-links
- :where (= file-from $s1)]
- file-path) prev
- (mapcar #'car prev)
- (-remove-item ignore-to prev)
- (-uniq prev)
- (--map (cons (org-roam--get-title-or-slug it) it) prev)
- (--sort (string-lessp (car it) (car other)) prev)))
- (make-links-out-src (name links-out)
- (helm-build-sync-source name
- :candidates links-out
- :keymap (let ((map (make-sparse-keymap)))
- (set-keymap-parent map helm-map)
- (define-key map (kbd "C-<return>")
- 'my/roam-open-link-run-open-file)
- map)
- :action
- '(("Open file other window" . find-file-other-window)
- ("Open file" . find-file)))))
- (let* ((file-path (buffer-file-name (or (buffer-base-buffer)
- (current-buffer))))
- (links-out (get-links-out file-path))
- (backlinks (my/roam-file-backlink-info file-path))
- (sources nil))
- ;; Links from current page out
- (when-let* ((links-out-src (and links-out
- (make-links-out-src "Links" links-out))))
- (push links-out-src sources))
- ;; Back-references to current page
- (when-let ((top-info-src (info-to-src "Backlinks" backlinks)))
- (push top-info-src sources))
- ;; Walk through pages of outgoing links
- (dolist (link links-out)
- ;; Show their links
- (when-let* ((links-out (get-links-out (cdr link) file-path))
- (links-out-src (make-links-out-src
- (format "Links (%s)" (car link))
- links-out)))
- (push links-out-src sources))
- ;; Show their back-references
- (when-let ((backlinks-src (info-to-src (format "Backlinks (%s)" (car link))
- (my/roam-file-backlink-info
- (cdr link) file-path))))
- (push backlinks-src sources)))
- (unless sources
- (user-error "No references available."))
- (helm :sources (nreverse sources) :prompt "Pick reference: "))))
- ;; -- Helper functions ---------------------------------------------------------
- (defun my/roam-open-backlink-run-open-file ()
- (interactive)
- (with-helm-alive-p (helm-exit-and-execute-action
- 'my/roam-open-backlink-open-file)))
- (defun my/roam-open-backlink-open-file (data)
- (find-file (car data))
- (goto-char (cadr data)))
- (defun my/roam-open-link-run-open-file ()
- (interactive)
- (with-helm-alive-p (helm-exit-and-execute-action 'find-file)))
- (defun my/roam-file-backlink-info (file-path &optional drop-to)
- "Produce a list of lists where
- 0: Description: Title and line
- 1: Link target path
- 2: Line start point"
- (when-let* ((backlinks (org-roam--get-backlinks file-path))
- (grouped-backlinks (--group-by (nth 0 it) backlinks)))
- (let (bl-info)
- (dolist (group grouped-backlinks)
- (let* ((file-from (car group)))
- (unless (equal drop-to file-from)
- (let* ((bls (cdr group))
- (title (org-roam--get-title-or-slug file-from)))
- (dolist (backlink bls)
- (pcase-let ((`(,file-from ,file-to ,props) backlink))
- (let* ((file-point (plist-get props :point))
- (line (-> (plist-get props :content)
- s-trim
- org-link-display-format
- substring-no-properties))
- (desc (format "%s: %s" title line)))
- (push (list desc file-from file-point) bl-info))))))))
- (--sort (string-lessp (car it) (car other)) bl-info))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement