(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:
Göktuğ Karakaşlı
2020-05-04 15:44:15 +03:00
committed by GitHub
parent 7df50c14ec
commit 11d239d661
7 changed files with 105 additions and 43 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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."
(let ((key (cdr ref))
(type (car ref)))
(org-roam-db-query (org-roam-db-query
[:insert :into refs [:insert :into refs :values $v1]
:values $v1] (list (vector key file type)))))
(list (vector ref file))))
;;;;; 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...

View File

@ -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)))

View File

@ -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)

View File

@ -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