mirror of
https://github.com/org-roam/org-roam
synced 2025-08-11 13:07:24 -05:00
(fix): org-roam-graph--build in seperate process (#679)
org-roam-graph--build accepts a callback function which is passed the resultant graph file as its sole argument. This prevents a race between graph building and opening. See: #666
This commit is contained in:
@ -217,24 +217,30 @@ into a digraph."
|
|||||||
(insert "}")
|
(insert "}")
|
||||||
(buffer-string))))
|
(buffer-string))))
|
||||||
|
|
||||||
(defun org-roam-graph--build (&optional node-query)
|
(defun org-roam-graph--build (&optional node-query callback)
|
||||||
"Generate a graph showing the relations between nodes in NODE-QUERY."
|
"Generate a graph showing the relations between nodes in NODE-QUERY.
|
||||||
(let ((name org-roam-graph-executable))
|
Execute CALLBACK when process exits successfully.
|
||||||
(unless (stringp name)
|
CALLBACK is passed the graph file as its sole argument."
|
||||||
|
(unless (stringp org-roam-graph-executable)
|
||||||
(user-error "`org-roam-graph-executable' is not a string"))
|
(user-error "`org-roam-graph-executable' is not a string"))
|
||||||
(unless (executable-find org-roam-graph-executable)
|
(unless (executable-find org-roam-graph-executable)
|
||||||
(user-error (concat "Cannot find executable \"%s\" to generate the graph. "
|
(user-error (concat "Cannot find executable \"%s\" to generate the graph. "
|
||||||
"Please adjust `org-roam-graph-executable'")
|
"Please adjust `org-roam-graph-executable'")
|
||||||
name))
|
org-roam-graph-executable))
|
||||||
(let* ((node-query (or node-query
|
(let* ((node-query (or node-query
|
||||||
`[:select [file titles]
|
`[:select [file titles] :from titles
|
||||||
:from titles
|
|
||||||
,@(org-roam-graph--expand-matcher 'file t)]))
|
,@(org-roam-graph--expand-matcher 'file t)]))
|
||||||
(graph (org-roam-graph--dot node-query))
|
(graph (org-roam-graph--dot node-query))
|
||||||
(temp-dot (make-temp-file "graph." nil ".dot" graph))
|
(temp-dot (make-temp-file "graph." nil ".dot" graph))
|
||||||
(temp-graph (make-temp-file "graph." nil ".svg")))
|
(temp-graph (make-temp-file "graph." nil ".svg")))
|
||||||
(call-process name nil 0 nil temp-dot "-Tsvg" "-o" temp-graph)
|
(make-process
|
||||||
temp-graph)))
|
:name "*org-roam-graph--build-process*"
|
||||||
|
:buffer "*org-roam-graph--build-process*"
|
||||||
|
:command `(,org-roam-graph-executable ,temp-dot "-Tsvg" "-o" ,temp-graph)
|
||||||
|
:sentinel (when callback
|
||||||
|
(lambda (process _event)
|
||||||
|
(when (= 0 (process-exit-status process))
|
||||||
|
(funcall callback temp-graph)))))))
|
||||||
|
|
||||||
(defun org-roam-graph--open (file)
|
(defun org-roam-graph--open (file)
|
||||||
"Open FILE using `org-roam-graph-viewer' with `view-file' as a fallback."
|
"Open FILE using `org-roam-graph-viewer' with `view-file' as a fallback."
|
||||||
@ -249,9 +255,10 @@ into a digraph."
|
|||||||
('nil (view-file file))
|
('nil (view-file file))
|
||||||
(_ (signal 'wrong-type-argument `((functionp stringp null) ,org-roam-graph-viewer)))))
|
(_ (signal 'wrong-type-argument `((functionp stringp null) ,org-roam-graph-viewer)))))
|
||||||
|
|
||||||
(defun org-roam-graph--build-connected-component (file &optional max-distance)
|
(defun org-roam-graph--build-connected-component (file &optional max-distance callback)
|
||||||
"Build a graph of nodes connected to FILE.
|
"Build a graph of nodes connected to FILE.
|
||||||
If MAX-DISTANCE is non-nil, limit nodes to MAX-DISTANCE steps."
|
If MAX-DISTANCE is non-nil, limit nodes to MAX-DISTANCE steps.
|
||||||
|
CALLBACK is passed to `org-roam-graph--build'."
|
||||||
(let* ((file (file-truename file))
|
(let* ((file (file-truename file))
|
||||||
(files (or (if (and max-distance (>= max-distance 0))
|
(files (or (if (and max-distance (>= max-distance 0))
|
||||||
(org-roam-db--links-with-max-distance file max-distance)
|
(org-roam-db--links-with-max-distance file max-distance)
|
||||||
@ -260,7 +267,7 @@ If MAX-DISTANCE is non-nil, limit nodes to MAX-DISTANCE steps."
|
|||||||
(query `[:select [file titles]
|
(query `[:select [file titles]
|
||||||
:from titles
|
:from titles
|
||||||
:where (in file [,@files])]))
|
:where (in file [,@files])]))
|
||||||
(org-roam-graph--build query)))
|
(org-roam-graph--build query callback)))
|
||||||
|
|
||||||
;;;; Commands
|
;;;; Commands
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
@ -282,11 +289,9 @@ ARG may be any of the following values:
|
|||||||
(unless (org-roam--org-roam-file-p file)
|
(unless (org-roam--org-roam-file-p file)
|
||||||
(user-error "\"%s\" is not an org-roam file" file)))
|
(user-error "\"%s\" is not an org-roam file" file)))
|
||||||
(pcase arg
|
(pcase arg
|
||||||
('nil (org-roam-graph--open (org-roam-graph--build node-query)))
|
('nil (org-roam-graph--build node-query #'org-roam-graph--open))
|
||||||
('(4) (org-roam-graph--open (org-roam-graph--build-connected-component file)))
|
('(4) (org-roam-graph--build-connected-component file nil #'org-roam-graph--open))
|
||||||
((pred integerp) (let ((graph (org-roam-graph--build-connected-component file (abs arg))))
|
((pred integerp) (org-roam-graph--build-connected-component file (abs arg) (when (>= arg 0) #'org-roam-graph--open)))
|
||||||
(when (>= arg 0)
|
|
||||||
(org-roam-graph--open graph))))
|
|
||||||
('(16) (org-roam-graph--build node-query))
|
('(16) (org-roam-graph--build node-query))
|
||||||
('- (org-roam-graph--build-connected-component file))
|
('- (org-roam-graph--build-connected-component file))
|
||||||
(_ (user-error "Unrecognized ARG: %s" arg)))))
|
(_ (user-error "Unrecognized ARG: %s" arg)))))
|
||||||
|
Reference in New Issue
Block a user