(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
- [#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
- [#1252](https://github.com/org-roam/org-roam/issues/1252) respect original link type during automatic replacement
## 1.2.2 (06-10-2020)

View File

@ -159,11 +159,11 @@ If there is no corresponding headline, return nil."
(org-id-get-create))))))))
;;; 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.
Respect `org-link-file-path-type', see the variable documentation for details.
If DIR is passed, use DIR as the default directory."
(pcase org-roam-link-file-path-type
If TYPE is non-nil, create a link of TYPE. Otherwise, respect
`org-link-file-path-type'."
(pcase (or type org-roam-link-file-path-type)
('absolute
(abbreviate-file-name (expand-file-name path)))
('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)))
(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.
TYPE defaults to \"file\".
Here, we also check if there is an ID for the file."
TYPE defaults to \"file\". LINK-TYPE is the type of file link to
be generated. Here, we also check if there is an ID for the
file."
(setq type (or type "file"))
(when-let ((id (and org-roam-prefer-id-links
(string-equal type "file")
@ -839,7 +840,7 @@ Here, we also check if there is an ID for the file."
target)))))
(setq type "id" target id))
(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
(if (functionp org-roam-link-title-format)
(funcall org-roam-link-title-format description type)
@ -1307,24 +1308,24 @@ file."
(org-roam--org-roam-file-p 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.
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
modified the description, and the description will not be
updated. Else, update with NEW-DESC."
(let (type path link-type label new-label)
(when-let ((link (org-element-lineage (org-element-context) '(link) t)))
(let ((type (org-element-property :type link))
(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)
(org-in-regexp org-link-bracket-re 1))
(let* ((label (if (match-end 2)
(setq link-type (when (file-name-absolute-p path) 'absolute)
label (if (match-end 2)
(match-string-no-properties 2)
(org-link-unescape (match-string-no-properties 1))))
(new-label (if (string-equal label old-desc)
new-desc
label)))
(org-roam-format-link new-path new-label type))))))
(setq new-label (if (string-equal label old-desc) new-desc label))
(org-roam-format-link new-path new-label type link-type)))))
(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.
@ -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, and the description will not be updated. Else,
update with NEW-DESC."
(save-excursion
(goto-char (point-min))
(while (re-search-forward org-link-any-re nil t)
(when-let ((new-link (save-match-data
(org-roam--get-link-replacement
old-path new-path old-desc new-desc))))
(replace-match new-link)))))
(org-with-point-at 1
(while (re-search-forward org-link-bracket-re nil t)
(when-let ((link (save-match-data (org-roam--get-link-replacement old-path new-path old-desc new-desc))))
(replace-match link)))))
(defun org-roam--fix-relative-links (old-path)
"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))
(org-roam--org-roam-file-p old-file))
(org-roam-db--ensure-built)
(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)))
(let* ((new-buffer (or (find-buffer-visiting new-file)
(find-file-noselect new-file)))
(files-affected (org-roam-db-query [:select :distinct [source]
:from links
:where (= dest $s1)]
old-path)))
old-file)))
;; Remove database entries for old-file.org
(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 (expand-file-name (car file)) old-path)
new-path
(setq file (if (string-equal (car file) old-file)
new-file
(car file)))
(with-current-buffer (or (find-buffer-visiting file)
(find-file-noselect file))
(org-roam--replace-link old-path new-path)
(org-roam--replace-link old-file new-file)
(save-buffer)
(org-roam-db--update-file)))
files-affected)
;; If the new path is in a different directory, relative links
;; will break. Fix all file-relative links:
(unless (string= (file-name-directory old-path)
(file-name-directory new-path))
(unless (string= (file-name-directory old-file)
(file-name-directory new-file))
(with-current-buffer new-buffer
(org-roam--fix-relative-links old-path)
(org-roam--fix-relative-links old-file)
(save-buffer)))
(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)
"Update the database if a new Org ID is created."