Contexual Org Roam buffer preview fn

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

  1. If link is embedded within a list - pull the list only
  2. If line has more than 300 characters - pull the entire line only
  3. 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:

1 Like