mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
(feat): fix citation links not showing up in graph (#547)
This change adds a `type` column to the refs column, and strips the prefix before storing the key in the `refs` table.
This commit is contained in:
@ -4,12 +4,15 @@
|
|||||||
|
|
||||||
### Breaking Changes
|
### Breaking Changes
|
||||||
* [#523](https://github.com/jethrokuan/org-roam/pull/523) remove `org-roam-completion-fuzzy-match` in favor of using completion mechanism's configuration options directly
|
* [#523](https://github.com/jethrokuan/org-roam/pull/523) remove `org-roam-completion-fuzzy-match` in favor of using completion mechanism's configuration options directly
|
||||||
|
* [#547](https://github.com/jethrokuan/org-roam/pull/547) Deprecate `org-roam-db--maybe-update`, in favour of `org-roam-db--update-maybe`.
|
||||||
|
* [#547](https://github.com/jethrokuan/org-roam/pull/547) Added `type` column to the `refs` table.
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
* [#509](https://github.com/jethrokuan/org-roam/pull/509) fix backup files being tracked in database
|
* [#509](https://github.com/jethrokuan/org-roam/pull/509) fix backup files being tracked in database
|
||||||
* [#509](https://github.com/jethrokuan/org-roam/pull/509) fix external org files being tracked in database
|
* [#509](https://github.com/jethrokuan/org-roam/pull/509) fix external org files being tracked in database
|
||||||
* [#537](https://github.com/jethrokuan/org-roam/pull/537) quote graphviz node and edge configuration options to allow multi-word configurations
|
* [#537](https://github.com/jethrokuan/org-roam/pull/537) quote graphviz node and edge configuration options to allow multi-word configurations
|
||||||
* [#545](https://github.com/jethrokuan/org-roam/pull/545) fix `org-roam--extract-links` to ensure that multiple citations (`cite:key1,key2`) are split correctly
|
* [#545](https://github.com/jethrokuan/org-roam/pull/545) fix `org-roam--extract-links` to ensure that multiple citations (`cite:key1,key2`) are split correctly
|
||||||
|
* [#547](https://github.com/jethrokuan/org-roam/pull/547) Fix unlinked citations.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
* [#538](https://github.com/jethrokuan/org-roam/pull/538) Optionally use text in first headline as title
|
* [#538](https://github.com/jethrokuan/org-roam/pull/538) Optionally use text in first headline as title
|
||||||
|
@ -114,14 +114,11 @@ When non-nil, the window will not be closed when deleting other windows."
|
|||||||
|
|
||||||
(defun org-roam-buffer--insert-citelinks ()
|
(defun org-roam-buffer--insert-citelinks ()
|
||||||
"Insert citation backlinks for the current buffer."
|
"Insert citation backlinks for the current buffer."
|
||||||
(if-let* ((roam-key (with-temp-buffer
|
(if-let* ((ref (with-temp-buffer
|
||||||
(insert-buffer-substring org-roam-buffer--current)
|
(insert-buffer-substring org-roam-buffer--current)
|
||||||
(org-roam--extract-ref)))
|
(org-roam--extract-ref)))
|
||||||
(org-ref-p (require 'org-ref nil t)) ; Ensure that org-ref is present
|
(org-ref-p (require 'org-ref nil t)) ; Ensure that org-ref is present
|
||||||
(cite-prefixes (-map (lambda (type)
|
(key-backlinks (org-roam--get-backlinks (cdr ref)))
|
||||||
(concat type ":")) org-ref-cite-types))
|
|
||||||
(key-backlinks (org-roam--get-backlinks
|
|
||||||
(s-chop-prefixes cite-prefixes roam-key)))
|
|
||||||
(grouped-backlinks (--group-by (nth 0 it) key-backlinks)))
|
(grouped-backlinks (--group-by (nth 0 it) key-backlinks)))
|
||||||
(progn
|
(progn
|
||||||
(insert (let ((l (length key-backlinks)))
|
(insert (let ((l (length key-backlinks)))
|
||||||
@ -196,6 +193,7 @@ When non-nil, the window will not be closed when deleting other windows."
|
|||||||
(run-hooks 'org-roam-buffer-prepare-hook)
|
(run-hooks 'org-roam-buffer-prepare-hook)
|
||||||
(read-only-mode 1)))))
|
(read-only-mode 1)))))
|
||||||
|
|
||||||
|
|
||||||
(cl-defun org-roam-buffer--update-maybe (&key redisplay)
|
(cl-defun org-roam-buffer--update-maybe (&key redisplay)
|
||||||
"Reconstructs `org-roam-buffer'.
|
"Reconstructs `org-roam-buffer'.
|
||||||
This needs to be quick or infrequent, because this is run at
|
This needs to be quick or infrequent, because this is run at
|
||||||
|
@ -77,6 +77,8 @@
|
|||||||
"org-roam 1.1.0")
|
"org-roam 1.1.0")
|
||||||
(define-obsolete-function-alias 'org-roam--capture 'org-roam-capture--capture
|
(define-obsolete-function-alias 'org-roam--capture 'org-roam-capture--capture
|
||||||
"org-roam 1.1.0")
|
"org-roam 1.1.0")
|
||||||
|
(define-obsolete-function-alias 'org-roam-db--maybe-update 'org-roam-db--update-maybe
|
||||||
|
"org-roam 1.1.0")
|
||||||
|
|
||||||
;;;; Variables
|
;;;; Variables
|
||||||
(define-obsolete-variable-alias 'org-roam-graphviz-extra-options
|
(define-obsolete-variable-alias 'org-roam-graphviz-extra-options
|
||||||
|
@ -56,7 +56,7 @@ when used with multiple Org-roam instances."
|
|||||||
:type 'string
|
:type 'string
|
||||||
:group 'org-roam)
|
:group 'org-roam)
|
||||||
|
|
||||||
(defconst org-roam-db--version 2)
|
(defconst org-roam-db--version 3)
|
||||||
(defconst org-roam-db--sqlite-available-p
|
(defconst org-roam-db--sqlite-available-p
|
||||||
(with-demoted-errors "Org-roam initialization: %S"
|
(with-demoted-errors "Org-roam initialization: %S"
|
||||||
(emacsql-sqlite-ensure-binary)
|
(emacsql-sqlite-ensure-binary)
|
||||||
@ -94,7 +94,7 @@ Performs a database upgrade when required."
|
|||||||
(when init-db
|
(when init-db
|
||||||
(org-roam-db--init conn))
|
(org-roam-db--init conn))
|
||||||
(let* ((version (caar (emacsql conn "PRAGMA user_version")))
|
(let* ((version (caar (emacsql conn "PRAGMA user_version")))
|
||||||
(version (org-roam-db--maybe-update conn version)))
|
(version (org-roam-db--update-maybe conn version)))
|
||||||
(cond
|
(cond
|
||||||
((> version org-roam-db--version)
|
((> version org-roam-db--version)
|
||||||
(emacsql-close conn)
|
(emacsql-close conn)
|
||||||
@ -134,7 +134,8 @@ SQL can be either the emacsql vector representation, or a string."
|
|||||||
|
|
||||||
(refs
|
(refs
|
||||||
[(ref :unique :not-null)
|
[(ref :unique :not-null)
|
||||||
(file :not-null)])))
|
(file :not-null)
|
||||||
|
(type :not-null)])))
|
||||||
|
|
||||||
(defun org-roam-db--init (db)
|
(defun org-roam-db--init (db)
|
||||||
"Initialize database DB with the correct schema and user version."
|
"Initialize database DB with the correct schema and user version."
|
||||||
@ -143,16 +144,16 @@ SQL can be either the emacsql vector representation, or a string."
|
|||||||
(emacsql db [:create-table $i1 $S2] table schema))
|
(emacsql db [:create-table $i1 $S2] table schema))
|
||||||
(emacsql db (format "PRAGMA user_version = %s" org-roam-db--version))))
|
(emacsql db (format "PRAGMA user_version = %s" org-roam-db--version))))
|
||||||
|
|
||||||
(defun org-roam-db--maybe-update (db version)
|
(defun org-roam-db--update-maybe (db version)
|
||||||
"Upgrades the database schema for DB, if VERSION is old."
|
"Upgrades the database schema for DB, if VERSION is old."
|
||||||
(emacsql-with-transaction db
|
(emacsql-with-transaction db
|
||||||
'ignore
|
'ignore
|
||||||
(when (= version 1)
|
(if (< version org-roam-db--version)
|
||||||
(progn
|
(progn
|
||||||
(warn "No good way to perform a DB upgrade, rebuilding from scratch...")
|
(message (format "Upgrading the Org-roam database from version %d to version %d"
|
||||||
(delete-file (org-roam-db--get))
|
version org-roam-db--version))
|
||||||
(org-roam-db-build-cache)))
|
(org-roam-db-build-cache t))))
|
||||||
version))
|
version)
|
||||||
|
|
||||||
(defun org-roam-db--close (&optional db)
|
(defun org-roam-db--close (&optional db)
|
||||||
"Closes the database connection for database DB.
|
"Closes the database connection for database DB.
|
||||||
@ -228,10 +229,11 @@ This is equivalent to removing the node from the graph."
|
|||||||
|
|
||||||
(defun org-roam-db--insert-ref (file ref)
|
(defun org-roam-db--insert-ref (file ref)
|
||||||
"Insert REF for FILE into the Org-roam cache."
|
"Insert REF for FILE into the Org-roam cache."
|
||||||
(org-roam-db-query
|
(let ((key (cdr ref))
|
||||||
[:insert :into refs
|
(type (car ref)))
|
||||||
:values $v1]
|
(org-roam-db-query
|
||||||
(list (vector ref file))))
|
[:insert :into refs :values $v1]
|
||||||
|
(list (vector key file type)))))
|
||||||
|
|
||||||
;;;;; Fetching
|
;;;;; Fetching
|
||||||
(defun org-roam-db--get-current-files ()
|
(defun org-roam-db--get-current-files ()
|
||||||
@ -368,8 +370,10 @@ If FORCE, force a rebuild of the cache from scratch."
|
|||||||
(setq all-links (append links all-links)))
|
(setq all-links (append links all-links)))
|
||||||
(let ((titles (org-roam--extract-and-format-titles file)))
|
(let ((titles (org-roam--extract-and-format-titles file)))
|
||||||
(setq all-titles (cons (vector file titles) all-titles)))
|
(setq all-titles (cons (vector file titles) all-titles)))
|
||||||
(when-let ((ref (org-roam--extract-ref)))
|
(when-let* ((ref (org-roam--extract-ref))
|
||||||
(setq all-refs (cons (vector ref file) all-refs))))
|
(type (car ref))
|
||||||
|
(key (cdr ref)))
|
||||||
|
(setq all-refs (cons (vector key file type) all-refs))))
|
||||||
(remhash file current-files))))
|
(remhash file current-files))))
|
||||||
(dolist (file (hash-table-keys current-files))
|
(dolist (file (hash-table-keys current-files))
|
||||||
;; These files are no longer around, remove from cache...
|
;; These files are no longer around, remove from cache...
|
||||||
|
@ -173,7 +173,8 @@ into a digraph."
|
|||||||
`[:with selected :as [:select [file] :from ,node-query]
|
`[:with selected :as [:select [file] :from ,node-query]
|
||||||
:select :distinct [file from]
|
:select :distinct [file from]
|
||||||
:from links :inner :join refs :on (and (= links:to refs:ref)
|
:from links :inner :join refs :on (and (= links:to refs:ref)
|
||||||
(= links:type "cite"))
|
(= links:type "cite")
|
||||||
|
(= refs:type "cite"))
|
||||||
:where (and (in file selected) (in from selected))])
|
:where (and (in file selected) (in from selected))])
|
||||||
(edges (org-roam-db-query edges-query))
|
(edges (org-roam-db-query edges-query))
|
||||||
(edges-cites (org-roam-db-query edges-cites-query)))
|
(edges-cites (org-roam-db-query edges-cites-query)))
|
||||||
|
88
org-roam.el
88
org-roam.el
@ -375,9 +375,44 @@ current buffer is used."
|
|||||||
(org-roam--format-title title file-path))
|
(org-roam--format-title title file-path))
|
||||||
(org-roam--extract-titles)))
|
(org-roam--extract-titles)))
|
||||||
|
|
||||||
|
(defun org-roam--ref-type-p (type)
|
||||||
|
"Return t if the ref from current buffer is TYPE."
|
||||||
|
(let ((current (car (org-roam--extract-ref))))
|
||||||
|
(eq current type)))
|
||||||
|
|
||||||
(defun org-roam--extract-ref ()
|
(defun org-roam--extract-ref ()
|
||||||
"Extract the ref from current buffer."
|
"Extract the ref from current buffer and return the type and the key of the ref."
|
||||||
(cdr (assoc "ROAM_KEY" (org-roam--extract-global-props '("ROAM_KEY")))))
|
(if-let ((ref (cdr (assoc "ROAM_KEY" (org-roam--extract-global-props '("ROAM_KEY"))))))
|
||||||
|
(let* ((type (org-roam--ref-type ref))
|
||||||
|
(key (cond ((string= "cite" type)
|
||||||
|
(s-chop-prefix (org-roam--cite-prefix ref) ref))
|
||||||
|
(t ref))))
|
||||||
|
(cons type key))
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(defun org-roam--ref-type (ref)
|
||||||
|
"Determine the type of the REF from the prefix."
|
||||||
|
(let* ((cite-prefix (org-roam--cite-prefix ref))
|
||||||
|
(is-website (seq-some
|
||||||
|
(lambda (prefix) (s-prefix? prefix ref))
|
||||||
|
'("http" "https")))
|
||||||
|
(type (cond (cite-prefix "cite")
|
||||||
|
(is-website "website")
|
||||||
|
(t "roam"))))
|
||||||
|
type))
|
||||||
|
|
||||||
|
(defun org-roam--cite-prefix (ref)
|
||||||
|
"Return the citation prefix of REF, or nil otherwise.
|
||||||
|
The prefixes are defined in `org-ref-cite-types`.
|
||||||
|
Examples:
|
||||||
|
(org-roam--cite-prefix \"cite:foo\") -> \"cite:\"
|
||||||
|
(org-roam--cite-prefix \"https://google.com\") -> nil"
|
||||||
|
(when (require 'org-ref nil t)
|
||||||
|
(seq-find
|
||||||
|
(lambda (prefix) (s-prefix? prefix ref))
|
||||||
|
(-map (lambda (type) (concat type ":"))
|
||||||
|
org-ref-cite-types))))
|
||||||
|
|
||||||
;;;; Title/Path/Slug conversion
|
;;;; Title/Path/Slug conversion
|
||||||
(defun org-roam--path-to-slug (path)
|
(defun org-roam--path-to-slug (path)
|
||||||
"Return a slug from PATH."
|
"Return a slug from PATH."
|
||||||
@ -555,18 +590,37 @@ command will offer you to create one."
|
|||||||
(when (y-or-n-p "Index file does not exist. Would you like to create it? ")
|
(when (y-or-n-p "Index file does not exist. Would you like to create it? ")
|
||||||
(org-roam-find-file "Index")))))
|
(org-roam-find-file "Index")))))
|
||||||
|
|
||||||
(defun org-roam--get-ref-path-completions ()
|
;;;; org-roam-find-ref
|
||||||
"Return a list of cons pairs for refs to absolute path of Org-roam files."
|
(defcustom org-roam-include-type-in-ref-path-completions nil
|
||||||
(let ((rows (org-roam-db-query [:select [ref file] :from refs])))
|
"When t, include the type in ref-path completions.
|
||||||
(mapcar (lambda (row)
|
Note that this only affects interactive calls.
|
||||||
(cons (car row)
|
See `org-roam--get-ref-path-completions' for details."
|
||||||
(cadr row))) rows)))
|
:type 'boolean
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
(defun org-roam-find-ref (&optional info)
|
(defun org-roam--get-ref-path-completions (&optional interactive)
|
||||||
|
"Return a list of cons pairs for refs to absolute path of Org-roam files.
|
||||||
|
When INTERACTIVE `org-roam-include-type-in-ref-path-completions'
|
||||||
|
are non-nil, format the car of the completion-candidates as
|
||||||
|
'type:ref'."
|
||||||
|
(let ((rows (org-roam-db-query [:select [type ref file] :from refs]))
|
||||||
|
(include-type (and interactive
|
||||||
|
org-roam-include-type-in-ref-path-completions)))
|
||||||
|
(mapcar (lambda (row)
|
||||||
|
(cl-destructuring-bind (type ref file) row
|
||||||
|
(cons (if include-type
|
||||||
|
(format "%s:%s" type ref)
|
||||||
|
ref)
|
||||||
|
file)))
|
||||||
|
rows)))
|
||||||
|
|
||||||
|
(defun org-roam-find-ref (arg &optional info)
|
||||||
"Find and open an Org-roam file from a ref.
|
"Find and open an Org-roam file from a ref.
|
||||||
INFO is an alist containing additional information."
|
INFO is an alist containing additional information.
|
||||||
(interactive)
|
ARG is used to forward interactive calls to
|
||||||
(let* ((completions (org-roam--get-ref-path-completions))
|
`org-roam--get-ref-path-completions'"
|
||||||
|
(interactive "p")
|
||||||
|
(let* ((completions (org-roam--get-ref-path-completions arg))
|
||||||
(ref (or (cdr (assoc 'ref info))
|
(ref (or (cdr (assoc 'ref info))
|
||||||
(org-roam-completion--completing-read "Ref: "
|
(org-roam-completion--completing-read "Ref: "
|
||||||
completions
|
completions
|
||||||
@ -658,7 +712,7 @@ file."
|
|||||||
(define-key map [mouse-1] 'org-open-at-point)
|
(define-key map [mouse-1] 'org-open-at-point)
|
||||||
(define-key map (kbd "RET") 'org-open-at-point)
|
(define-key map (kbd "RET") 'org-open-at-point)
|
||||||
map)
|
map)
|
||||||
"Keymap for `org-roam-backlinks-mode'.")
|
"Keymap for symbol `org-roam-backlinks-mode'.")
|
||||||
|
|
||||||
(define-minor-mode org-roam-backlinks-mode
|
(define-minor-mode org-roam-backlinks-mode
|
||||||
"Minor mode for the `org-roam-buffer'.
|
"Minor mode for the `org-roam-buffer'.
|
||||||
@ -731,7 +785,7 @@ for Org-ref cite links."
|
|||||||
;;; The global minor org-roam-mode
|
;;; The global minor org-roam-mode
|
||||||
(defvar org-roam-mode-map
|
(defvar org-roam-mode-map
|
||||||
(make-sparse-keymap)
|
(make-sparse-keymap)
|
||||||
"Keymap for mode `org-roam-mode'.")
|
"Keymap for mode symbol `org-roam-mode'.")
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-minor-mode org-roam-mode
|
(define-minor-mode org-roam-mode
|
||||||
@ -755,11 +809,11 @@ Otherwise, behave as if called interactively."
|
|||||||
:global t
|
:global t
|
||||||
(cond
|
(cond
|
||||||
(org-roam-mode
|
(org-roam-mode
|
||||||
(org-roam-db-build-cache)
|
|
||||||
(add-hook 'find-file-hook #'org-roam--find-file-hook-function)
|
(add-hook 'find-file-hook #'org-roam--find-file-hook-function)
|
||||||
(add-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
(add-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
||||||
(advice-add 'rename-file :after #'org-roam--rename-file-advice)
|
(advice-add 'rename-file :after #'org-roam--rename-file-advice)
|
||||||
(advice-add 'delete-file :before #'org-roam--delete-file-advice))
|
(advice-add 'delete-file :before #'org-roam--delete-file-advice)
|
||||||
|
(org-roam-db-build-cache))
|
||||||
(t
|
(t
|
||||||
(remove-hook 'find-file-hook #'org-roam--find-file-hook-function)
|
(remove-hook 'find-file-hook #'org-roam--find-file-hook-function)
|
||||||
(remove-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
(remove-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
||||||
@ -774,7 +828,7 @@ Otherwise, behave as if called interactively."
|
|||||||
(remove-hook 'after-save-hook #'org-roam-db--update-file t))))))
|
(remove-hook 'after-save-hook #'org-roam-db--update-file t))))))
|
||||||
|
|
||||||
(defun org-roam--find-file-hook-function ()
|
(defun org-roam--find-file-hook-function ()
|
||||||
"Called by `find-file-hook' when mode `org-roam-mode' is on."
|
"Called by `find-file-hook' when mode symbol `org-roam-mode' is on."
|
||||||
(when (org-roam--org-roam-file-p)
|
(when (org-roam--org-roam-file-p)
|
||||||
(setq org-roam-last-window (get-buffer-window))
|
(setq org-roam-last-window (get-buffer-window))
|
||||||
(add-hook 'post-command-hook #'org-roam-buffer--update-maybe nil t)
|
(add-hook 'post-command-hook #'org-roam-buffer--update-maybe nil t)
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
|
|
||||||
(expect (org-roam-db-query [:select * :from refs])
|
(expect (org-roam-db-query [:select * :from refs])
|
||||||
:to-have-same-items-as
|
:to-have-same-items-as
|
||||||
(list (list "https://google.com/" (org-roam-test-abs-path "web_ref.org"))))
|
(list (list "https://google.com/" (org-roam-test-abs-path "web_ref.org") "website")))
|
||||||
|
|
||||||
;; Expect rebuilds to be really quick (nothing changed)
|
;; Expect rebuilds to be really quick (nothing changed)
|
||||||
(expect (org-roam-db-build-cache)
|
(expect (org-roam-db-build-cache)
|
||||||
@ -299,7 +299,7 @@
|
|||||||
(it "delete web_ref"
|
(it "delete web_ref"
|
||||||
(expect (org-roam-db-query [:select * :from refs])
|
(expect (org-roam-db-query [:select * :from refs])
|
||||||
:to-have-same-items-as
|
:to-have-same-items-as
|
||||||
(list (list "https://google.com/" (org-roam-test-abs-path "web_ref.org"))))
|
(list (list "https://google.com/" (org-roam-test-abs-path "web_ref.org") "website")))
|
||||||
(delete-file (org-roam-test-abs-path "web_ref.org"))
|
(delete-file (org-roam-test-abs-path "web_ref.org"))
|
||||||
(expect (org-roam-db-query [:select * :from refs])
|
(expect (org-roam-db-query [:select * :from refs])
|
||||||
:to-have-same-items-as
|
:to-have-same-items-as
|
||||||
|
Reference in New Issue
Block a user