Browse Source

Allow different methods to get an attachment into the directory.

Supported methods are copy, link, and move.
Carsten Dominik 16 years ago
parent
commit
8518c9ed81
4 changed files with 106 additions and 38 deletions
  1. 18 1
      ORGWEBPAGE/Changes.org
  2. 28 21
      doc/org.texi
  3. 6 1
      lisp/ChangeLog
  4. 54 15
      lisp/org-attach.el

+ 18 - 1
ORGWEBPAGE/Changes.org

@@ -10,11 +10,28 @@
 #+LINK_UP: index.html
 #+LINK_UP: index.html
 #+LINK_HOME: http://orgmode.org
 #+LINK_HOME: http://orgmode.org
 
 
-* Version 6.08
+
+* Version 6.09 (in preparation)
 :PROPERTIES:
 :PROPERTIES:
 :VISIBILITY: content
 :VISIBILITY: content
 :END:
 :END:
 
 
+** Details
+*** Changes to the attachment system
+
+    - The default method to attach a file is now to copy it
+      instead of moving it.
+    - You can modify the default method using the variable
+      `org-attach-method'.  I believe that most Unix people want
+      to set it to `ln' to create hard links.
+    - The keys =c=, =m=, and =l= specifically select =copy=,
+      =move=, or =link=, respectively, as the attachment method
+      for a file, overruling  `org-attach-method'.
+    - To create a new attachment as an Emacs buffer, you have not
+      now use =n= instead of =c=.
+
+* Version 6.08
+
 ** Incompatible changes
 ** Incompatible changes
 
 
    - Changes in the structure of IDs, see [[*The%20default%20structure%20of%20IDs%20has%20changed][here]] for details.
    - Changes in the structure of IDs, see [[*The%20default%20structure%20of%20IDs%20has%20changed][here]] for details.

+ 28 - 21
doc/org.texi

@@ -775,9 +775,9 @@ CONTENTS view up to headlines of level N will be shown.  Note that inside
 tables, @kbd{S-@key{TAB}} jumps to the previous field.
 tables, @kbd{S-@key{TAB}} jumps to the previous field.
 
 
 @cindex show all, command
 @cindex show all, command
-@kindex C-c C-a C-a
-@item C-c C-a C-a
-Show all.
+@kindex C-u C-u C-u @key{TAB}
+@item C-u C-u C-u @key{TAB}
+Show all, including drawers.
 @kindex C-c C-r
 @kindex C-c C-r
 @item C-c C-r
 @item C-c C-r
 Reveal context around point, showing the current entry, the following heading
 Reveal context around point, showing the current entry, the following heading
@@ -5166,21 +5166,17 @@ It is often useful to associate reference material with an outline node/task.
 Small chunks of plain text can simply be stored in the subtree of a project.
 Small chunks of plain text can simply be stored in the subtree of a project.
 Hyperlinks (@pxref{Hyperlinks}) can be used to establish associations with
 Hyperlinks (@pxref{Hyperlinks}) can be used to establish associations with
 files that live elsewhere on your computer or in the cloud, like emails or
 files that live elsewhere on your computer or in the cloud, like emails or
-source code files belonging to a project.  However, you may also have files
-that only belong to a given project and that you would like to store in a
-directory belonging to an outline node.
-
-Org allows to associate an arbitary number of files with each indivdual task.
-These files are moved to special directories named by the unique ID of each
-entry.  These directories are located in the @file{data} directory which
-lives in the same directory where your org-file lives@footnote{If you move
-entries or Org-files from one directory to the next, you may want to
-configure @code{org-attach-directory} to contain an absolute path.}.  If you
-initilize this directory with @code{git-init}, Org will automaically commit
-changes when it see them.  The attachment system has been contributed to Org
-by John Wiegley.
-
-The following commands deal with attachments.
+source code files belonging to a project.  Another method is @i{attachments},
+which are files located in a directory belonging to an outline node.  Org
+uses directories named by the unique ID of each entry.  These directories are
+located in the @file{data} directory which lives in the same directory where
+your org-file lives@footnote{If you move entries or Org-files from one
+directory to the next, you may want to configure @code{org-attach-directory}
+to contain an absolute path.}.  If you initilize this directory with
+@code{git-init}, Org will automaically commit changes when it sees them.  The
+attachment system has been contributed to Org by John Wiegley.
+
+@noindent The following commands deal with attachments.
 
 
 @table @kbd
 @table @kbd
 
 
@@ -5193,10 +5189,17 @@ to select a command:
 @table @kbd
 @table @kbd
 @kindex C-c C-a a 
 @kindex C-c C-a a 
 @item a 
 @item a 
-Select a file and move it into the task's attachment directory.
+Select a file and move it into the task's attachment directory.  The file
+will be copied, moved, or linked, depending on @code{org-attach-method}.
 
 
 @kindex C-c C-a c
 @kindex C-c C-a c
-@item c
+@kindex C-c C-a m 
+@kindex C-c C-a l 
+@item c/m/l
+Attach a file using the copy/move/link method.
+
+@kindex C-c C-a n
+@item n
 Create a new attachment as an Emacs buffer.
 Create a new attachment as an Emacs buffer.
 
 
 @kindex C-c C-a z
 @kindex C-c C-a z
@@ -5207,7 +5210,7 @@ attachments yourself.
 @kindex C-c C-a o
 @kindex C-c C-a o
 @item o
 @item o
 Open current task's attachment.  If there are more than one, prompt for a
 Open current task's attachment.  If there are more than one, prompt for a
-file name first.
+file name first.  Opening will follow the rules set by @code{org-file-apps}.
 
 
 @kindex C-c C-a O
 @kindex C-c C-a O
 @item O
 @item O
@@ -5221,6 +5224,10 @@ Open the current task's attachment directory.
 @item F
 @item F
 Also open the directory, but force using @code{dired} in Emacs.
 Also open the directory, but force using @code{dired} in Emacs.
 
 
+@kindex C-c C-a d
+@item d
+Select and delete a single attachment.
+
 @kindex C-c C-a D
 @kindex C-c C-a D
 @item D
 @item D
 Delete all of a task's attachments.  A safer way is to open the directory in
 Delete all of a task's attachments.  A safer way is to open the directory in

+ 6 - 1
lisp/ChangeLog

@@ -1,8 +1,13 @@
+2008-10-07  Carsten Dominik  <dominik@science.uva.nl>
+
+	* org-attach.el (org-attach): Support the new keys.
+	(org-attach-method): New option.
+
 2008-10-06  Carsten Dominik  <dominik@science.uva.nl>
 2008-10-06  Carsten Dominik  <dominik@science.uva.nl>
 
 
 	* org-bbdb.el (org-bbdb-anniversaries): Fix but with 29 Feb/1
 	* org-bbdb.el (org-bbdb-anniversaries): Fix but with 29 Feb/1
 	March.
 	March.
-	
+
 	* org.el (org-remove-uniherited-tags): Fix reverse interpretation
 	* org.el (org-remove-uniherited-tags): Fix reverse interpretation
 	of the list value o `org-use-tag-inheritance'.
 	of the list value o `org-use-tag-inheritance'.
 
 

+ 54 - 15
lisp/org-attach.el

@@ -63,6 +63,19 @@ where the Org file lives."
 	  (const :tag "None" nil)
 	  (const :tag "None" nil)
 	  (string :tag "Tag")))
 	  (string :tag "Tag")))
 
 
+(defcustom org-attach-method 'cp
+  "Preferred method to attach a file.
+Allowed values are:
+
+mv    rename the file to move it into the attachment directory
+cp    copy the file
+mv    create a hard link when possible.  If not, fall back to copy."
+  :group 'org-attach
+  :type '(choice
+	  (const :tag "Copy" cp)
+	  (const :tag "Move/Rename" mv)
+	  (const :tag "Link" ln)))
+
 (defcustom org-attach-expert nil
 (defcustom org-attach-expert nil
   "Non-nil means do not show the splash buffer with the attach dispatcher."
   "Non-nil means do not show the splash buffer with the attach dispatcher."
   :group 'org-attach
   :group 'org-attach
@@ -90,31 +103,39 @@ Shows a list of commands and prompts for another key to execute a command."
 	    (with-output-to-temp-buffer "*Org Attach*"
 	    (with-output-to-temp-buffer "*Org Attach*"
 	      (princ "Select an Attachment Command:
 	      (princ "Select an Attachment Command:
 
 
-a    Select a file and move it into the task's attachment  directory.
-c    Create a new attachment, as an Emacs buffer.
-z    Synchronize the current task with its attachment
-     directory, in case you added attachments yourself.
+a       Select a file and attach it to the task, using `org-attach-method'.
+c/m/l   Attach a file using copy/move/link method.
+n       Create a new attachment, as an Emacs buffer.
+z       Synchronize the current task with its attachment
+        directory, in case you added attachments yourself.
 
 
-o    Open current task's attachments.
-O    Like \"o\", but force opening in Emacs.
-f    Open current task's attachment directory.
-F    Like \"f\", but force using dired in Emacs.
+o       Open current task's attachments.
+O       Like \"o\", but force opening in Emacs.
+f       Open current task's attachment directory.
+F       Like \"f\", but force using dired in Emacs.
 
 
-D    Delete all of a task's attachments.  A safer way is
-     to open the directory in dired and delete from there.")))
+D       Delete all of a task's attachments.  A safer way is
+        to open the directory in dired and delete from there.")))
 	  (shrink-window-if-larger-than-buffer (get-buffer-window "*Org Attach*"))
 	  (shrink-window-if-larger-than-buffer (get-buffer-window "*Org Attach*"))
 	  (message "Select command: [azoOfFD^a]")
 	  (message "Select command: [azoOfFD^a]")
 	  (setq c (read-char-exclusive))
 	  (setq c (read-char-exclusive))
 	  (and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*"))))
 	  (and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*"))))
       (cond
       (cond
        ((memq c '(?a ?\C-a)) (call-interactively 'org-attach-attach))
        ((memq c '(?a ?\C-a)) (call-interactively 'org-attach-attach))
-       ((memq c '(?c ?\C-c)) (call-interactively 'org-attach-new))
+       ((memq c '(?c ?\C-c))
+	(let ((org-attach-method 'cp)) (call-interactively 'org-attach-attach)))
+       ((memq c '(?m ?\C-m))
+	(let ((org-attach-method 'mv)) (call-interactively 'org-attach-attach)))
+       ((memq c '(?l ?\C-l))
+	(let ((org-attach-method 'ln)) (call-interactively 'org-attach-attach)))
+       ((memq c '(?n ?\C-n)) (call-interactively 'org-attach-new))
        ((memq c '(?z ?\C-z)) (call-interactively 'org-attach-sync))
        ((memq c '(?z ?\C-z)) (call-interactively 'org-attach-sync))
        ((memq c '(?o ?\C-o)) (call-interactively 'org-attach-open))
        ((memq c '(?o ?\C-o)) (call-interactively 'org-attach-open))
        ((eq c ?O)            (call-interactively 'org-attach-open-in-emacs))
        ((eq c ?O)            (call-interactively 'org-attach-open-in-emacs))
        ((memq c '(?f ?\C-f)) (call-interactively 'org-attach-reveal))
        ((memq c '(?f ?\C-f)) (call-interactively 'org-attach-reveal))
        ((memq c '(?F))       (call-interactively 'org-attach-reveal-in-emacs))
        ((memq c '(?F))       (call-interactively 'org-attach-reveal-in-emacs))
        ((eq c ?D)            (call-interactively 'org-attach-delete))
        ((eq c ?D)            (call-interactively 'org-attach-delete))
+       ((eq c ?q)            ((message "Abort")))
        (t (error "No such attachment command %c" c))))))
        (t (error "No such attachment command %c" c))))))
 
 
 (defun org-attach-dir (&optional create-if-not-exists-p)
 (defun org-attach-dir (&optional create-if-not-exists-p)
@@ -161,21 +182,39 @@ the directory and the corresponding ID will be created."
   "Turn the autotag off."
   "Turn the autotag off."
   (org-attach-tag 'off))
   (org-attach-tag 'off))
 
 
-(defun org-attach-attach (file &optional visit-dir)
+(defun org-attach-attach (file &optional visit-dir method)
   "Move FILE into the attachment directory of the current task.
   "Move FILE into the attachment directory of the current task.
 If VISIT-DIR is non-nil, visit the direcory with dired."
 If VISIT-DIR is non-nil, visit the direcory with dired."
   (interactive "fFile to keep as an attachment: \nP")
   (interactive "fFile to keep as an attachment: \nP")
+  (setq method (or method org-attach-method))
   (let ((basename (file-name-nondirectory file)))
   (let ((basename (file-name-nondirectory file)))
     (org-entry-add-to-multivalued-property (point) "Attachments"
     (org-entry-add-to-multivalued-property (point) "Attachments"
 					   basename)
 					   basename)
-    (let ((attach-dir (org-attach-dir t)))
-      (rename-file file (expand-file-name basename attach-dir))
+    (let* ((attach-dir (org-attach-dir t))
+	   (fname (expand-file-name basename attach-dir)))
+      (cond
+       ((eq method 'mv)	(rename-file file fname))
+       ((eq method 'cp)	(copy-file file fname))
+       ((eq method 'ln) 
+	(require 'eshell)
+	(require 'esh-opt)
+	(require 'em-unix)
+	(eshell/ln file fname)))
       (org-attach-commit)
       (org-attach-commit)
       (org-attach-tag)
       (org-attach-tag)
       (if visit-dir
       (if visit-dir
 	  (dired attach-dir)
 	  (dired attach-dir)
 	(message "File \"%s\" is now a task attachment." basename)))))
 	(message "File \"%s\" is now a task attachment." basename)))))
 
 
+(defun org-attach-attach-cp ()
+  (interactive)
+  (let ((org-attach-method 'cp)) (call-interactively 'org-attach-attach)))
+(defun org-attach-attach-mv ()
+  (interactive)
+  (let ((org-attach-method 'mv)) (call-interactively 'org-attach-attach)))
+(defun org-attach-attach-ln ()
+  (let ((org-attach-method 'ln)) (call-interactively 'org-attach-attach)))
+
 (defun org-attach-new (file)
 (defun org-attach-new (file)
   "Create a new attachment FILE for the current task.
   "Create a new attachment FILE for the current task.
 The attachment is created as an Emacs buffer."
 The attachment is created as an Emacs buffer."
@@ -243,6 +282,7 @@ If IN-EMACS is non-nil, force opening in Emacs."
 (defun org-attach-open-in-emacs ()
 (defun org-attach-open-in-emacs ()
   "Open attachment, force opening in Emacs.
   "Open attachment, force opening in Emacs.
 See `org-attach-open'."
 See `org-attach-open'."
+  (interactive)
   (org-attach-open 'in-emacs))
   (org-attach-open 'in-emacs))
 
 
 
 
@@ -251,7 +291,6 @@ See `org-attach-open'."
   (let* ((attach-dir (org-attach-dir t))
   (let* ((attach-dir (org-attach-dir t))
 	 (file (read-file-name "Attachment: " attach-dir nil t)))
 	 (file (read-file-name "Attachment: " attach-dir nil t)))
     (org-open-file file in-emacs)))
     (org-open-file file in-emacs)))
-  
 
 
 (provide 'org-attach)
 (provide 'org-attach)