emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [BUG] Attachments not resolved correctly from symlinked Org files
@ 2024-04-28 20:22 Karthik Chikmagalur
  2024-04-30  9:09 ` Ihor Radchenko
  0 siblings, 1 reply; 6+ messages in thread
From: Karthik Chikmagalur @ 2024-04-28 20:22 UTC (permalink / raw)
  To: emacs-orgmode

Attachment paths are not resolved correctly when the Org file is
symlinked elsewhere. This may or may not be a bug, but I think it's
undesired behavior:

1. Create an Org file somewhere, say ~/Desktop/test.org.

2. In test.org, create an attachment: `C-c C-a m' as a file.  Either the
   "copy" or "move" attachment method can be used.

3. Symlink test.org from elsewhere, say

/tmp/test.org -> ~/Desktop/test.org

4. In a fresh Emacs session, open /tmp/test.org and try to open the
attachment directory (`C-c C-a f').

Two things happen:

- An empty directory is created, like
  /tmp/data/48/2697ee-913c-4eee-b1fb-636416d3fb6b

- The original attachment can't be found, since it's actually in
  ~/Desktop/data/48/2697ee-913c-4eee-b1fb-636416d3fb6b

Tested with `emacs -q' with Org 9.6.23, and with commit
1ae978f940c0f88473f2232177c63a0de7fb7a1c from two weeks ago.

Karthik


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] Attachments not resolved correctly from symlinked Org files
  2024-04-28 20:22 [BUG] Attachments not resolved correctly from symlinked Org files Karthik Chikmagalur
@ 2024-04-30  9:09 ` Ihor Radchenko
  2024-05-01 15:18   ` Karthik Chikmagalur
  0 siblings, 1 reply; 6+ messages in thread
From: Ihor Radchenko @ 2024-04-30  9:09 UTC (permalink / raw)
  To: Karthik Chikmagalur; +Cc: emacs-orgmode

Karthik Chikmagalur <karthikchikmagalur@gmail.com> writes:

> Attachment paths are not resolved correctly when the Org file is
> symlinked elsewhere. This may or may not be a bug, but I think it's
> undesired behavior:
> ...
> 3. Symlink test.org from elsewhere, say
>
> /tmp/test.org -> ~/Desktop/test.org
> ...
> - An empty directory is created, like
>   /tmp/data/48/2697ee-913c-4eee-b1fb-636416d3fb6b
>
> - The original attachment can't be found, since it's actually in
>   ~/Desktop/data/48/2697ee-913c-4eee-b1fb-636416d3fb6b

I can see the problem.
But what would you expect to happen if there was no attachment in the
original directory? Should the attachment be created relative to the
original file? To the symlink?

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] Attachments not resolved correctly from symlinked Org files
  2024-04-30  9:09 ` Ihor Radchenko
@ 2024-05-01 15:18   ` Karthik Chikmagalur
  2024-05-04  7:52     ` Ihor Radchenko
  0 siblings, 1 reply; 6+ messages in thread
From: Karthik Chikmagalur @ 2024-05-01 15:18 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode

> I can see the problem.
> But what would you expect to happen if there was no attachment in the
> original directory? Should the attachment be created relative to the
> original file? To the symlink?

I don't know.  I would expect the attachment to always be created
relative to the original file, but other users might have the opposite
expectation.

Karthik


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] Attachments not resolved correctly from symlinked Org files
  2024-05-01 15:18   ` Karthik Chikmagalur
@ 2024-05-04  7:52     ` Ihor Radchenko
  2024-06-04  9:33       ` Ihor Radchenko
  0 siblings, 1 reply; 6+ messages in thread
From: Ihor Radchenko @ 2024-05-04  7:52 UTC (permalink / raw)
  To: Karthik Chikmagalur; +Cc: emacs-orgmode

Karthik Chikmagalur <karthikchikmagalur@gmail.com> writes:

>> I can see the problem.
>> But what would you expect to happen if there was no attachment in the
>> original directory? Should the attachment be created relative to the
>> original file? To the symlink?
>
> I don't know.  I would expect the attachment to always be created
> relative to the original file, but other users might have the opposite
> expectation.

What about the approach we already use in
`org-attach-id-to-path-function-list' - check if an attachment directory
already exists, generated using any rule, and only if not, create a new?

Similarly, in `org-attach-dir', we can first check local attachment
directory and return it if it exists. Then, we check attachment
directory for the symlink source, and return it when it exists.
If none exists, create attachment locally or relative to the symlink
source, according to some customization. The default will be creating
locally, to follow the existing behavior.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [BUG] Attachments not resolved correctly from symlinked Org files
  2024-05-04  7:52     ` Ihor Radchenko
@ 2024-06-04  9:33       ` Ihor Radchenko
  2024-06-14 11:44         ` Ihor Radchenko
  0 siblings, 1 reply; 6+ messages in thread
From: Ihor Radchenko @ 2024-06-04  9:33 UTC (permalink / raw)
  To: Karthik Chikmagalur; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 667 bytes --]

Ihor Radchenko <yantar92@posteo.net> writes:

> What about the approach we already use in
> `org-attach-id-to-path-function-list' - check if an attachment directory
> already exists, generated using any rule, and only if not, create a new?
>
> Similarly, in `org-attach-dir', we can first check local attachment
> directory and return it if it exists. Then, we check attachment
> directory for the symlink source, and return it when it exists.
> If none exists, create attachment locally or relative to the symlink
> source, according to some customization. The default will be creating
> locally, to follow the existing behavior.

See the attached tentative patch.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-attach-dir-from-id-Search-existing-attachments-f.patch --]
[-- Type: text/x-patch, Size: 4855 bytes --]

From add9e512fa80e53bfa396ebc4d0bdf35b3bee089 Mon Sep 17 00:00:00 2001
Message-ID: <add9e512fa80e53bfa396ebc4d0bdf35b3bee089.1717493559.git.yantar92@posteo.net>
From: Ihor Radchenko <yantar92@posteo.net>
Date: Tue, 4 Jun 2024 11:30:44 +0200
Subject: [PATCH] org-attach-dir-from-id: Search existing attachments for
 symlinks

* lisp/org-attach.el (org-attach-dir-from-id): When current buffer
displays a symlinked file, search for existing attachments in the
original file dir.
* etc/ORG-NEWS (=org-attach= now considers symlinked files when
searching pre-existing attach dirs): Announce the change.

Reported-by: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
Link: https://orgmode.org/list/87seyydnf7.fsf@localhost
---
 etc/ORG-NEWS       |  8 ++++++++
 lisp/org-attach.el | 39 +++++++++++++++++++++++++++++----------
 2 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 4b0b77ca8..4ac88f139 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -41,6 +41,14 @@ all the references are resolved in the generated png.
 # This also includes changes in function behavior from Elisp perspective.
 
 ** Miscellaneous
+*** =org-attach= now considers symlinked files when searching pre-existing attach dirs
+
+When Org buffer is opened from a symlink, Org mode looks into the
+original file directory when searching if an attach directory already exists.
+This way, attachments will remain accessible when opening symlinked Org file.
+
+When no attach dir exists, Org mode will still prefer creating it in
+the "default" directory - where the symlink is located.
 
 * Version 9.7
 
diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 16f6e1e29..d4bff03ad 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -433,22 +433,42 @@ (defun org-attach-dir-get-create ()
       (make-directory attach-dir t))
     attach-dir))
 
-(defun org-attach-dir-from-id (id  &optional existing)
+(defun org-attach-dir-from-id (id &optional existing)
   "Return a folder path based on `org-attach-id-dir' and ID.
 Try id-to-path functions in `org-attach-id-to-path-function-list'
 ignoring nils.  If EXISTING is non-nil, then return the first path
-found in the filesystem.  Otherwise return the first non-nil value."
+found in the filesystem.  Otherwise return the first non-nil value.
+
+The existing paths are searched in
+1. `org-attach-id-dir';
+2. in \"data/\" dir - the default value of `org-attach-id-dir';
+3. if current buffer is a symlink, (1) and (2) searches are repeated
+   in the `default-directory' of symlink target."
   (let ((fun-list org-attach-id-to-path-function-list)
         (base-dir (expand-file-name org-attach-id-dir))
-        (default-base-dir (expand-file-name "data/"))
+        (fallback-dirs (list (expand-file-name "data/")))
         preferred first)
+    (when (and (buffer-file-name)
+               (file-symlink-p (buffer-file-name)))
+      (let ((default-directory
+             (file-name-directory
+              (file-truename (buffer-file-name)))))
+        (cl-pushnew (expand-file-name org-attach-id-dir) fallback-dirs)
+        (cl-pushnew (expand-file-name "data/") fallback-dirs)))
+    (setq fallback-dirs (delete base-dir fallback-dirs))
+    (setq fallback-dirs (seq-filter #'file-directory-p fallback-dirs))
     (while (and fun-list
                 (not preferred))
       (let* ((name (funcall (car fun-list) id))
              (candidate (and name (expand-file-name name base-dir)))
-             ;; Try the default value `org-attach-id-dir' as a fallback.
-             (candidate2 (and name (not (equal base-dir default-base-dir))
-                              (expand-file-name name default-base-dir))))
+             ;; Try the default value `org-attach-id-dir', and linked
+             ;; dirs if buffer is a symlink as a fallback.
+             (fallback-candidates
+              (and name (mapcar
+                         (lambda (dir) (expand-file-name name dir))
+                         fallback-dirs)))
+             (fallback-candidates
+              (seq-filter #'file-directory-p fallback-candidates)))
         (setq fun-list (cdr fun-list))
         (when candidate
           (if (or (not existing) (file-directory-p candidate))
@@ -456,10 +476,9 @@ (defun org-attach-dir-from-id (id  &optional existing)
             (unless first
               (setq first candidate)))
           (when (and existing
-                     candidate2
-                     (not (file-directory-p candidate))
-                     (file-directory-p candidate2))
-            (setq preferred candidate2)))))
+                     fallback-candidates
+                     (not (file-directory-p candidate)))
+            (setq preferred (car fallback-candidates))))))
     (or preferred first)))
 
 (defun org-attach-check-absolute-path (dir)
-- 
2.45.1


[-- Attachment #3: Type: text/plain, Size: 225 bytes --]



-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [BUG] Attachments not resolved correctly from symlinked Org files
  2024-06-04  9:33       ` Ihor Radchenko
@ 2024-06-14 11:44         ` Ihor Radchenko
  0 siblings, 0 replies; 6+ messages in thread
From: Ihor Radchenko @ 2024-06-14 11:44 UTC (permalink / raw)
  To: Karthik Chikmagalur; +Cc: emacs-orgmode

Ihor Radchenko <yantar92@posteo.net> writes:

> Ihor Radchenko <yantar92@posteo.net> writes:
>
>> What about the approach we already use in
>> `org-attach-id-to-path-function-list' - check if an attachment directory
>> already exists, generated using any rule, and only if not, create a new?
>>
>> Similarly, in `org-attach-dir', we can first check local attachment
>> directory and return it if it exists. Then, we check attachment
>> directory for the symlink source, and return it when it exists.
>> If none exists, create attachment locally or relative to the symlink
>> source, according to some customization. The default will be creating
>> locally, to follow the existing behavior.
>
> See the attached tentative patch.

Applied, onto main.
https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=1686b6f3b

As for creating attachment directories in the symlink source dir, I
suggest posting a feature request. Then, we will see if such a feature
would be useful for people.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-06-14 11:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-28 20:22 [BUG] Attachments not resolved correctly from symlinked Org files Karthik Chikmagalur
2024-04-30  9:09 ` Ihor Radchenko
2024-05-01 15:18   ` Karthik Chikmagalur
2024-05-04  7:52     ` Ihor Radchenko
2024-06-04  9:33       ` Ihor Radchenko
2024-06-14 11:44         ` Ihor Radchenko

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).