;;; dired-aux.el --- less commonly used parts of dired -*-byte-compile-dynamic: t;-*-
-;; Copyright (C) 1985, 1986, 1992, 1994, 1998, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1992, 1994, 1998, 2000, 2001
+;; Free Software Foundation, Inc.
;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>.
;; Maintainer: FSF
+;; Keywords: files
;; This file is part of GNU Emacs.
;;;###autoload
(defun dired-diff (file &optional switches)
"Compare file at point with file FILE using `diff'.
-FILE defaults to the file at the mark.
+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 options for `diff'."
"Change the group of the marked (or next ARG) files."
(interactive "P")
(if (memq system-type '(ms-dos windows-nt))
- (error "chgrp not supported on this system."))
+ (error "chgrp not supported on this system"))
(dired-do-chxxx "Group" "chgrp" 'chgrp arg))
;;;###autoload
"Change the owner of the marked (or next ARG) files."
(interactive "P")
(if (memq system-type '(ms-dos windows-nt))
- (error "chown not supported on this system."))
+ (error "chown not supported on this system"))
(dired-do-chxxx "Owner" dired-chown-program 'chown arg))
;; Process all the files in FILES in batches of a convenient size,
;; and this file won't fit in the length limit, process now.
(if (and pending (> (+ thislength pending-length) max))
(setq failures
- (nconc (apply function (append args pending))
+ (nconc (apply function (append args (nreverse pending)))
failures)
pending nil
pending-length 0))
(setq pending files)
(setq pending-length (+ thislength pending-length))
(setq files rest)))
- (nconc (apply function (append args pending))
+ (nconc (apply function (append args (nreverse pending)))
failures)))
;;;###autoload
the next ARG files are used. Just \\[universal-argument] means the current file.
The prompt mentions the file(s) or the marker, as appropriate.
-If there is output, it goes to a separate buffer.
+If there is a `*' in COMMAND, surrounded by whitespace, this runs
+COMMAND just once with the entire file list substituted there.
-Normally the command is run on each file individually.
-However, if there is a `*' in the command then it is run
-just once with the entire file list substituted there.
+If there is no `*', but there is a `?' in COMMAND, surrounded by
+whitespace, this runs COMMAND on each file individually with the
+file name substituted for `?'.
-If there is no `*', but a `?' in the command then it is still run
-on each file individually but with the filename substituted there
-instead of at the end of the command.
+Otherwise, this runs COMMAND on each file individually with the
+file name added at the end of COMMAND (separated by a space).
-No automatic redisplay of dired buffers is attempted, as there's no
-telling what files the command may have changed. Type
-\\[dired-do-redisplay] to redisplay the marked files.
+`*' 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 `*\"\"'.
-The shell command has the top level directory as working directory, so
-output files usually are created there instead of in a subdir.
+If COMMAND produces output, it goes to a separate buffer.
+
+This feature does not try to redisplay Dired buffers afterward, as
+there's no telling what files COMMAND may have changed.
+Type \\[dired-do-redisplay] to redisplay the marked files.
+
+When COMMAND runs, its working directory is the top-level directory of
+the Dired buffer, so output files usually are created there instead of
+in a subdir.
In a noninteractive call (from Lisp code), you must specify
the list of file names explicitly with the FILE-LIST argument."
files)
current-prefix-arg
files)))
- (let* ((on-each (not (string-match "\\*" command))))
- (if on-each
- (dired-bunch-files
- (- 10000 (length command))
- (function (lambda (&rest files)
- (dired-run-shell-command
- (dired-shell-stuff-it command files t arg))))
- nil
- file-list)
- ;; execute the shell command
- (dired-run-shell-command
- (dired-shell-stuff-it command file-list nil arg)))))
+ (let* ((on-each (not (string-match "\\(^\\|[ \t]\\)\\*\\([ \t]\\|$\\)" command)))
+ (subst (not (string-match "\\(^\\|[ \t]\\)\\?\\([ \t]\\|$\\)" command)))
+ (star (not (string-match "\\*" command)))
+ (qmark (not (string-match "\\?" command))))
+ ;; Get confirmation for wildcards that may have been meant
+ ;; to control substitution of a file name or the file name list.
+ (if (cond ((and star (not on-each))
+ (y-or-n-p "Confirm--do you mean to use `*' as a wildcard? "))
+ ((and qmark (not subst))
+ (y-or-n-p "Confirm--do you mean to use `?' as a wildcard? "))
+ (t))
+ (if on-each
+ (dired-bunch-files
+ (- 10000 (length command))
+ (function (lambda (&rest files)
+ (dired-run-shell-command
+ (dired-shell-stuff-it command files t arg))))
+ nil
+ file-list)
+ ;; execute the shell command
+ (dired-run-shell-command
+ (dired-shell-stuff-it command file-list nil arg))))))
;; Might use {,} for bash or csh:
(defvar dired-mark-prefix ""
;; 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.
-;; See dired-trns.el for an approach to this.
- ;; Bug: There is no way to quote a * or a ?
- ;; On the other hand, you can never accidentally get a * or a ? into
- ;; your cmd.
(let ((stuff-it
- (cond ((string-match "\\*" command)
- (function (lambda (x)
- (dired-replace-in-string "\\*" x command))))
- ((string-match "\\?" command)
- (function (lambda (x)
- (dired-replace-in-string "\\?" x command))))
- (t (function (lambda (x) (concat command " " x)))))))
+ (cond ((string-match "\\(^\\|[ \t]\\)\\*\\([ \t]\\|$\\)" command)
+ (lambda (x)
+ (string-match "\\(^\\|[ \t]\\)\\(\\*\\)\\([ \t]\\|$\\)" command)
+ (replace-match x t t command 2)))
+ ((string-match "\\(^\\|[ \t]\\)\\?\\([ \t]\\|$\\)" command)
+ (lambda (x)
+ (string-match "\\(^\\|[ \t]\\)\\(\\?\\)\\([ \t]\\|$\\)" command)
+ (replace-match x t t command 2)))
+ (t (lambda (x) (concat command dired-mark-separator x))))))
(if on-each
(mapconcat stuff-it (mapcar 'shell-quote-argument file-list) ";")
- (let ((fns (mapconcat 'shell-quote-argument
- file-list dired-mark-separator)))
+ (let ((files (mapconcat 'shell-quote-argument
+ file-list dired-mark-separator)))
(if (> (length file-list) 1)
- (setq fns (concat dired-mark-prefix fns dired-mark-postfix)))
- (funcall stuff-it fns)))))
+ (setq files (concat dired-mark-prefix files dired-mark-postfix)))
+ (funcall stuff-it files)))))
;; This is an extra function so that it can be redefined by ange-ftp.
(defun dired-run-shell-command (command)
(while (/= 0 arg)
(setq file (dired-get-filename nil t))
(if (not file)
- (error "Can only kill file lines.")
+ (error "Can only kill file lines")
(save-excursion (and file
(dired-goto-subdir file)
(dired-kill-subdir)))
(defcustom dired-recursive-copies nil
"*Decide whether recursive copies are allowed.
-Nil means no recursive copies.
+nil means no recursive copies.
`always' means copy recursively without asking.
`top' means ask for each directory at top level.
Anything else means ask for each directory."
"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 be a plain file if only one marked
- file exists.
+ file exists. The way the default for the target directory is
+ computed depends on the value of `dired-dwim-target-directory'.
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'.
;; symlinks.
(defvar dired-copy-how-to-fn nil
- "Nil or a function used by `dired-do-copy' to determine target.
+ "nil or a function used by `dired-do-copy' to determine target.
See HOW-TO argument for `dired-do-create-files'.")
;;;###autoload
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."
+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."
(interactive "P")
(let ((dired-recursive-copies dired-recursive-copies))
(dired-do-create-files 'copy (function dired-copy-file)
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 symbolic links are made in that directory
-with the same names that the files currently have."
+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."
(interactive "P")
(dired-do-create-files 'symlink (function make-symbolic-link)
"Symlink" arg dired-keep-marker-symlink))
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 hard links are made in that directory
-with the same names that the files currently have."
+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."
(interactive "P")
(dired-do-create-files 'hardlink (function add-name-to-file)
"Hardlink" arg dired-keep-marker-hardlink))
(defun dired-do-rename (&optional arg)
"Rename current file or all marked (or next ARG) files.
When renaming just the current file, you specify the new name.
-When renaming multiple or marked files, you specify a directory."
+When renaming multiple or marked files, you specify a directory.
+The default suggested for the target directory depends on the value
+of `dired-dwim-target', which see."
(interactive "P")
(dired-do-create-files 'move (function dired-rename-file)
"Move" arg dired-keep-marker-rename "Rename"))
;;;###autoload
(defun dired-do-rename-regexp (regexp newname &optional arg whole-path)
- "Rename marked files containing REGEXP to NEWNAME.
+ "Rename selected files whose names match REGEXP to NEWNAME.
+
+With non-zero prefix argument ARG, the command operates on the next ARG
+files. Otherwise, it operates on all the marked files, or the current
+file if none are marked.
+
As each match is found, the user must type a character saying
what to do with it. For directions, type \\[help-command] at that time.
NEWNAME may contain \\=\\<n> or \\& as in `query-replace-regexp'.
;;;###autoload
(defun dired-do-copy-regexp (regexp newname &optional arg whole-path)
- "Copy all marked files containing REGEXP to NEWNAME.
+ "Copy selected files whose names match REGEXP to NEWNAME.
See function `dired-do-rename-regexp' for more info."
(interactive (dired-mark-read-regexp "Copy"))
(let ((dired-recursive-copies nil)) ; No recursive copies.
;;;###autoload
(defun dired-do-hardlink-regexp (regexp newname &optional arg whole-path)
- "Hardlink all marked files containing REGEXP to NEWNAME.
+ "Hardlink selected files whose names match REGEXP to NEWNAME.
See function `dired-do-rename-regexp' for more info."
(interactive (dired-mark-read-regexp "HardLink"))
(dired-do-create-files-regexp
;;;###autoload
(defun dired-do-symlink-regexp (regexp newname &optional arg whole-path)
- "Symlink all marked files containing REGEXP to NEWNAME.
+ "Symlink selected files whose names match REGEXP to NEWNAME.
See function `dired-do-rename-regexp' for more info."
(interactive (dired-mark-read-regexp "SymLink"))
(dired-do-create-files-regexp
(dired-insert-subdir-newpos dirname)) ; else compute new position
(dired-insert-subdir-doupdate
dirname elt (dired-insert-subdir-doinsert dirname switches))
- (if switches-have-R (dired-build-subdir-alist))
+ (if switches-have-R (dired-build-subdir-alist switches))
(dired-initial-position dirname)
(save-excursion (dired-mark-remembered mark-alist))))
dir (file-name-directory (directory-file-name dir))))
;;(setq dir (expand-file-name dir))
(or (dired-goto-subdir dir)
- (error "Cannot go up to %s - not in this tree." dir))))
+ (error "Cannot go up to %s - not in this tree" dir))))
;;;###autoload
(defun dired-tree-down ()
(defun dired-do-query-replace-regexp (from to &optional delimited)
"Do `query-replace-regexp' of FROM with TO, on all marked files.
Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
-If you exit (\\[keyboard-quit] or ESC), you can resume the query replace
+If you exit (\\[keyboard-quit], RET or q), you can resume the query replace
with the command \\[tags-loop-continue]."
(interactive
"sQuery replace in marked files (regexp): \nsQuery replace %s by: \nP")