(fix): respect original link type during replacement (#1252)

During automatic link replacement, respect the original link type
i.e. absolute links remain absolute. Fixes #1228.
This commit is contained in:
Jethro Kuan
2020-11-11 14:25:50 +08:00
committed by GitHub
parent aef71f1623
commit e96685b1a9
3 changed files with 35 additions and 38 deletions

View File

@ -19,6 +19,7 @@
- [#1226](https://github.com/org-roam/org-roam/issues/1226) only update relative path of file links - [#1226](https://github.com/org-roam/org-roam/issues/1226) only update relative path of file links
- [#1232](https://github.com/org-roam/org-roam/issues/1232) fix incorrect title extractions from narrowed buffers - [#1232](https://github.com/org-roam/org-roam/issues/1232) fix incorrect title extractions from narrowed buffers
- [#1233](https://github.com/org-roam/org-roam/issues/1233) fixes bug where descriptive file links become plain links during update for relative paths - [#1233](https://github.com/org-roam/org-roam/issues/1233) fixes bug where descriptive file links become plain links during update for relative paths
- [#1252](https://github.com/org-roam/org-roam/issues/1252) respect original link type during automatic replacement
## 1.2.2 (06-10-2020) ## 1.2.2 (06-10-2020)

View File

@ -159,11 +159,11 @@ If there is no corresponding headline, return nil."
(org-id-get-create)))))))) (org-id-get-create))))))))
;;; Path-related functions ;;; Path-related functions
(defun org-roam-link-get-path (path) (defun org-roam-link-get-path (path &optional type)
"Return the PATH of the link to use. "Return the PATH of the link to use.
Respect `org-link-file-path-type', see the variable documentation for details. If TYPE is non-nil, create a link of TYPE. Otherwise, respect
If DIR is passed, use DIR as the default directory." `org-link-file-path-type'."
(pcase org-roam-link-file-path-type (pcase (or type org-roam-link-file-path-type)
('absolute ('absolute
(abbreviate-file-name (expand-file-name path))) (abbreviate-file-name (expand-file-name path)))
('noabbrev ('noabbrev

View File

@ -825,10 +825,11 @@ Each ref is returned as a cons of its type and its key."
(slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs))) (slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs)))
(downcase slug)))) (downcase slug))))
(defun org-roam-format-link (target &optional description type) (defun org-roam-format-link (target &optional description type link-type)
"Formats an org link for a given file TARGET, link DESCRIPTION and link TYPE. "Formats an org link for a given file TARGET, link DESCRIPTION and link TYPE.
TYPE defaults to \"file\". TYPE defaults to \"file\". LINK-TYPE is the type of file link to
Here, we also check if there is an ID for the file." be generated. Here, we also check if there is an ID for the
file."
(setq type (or type "file")) (setq type (or type "file"))
(when-let ((id (and org-roam-prefer-id-links (when-let ((id (and org-roam-prefer-id-links
(string-equal type "file") (string-equal type "file")
@ -839,7 +840,7 @@ Here, we also check if there is an ID for the file."
target))))) target)))))
(setq type "id" target id)) (setq type "id" target id))
(when (string-equal type "file") (when (string-equal type "file")
(setq target (org-roam-link-get-path target))) (setq target (org-roam-link-get-path target link-type)))
(setq description (setq description
(if (functionp org-roam-link-title-format) (if (functionp org-roam-link-title-format)
(funcall org-roam-link-title-format description type) (funcall org-roam-link-title-format description type)
@ -1307,24 +1308,24 @@ file."
(org-roam--org-roam-file-p file)) (org-roam--org-roam-file-p file))
(org-roam-db--clear-file (expand-file-name file)))) (org-roam-db--clear-file (expand-file-name file))))
(defun org-roam--get-link-replacement (old-path new-path old-desc new-desc) (defun org-roam--get-link-replacement (old-path new-path &optional old-desc new-desc)
"Create replacement text for link at point if OLD-PATH is a match. "Create replacement text for link at point if OLD-PATH is a match.
Will update link to NEW-PATH. If OLD-DESC is set, and is not the Will update link to NEW-PATH. If OLD-DESC is set, and is not the
same as the link description, it is assumed that the user has same as the link description, it is assumed that the user has
modified the description, and the description will not be modified the description, and the description will not be
updated. Else, update with NEW-DESC." updated. Else, update with NEW-DESC."
(when-let ((link (org-element-lineage (org-element-context) '(link) t))) (let (type path link-type label new-label)
(let ((type (org-element-property :type link)) (when-let ((link (org-element-lineage (org-element-context) '(link) t)))
(path (org-element-property :path link))) (setq type (org-element-property :type link)
path (org-element-property :path link))
(when (and (string-equal (expand-file-name path) old-path) (when (and (string-equal (expand-file-name path) old-path)
(org-in-regexp org-link-bracket-re 1)) (org-in-regexp org-link-bracket-re 1))
(let* ((label (if (match-end 2) (setq link-type (when (file-name-absolute-p path) 'absolute)
(match-string-no-properties 2) label (if (match-end 2)
(org-link-unescape (match-string-no-properties 1)))) (match-string-no-properties 2)
(new-label (if (string-equal label old-desc) (org-link-unescape (match-string-no-properties 1))))
new-desc (setq new-label (if (string-equal label old-desc) new-desc label))
label))) (org-roam-format-link new-path new-label type link-type)))))
(org-roam-format-link new-path new-label type))))))
(defun org-roam--replace-link (old-path new-path &optional old-desc new-desc) (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. "Replace Org-roam file links with path OLD-PATH to path NEW-PATH.
@ -1332,13 +1333,10 @@ If OLD-DESC is passed, and is not the same as the link
description, it is assumed that the user has modified the description, it is assumed that the user has modified the
description, and the description will not be updated. Else, description, and the description will not be updated. Else,
update with NEW-DESC." update with NEW-DESC."
(save-excursion (org-with-point-at 1
(goto-char (point-min)) (while (re-search-forward org-link-bracket-re nil t)
(while (re-search-forward org-link-any-re nil t) (when-let ((link (save-match-data (org-roam--get-link-replacement old-path new-path old-desc new-desc))))
(when-let ((new-link (save-match-data (replace-match link)))))
(org-roam--get-link-replacement
old-path new-path old-desc new-desc))))
(replace-match new-link)))))
(defun org-roam--fix-relative-links (old-path) (defun org-roam--fix-relative-links (old-path)
"Fix file-relative links in current buffer. "Fix file-relative links in current buffer.
@ -1440,36 +1438,34 @@ When NEW-FILE-OR-DIR is a directory, we use it to compute the new file path."
(not (backup-file-name-p new-file)) (not (backup-file-name-p new-file))
(org-roam--org-roam-file-p old-file)) (org-roam--org-roam-file-p old-file))
(org-roam-db--ensure-built) (org-roam-db--ensure-built)
(let* ((old-path (expand-file-name old-file)) (let* ((new-buffer (or (find-buffer-visiting new-file)
(new-path (expand-file-name new-file)) (find-file-noselect new-file)))
(new-buffer (or (find-buffer-visiting new-path)
(find-file-noselect new-path)))
(files-affected (org-roam-db-query [:select :distinct [source] (files-affected (org-roam-db-query [:select :distinct [source]
:from links :from links
:where (= dest $s1)] :where (= dest $s1)]
old-path))) old-file)))
;; Remove database entries for old-file.org ;; Remove database entries for old-file.org
(org-roam-db--clear-file old-file) (org-roam-db--clear-file old-file)
;; Replace links from old-file.org -> new-file.org in all Org-roam files with these links ;; Replace links from old-file.org -> new-file.org in all Org-roam files with these links
(mapc (lambda (file) (mapc (lambda (file)
(setq file (if (string-equal (expand-file-name (car file)) old-path) (setq file (if (string-equal (car file) old-file)
new-path new-file
(car file))) (car file)))
(with-current-buffer (or (find-buffer-visiting file) (with-current-buffer (or (find-buffer-visiting file)
(find-file-noselect file)) (find-file-noselect file))
(org-roam--replace-link old-path new-path) (org-roam--replace-link old-file new-file)
(save-buffer) (save-buffer)
(org-roam-db--update-file))) (org-roam-db--update-file)))
files-affected) files-affected)
;; If the new path is in a different directory, relative links ;; If the new path is in a different directory, relative links
;; will break. Fix all file-relative links: ;; will break. Fix all file-relative links:
(unless (string= (file-name-directory old-path) (unless (string= (file-name-directory old-file)
(file-name-directory new-path)) (file-name-directory new-file))
(with-current-buffer new-buffer (with-current-buffer new-buffer
(org-roam--fix-relative-links old-path) (org-roam--fix-relative-links old-file)
(save-buffer))) (save-buffer)))
(when (org-roam--org-roam-file-p new-file) (when (org-roam--org-roam-file-p new-file)
(org-roam-db--update-file new-path)))))) (org-roam-db--update-file new-file))))))
(defun org-roam--id-new-advice (&rest _args) (defun org-roam--id-new-advice (&rest _args)
"Update the database if a new Org ID is created." "Update the database if a new Org ID is created."