Update copyright notices for 2013.
[bpt/emacs.git] / lisp / dired-aux.el
index b63940c..1344341 100644 (file)
@@ -1,7 +1,7 @@
 ;;; dired-aux.el --- less commonly used parts of dired
 
 ;;; dired-aux.el --- less commonly used parts of dired
 
-;; Copyright (C) 1985-1986, 1992, 1994, 1998, 2000-2011
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1992, 1994, 1998, 2000-2013 Free Software
+;; Foundation, Inc.
 
 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>.
 ;; Maintainer: FSF
 
 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>.
 ;; Maintainer: FSF
@@ -54,29 +54,38 @@ into this list; they also should call `dired-log' to log the errors.")
 ;;;###autoload
 (defun dired-diff (file &optional switches)
   "Compare file at point with file FILE using `diff'.
 ;;;###autoload
 (defun dired-diff (file &optional switches)
   "Compare file at point with file FILE using `diff'.
-FILE defaults to the file at the mark.  (That's the mark set by
-\\[set-mark-command], not by Dired's \\[dired-mark] command.)
-The prompted-for FILE is the first file given to `diff'.
-With prefix arg, prompt for second argument SWITCHES,
-which is the string of command switches for `diff'."
+If called interactively, prompt for FILE.  If the file at point
+has a backup file, use that as the default.  If the mark is active
+in Transient Mark mode, use the file at the mark as the default.
+\(That's the mark set by \\[set-mark-command], not by Dired's
+\\[dired-mark] command.)
+
+FILE is the first file given to `diff'.  The file at point
+is the second file given to `diff'.
+
+With prefix arg, prompt for second argument SWITCHES, which is
+the string of command switches for the third argument of `diff'."
   (interactive
    (let* ((current (dired-get-filename t))
   (interactive
    (let* ((current (dired-get-filename t))
+         ;; Get the latest existing backup file.
+         (oldf (diff-latest-backup-file current))
          ;; Get the file at the mark.
          ;; Get the file at the mark.
-         (file-at-mark (if (mark t)
+         (file-at-mark (if (and transient-mark-mode mark-active)
                            (save-excursion (goto-char (mark t))
                                            (dired-get-filename t t))))
                            (save-excursion (goto-char (mark t))
                                            (dired-get-filename t t))))
+         (default-file (or file-at-mark
+                           (and oldf (file-name-nondirectory oldf))))
          ;; Use it as default if it's not the same as the current file,
          ;; Use it as default if it's not the same as the current file,
-         ;; and the target dir is the current dir or the mark is active.
-         (default (if (and (not (equal file-at-mark current))
+         ;; and the target dir is current or there is a default file.
+         (default (if (and (not (equal default-file current))
                            (or (equal (dired-dwim-target-directory)
                                       (dired-current-directory))
                            (or (equal (dired-dwim-target-directory)
                                       (dired-current-directory))
-                               mark-active))
-                      file-at-mark))
+                               default-file))
+                      default-file))
          (target-dir (if default
                          (dired-current-directory)
                        (dired-dwim-target-directory)))
          (defaults (dired-dwim-target-defaults (list current) target-dir)))
          (target-dir (if default
                          (dired-current-directory)
                        (dired-dwim-target-directory)))
          (defaults (dired-dwim-target-defaults (list current) target-dir)))
-     (require 'diff)
      (list
       (minibuffer-with-setup-hook
          (lambda ()
      (list
       (minibuffer-with-setup-hook
          (lambda ()
@@ -236,16 +245,27 @@ List has a form of (file-name full-file-name (attribute-list))."
   ;; OP-SYMBOL is the type of operation (for use in `dired-mark-pop-up').
   ;; ARG describes which files to use, as in `dired-get-marked-files'.
   (let* ((files (dired-get-marked-files t arg))
   ;; OP-SYMBOL is the type of operation (for use in `dired-mark-pop-up').
   ;; ARG describes which files to use, as in `dired-get-marked-files'.
   (let* ((files (dired-get-marked-files t arg))
-        (default (and (eq op-symbol 'touch)
-                      (stringp (car files))
-                      (format-time-string "%Y%m%d%H%M.%S"
-                                          (nth 5 (file-attributes (car files))))))
+        ;; The source of default file attributes is the file at point.
+        (default-file (dired-get-filename t t))
+        (default (when default-file
+                   (cond ((eq op-symbol 'touch)
+                          (format-time-string
+                           "%Y%m%d%H%M.%S"
+                           (nth 5 (file-attributes default-file))))
+                         ((eq op-symbol 'chown)
+                          (nth 2 (file-attributes default-file 'string)))
+                         ((eq op-symbol 'chgrp)
+                          (nth 3 (file-attributes default-file 'string))))))
         (prompt (concat "Change " attribute-name " of %s to"
                         (if (eq op-symbol 'touch)
                             " (default now): "
                           ": ")))
         (new-attribute (dired-mark-read-string prompt nil op-symbol
         (prompt (concat "Change " attribute-name " of %s to"
                         (if (eq op-symbol 'touch)
                             " (default now): "
                           ": ")))
         (new-attribute (dired-mark-read-string prompt nil op-symbol
-                                               arg files default))
+                                               arg files default
+                                               (cond ((eq op-symbol 'chown)
+                                                      (system-users))
+                                                     ((eq op-symbol 'chgrp)
+                                                      (system-groups)))))
         (operation (concat program " " new-attribute))
         failures)
     (setq failures
         (operation (concat program " " new-attribute))
         failures)
     (setq failures
@@ -253,7 +273,10 @@ List has a form of (file-name full-file-name (attribute-list))."
                             (function dired-check-process)
                             (append
                              (list operation program)
                             (function dired-check-process)
                             (append
                              (list operation program)
-                             (unless (string-equal new-attribute "")
+                             (unless (or (string-equal new-attribute "")
+                                         ;; Use `eq' instead of `equal'
+                                         ;; to detect empty input (bug#12399).
+                                         (eq new-attribute default))
                                (if (eq op-symbol 'touch)
                                    (list "-t" new-attribute)
                                  (list new-attribute)))
                                (if (eq op-symbol 'touch)
                                    (list "-t" new-attribute)
                                  (list new-attribute)))
@@ -269,11 +292,15 @@ List has a form of (file-name full-file-name (attribute-list))."
 ;;;###autoload
 (defun dired-do-chmod (&optional arg)
   "Change the mode of the marked (or next ARG) files.
 ;;;###autoload
 (defun dired-do-chmod (&optional arg)
   "Change the mode of the marked (or next ARG) files.
-Symbolic modes like `g+w' are allowed."
+Symbolic modes like `g+w' are allowed.
+Type M-n to pull the file attributes of the file at point
+into the minibuffer."
   (interactive "P")
   (let* ((files (dired-get-marked-files t arg))
   (interactive "P")
   (let* ((files (dired-get-marked-files t arg))
-        (modestr (and (stringp (car files))
-                      (nth 8 (file-attributes (car files)))))
+        ;; The source of default file attributes is the file at point.
+        (default-file (dired-get-filename t t))
+        (modestr (when default-file
+                   (nth 8 (file-attributes default-file))))
         (default
           (and (stringp modestr)
                (string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
         (default
           (and (stringp modestr)
                (string-match "^.\\(...\\)\\(...\\)\\(...\\)$" modestr)
@@ -287,7 +314,10 @@ Symbolic modes like `g+w' are allowed."
                 "Change mode of %s to: "
                 nil 'chmod arg files default))
         num-modes)
                 "Change mode of %s to: "
                 nil 'chmod arg files default))
         num-modes)
-    (cond ((equal modes "")
+    (cond ((or (equal modes "")
+              ;; Use `eq' instead of `equal'
+              ;; to detect empty input (bug#12399).
+              (eq modes default))
           ;; We used to treat empty input as DEFAULT, but that is not
           ;; such a good idea (Bug#9361).
           (error "No file mode specified"))
           ;; We used to treat empty input as DEFAULT, but that is not
           ;; such a good idea (Bug#9361).
           (error "No file mode specified"))
@@ -303,7 +333,9 @@ Symbolic modes like `g+w' are allowed."
 
 ;;;###autoload
 (defun dired-do-chgrp (&optional arg)
 
 ;;;###autoload
 (defun dired-do-chgrp (&optional arg)
-  "Change the group of the marked (or next ARG) files."
+  "Change the group of the marked (or next ARG) files.
+Type M-n to pull the file attributes of the file at point
+into the minibuffer."
   (interactive "P")
   (if (memq system-type '(ms-dos windows-nt))
       (error "chgrp not supported on this system"))
   (interactive "P")
   (if (memq system-type '(ms-dos windows-nt))
       (error "chgrp not supported on this system"))
@@ -311,7 +343,9 @@ Symbolic modes like `g+w' are allowed."
 
 ;;;###autoload
 (defun dired-do-chown (&optional arg)
 
 ;;;###autoload
 (defun dired-do-chown (&optional arg)
-  "Change the owner of the marked (or next ARG) files."
+  "Change the owner of the marked (or next ARG) files.
+Type M-n to pull the file attributes of the file at point
+into the minibuffer."
   (interactive "P")
   (if (memq system-type '(ms-dos windows-nt))
       (error "chown not supported on this system"))
   (interactive "P")
   (if (memq system-type '(ms-dos windows-nt))
       (error "chown not supported on this system"))
@@ -320,7 +354,9 @@ Symbolic modes like `g+w' are allowed."
 ;;;###autoload
 (defun dired-do-touch (&optional arg)
   "Change the timestamp of the marked (or next ARG) files.
 ;;;###autoload
 (defun dired-do-touch (&optional arg)
   "Change the timestamp of the marked (or next ARG) files.
-This calls touch."
+This calls touch.
+Type M-n to pull the file attributes of the file at point
+into the minibuffer."
   (interactive "P")
   (dired-do-chxxx "Timestamp" dired-touch-program 'touch arg))
 
   (interactive "P")
   (dired-do-chxxx "Timestamp" dired-touch-program 'touch arg))
 
@@ -385,23 +421,25 @@ Uses the shell command coming from variables `lpr-command' and
     (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
 
 (defun dired-mark-read-string (prompt initial op-symbol arg files
     (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
 
 (defun dired-mark-read-string (prompt initial op-symbol arg files
-                              &optional default-value)
+                              &optional default-value collection)
   "Read args for a Dired marked-files command, prompting with PROMPT.
 Return the user input (a string).
 
 INITIAL, if non-nil, is the initial minibuffer input.
 OP-SYMBOL is an operation symbol (see `dired-no-confirm').
   "Read args for a Dired marked-files command, prompting with PROMPT.
 Return the user input (a string).
 
 INITIAL, if non-nil, is the initial minibuffer input.
 OP-SYMBOL is an operation symbol (see `dired-no-confirm').
-ARG is normally the prefix argument for the calling command.
-FILES should be a list of file names.
+ARG is normally the prefix argument for the calling command;
+it is passed as the first argument to `dired-mark-prompt'.
+FILES should be a list of marked files' names.
 
 
-DEFAULT-VALUE, if non-nil, should be a \"standard\" value or list
-of such values, available via history commands.  Note that if the
-user enters empty input, this function returns the empty string,
-not DEFAULT-VALUE."
+Optional arg DEFAULT-VALUE is a default value or list of default
+values, passed as the seventh arg to `completing-read'.
+
+Optional arg COLLECTION is a collection of possible completions,
+passed as the second arg to `completing-read'."
   (dired-mark-pop-up nil op-symbol files
   (dired-mark-pop-up nil op-symbol files
-                    'read-from-minibuffer
+                    'completing-read
                     (format prompt (dired-mark-prompt arg files))
                     (format prompt (dired-mark-prompt arg files))
-                    initial nil nil nil default-value))
+                    collection nil nil initial nil default-value nil))
 \f
 ;;; Cleaning a directory: flagging some backups for deletion.
 
 \f
 ;;; Cleaning a directory: flagging some backups for deletion.
 
@@ -539,8 +577,17 @@ offer a smarter default choice of shell command."
 (defun dired-do-async-shell-command (command &optional arg file-list)
   "Run a shell command COMMAND on the marked files asynchronously.
 
 (defun dired-do-async-shell-command (command &optional arg file-list)
   "Run a shell command COMMAND on the marked files asynchronously.
 
-Like `dired-do-shell-command' but if COMMAND doesn't end in ampersand,
-adds `* &' surrounded by whitespace and executes the command asynchronously.
+Like `dired-do-shell-command', but adds `&' at the end of COMMAND
+to execute it asynchronously.
+
+When operating on multiple files, asynchronous commands
+are executed in the background on each file in parallel.
+In shell syntax this means separating the individual commands
+with `&'.  However, when COMMAND ends in `;' or `;&' then commands
+are executed in the background on each file sequentially waiting
+for each command to terminate before running the next command.
+In shell syntax this means separating the individual commands with `;'.
+
 The output appears in the buffer `*Async Shell Command*'."
   (interactive
    (let ((files (dired-get-marked-files t current-prefix-arg)))
 The output appears in the buffer `*Async Shell Command*'."
   (interactive
    (let ((files (dired-get-marked-files t current-prefix-arg)))
@@ -549,18 +596,14 @@ The output appears in the buffer `*Async Shell Command*'."
       (dired-read-shell-command "& on %s: " current-prefix-arg files)
       current-prefix-arg
       files)))
       (dired-read-shell-command "& on %s: " current-prefix-arg files)
       current-prefix-arg
       files)))
-  (unless (string-match "[*?][ \t]*\\'" command)
-    (setq command (concat command " *")))
   (unless (string-match "&[ \t]*\\'" command)
     (setq command (concat command " &")))
   (dired-do-shell-command command arg file-list))
 
   (unless (string-match "&[ \t]*\\'" command)
     (setq command (concat command " &")))
   (dired-do-shell-command command arg file-list))
 
-;; The in-background argument is only needed in Emacs 18 where
-;; shell-command doesn't understand an appended ampersand `&'.
 ;;;###autoload
 (defun dired-do-shell-command (command &optional arg file-list)
   "Run a shell command COMMAND on the marked files.
 ;;;###autoload
 (defun dired-do-shell-command (command &optional arg file-list)
   "Run a shell command COMMAND on the marked files.
-If no files are marked or a specific numeric prefix arg is given,
+If no files are marked or a numeric prefix arg is given,
 the next ARG files are used.  Just \\[universal-argument] means the current file.
 The prompt mentions the file(s) or the marker, as appropriate.
 
 the next ARG files are used.  Just \\[universal-argument] means the current file.
 The prompt mentions the file(s) or the marker, as appropriate.
 
@@ -576,10 +619,23 @@ file name added at the end of COMMAND (separated by a space).
 
 `*' and `?' when not surrounded by whitespace have no special
 significance for `dired-do-shell-command', and are passed through
 
 `*' and `?' when not surrounded by whitespace have no special
 significance for `dired-do-shell-command', and are passed through
-normally to the shell, but you must confirm first.  To pass `*' by
-itself to the shell as a wildcard, type `*\"\"'.
+normally to the shell, but you must confirm first.
+
+If you want to use `*' as a shell wildcard with whitespace around
+it, write `*\"\"' in place of just `*'.  This is equivalent to just
+`*' in the shell, but avoids Dired's special handling.
 
 
-If COMMAND produces output, it goes to a separate buffer.
+If COMMAND ends in `&', `;', or `;&', it is executed in the
+background asynchronously, and the output appears in the buffer
+`*Async Shell Command*'.  When operating on multiple files and COMMAND
+ends in `&', the shell command is executed on each file in parallel.
+However, when COMMAND ends in `;' or `;&' then commands are executed
+in the background on each file sequentially waiting for each command
+to terminate before running the next command.  You can also use
+`dired-do-async-shell-command' that automatically adds `&'.
+
+Otherwise, COMMAND is executed synchronously, and the output
+appears in the buffer `*Shell Command Output*'.
 
 This feature does not try to redisplay Dired buffers afterward, as
 there's no telling what files COMMAND may have changed.
 
 This feature does not try to redisplay Dired buffers afterward, as
 there's no telling what files COMMAND may have changed.
@@ -598,23 +654,20 @@ can be produced by `dired-get-marked-files', for example."
    (let ((files (dired-get-marked-files t current-prefix-arg)))
      (list
       ;; Want to give feedback whether this file or marked files are used:
    (let ((files (dired-get-marked-files t current-prefix-arg)))
      (list
       ;; Want to give feedback whether this file or marked files are used:
-      (dired-read-shell-command (concat "! on "
-                                       "%s: ")
-                               current-prefix-arg
-                               files)
+      (dired-read-shell-command "! on %s: " current-prefix-arg files)
       current-prefix-arg
       files)))
   (let* ((on-each (not (string-match dired-star-subst-regexp command)))
       current-prefix-arg
       files)))
   (let* ((on-each (not (string-match dired-star-subst-regexp command)))
-        (subst (not (string-match dired-quark-subst-regexp command)))
-        (star (not (string-match "\\*" command)))
-        (qmark (not (string-match "\\?" command))))
+        (no-subst (not (string-match dired-quark-subst-regexp command)))
+        (star (string-match "\\*" command))
+        (qmark (string-match "\\?" command)))
     ;; Get confirmation for wildcards that may have been meant
     ;; to control substitution of a file name or the file name list.
     ;; Get confirmation for wildcards that may have been meant
     ;; to control substitution of a file name or the file name list.
-    (if (cond ((not (or on-each subst))
+    (if (cond ((not (or on-each no-subst))
               (error "You can not combine `*' and `?' substitution marks"))
               (error "You can not combine `*' and `?' substitution marks"))
-             ((and star (not on-each))
+             ((and star on-each)
               (y-or-n-p "Confirm--do you mean to use `*' as a wildcard? "))
               (y-or-n-p "Confirm--do you mean to use `*' as a wildcard? "))
-             ((and qmark (not subst))
+             ((and qmark no-subst)
               (y-or-n-p "Confirm--do you mean to use `?' as a wildcard? "))
              (t))
        (if on-each
               (y-or-n-p "Confirm--do you mean to use `?' as a wildcard? "))
              (t))
        (if on-each
@@ -645,23 +698,34 @@ can be produced by `dired-get-marked-files', for example."
 ;; Might be redefined for smarter things and could then use RAW-ARG
 ;; (coming from interactive P and currently ignored) to decide what to do.
 ;; Smart would be a way to access basename or extension of file names.
 ;; Might be redefined for smarter things and could then use RAW-ARG
 ;; (coming from interactive P and currently ignored) to decide what to do.
 ;; Smart would be a way to access basename or extension of file names.
-  (let ((stuff-it
-        (if (or (string-match dired-star-subst-regexp command)
-                (string-match dired-quark-subst-regexp command))
-            (lambda (x)
-              (let ((retval command))
-                (while (string-match
-                        "\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval)
-                  (setq retval (replace-match x t t retval 2)))
-                retval))
-          (lambda (x) (concat command dired-mark-separator x)))))
-    (if on-each
-       (mapconcat stuff-it (mapcar 'shell-quote-argument file-list) ";")
-      (let ((files (mapconcat 'shell-quote-argument
-                             file-list dired-mark-separator)))
-       (if (> (length file-list) 1)
-           (setq files (concat dired-mark-prefix files dired-mark-postfix)))
-       (funcall stuff-it files)))))
+  (let* ((in-background (string-match "[ \t]*&[ \t]*\\'" command))
+        (command (if in-background
+                     (substring command 0 (match-beginning 0))
+                   command))
+        (sequentially (string-match "[ \t]*;[ \t]*\\'" command))
+        (command (if sequentially
+                     (substring command 0 (match-beginning 0))
+                   command))
+        (stuff-it
+         (if (or (string-match dired-star-subst-regexp command)
+                 (string-match dired-quark-subst-regexp command))
+             (lambda (x)
+               (let ((retval command))
+                 (while (string-match
+                         "\\(^\\|[ \t]\\)\\([*?]\\)\\([ \t]\\|$\\)" retval)
+                   (setq retval (replace-match x t t retval 2)))
+                 retval))
+           (lambda (x) (concat command dired-mark-separator x)))))
+    (concat
+     (if on-each
+        (mapconcat stuff-it (mapcar 'shell-quote-argument file-list)
+                   (if (and in-background (not sequentially)) "&" ";"))
+       (let ((files (mapconcat 'shell-quote-argument
+                              file-list dired-mark-separator)))
+        (if (> (length file-list) 1)
+            (setq files (concat dired-mark-prefix files dired-mark-postfix)))
+        (funcall stuff-it files)))
+     (if in-background "&" ""))))
 
 ;; This is an extra function so that it can be redefined by ange-ftp.
 ;;;###autoload
 
 ;; This is an extra function so that it can be redefined by ange-ftp.
 ;;;###autoload
@@ -927,8 +991,7 @@ return t; if SYM is q or ESC, return nil."
                 (concat (apply 'format prompt args)
                         (if help-form
                             (format " [Type yn!q or %s] "
                 (concat (apply 'format prompt args)
                         (if help-form
                             (format " [Type yn!q or %s] "
-                                    (key-description
-                                     (char-to-string help-char)))
+                                    (key-description (vector help-char)))
                           " [Type y, n, q or !] ")))
           (set sym (setq char (read-char-choice prompt char-choices)))
           (if (memq char '(?y ?\s ?!)) t)))))
                           " [Type y, n, q or !] ")))
           (set sym (setq char (read-char-choice prompt char-choices)))
           (if (memq char '(?y ?\s ?!)) t)))))
@@ -1262,6 +1325,9 @@ Special value `always' suppresses confirmation."
 
 (defun dired-copy-file-recursive (from to ok-flag &optional
                                       preserve-time top recursive)
 
 (defun dired-copy-file-recursive (from to ok-flag &optional
                                       preserve-time top recursive)
+  (when (and (eq t (car (file-attributes from)))
+            (file-in-directory-p to from))
+    (error "Cannot copy `%s' into its subdirectory `%s'" from to))
   (let ((attrs (file-attributes from)))
     (if (and recursive
             (eq t (car attrs))
   (let ((attrs (file-attributes from)))
     (if (and recursive
             (eq t (car attrs))
@@ -1396,9 +1462,9 @@ NAME-CONSTRUCTOR should be a function accepting a single
 argument, the name of an old file, and returning either the
 corresponding new file name or nil to skip.
 
 argument, the name of an old file, and returning either the
 corresponding new file name or nil to skip.
 
-Optional MARKER-CHAR is a character with which to mark every
-newfile's entry, or t to use the current marker character if the
-old file was marked."
+If optional argument MARKER-CHAR is non-nil, mark each
+newly-created file's Dired entry with the character MARKER-CHAR,
+or with the current marker character if MARKER-CHAR is t."
   (let (dired-create-files-failures failures
        skipped (success-count 0) (total (length fn-list)))
     (let (to overwrite-query
   (let (dired-create-files-failures failures
        skipped (success-count 0) (total (length fn-list)))
     (let (to overwrite-query
@@ -1428,10 +1494,32 @@ ESC or `q' to not overwrite any of the remaining files,
                   (cond  ((integerp marker-char) marker-char)
                          (marker-char (dired-file-marker from)) ; slow
                          (t nil))))
                   (cond  ((integerp marker-char) marker-char)
                          (marker-char (dired-file-marker from)) ; slow
                          (t nil))))
-           (when (and (file-directory-p from)
-                      (file-directory-p to)
-                      (eq file-creator 'dired-copy-file))
-             (setq to (file-name-directory to)))
+            ;; Handle the `dired-copy-file' file-creator specially
+            ;; When copying a directory to another directory or
+            ;; possibly to itself or one of its subdirectories.
+            ;; e.g "~/foo/" => "~/test/"
+            ;; or "~/foo/" =>"~/foo/"
+            ;; or "~/foo/ => ~/foo/bar/")
+            ;; In this case the 'name-constructor' have set the destination
+            ;; TO to "~/test/foo" because the old emacs23 behavior
+            ;; of `copy-directory' was to not create the subdirectory
+            ;; and instead copy the contents.
+            ;; With the new behavior of `copy-directory'
+            ;; (similar to the `cp' shell command) we don't
+            ;; need such a construction of the target directory,
+            ;; so modify the destination TO to "~/test/" instead of "~/test/foo/".
+            (let ((destname (file-name-directory to)))
+              (when (and (file-directory-p from)
+                         (file-directory-p to)
+                         (eq file-creator 'dired-copy-file))
+                (setq to destname))
+             ;; If DESTNAME is a subdirectory of FROM, not a symlink,
+             ;; and the method in use is copying, signal an error.
+             (and (eq t (car (file-attributes destname)))
+                  (eq file-creator 'dired-copy-file)
+                  (file-in-directory-p destname from)
+                  (error "Cannot copy `%s' into its subdirectory `%s'"
+                         from to)))
             (condition-case err
                 (progn
                   (funcall file-creator from to dired-overwrite-confirmed)
             (condition-case err
                 (progn
                   (funcall file-creator from to dired-overwrite-confirmed)
@@ -1479,10 +1567,11 @@ ESC or `q' to not overwrite any of the remaining files,
                                        &optional marker-char op1
                                        how-to)
   "Create a new file for each marked file.
                                        &optional marker-char op1
                                        how-to)
   "Create a new file for each marked file.
-Prompts user for target, which is a directory in which to create
-  the new files.  Target may also be a plain file if only one marked
-  file exists.  The way the default for the target directory is
-  computed depends on the value of `dired-dwim-target-directory'.
+Prompt user for a target directory in which to create the new
+  files.  The target may also be a non-directory file, if only
+  one file is marked.  The initial suggestion for target is the
+  Dired buffer's current directory (or, if `dired-dwim-target' is
+  non-nil, the current directory of a neighboring Dired window).
 OP-SYMBOL is the symbol for the operation.  Function `dired-mark-pop-up'
   will determine whether pop-ups are appropriate for this OP-SYMBOL.
 FILE-CREATOR and OPERATION as in `dired-create-files'.
 OP-SYMBOL is the symbol for the operation.  Function `dired-mark-pop-up'
   will determine whether pop-ups are appropriate for this OP-SYMBOL.
 FILE-CREATOR and OPERATION as in `dired-create-files'.
@@ -1687,16 +1776,21 @@ See HOW-TO argument for `dired-do-create-files'.")
 ;;;###autoload
 (defun dired-do-copy (&optional arg)
   "Copy all marked (or next ARG) files, or copy the current file.
 ;;;###autoload
 (defun dired-do-copy (&optional arg)
   "Copy all marked (or next ARG) files, or copy the current file.
-This normally preserves the last-modified date when copying.
-When operating on just the current file, you specify the new name.
-When operating on multiple or marked files, you specify a directory,
-and new copies of these files are made in that directory
-with the same names that the files currently have.  The default
-suggested for the target directory depends on the value of
-`dired-dwim-target', which see.
+When operating on just the current file, prompt for the new name.
+
+When operating on multiple or marked files, prompt for a target
+directory, and make the new copies in that directory, with the
+same names as the original files.  The initial suggestion for the
+target directory is the Dired buffer's current directory (or, if
+`dired-dwim-target' is non-nil, the current directory of a
+neighboring Dired window).
 
 
-This command copies symbolic links by creating new ones,
-like `cp -d'."
+If `dired-copy-preserve-time' is non-nil, this command preserves
+the modification time of each old file in the copy, similar to
+the \"-p\" option for the \"cp\" shell command.
+
+This command copies symbolic links by creating new ones, similar
+to the \"-d\" option for the \"cp\" shell command."
   (interactive "P")
   (let ((dired-recursive-copies dired-recursive-copies))
     (dired-do-create-files 'copy (function dired-copy-file)
   (interactive "P")
   (let ((dired-recursive-copies dired-recursive-copies))
     (dired-do-create-files 'copy (function dired-copy-file)
@@ -1962,9 +2056,10 @@ See Info node `(emacs)Subdir switches' for more details."
 
 ;;;###autoload
 (defun dired-insert-subdir (dirname &optional switches no-error-if-not-dir-p)
 
 ;;;###autoload
 (defun dired-insert-subdir (dirname &optional switches no-error-if-not-dir-p)
-  "Insert this subdirectory into the same dired buffer.
-If it is already present, overwrites previous entry,
-  else inserts it at its natural place (as `ls -lR' would have done).
+  "Insert this subdirectory into the same Dired buffer.
+If it is already present, overwrite the previous entry;
+  otherwise, insert it at its natural place (as `ls -lR' would
+  have done).
 With a prefix arg, you may edit the `ls' switches used for this listing.
   You can add `R' to the switches to expand the whole tree starting at
   this subdirectory.
 With a prefix arg, you may edit the `ls' switches used for this listing.
   You can add `R' to the switches to expand the whole tree starting at
   this subdirectory.