瀏覽代碼

Allow different methods to get an attachment into the directory.

Supported methods are copy, link, and move.
Carsten Dominik 16 年之前
父節點
當前提交
8518c9ed81
共有 4 個文件被更改,包括 106 次插入38 次删除
  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_HOME: http://orgmode.org
 
-* Version 6.08
+
+* Version 6.09 (in preparation)
 :PROPERTIES:
 :VISIBILITY: content
 :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
 
    - 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.
 
 @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
 @item C-c C-r
 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.
 Hyperlinks (@pxref{Hyperlinks}) can be used to establish associations with
 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
 
@@ -5193,10 +5189,17 @@ to select a command:
 @table @kbd
 @kindex C-c C-a 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
-@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.
 
 @kindex C-c C-a z
@@ -5207,7 +5210,7 @@ attachments yourself.
 @kindex C-c C-a o
 @item o
 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
 @item O
@@ -5221,6 +5224,10 @@ Open the current task's attachment directory.
 @item F
 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
 @item D
 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>
 
 	* org-bbdb.el (org-bbdb-anniversaries): Fix but with 29 Feb/1
 	March.
-	
+
 	* org.el (org-remove-uniherited-tags): Fix reverse interpretation
 	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)
 	  (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
   "Non-nil means do not show the splash buffer with the attach dispatcher."
   :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*"
 	      (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*"))
 	  (message "Select command: [azoOfFD^a]")
 	  (setq c (read-char-exclusive))
 	  (and (get-buffer "*Org Attach*") (kill-buffer "*Org Attach*"))))
       (cond
        ((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 '(?o ?\C-o)) (call-interactively 'org-attach-open))
        ((eq c ?O)            (call-interactively 'org-attach-open-in-emacs))
        ((memq c '(?f ?\C-f)) (call-interactively 'org-attach-reveal))
        ((memq c '(?F))       (call-interactively 'org-attach-reveal-in-emacs))
        ((eq c ?D)            (call-interactively 'org-attach-delete))
+       ((eq c ?q)            ((message "Abort")))
        (t (error "No such attachment command %c" c))))))
 
 (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."
   (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.
 If VISIT-DIR is non-nil, visit the direcory with dired."
   (interactive "fFile to keep as an attachment: \nP")
+  (setq method (or method org-attach-method))
   (let ((basename (file-name-nondirectory file)))
     (org-entry-add-to-multivalued-property (point) "Attachments"
 					   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-tag)
       (if visit-dir
 	  (dired attach-dir)
 	(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)
   "Create a new attachment FILE for the current task.
 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 ()
   "Open attachment, force opening in Emacs.
 See `org-attach-open'."
+  (interactive)
   (org-attach-open 'in-emacs))
 
 
@@ -251,7 +291,6 @@ See `org-attach-open'."
   (let* ((attach-dir (org-attach-dir t))
 	 (file (read-file-name "Attachment: " attach-dir nil t)))
     (org-open-file file in-emacs)))
-  
 
 (provide 'org-attach)