Problem Description:
Org roam buffer pulls large amount of text – the entirety from heading to heading for every backlink. Simple solutions include creating boundaries with respect to character length and line length as described here :For the sidebar to be functional, am I not supposed to not add links wherever I want? - #14 by akashp
Proposed Solution (contextual):
Pull text depending on context
- If link is embedded within a list - pull the list only
- If line has more than 300 characters - pull the entire line only
- Otherwise pull 2 lines backwards and forwards - without intruding on different heading territories
Function proposal:
(with-eval-after-load 'org-roam
(defun custom/org-roam-preview-context-function ()
"Return the preview content at point - depending on context.
This function handles different cases:
- If the current line is an Org-mode list item, show the entire list.
- If the current line has more than 300 characters, it retrieves the whole line.
- Otherwise, it retrieves two lines before and after the current line, without crossing headlines."
(let* ((line-beg (save-excursion (org-beginning-of-line) (point))) ; Start of current line
(line-end (save-excursion (org-end-of-line) (point))) ; End of current line
(line-length (- line-end line-beg)) ; Calculate line length
(is-item (org-at-item-p)) ; Check if the line is an item
(beg (cond
;; If the line is an item, go to item list beginning
(is-item
(save-excursion
(let* ((struct (org-list-struct))
(pos (progn (beginning-of-line) (point)))
(ind (org-list-get-nth 1 pos struct))
(n (if (= 0 ind)
(progn (org-beginning-of-item-list) 0)
(log ind 2))))
(while (> n 0)
(org-beginning-of-item-list)
(forward-line -1)
(org-beginning-of-item-list)
(setq n
(log (org-list-get-nth 1
(progn (beginning-of-line) (point))
struct))))
(point))))
;; If the line length is greater than 300, return the whole line
((> line-length 300)
line-beg)
;; Otherwise, go two lines before the current line or beginning of block whichever comes first
(t
(let ((meta-end (save-excursion (org-roam-end-of-meta-data t) (point)))
(line-beg-1 (save-excursion (org-beginning-of-line -1) (point))))
(if (>= meta-end line-beg-1)
meta-end
line-beg-1)))))
(end (cond
;; If the line is an item, go to the end of item
(is-item
(save-excursion
(org-end-of-item-list) (point)))
;; If the line length is greater than 300, return the whole line
((> line-length 300)
line-end)
;; Otherwise, go two lines after the current line
(t
(let ((next-heading (save-excursion (org-next-visible-heading 1) (point)))
(line-end+3 (save-excursion (org-end-of-line 3) (point))))
(if (<= next-heading line-end+3) next-heading line-end+3))))))
;; Return the trimmed content between `beg` and `end`
(string-trim (buffer-substring-no-properties beg end))))
(setopt org-roam-preview-function #'custom/org-roam-preview-context-function))
Profit (?):
Better readability and usefulness.
let me know in you find any bugs.
Thanks.
Screenshot: