;;; 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
;;;###autoload
(defun dired-diff (file &optional switches)
"Compare file at point with file FILE using `diff'.
-If called interactively, prompt for FILE; if the file at point
-has a backup file, use that as the default.
-
-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 file at point
+is a backup file, use its original. 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))
- (oldf (file-newest-backup current))
- (dir (if oldf (file-name-directory oldf))))
- (list (read-file-name
- (format "Diff %s with%s: "
- (file-name-nondirectory current)
- (if oldf
- (concat " (default "
- (file-name-nondirectory oldf)
- ")")
- ""))
- dir oldf t)
- (if current-prefix-arg
- (read-string "Options for diff: "
- (if (stringp diff-switches)
- diff-switches
- (mapconcat 'identity diff-switches " ")))))))
+ ;; Get the latest existing backup file or its original.
+ (oldf (if (backup-file-name-p current)
+ (file-name-sans-versions current)
+ (diff-latest-backup-file current)))
+ ;; Get the file at the mark.
+ (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 current or there is a default file.
+ (default (if (and (not (equal default-file current))
+ (or (equal (dired-dwim-target-directory)
+ (dired-current-directory))
+ default-file))
+ default-file))
+ (target-dir (if default
+ (dired-current-directory)
+ (dired-dwim-target-directory)))
+ (defaults (dired-dwim-target-defaults (list current) target-dir)))
+ (list
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (set (make-local-variable 'minibuffer-default-add-function) nil)
+ (setq minibuffer-default defaults))
+ (read-file-name
+ (format "Diff %s with%s: " current
+ (if default (format " (default %s)" default) ""))
+ target-dir default t))
+ (if current-prefix-arg
+ (read-string "Options for diff: "
+ (if (stringp diff-switches)
+ diff-switches
+ (mapconcat 'identity diff-switches " ")))))))
(let ((current (dired-get-filename t)))
(when (or (equal (expand-file-name file)
(expand-file-name current))
(equal (expand-file-name current file)
(expand-file-name current))))
(error "Attempt to compare the file to itself"))
- (diff file current switches)))
+ (if (and (backup-file-name-p current)
+ (equal file (file-name-sans-versions current)))
+ (diff current file switches)
+ (diff file current switches))))
;;;###autoload
(defun dired-backup-diff (&optional switches)
;; 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): "
;;;###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)
;;;###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"))
;;;###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"))
;;;###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))
:group 'dired
:version "23.1")
-(defvar dired-isearch-filter-predicate-orig nil)
-
(defun dired-isearch-filenames-toggle ()
"Toggle file names searching on or off.
When on, Isearch skips matches outside file names using the predicate
`dired-isearch-filter-filenames' that matches only at file names.
When off, it uses the original predicate."
(interactive)
- (setq isearch-filter-predicate
- (if (eq isearch-filter-predicate 'dired-isearch-filter-filenames)
- dired-isearch-filter-predicate-orig
- 'dired-isearch-filter-filenames))
+ (setq isearch-filter-predicates
+ (if (memq 'dired-isearch-filter-filenames isearch-filter-predicates)
+ (delq 'dired-isearch-filter-filenames isearch-filter-predicates)
+ (cons 'dired-isearch-filter-filenames isearch-filter-predicates)))
(setq isearch-success t isearch-adjusted t)
(isearch-update))
(when (or (eq dired-isearch-filenames t)
(and (eq dired-isearch-filenames 'dwim)
(get-text-property (point) 'dired-filename)))
- (setq isearch-message-prefix-add "filename ")
- (define-key isearch-mode-map "\M-sf" 'dired-isearch-filenames-toggle)
- (setq dired-isearch-filter-predicate-orig
- (default-value 'isearch-filter-predicate))
- (setq-default isearch-filter-predicate 'dired-isearch-filter-filenames)
+ (define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-toggle)
+ (add-hook 'isearch-filter-predicates 'dired-isearch-filter-filenames nil t)
(add-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end nil t)))
(defun dired-isearch-filenames-end ()
"Clean up the Dired file name search after terminating isearch."
(setq isearch-message-prefix-add nil)
- (define-key isearch-mode-map "\M-sf" nil)
- (setq-default isearch-filter-predicate dired-isearch-filter-predicate-orig)
+ (define-key isearch-mode-map "\M-sff" nil)
+ (remove-hook 'isearch-filter-predicates 'dired-isearch-filter-filenames t)
(remove-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end t))
(defun dired-isearch-filter-filenames (beg end)
- "Test whether the current search hit is a visible file name.
+ "Test whether the current search hit is a file name.
Return non-nil if the text from BEG to END is part of a file
-name (has the text property `dired-filename') and is visible."
- (and (isearch-filter-visible beg end)
- (if dired-isearch-filenames
- (text-property-not-all (min beg end) (max beg end)
- 'dired-filename nil)
- t)))
+name (has the text property `dired-filename')."
+ (if dired-isearch-filenames
+ (text-property-not-all (min beg end) (max beg end)
+ 'dired-filename nil)
+ t))
+
+(put 'dired-isearch-filter-filenames 'isearch-message-prefix "filename ")
;;;###autoload
(defun dired-isearch-filenames ()