Update copyright notices for 2013.
[bpt/emacs.git] / lisp / dired-aux.el
index 6186f76..1344341 100644 (file)
@@ -1,7 +1,7 @@
 ;;; dired-aux.el --- less commonly used parts of dired
 
-;; Copyright (C) 1985-1986, 1992, 1994, 1998, 2000-2012
-;;   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
@@ -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'.
-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))
+         ;; Get the latest existing backup file.
+         (oldf (diff-latest-backup-file current))
          ;; 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))))
+         (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,
-         ;; 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))
-                               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)))
-     (require 'diff)
      (list
       (minibuffer-with-setup-hook
          (lambda ()
@@ -236,10 +245,17 @@ 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))
-        (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): "
@@ -257,7 +273,10 @@ List has a form of (file-name full-file-name (attribute-list))."
                             (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)))
@@ -273,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.
-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))
-        (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)
@@ -291,7 +314,10 @@ Symbolic modes like `g+w' are allowed."
                 "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"))
@@ -307,7 +333,9 @@ Symbolic modes like `g+w' are allowed."
 
 ;;;###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"))
@@ -315,7 +343,9 @@ Symbolic modes like `g+w' are allowed."
 
 ;;;###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"))
@@ -324,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.
-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))