diff --git a/README.org b/README.org index edeccc5..e1d5914 100644 --- a/README.org +++ b/README.org @@ -105,6 +105,12 @@ the document to annotate. *** new (all formats) + - ~org-noter-enable-sync-renames~ :: Optional feature to update document + paths when renaming or moving document files or notes files. This allows + you to change your mind later about the names and locations of your + document files and notes files without having to manually update all the + links. + - ~org-noter-toggle-notes-window-location~ (~M-T~) :: Toggle between horizontal and vertical document/notes layout. diff --git a/org-noter-core.el b/org-noter-core.el index 8cfc3b3..302f3c5 100644 --- a/org-noter-core.el +++ b/org-noter-core.el @@ -1744,6 +1744,9 @@ This is delegated to each document mode (eg pdf)." DOCUMENT-PATH is the original filename. NEW-DOCUMENT-PATH is the new filename. +Call `org-noter-enable-sync-renames' to enable this feature and +`org-noter-disable-sync-renames' to disable it. + This advice runs after `dired-rename-file' completes successfully on files with `file-name-extension' in `org-noter--doc-extensions'. @@ -1757,8 +1760,8 @@ of the notes file will not be changed, as there may be other documents referenced in the notes file. An `org-noter' session can still be initiated from the notes file, but not vice-versa, nor will future renames of the document be synced in the notes -file. -" +file." + (when (and (member-ignore-case (file-name-extension document-path) org-noter--doc-extensions) (not (file-exists-p document-path)) @@ -1820,9 +1823,63 @@ file. (rename-file notes-path new-notes-path))) (throw 'break t)))))))))))) -(advice-add 'dired-rename-file :after 'org-noter--sync-doc-rename-in-notes) -;;uncomment or eval next line to disable. -;;(advice-remove 'dired-rename-file 'org-noter--sync-doc-rename-in-notes) +(defun org-noter--sync-notes-rename-in-notes (notes-path new-notes-path &optional _ok-if-already-exists) + "Update org-noter references to docs when notes file is moved. + +NOTES-PATH is the original filename. +NEW-NOTES-PATH is the new filename. + +Call `org-noter-enable-sync-renames' to enable this feature and +`org-noter-disable-sync-renames' to disable it. + +This advice runs after `dired-rename-file' moves an '.org' file to +a different directory. + +If the notes file is moved to a path below any of its linked +documents, a warning will be issued, but the sync will proceed. +An `org-noter' session can still be initiated from the notes +file, but not vice-versa, but future renames of the notes file +will continue to sync the document references." + + (when (and (string-equal (file-name-extension notes-path) "org") + (not (file-exists-p notes-path)) + (file-exists-p new-notes-path) + (not (string-equal (file-name-directory notes-path) + (file-name-directory new-notes-path)))) + ;; continue if it is an org file + ;; and the rename was successful + ;; and the directory changes + (let* (;;(document-name (file-name-nondirectory document-path)) + ;;(document-base (file-name-base document-name)) + ( notes-directory (file-name-directory notes-path)) + (new-notes-directory (file-name-directory new-notes-path)) + (problem-path-list nil) + (this-org-file-uses-noter nil)) + + ;; update each document's relative path + (with-temp-buffer + (insert-file-contents new-notes-path) + (org-with-point-at (point-min) + (while (re-search-forward (org-re-property org-noter-property-doc-file) nil t) + (let* (( doc-file-rel-path (match-string 3)) + ( doc-file-abs-path (expand-file-name doc-file-rel-path notes-directory)) + (new-doc-file-rel-path (file-relative-name doc-file-abs-path new-notes-directory))) + (setq this-org-file-uses-noter t) + ;; sync the document path to the new notes file + (org-set-property org-noter-property-doc-file new-doc-file-rel-path) + (next-line) + ;; add problematic paths to the list + (when (string-prefix-p "../" new-doc-file-rel-path) + (push new-doc-file-rel-path problem-path-list))))) + ;; warn against docs that reside above notes in path + (when problem-path-list + (let ((msg (format-message + "Notes file has moved below some documents. `org-noter' will not be able to find the notes file from the document path for these files:"))) + (dolist (doc-path problem-path-list) + (setq msg (concat msg (format-message "\n%s" doc-path)))) + (display-warning 'org-noter msg :warning))) + (when this-org-file-uses-noter + (write-file new-notes-path nil)))))) ;; -------------------------------------------------------------------------------- ;;; User commands @@ -2474,6 +2531,28 @@ As such, it will only work when the notes window exists." (user-error "There is no next note")))) (select-window (org-noter--get-doc-window))) +(defun org-noter-enable-sync-renames () + "Enable `dired-rename-file' advice for moving docs and notes. +Enables `org-noter--sync-doc-rename-in-notes' and +`org-noter--sync-notes-rename-in-notes' as advice :after +`dired-rename-file'. + +In dired, this affects the renaming of supported document files +and .org files. + +This feature can be turn off with `org-noter-disable-sync-renames'." + (interactive) + (advice-add 'dired-rename-file :after 'org-noter--sync-doc-rename-in-notes) + (advice-add 'dired-rename-file :after 'org-noter--sync-notes-rename-in-notes)) + +(defun org-noter-disable-sync-renames () + "Disable `dired-rename-file' advice for moving docs and notes. +Run this if you change your mind about using the rename +synchronization features." + (interactive) + (advice-remove 'dired-rename-file 'org-noter--sync-doc-rename-in-notes) + (advice-remove 'dired-rename-file 'org-noter--sync-notes-rename-in-notes)) + (define-minor-mode org-noter-doc-mode "Minor mode for the document buffer. Keymap: