mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
(feat): remove all symlink resolutions (#1109)
file-truename calls alone accounts for over 20% of CPU samples in org-roam-db-build-cache. It's expensive and unnecessary. To get an absolute path, expand-file-name alone is enough. Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
This commit is contained in:
@ -4,9 +4,12 @@
|
||||
|
||||
In this release we support fuzzy links of the form `[[Title]]`, `[[*Headline]]` and `[[Title*Headline]]`. Completion for these fuzzy links is supported via `completion-at-point`.
|
||||
|
||||
Org-roam also now does not resolve symlinks. This significantly speeds up cache builds, but may result in some workflows breaking. In particular, Org-roam now cannot figure out if two distinct file paths in the Org-roam directory are the same file, and both files will be processed as if they were different files. This error seems to be unavoidable now that symlinks are not resolved, but this workflow is rare and should not affect most users.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- [#910](https://github.com/org-roam/org-roam/pull/910) Deprecate `company-org-roam`, using `completion-at-point` instead. To use this with company, add the `company-capf` backend instead.
|
||||
- [#1109](https://github.com/org-roam/org-roam/pull/1109) Org-roam now does not resolve symlinks.
|
||||
|
||||
### Features
|
||||
|
||||
|
@ -110,9 +110,9 @@ For example: (setq org-roam-buffer-window-parameters '((no-other-window . t)))"
|
||||
(defun org-roam-buffer--insert-title ()
|
||||
"Insert the org-roam-buffer title."
|
||||
(insert (propertize (org-roam--get-title-or-slug
|
||||
(file-truename (buffer-file-name org-roam-buffer--current)))
|
||||
'font-lock-face
|
||||
'org-document-title)))
|
||||
(buffer-file-name org-roam-buffer--current))
|
||||
'font-lock-face
|
||||
'org-document-title)))
|
||||
|
||||
(defun org-roam-buffer--pluralize (string number)
|
||||
"Conditionally pluralize STRING if NUMBER is above 1."
|
||||
@ -152,7 +152,7 @@ For example: (setq org-roam-buffer-window-parameters '((no-other-window . t)))"
|
||||
|
||||
(defun org-roam-buffer--insert-backlinks ()
|
||||
"Insert the org-roam-buffer backlinks string for the current buffer."
|
||||
(if-let* ((file-path (file-truename (buffer-file-name org-roam-buffer--current)))
|
||||
(if-let* ((file-path (buffer-file-name org-roam-buffer--current))
|
||||
(titles (with-current-buffer org-roam-buffer--current
|
||||
(org-roam--extract-titles)))
|
||||
(backlinks (org-roam--get-backlinks (push file-path titles)))
|
||||
|
@ -79,7 +79,7 @@ value like `most-positive-fixnum'."
|
||||
:type 'int
|
||||
:group 'org-roam)
|
||||
|
||||
(defconst org-roam-db--version 7)
|
||||
(defconst org-roam-db--version 8)
|
||||
|
||||
(defvar org-roam-db--connection (make-hash-table :test #'equal)
|
||||
"Database connection to Org-roam database.")
|
||||
@ -92,7 +92,7 @@ value like `most-positive-fixnum'."
|
||||
|
||||
(defun org-roam-db--get-connection ()
|
||||
"Return the database connection, if any."
|
||||
(gethash (file-truename org-roam-directory)
|
||||
(gethash (expand-file-name org-roam-directory)
|
||||
org-roam-db--connection))
|
||||
|
||||
(defun org-roam-db ()
|
||||
@ -106,7 +106,7 @@ Performs a database upgrade when required."
|
||||
(make-directory (file-name-directory db-file) t)
|
||||
(let ((conn (emacsql-sqlite3 db-file)))
|
||||
(set-process-query-on-exit-flag (emacsql-process conn) nil)
|
||||
(puthash (file-truename org-roam-directory)
|
||||
(puthash (expand-file-name org-roam-directory)
|
||||
conn
|
||||
org-roam-db--connection)
|
||||
(when init-db
|
||||
@ -219,8 +219,8 @@ the current `org-roam-directory'."
|
||||
(defun org-roam-db--clear-file (&optional filepath)
|
||||
"Remove any related links to the file at FILEPATH.
|
||||
This is equivalent to removing the node from the graph."
|
||||
(let ((file (file-truename (or filepath
|
||||
(buffer-file-name (buffer-base-buffer))))))
|
||||
(let ((file (expand-file-name (or filepath
|
||||
(buffer-file-name (buffer-base-buffer))))))
|
||||
(dolist (table (mapcar #'car org-roam-db--table-schemata))
|
||||
(org-roam-db-query `[:delete :from ,table
|
||||
:where (= ,(if (eq table 'links) 'from 'file) $s1)]
|
||||
@ -403,7 +403,7 @@ connections, nil is returned."
|
||||
;;;;; Updating
|
||||
(defun org-roam-db--update-meta ()
|
||||
"Update the metadata of the current buffer into the cache."
|
||||
(let* ((file (file-truename (buffer-file-name)))
|
||||
(let* ((file (buffer-file-name))
|
||||
(attr (file-attributes file))
|
||||
(atime (file-attribute-access-time attr))
|
||||
(mtime (file-attribute-modification-time attr))
|
||||
@ -415,7 +415,7 @@ connections, nil is returned."
|
||||
|
||||
(defun org-roam-db--update-titles ()
|
||||
"Update the title of the current buffer into the cache."
|
||||
(let* ((file (file-truename (buffer-file-name)))
|
||||
(let* ((file (buffer-file-name))
|
||||
(titles (or (org-roam--extract-titles)
|
||||
(list (org-roam--path-to-slug file)))))
|
||||
(org-roam-db-query [:delete :from titles
|
||||
@ -425,7 +425,7 @@ connections, nil is returned."
|
||||
|
||||
(defun org-roam-db--update-tags ()
|
||||
"Update the tags of the current buffer into the cache."
|
||||
(let ((file (file-truename (buffer-file-name)))
|
||||
(let ((file (buffer-file-name))
|
||||
(tags (org-roam--extract-tags)))
|
||||
(org-roam-db-query [:delete :from tags
|
||||
:where (= file $s1)]
|
||||
@ -435,7 +435,7 @@ connections, nil is returned."
|
||||
|
||||
(defun org-roam-db--update-refs ()
|
||||
"Update the ref of the current buffer into the cache."
|
||||
(let ((file (file-truename (buffer-file-name))))
|
||||
(let ((file (buffer-file-name)))
|
||||
(org-roam-db-query [:delete :from refs
|
||||
:where (= file $s1)]
|
||||
file)
|
||||
@ -444,7 +444,7 @@ connections, nil is returned."
|
||||
|
||||
(defun org-roam-db--update-links ()
|
||||
"Update the file links of the current buffer in the cache."
|
||||
(let ((file (file-truename (buffer-file-name))))
|
||||
(let ((file (buffer-file-name)))
|
||||
(org-roam-db-query [:delete :from links
|
||||
:where (= from $s1)]
|
||||
file)
|
||||
@ -453,7 +453,7 @@ connections, nil is returned."
|
||||
|
||||
(defun org-roam-db--update-headlines ()
|
||||
"Update the file headlines of the current buffer into the cache."
|
||||
(let* ((file (file-truename (buffer-file-name))))
|
||||
(let* ((file (buffer-file-name)))
|
||||
(org-roam-db-query [:delete :from headlines
|
||||
:where (= file $s1)]
|
||||
file)
|
||||
|
@ -265,7 +265,7 @@ CALLBACK is passed the graph file as its sole argument."
|
||||
"Build a graph of nodes connected to FILE.
|
||||
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 (expand-file-name file))
|
||||
(files (or (if (and max-distance (>= max-distance 0))
|
||||
(org-roam-db--links-with-max-distance file max-distance)
|
||||
(org-roam-db--connected-component file))
|
||||
|
54
org-roam.el
54
org-roam.el
@ -368,8 +368,7 @@ If FILE is not specified, use the current buffer's file-path."
|
||||
(org-roam--org-file-p path)
|
||||
(not (and org-roam-file-exclude-regexp
|
||||
(string-match-p org-roam-file-exclude-regexp path)))
|
||||
(f-descendant-of-p (file-truename path)
|
||||
(file-truename org-roam-directory))))))
|
||||
(f-descendant-of-p path (expand-file-name org-roam-directory))))))
|
||||
|
||||
(defun org-roam--org-roam-headline-p (&optional id)
|
||||
"Return t if ID is part of Org-roam system, nil otherwise.
|
||||
@ -506,7 +505,7 @@ Use external shell commands if defined in `org-roam-list-files-commands'."
|
||||
|
||||
(defun org-roam--list-all-files ()
|
||||
"Return a list of all Org-roam files within `org-roam-directory'."
|
||||
(org-roam--list-files (file-truename org-roam-directory)))
|
||||
(org-roam--list-files (expand-file-name org-roam-directory)))
|
||||
|
||||
;;;; Org extraction functions
|
||||
(defun org-roam--extract-global-props (props)
|
||||
@ -597,7 +596,7 @@ in temp buffers. In cases where this occurs, we do know the file path, and pass
|
||||
it as FILE-PATH."
|
||||
(require 'org-ref nil t)
|
||||
(unless file-path
|
||||
(setq file-path (file-truename (buffer-file-name))))
|
||||
(setq file-path (buffer-file-name)))
|
||||
(save-excursion
|
||||
(let (links)
|
||||
(org-element-map (org-element-parse-buffer) 'link
|
||||
@ -632,8 +631,7 @@ it as FILE-PATH."
|
||||
(_ (if (or (file-remote-p path)
|
||||
(org-roam--url-p path))
|
||||
(list path)
|
||||
(let ((file-maybe (file-truename
|
||||
(expand-file-name path (file-name-directory file-path)))))
|
||||
(let ((file-maybe (expand-file-name path (file-name-directory file-path))))
|
||||
(if (f-exists? file-maybe)
|
||||
(list file-maybe)
|
||||
(list path))))))))
|
||||
@ -646,7 +644,7 @@ it as FILE-PATH."
|
||||
"Extract all headlines with IDs within the current buffer.
|
||||
If FILE-PATH is nil, use the current file."
|
||||
(let ((file-path (or file-path
|
||||
(file-truename (buffer-file-name)))))
|
||||
(buffer-file-name))))
|
||||
;; Use `org-map-region' instead of `org-map-entries' as the latter
|
||||
;; would require another step to remove all nil values.
|
||||
(let ((result nil))
|
||||
@ -713,14 +711,14 @@ If NESTED, return the first successful result from SOURCES."
|
||||
"Extract tags from using the directory path FILE.
|
||||
All sub-directories relative to `org-roam-directory' are used as tags."
|
||||
(when-let ((dir-relative (file-name-directory
|
||||
(file-relative-name file (file-truename org-roam-directory)))))
|
||||
(file-relative-name file (expand-file-name org-roam-directory)))))
|
||||
(f-split dir-relative)))
|
||||
|
||||
(defun org-roam--extract-tags-last-directory (file)
|
||||
"Extract tags from using the directory path FILE.
|
||||
The final directory component is used as a tag."
|
||||
(when-let ((dir-relative (file-name-directory
|
||||
(file-relative-name file (file-truename org-roam-directory)))))
|
||||
(file-relative-name file (expand-file-name org-roam-directory)))))
|
||||
(last (f-split dir-relative))))
|
||||
|
||||
(defun org-roam--extract-tags-first-directory (file)
|
||||
@ -728,7 +726,7 @@ The final directory component is used as a tag."
|
||||
The first directory component after `org-roam-directory' is used as a
|
||||
tag."
|
||||
(when-let ((dir-relative (file-name-directory
|
||||
(file-relative-name file (file-truename org-roam-directory)))))
|
||||
(file-relative-name file (expand-file-name org-roam-directory)))))
|
||||
(list (car (f-split dir-relative)))))
|
||||
|
||||
(defun org-roam--extract-tags-prop (_file)
|
||||
@ -818,7 +816,7 @@ Examples:
|
||||
(defun org-roam--path-to-slug (path)
|
||||
"Return a slug from PATH."
|
||||
(-> path
|
||||
(file-relative-name (file-truename org-roam-directory))
|
||||
(file-relative-name (expand-file-name org-roam-directory))
|
||||
(file-name-sans-extension)))
|
||||
|
||||
(defun org-roam--get-title-or-slug (path)
|
||||
@ -856,7 +854,6 @@ TYPE defaults to \"file\"."
|
||||
(-> (or (buffer-base-buffer)
|
||||
(current-buffer))
|
||||
(buffer-file-name)
|
||||
(file-truename)
|
||||
(file-name-directory)))))
|
||||
(org-roam-link-make-string
|
||||
(concat (or type "file") ":" (if here
|
||||
@ -906,7 +903,7 @@ whose title is 'Index'."
|
||||
`((functionp stringp)
|
||||
,wrong-type))))))
|
||||
(if (f-relative-p index)
|
||||
(concat (file-truename org-roam-directory) path)
|
||||
(concat (expand-file-name org-roam-directory) path)
|
||||
index)))
|
||||
|
||||
;;;; org-roam-find-ref
|
||||
@ -983,15 +980,14 @@ Return nil if the file does not exist."
|
||||
|
||||
(defun org-roam--file-path-from-id (id)
|
||||
"Return path for Org-roam file with ID."
|
||||
(file-truename
|
||||
(let* ((ext (or (car org-roam-file-extensions)
|
||||
"org"))
|
||||
(file (concat id "." ext)))
|
||||
(expand-file-name
|
||||
(if org-roam-encrypt-files
|
||||
(concat file ".gpg")
|
||||
file)
|
||||
org-roam-directory))))
|
||||
(let* ((ext (or (car org-roam-file-extensions)
|
||||
"org"))
|
||||
(file (concat id "." ext)))
|
||||
(expand-file-name
|
||||
(if org-roam-encrypt-files
|
||||
(concat file ".gpg")
|
||||
file)
|
||||
org-roam-directory)))
|
||||
|
||||
;;; org-roam-backlinks-mode
|
||||
(define-minor-mode org-roam-backlinks-mode
|
||||
@ -1043,7 +1039,7 @@ This function hooks into `org-open-at-point' via `org-open-at-point-functions'."
|
||||
((let* ((context (org-element-context))
|
||||
(path (org-element-property :path context)))
|
||||
(when (and (eq (org-element-type context) 'link)
|
||||
(org-roam--org-roam-file-p (file-truename path)))
|
||||
(org-roam--org-roam-file-p path))
|
||||
(org-roam-buffer--find-file path)
|
||||
(org-show-context)
|
||||
t)))
|
||||
@ -1527,7 +1523,7 @@ during the next idle slot."
|
||||
"Advice for maintaining cache consistency when FILE is deleted."
|
||||
(when (and (not (auto-save-file-name-p file))
|
||||
(org-roam--org-roam-file-p file))
|
||||
(org-roam-db--clear-file (file-truename file))))
|
||||
(org-roam-db--clear-file (expand-file-name file))))
|
||||
|
||||
(defun org-roam--replace-link (old-path new-path &optional old-desc new-desc)
|
||||
"Replace Org-roam file links with path OLD-PATH to path NEW-PATH.
|
||||
@ -1541,7 +1537,7 @@ update with NEW-DESC."
|
||||
(when-let ((link (org-element-lineage (org-element-context) '(link) t)))
|
||||
(let ((type (org-element-property :type link))
|
||||
(path (org-element-property :path link)))
|
||||
(when (and (string-equal (file-truename path) old-path)
|
||||
(when (and (string-equal (expand-file-name path) old-path)
|
||||
(org-in-regexp org-link-bracket-re 1))
|
||||
(let* ((label (if (match-end 2)
|
||||
(match-string-no-properties 2)
|
||||
@ -1611,7 +1607,7 @@ OLD-TITLE, and replace the link descriptions with the NEW-TITLE
|
||||
if applicable.
|
||||
|
||||
To be added to `org-roam-title-change-hook'."
|
||||
(let* ((current-path (file-truename (buffer-file-name)))
|
||||
(let* ((current-path (buffer-file-name))
|
||||
(files-affected (org-roam-db-query [:select :distinct [from]
|
||||
:from links
|
||||
:where (= to $s1)]
|
||||
@ -1654,8 +1650,8 @@ When NEW-FILE-OR-DIR is a directory, we use it to compute the new file path."
|
||||
(not (backup-file-name-p new-file))
|
||||
(org-roam--org-roam-file-p old-file))
|
||||
(org-roam-db--ensure-built)
|
||||
(let* ((old-path (file-truename old-file))
|
||||
(new-path (file-truename new-file))
|
||||
(let* ((old-path (expand-file-name old-file))
|
||||
(new-path (expand-file-name new-file))
|
||||
(new-buffer (or (find-buffer-visiting new-path)
|
||||
(find-file-noselect new-path)))
|
||||
(files-affected (org-roam-db-query [:select :distinct [from]
|
||||
@ -1666,7 +1662,7 @@ When NEW-FILE-OR-DIR is a directory, we use it to compute the new file path."
|
||||
(org-roam-db--clear-file old-file)
|
||||
;; Replace links from old-file.org -> new-file.org in all Org-roam files with these links
|
||||
(mapc (lambda (file)
|
||||
(setq file (if (string-equal (file-truename (car file)) old-path)
|
||||
(setq file (if (string-equal (expand-file-name (car file)) old-path)
|
||||
new-path
|
||||
(car file)))
|
||||
(with-current-buffer (or (find-buffer-visiting file)
|
||||
|
Reference in New Issue
Block a user