From 3bafeda53c52c6b9fc3a611cbcb23bfb4594ca64 Mon Sep 17 00:00:00 2001
From: Eric Danan <eric.danan@u-cergy.fr>
Date: Thu, 21 Jun 2018 15:45:32 +0200
Subject: [PATCH] org-attach: Add mechanism to store attachment to current
 buffer

* lisp/org-attach.el (org-stored-attachments): New variable.
(org-store-attachment): New autoloaded, interactive command to store
an attachment to the current buffer in the above variable.
(org-attach-attach): If called interactively and there are stored
attachments, prompt to select one of them.  Also if the attachment is
to a buffer not visiting a file, fallback to writing the buffer rather
than using the specified or default attachment method.
---
 lisp/org-attach.el | 47 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 192815f4..df8e458d 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -152,6 +152,9 @@ (defcustom org-attach-annex-auto-get 'ask
 	  (const :tag "always get from annex if necessary" t)
 	  (const :tag "never get from annex" nil)))
 
+(defvar org-stored-attachments nil
+  "Contains the attachments stored with `org-store-attachment'.")
+
 ;;;###autoload
 (defun org-attach ()
   "The dispatcher for attachment commands.
@@ -193,7 +196,7 @@ (defun org-attach ()
 s       Set a specific attachment directory for this entry or reset to default.
 i       Make children of the current entry inherit its attachment directory.")))
 	  (org-fit-window-to-buffer (get-buffer-window "*Org Attach*"))
-	  (message "Select command: [acmlzoOfFdD]")
+	  (message "Select command: [acmlyunzoOfFdD]")
 	  (setq c (read-char-exclusive))
 	  (and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*"))))
       (cond
@@ -397,14 +400,22 @@ (defun org-attach-attach (file &optional visit-dir method)
 `org-attach-method'."
   (interactive
    (list
-    (read-file-name "File to keep as an attachment:"
-                    (or (progn
-                          (require 'dired-aux)
-                          (dired-dwim-target-directory))
-                        default-directory))
+    (if org-stored-attachments
+	(let ((file (org-completing-read "Attachment: "
+					 org-stored-attachments)))
+	  (setq org-stored-attachments
+		(remove file org-stored-attachments))
+	  file)
+      (read-file-name "File to keep as an attachment:"
+                      (or (progn
+                            (require 'dired-aux)
+                            (dired-dwim-target-directory))
+                          default-directory)))
     current-prefix-arg
     nil))
-  (setq method (or method org-attach-method))
+  (setq method (if (file-exists-p file)
+		   (or method org-attach-method)
+		 'buf))
   (let ((basename (file-name-nondirectory file)))
     (when (and org-attach-file-list-property (not org-attach-inherited))
       (org-entry-add-to-multivalued-property
@@ -416,12 +427,15 @@ (defun org-attach-attach (file &optional visit-dir method)
        ((eq method 'cp) (copy-file file fname))
        ((eq method 'ln) (add-name-to-file file fname))
        ((eq method 'lns) (make-symbolic-link file fname))
-       ((eq method 'url) (url-copy-file file fname)))
+       ((eq method 'url) (url-copy-file file fname))
+       ((eq method 'buf) (with-current-buffer file
+			   (write-file fname t))))
       (when org-attach-commit
         (org-attach-commit))
       (org-attach-tag)
       (cond ((eq org-attach-store-link-p 'attached)
              (org-attach-store-link fname))
+	    ((eq method 'buf))
             ((eq org-attach-store-link-p t)
              (org-attach-store-link file)))
       (if visit-dir
@@ -613,6 +627,23 @@ (defun org-attach-dired-to-subtree (files)
       (org-attach-attach file))
     (select-window start-win)))
 
+;;;###autoload
+(defun org-store-attachment (file)
+ "Store an attachment to the current buffer.
+\\<org-mode-map>
+This attachment is added to `org-stored-attachments' and can later be inserted
+into an Org buffer with `org-attach' (`\\[org-attach]').
+
+If the current buffer is a dired buffer, store an attachments to
+the file at point instead."
+ (interactive
+  (list (if (derived-mode-p 'dired-mode)
+	    (ignore-errors (dired-get-filename))
+	  (or (buffer-file-name (buffer-base-buffer))
+	      (buffer-name (buffer-base-buffer))))))
+ (when file
+   (push file org-stored-attachments)))
+   
 
 
 (add-hook 'org-archive-hook 'org-attach-archive-delete-maybe)
-- 
2.17.0

