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
|
||||
* [#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
|
||||
* [#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
|
||||
* [#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
|
||||
* [#547](https://github.com/jethrokuan/org-roam/pull/547) Fix unlinked citations.
|
||||
|
||||
### Features
|
||||
* [#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 ()
|
||||
"Insert citation backlinks for the current buffer."
|
||||
(if-let* ((roam-key (with-temp-buffer
|
||||
(insert-buffer-substring org-roam-buffer--current)
|
||||
(org-roam--extract-ref)))
|
||||
(if-let* ((ref (with-temp-buffer
|
||||
(insert-buffer-substring org-roam-buffer--current)
|
||||
(org-roam--extract-ref)))
|
||||
(org-ref-p (require 'org-ref nil t)) ; Ensure that org-ref is present
|
||||
(cite-prefixes (-map (lambda (type)
|
||||
(concat type ":")) org-ref-cite-types))
|
||||
(key-backlinks (org-roam--get-backlinks
|
||||
(s-chop-prefixes cite-prefixes roam-key)))
|
||||
(key-backlinks (org-roam--get-backlinks (cdr ref)))
|
||||
(grouped-backlinks (--group-by (nth 0 it) key-backlinks)))
|
||||
(progn
|
||||
(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)
|
||||
(read-only-mode 1)))))
|
||||
|
||||
|
||||
(cl-defun org-roam-buffer--update-maybe (&key redisplay)
|
||||
"Reconstructs `org-roam-buffer'.
|
||||
This needs to be quick or infrequent, because this is run at
|
||||
|
@ -77,6 +77,8 @@
|
||||
"org-roam 1.1.0")
|
||||
(define-obsolete-function-alias 'org-roam--capture 'org-roam-capture--capture
|
||||
"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
|
||||
(define-obsolete-variable-alias 'org-roam-graphviz-extra-options
|
||||
|
@ -56,7 +56,7 @@ when used with multiple Org-roam instances."
|
||||
:type 'string
|
||||
:group 'org-roam)
|
||||
|
||||
(defconst org-roam-db--version 2)
|
||||
(defconst org-roam-db--version 3)
|
||||
(defconst org-roam-db--sqlite-available-p
|
||||
(with-demoted-errors "Org-roam initialization: %S"
|
||||
(emacsql-sqlite-ensure-binary)
|
||||
@ -94,7 +94,7 @@ Performs a database upgrade when required."
|
||||
(when init-db
|
||||
(org-roam-db--init conn))
|
||||
(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
|
||||
((> version org-roam-db--version)
|
||||
(emacsql-close conn)
|
||||
@ -134,7 +134,8 @@ SQL can be either the emacsql vector representation, or a string."
|
||||
|
||||
(refs
|
||||
[(ref :unique :not-null)
|
||||
(file :not-null)])))
|
||||
(file :not-null)
|
||||
(type :not-null)])))
|
||||
|
||||
(defun org-roam-db--init (db)
|
||||
"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 (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."
|
||||
(emacsql-with-transaction db
|
||||
'ignore
|
||||
(when (= version 1)
|
||||
(progn
|
||||
(warn "No good way to perform a DB upgrade, rebuilding from scratch...")
|
||||
(delete-file (org-roam-db--get))
|
||||
(org-roam-db-build-cache)))
|
||||
version))
|
||||
(if (< version org-roam-db--version)
|
||||
(progn
|
||||
(message (format "Upgrading the Org-roam database from version %d to version %d"
|
||||
version org-roam-db--version))
|
||||
(org-roam-db-build-cache t))))
|
||||
version)
|
||||
|
||||
(defun org-roam-db--close (&optional 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)
|
||||
"Insert REF for FILE into the Org-roam cache."
|
||||
(org-roam-db-query
|
||||
[:insert :into refs
|
||||
:values $v1]
|
||||
(list (vector ref file))))
|
||||
(let ((key (cdr ref))
|
||||
(type (car ref)))
|
||||
(org-roam-db-query
|
||||
[:insert :into refs :values $v1]
|
||||
(list (vector key file type)))))
|
||||
|
||||
;;;;; Fetching
|
||||
(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)))
|
||||
(let ((titles (org-roam--extract-and-format-titles file)))
|
||||
(setq all-titles (cons (vector file titles) all-titles)))
|
||||
(when-let ((ref (org-roam--extract-ref)))
|
||||
(setq all-refs (cons (vector ref file) all-refs))))
|
||||
(when-let* ((ref (org-roam--extract-ref))
|
||||
(type (car ref))
|
||||
(key (cdr ref)))
|
||||
(setq all-refs (cons (vector key file type) all-refs))))
|
||||
(remhash file current-files))))
|
||||
(dolist (file (hash-table-keys current-files))
|
||||
;; These files are no longer around, remove from cache...
|
||||
|
@ -173,7 +173,8 @@ into a digraph."
|
||||
`[:with selected :as [:select [file] :from ,node-query]
|
||||
:select :distinct [file from]
|
||||
: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))])
|
||||
(edges (org-roam-db-query edges-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--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 ()
|
||||
"Extract the ref from current buffer."
|
||||
(cdr (assoc "ROAM_KEY" (org-roam--extract-global-props '("ROAM_KEY")))))
|
||||
"Extract the ref from current buffer and return the type and the key of the ref."
|
||||
(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
|
||||
(defun org-roam--path-to-slug (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? ")
|
||||
(org-roam-find-file "Index")))))
|
||||
|
||||
(defun org-roam--get-ref-path-completions ()
|
||||
"Return a list of cons pairs for refs to absolute path of Org-roam files."
|
||||
(let ((rows (org-roam-db-query [:select [ref file] :from refs])))
|
||||
(mapcar (lambda (row)
|
||||
(cons (car row)
|
||||
(cadr row))) rows)))
|
||||
;;;; org-roam-find-ref
|
||||
(defcustom org-roam-include-type-in-ref-path-completions nil
|
||||
"When t, include the type in ref-path completions.
|
||||
Note that this only affects interactive calls.
|
||||
See `org-roam--get-ref-path-completions' for details."
|
||||
: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.
|
||||
INFO is an alist containing additional information."
|
||||
(interactive)
|
||||
(let* ((completions (org-roam--get-ref-path-completions))
|
||||
INFO is an alist containing additional information.
|
||||
ARG is used to forward interactive calls to
|
||||
`org-roam--get-ref-path-completions'"
|
||||
(interactive "p")
|
||||
(let* ((completions (org-roam--get-ref-path-completions arg))
|
||||
(ref (or (cdr (assoc 'ref info))
|
||||
(org-roam-completion--completing-read "Ref: "
|
||||
completions
|
||||
@ -658,7 +712,7 @@ file."
|
||||
(define-key map [mouse-1] 'org-open-at-point)
|
||||
(define-key map (kbd "RET") 'org-open-at-point)
|
||||
map)
|
||||
"Keymap for `org-roam-backlinks-mode'.")
|
||||
"Keymap for symbol `org-roam-backlinks-mode'.")
|
||||
|
||||
(define-minor-mode org-roam-backlinks-mode
|
||||
"Minor mode for the `org-roam-buffer'.
|
||||
@ -731,7 +785,7 @@ for Org-ref cite links."
|
||||
;;; The global minor org-roam-mode
|
||||
(defvar org-roam-mode-map
|
||||
(make-sparse-keymap)
|
||||
"Keymap for mode `org-roam-mode'.")
|
||||
"Keymap for mode symbol `org-roam-mode'.")
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode org-roam-mode
|
||||
@ -755,11 +809,11 @@ Otherwise, behave as if called interactively."
|
||||
:global t
|
||||
(cond
|
||||
(org-roam-mode
|
||||
(org-roam-db-build-cache)
|
||||
(add-hook 'find-file-hook #'org-roam--find-file-hook-function)
|
||||
(add-hook 'kill-emacs-hook #'org-roam-db--close-all)
|
||||
(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
|
||||
(remove-hook 'find-file-hook #'org-roam--find-file-hook-function)
|
||||
(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))))))
|
||||
|
||||
(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)
|
||||
(setq org-roam-last-window (get-buffer-window))
|
||||
(add-hook 'post-command-hook #'org-roam-buffer--update-maybe nil t)
|
||||
|
@ -107,7 +107,7 @@
|
||||
|
||||
(expect (org-roam-db-query [:select * :from refs])
|
||||
: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 (org-roam-db-build-cache)
|
||||
@ -299,7 +299,7 @@
|
||||
(it "delete web_ref"
|
||||
(expect (org-roam-db-query [:select * :from refs])
|
||||
: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"))
|
||||
(expect (org-roam-db-query [:select * :from refs])
|
||||
:to-have-same-items-as
|
||||
|
Reference in New Issue
Block a user