]> code.delx.au - gnu-emacs/blobdiff - lisp/dired.el
(viper-insert-prev-from-insertion-ring)
[gnu-emacs] / lisp / dired.el
index e7dedadd7e1d18e9ad7131f3ada1d80bec8d6bea..8ca1d47b2b19289f9319e0c31380450d1b4c1d1b 100644 (file)
@@ -1,9 +1,11 @@
 ;;; dired.el --- directory-browsing commands
 
-;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 1997, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 1997, 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.
 
@@ -40,7 +42,7 @@
   :group 'environment)
 
 (defgroup dired-mark nil
-  "Handling marks in dired."
+  "Handling marks in Dired."
   :prefix "dired-"
   :group 'dired)
 
   "*Switches passed to `ls' for dired.  MUST contain the `l' option.
 May contain all other options that don't contradict `-l';
 may contain even `F', `b', `i' and `s'.  See also the variable
-`dired-ls-F-marks-symlinks' concerning the `F' switch."
+`dired-ls-F-marks-symlinks' concerning the `F' switch.
+On systems such as MS-DOS and MS-Windows, which use `ls' emulation in Lisp,
+some of the `ls' switches are not supported; see the doc string of
+`insert-directory' on ls-lisp.el for more details."
   :type 'string
   :group 'dired)
 
@@ -152,37 +157,35 @@ The target is used in the prompt for file copy, rename etc."
   :type 'boolean
   :group 'dired)
 
-(defcustom dired-free-space-program "df"
-  "*Program to get the amount of free space on a file system.
-We assume the output has the format of `df'.
-The value of this variable must be just a command name or file name;
-if you want to specify options, use `dired-free-space-args'.
-
-A value of nil disables this feature."
-  :type '(choice (string :tag "Program") (const :tag "None" nil))
-  :group 'dired)
-
-(defcustom dired-free-space-args "-Pk"
-  "*Options to use when running `dired-free-space-program'."
-  :type 'string
-  :group 'dired)
+; These variables were deleted and the replacements are on files.el.
+; We leave aliases behind for back-compatibility.
+(defvaralias 'dired-free-space-program 'directory-free-space-program)
+(defvaralias 'dired-free-space-args 'directory-free-space-args)
 
 ;;; Hook variables
 
-(defvar dired-load-hook nil
+(defcustom dired-load-hook nil
   "Run after loading dired.
-You can customize key bindings or load extensions with this.")
+You can customize key bindings or load extensions with this."
+  :group 'dired
+  :type 'hook)
 
-(defvar dired-mode-hook nil
-  "Run at the very end of dired-mode.")
+(defcustom dired-mode-hook nil
+  "Run at the very end of dired-mode."
+  :group 'dired
+  :type 'hook)
 
-(defvar dired-before-readin-hook nil
-  "This hook is run before a dired buffer is read in (created or reverted).")
+(defcustom dired-before-readin-hook nil
+  "This hook is run before a dired buffer is read in (created or reverted)."
+  :group 'dired
+  :type 'hook)
 
-(defvar dired-after-readin-hook nil
+(defcustom dired-after-readin-hook nil
   "Hook run after each time a file or directory is read by Dired.
 After each listing of a file or directory, this hook is run
-with the buffer narrowed to the listing.")
+with the buffer narrowed to the listing."
+  :group 'dired
+  :type 'hook)
 ;; Note this can't simply be run inside function `dired-ls' as the hook
 ;; functions probably depend on the dired-subdir-alist to be OK.
 
@@ -312,101 +315,110 @@ Subexpression 2 must end right before the \\n or \\r.")
 ;; It should end with a noun that can be pluralized by adding `s'.
 ;; Return value is the number of files marked, or nil if none were marked.
 (defmacro dired-mark-if (predicate msg)
-  (` (let (buffer-read-only count)
-       (save-excursion
-        (setq count 0)
-        (if (, msg) (message "Marking %ss..." (, msg)))
-        (goto-char (point-min))
-        (while (not (eobp))
-          (if (, predicate)
-              (progn
-                (delete-char 1)
-                (insert dired-marker-char)
-                (setq count (1+ count))))
-          (forward-line 1))
-        (if (, msg) (message "%s %s%s %s%s."
-                         count
-                         (, msg)
-                         (dired-plural-s count)
-                         (if (eq dired-marker-char ?\040) "un" "")
-                         (if (eq dired-marker-char dired-del-marker)
-                             "flagged" "marked"))))
-       (and (> count 0) count))))
+  `(let (buffer-read-only count)
+    (save-excursion
+      (setq count 0)
+      (if ,msg (message "Marking %ss..." ,msg))
+      (goto-char (point-min))
+      (while (not (eobp))
+        (if ,predicate
+            (progn
+              (delete-char 1)
+              (insert dired-marker-char)
+              (setq count (1+ count))))
+        (forward-line 1))
+      (if ,msg (message "%s %s%s %s%s."
+                        count
+                        ,msg
+                        (dired-plural-s count)
+                        (if (eq dired-marker-char ?\040) "un" "")
+                        (if (eq dired-marker-char dired-del-marker)
+                            "flagged" "marked"))))
+    (and (> count 0) count)))
 
 (defmacro dired-map-over-marks (body arg &optional show-progress)
-;;  "Macro: Perform BODY with point somewhere on each marked line
-;;and return a list of BODY's results.
-;;If no marked file could be found, execute BODY on the current line.
-;;  If ARG is an integer, use the next ARG (or previous -ARG, if ARG<0)
-;;  files instead of the marked files.
-;;  In that case point is dragged along.  This is so that commands on
-;;  the next ARG (instead of the marked) files can be chained easily.
-;;  If ARG is otherwise non-nil, use current file instead.
-;;If optional third arg SHOW-PROGRESS evaluates to non-nil,
-;;   redisplay the dired buffer after each file is processed.
-;;No guarantee is made about the position on the marked line.
-;;  BODY must ensure this itself if it depends on this.
-;;Search starts at the beginning of the buffer, thus the car of the list
-;;  corresponds to the line nearest to the buffer's bottom.  This
-;;  is also true for (positive and negative) integer values of ARG.
-;;BODY should not be too long as it is expanded four times."
-;;
-;;Warning: BODY must not add new lines before point - this may cause an
-;;endless loop.
-;;This warning should not apply any longer, sk  2-Sep-1991 14:10.
-  (` (prog1
-        (let (buffer-read-only case-fold-search found results)
-          (if (, arg)
-              (if (integerp (, arg))
-                  (progn;; no save-excursion, want to move point.
-                    (dired-repeat-over-lines
-                     (, arg)
-                     (function (lambda ()
-                                 (if (, show-progress) (sit-for 0))
-                                 (setq results (cons (, body) results)))))
-                    (if (< (, arg) 0)
-                        (nreverse results)
-                      results))
-                ;; non-nil, non-integer ARG means use current file:
-                (list (, body)))
-            (let ((regexp (dired-marker-regexp)) next-position)
-              (save-excursion
-                (goto-char (point-min))
-                ;; remember position of next marked file before BODY
-                ;; can insert lines before the just found file,
-                ;; confusing us by finding the same marked file again
-                ;; and again and...
+  "Eval BODY with point on each marked line.  Return a list of BODY's results.
+If no marked file could be found, execute BODY on the current line.
+  If ARG is an integer, use the next ARG (or previous -ARG, if ARG<0)
+  files instead of the marked files.
+  In that case point is dragged along.  This is so that commands on
+  the next ARG (instead of the marked) files can be chained easily.
+  If ARG is otherwise non-nil, use current file instead.
+If optional third arg SHOW-PROGRESS evaluates to non-nil,
+  redisplay the dired buffer after each file is processed.
+No guarantee is made about the position on the marked line.
+  BODY must ensure this itself if it depends on this.
+Search starts at the beginning of the buffer, thus the car of the list
+  corresponds to the line nearest to the buffer's bottom.  This
+  is also true for (positive and negative) integer values of ARG.
+BODY should not be too long as it is expanded four times."
+  ;;
+  ;;Warning: BODY must not add new lines before point - this may cause an
+  ;;endless loop.
+  ;;This warning should not apply any longer, sk  2-Sep-1991 14:10.
+  `(prog1
+       (let (buffer-read-only case-fold-search found results)
+        (if ,arg
+            (if (integerp ,arg)
+                (progn ;; no save-excursion, want to move point.
+                  (dired-repeat-over-lines
+                   ,arg
+                   (function (lambda ()
+                               (if ,show-progress (sit-for 0))
+                               (setq results (cons ,body results)))))
+                  (if (< ,arg 0)
+                      (nreverse results)
+                    results))
+              ;; non-nil, non-integer ARG means use current file:
+              (list ,body))
+          (let ((regexp (dired-marker-regexp)) next-position)
+            (save-excursion
+              (goto-char (point-min))
+              ;; remember position of next marked file before BODY
+              ;; can insert lines before the just found file,
+              ;; confusing us by finding the same marked file again
+              ;; and again and...
+              (setq next-position (and (re-search-forward regexp nil t)
+                                       (point-marker))
+                    found (not (null next-position)))
+              (while next-position
+                (goto-char next-position)
+                (if ,show-progress (sit-for 0))
+                (setq results (cons ,body results))
+                ;; move after last match
+                (goto-char next-position)
+                (forward-line 1)
+                (set-marker next-position nil)
                 (setq next-position (and (re-search-forward regexp nil t)
-                                         (point-marker))
-                      found (not (null next-position)))
-                (while next-position
-                  (goto-char next-position)
-                  (if (, show-progress) (sit-for 0))
-                  (setq results (cons (, body) results))
-                  ;; move after last match
-                  (goto-char next-position)
-                  (forward-line 1)
-                  (set-marker next-position nil)
-                  (setq next-position (and (re-search-forward regexp nil t)
-                                           (point-marker)))))
-              (if found
-                  results
-                (list (, body))))))
-       ;; save-excursion loses, again
-       (dired-move-to-filename))))
-
-(defun dired-get-marked-files (&optional localp arg)
+                                         (point-marker)))))
+            (if found
+                results
+              (list ,body)))))
+     ;; save-excursion loses, again
+     (dired-move-to-filename)))
+
+(defun dired-get-marked-files (&optional localp arg filter)
   "Return the marked files' names as list of strings.
 The list is in the same order as the buffer, that is, the car is the
   first marked file.
-Values returned are normally absolute pathnames.
+Values returned are normally absolute file names.
 Optional arg LOCALP as in `dired-get-filename'.
-Optional second argument ARG forces to use other files.  If ARG is an
-  integer, use the next ARG files.  If ARG is otherwise non-nil, use
-  current file.  Usually ARG comes from the current prefix arg."
-  (save-excursion
-    (nreverse (dired-map-over-marks (dired-get-filename localp) arg))))
-
+Optional second argument ARG specifies files near point
+ instead of marked files.  If ARG is an integer, use the next ARG files.
+  If ARG is otherwise non-nil, use file.  Usually ARG comes from
+  the command's prefix arg.
+Optional third argument FILTER, if non-nil, is a function to select
+  some of the files--those for which (funcall FILTER FILENAME) is non-nil."
+  (let ((all-of-them
+        (save-excursion
+          (dired-map-over-marks (dired-get-filename localp) arg)))
+       result)
+    (if (not filter)
+       (nreverse all-of-them)
+      (dolist (file all-of-them)
+       (if (funcall filter file)
+           (push file result)))
+      result)))
 \f
 ;; Function dired-ls is redefinable for VMS, ange-ftp, Prospero or
 ;; other special applications.
@@ -601,7 +613,8 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
   ;; Also, we can run this hook which may want to modify the switches
   ;; based on default-directory, e.g. with ange-ftp to a SysV host
   ;; where ls won't understand -Al switches.
-  (let (dirname)
+  (let (dirname
+       (indent-tabs-mode nil))
     (if (consp dir-or-list)
        (setq dirname (car dir-or-list))
       (setq dirname dir-or-list))
@@ -633,6 +646,8 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
       (let ((attributes (file-attributes dirname)))
        (if (eq (car attributes) t)
            (set-visited-file-modtime (nth 5 attributes))))
+      (if (consp buffer-undo-list)
+         (setq buffer-undo-list nil))
       (set-buffer-modified-p nil))))
 
 ;; Subroutines of dired-readin
@@ -680,28 +695,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
         (cdr dir-or-list))
       ;; Expand the file name here because it may have been abbreviated
       ;; in dired-noselect.
-      (insert-directory (expand-file-name dir-or-list) switches wildcard full-p)
-      (when (and full-p dired-free-space-program)
-       (save-excursion
-         (goto-char (point-min))
-         (when (re-search-forward "total [0-9]+$" nil t)
-           (insert "  free ")
-           (let ((beg (point)))
-             (if (zerop (call-process dired-free-space-program nil t nil
-                                      dired-free-space-args
-                                      (expand-file-name dir-or-list)))
-                 (progn
-                   (goto-char beg)
-                   (forward-line 1)
-                   (skip-chars-forward "^ \t")
-                   (forward-word 2)
-                   (skip-chars-forward " \t")
-                   (delete-region beg (point))
-                   (forward-word 1)
-                   (delete-region (point)
-                                  (progn (forward-line 1) (point))))
-               ;; The dired-free-space-program failed; delete its output
-               (delete-region (- beg 7) (point))))))))
+      (insert-directory (expand-file-name dir-or-list) switches wildcard full-p))
     ;; Quote certain characters, unless ls quoted them for us.
     (if (not (string-match "b" dired-actual-switches))
        (save-excursion
@@ -723,11 +717,13 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
     (while (< (point) end)
       (condition-case nil
          (if (dired-move-to-filename)
-             (put-text-property (point)
-                                (save-excursion
-                                  (dired-move-to-end-of-filename)
-                                  (point))
-                                'mouse-face 'highlight))
+             (add-text-properties
+              (point)
+              (save-excursion
+                (dired-move-to-end-of-filename)
+                (point))
+              '(mouse-face highlight
+                help-echo "mouse-2: visit this file in other window")))
        (error nil))
       (forward-line 1))))
 
@@ -921,13 +917,12 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
     (define-key map "*\177" 'dired-unmark-backward)
     (define-key map "*\C-n" 'dired-next-marked-file)
     (define-key map "*\C-p" 'dired-prev-marked-file)
-    (define-key map "*t" 'dired-do-toggle)
+    (define-key map "*t" 'dired-toggle-marks)
     ;; Lower keys for commands not operating on all the marked files
     (define-key map "a" 'dired-find-alternate-file)
     (define-key map "d" 'dired-flag-file-deletion)
     (define-key map "e" 'dired-find-file)
     (define-key map "f" 'dired-find-file)
-    (define-key map "w" 'dired-show-file-type)
     (define-key map "\C-m" 'dired-advertised-find-file)
     (define-key map "g" 'revert-buffer)
     (define-key map "h" 'describe-mode)
@@ -941,10 +936,12 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
     (define-key map "p" 'dired-previous-line)
     (define-key map "q" 'quit-window)
     (define-key map "s" 'dired-sort-toggle-or-edit)
-    (define-key map "t" 'dired-do-toggle)
+    (define-key map "t" 'dired-toggle-marks)
     (define-key map "u" 'dired-unmark)
     (define-key map "v" 'dired-view-file)
+    (define-key map "w" 'dired-copy-filename-as-kill)
     (define-key map "x" 'dired-do-flagged-delete)
+    (define-key map "y" 'dired-show-file-type)
     (define-key map "+" 'dired-create-directory)
     ;; moving
     (define-key map "<" 'dired-prev-dirline)
@@ -1120,7 +1117,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
       '(menu-item "Mark" dired-mark
                  :help "Mark current line's file for future operations"))
     (define-key map [menu-bar mark toggle-marks]
-      '(menu-item "Toggle Marks" dired-do-toggle
+      '(menu-item "Toggle Marks" dired-toggle-marks
                  :help "Mark unmarked files, unmark marked ones"))
 
     (define-key map [menu-bar operate]
@@ -1183,7 +1180,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
 (defun dired-mode (&optional dirname switches)
   "\
 Mode for \"editing\" directory listings.
-In dired, you are \"editing\" a list of the files in a directory and
+In Dired, you are \"editing\" a list of the files in a directory and
   \(optionally) its subdirectories, in the format of `ls -lR'.
   Each directory is a page: use \\[backward-page] and \\[forward-page] to move pagewise.
 \"Editing\" means that you can run shell commands on files, visit,
@@ -1289,7 +1286,9 @@ In the latter case, you have to do \\[dired-build-subdir-alist] to
 parse the buffer again."
   (interactive)
   (let (buffer-read-only)
-    (undo)))
+    (undo)
+    (message "Change in Dired buffer undone.
+Actual changes in files cannot be undone by Emacs.")))
 
 (defun dired-next-line (arg)
   "Move down lines then position at filename.
@@ -1323,7 +1322,7 @@ Optional prefix ARG says how many lines to move; default is one line."
   (dired-next-dirline (- arg)))
 
 (defun dired-up-directory (&optional other-window)
-  "Run dired on parent directory of current directory.
+  "Run Dired on parent directory of current directory.
 Find the parent directory either in this buffer or another buffer.
 Creates a buffer if necessary."
   (interactive "P")
@@ -1339,65 +1338,95 @@ Creates a buffer if necessary."
            (dired up))
          (dired-goto-file dir)))))
 
-;; Force `f' rather than `e' in the mode doc:
-(defalias 'dired-advertised-find-file 'dired-find-file)
-(defun dired-find-file ()
-  "In dired, visit the file or directory named on this line."
+(defun dired-get-file-for-visit ()
+  "Get the current line's file name, with an error if file does not exist."
   (interactive)
   (let ((file-name (file-name-sans-versions (dired-get-filename) t)))
     (if (file-exists-p file-name)
-       (find-file file-name)
+       file-name
       (if (file-symlink-p file-name)
          (error "File is a symlink to a nonexistent target")
        (error "File no longer exists; type `g' to update Dired buffer")))))
 
+;; Force `f' rather than `e' in the mode doc:
+(defalias 'dired-advertised-find-file 'dired-find-file)
+(defun dired-find-file ()
+  "In Dired, visit the file or directory named on this line."
+  (interactive)
+  (find-file (dired-get-file-for-visit)))
+
 (defun dired-find-alternate-file ()
-  "In dired, visit this file or directory instead of the dired buffer."
+  "In Dired, visit this file or directory instead of the dired buffer."
   (interactive)
   (set-buffer-modified-p nil)
-  (find-alternate-file (dired-get-filename)))
+  (find-alternate-file (dired-get-file-for-visit)))
 
 (defun dired-mouse-find-file-other-window (event)
-  "In dired, visit the file or directory name you click on."
+  "In Dired, visit the file or directory name you click on."
   (interactive "e")
-  (let (file)
+  (let (window pos file)
     (save-excursion
-      (set-buffer (window-buffer (posn-window (event-end event))))
-      (save-excursion
-       (goto-char (posn-point (event-end event)))
-       (setq file (dired-get-filename))))
-    (select-window (posn-window (event-end event)))
+      (setq window (posn-window (event-end event))
+           pos (posn-point (event-end event)))
+      (if (not (windowp window))
+         (error "No file chosen"))
+      (set-buffer (window-buffer window))
+      (goto-char pos)
+      (setq file (dired-get-file-for-visit)))
+    (select-window window)
     (find-file-other-window (file-name-sans-versions file t))))
 
+(defcustom dired-view-command-alist
+  '(("[.]ps\\'" . "gv -spartan -color -watch")
+    ("[.]pdf\\'" . "xpdf")
+    ("[.]dvi\\'" . "xdvi -sidemargin 0.5 -topmargin 1"))
+  "Alist specifying how to view special types of files.
+Each element has the form (REGEXP . SHELL-COMMAND).
+When the file name matches REGEXP, `dired-view-file'
+invokes SHELL-COMMAND to view the file, putting the file name
+at the end of the command."
+  :group 'dired
+  :type '(alist :key-type regexp :value-type string)
+  :version "21.4")
+
 (defun dired-view-file ()
-  "In dired, examine a file in view mode, returning to dired when done.
-When file is a directory, show it in this buffer if it is inserted;
-otherwise, display it in another buffer."
+  "In Dired, examine a file in view mode, returning to dired when done.
+When file is a directory, show it in this buffer if it is inserted.
+Some kinds of files are displayed using external viewer programs;
+see `dired-view-command-alist'.  Otherwise, display it in another buffer."
   (interactive)
-  (if (file-directory-p (dired-get-filename))
-      (or (and (cdr dired-subdir-alist)
-              (dired-goto-subdir (dired-get-filename)))
-         (dired (dired-get-filename)))
-    (view-file (dired-get-filename))))
+  (let ((file (dired-get-file-for-visit)))
+    (if (file-directory-p file)
+       (or (and (cdr dired-subdir-alist)
+                (dired-goto-subdir file))
+           (dired file))
+      (let (cmd)
+       ;; Look for some other way to view a certain file.
+       (dolist (elt dired-view-command-alist)
+         (if (string-match (car elt) file)
+             (setq cmd (cdr elt))))
+       (if cmd
+           (dired-run-shell-command (concat cmd " " file))
+         (view-file file))))))
 
 (defun dired-find-file-other-window ()
-  "In dired, visit this file or directory in another window."
+  "In Dired, visit this file or directory in another window."
   (interactive)
-  (find-file-other-window (file-name-sans-versions (dired-get-filename) t)))
+  (find-file-other-window (dired-get-file-for-visit)))
 
 (defun dired-display-file ()
-  "In dired, display this file or directory in another window."
+  "In Dired, display this file or directory in another window."
   (interactive)
-  (let ((file (file-name-sans-versions (dired-get-filename) t)))
-    (display-buffer (find-file-noselect file))))
+  (display-buffer (find-file-noselect (dired-get-file-for-visit))))
 \f
-;;; Functions for extracting and manipulating file names in dired buffers.
+;;; Functions for extracting and manipulating file names in Dired buffers.
 
 (defun dired-get-filename (&optional localp no-error-if-not-filep)
-  "In dired, return name of file mentioned on this line.
+  "In Dired, return name of file mentioned on this line.
 Value returned normally includes the directory name.
 Optional arg LOCALP with value `no-dir' means don't include directory
-  name in result.  A value of t means construct name relative to
+  name in result.  A value of `verbatim' means to return the name exactly as
+  it occurs in the buffer, and a value of t means construct name relative to
   `default-directory', which still may contain slashes if in a subdirectory.
 Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
   this line, otherwise an error occurs."
@@ -1423,18 +1452,34 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
                             file)
                         "\"")))))
     (and file (file-name-absolute-p file)
+        ;; A relative file name can start with ~.
+        ;; Don't treat it as absolute in this context.
+        (not (eq (aref file 0) ?~))
         (setq already-absolute t))
     (and file buffer-file-coding-system
         (not file-name-coding-system)
         (not default-file-name-coding-system)
         (setq file (encode-coding-string file buffer-file-coding-system)))
     (cond
+     ((null file)
+      nil)
+     ((eq localp 'verbatim)
+      file)
      ((and (eq localp 'no-dir) already-absolute)
       (file-name-nondirectory file))
-     ((or already-absolute (eq localp 'no-dir))
+     (already-absolute
+      (if (find-file-name-handler file nil)
+         (concat "/:" file)
+       file))
+     ((eq localp 'no-dir)
       file)
+     ((equal (dired-current-directory) "/")
+      (setq file (concat (dired-current-directory localp) file))
+      (if (find-file-name-handler file nil)
+         (concat "/:" file)
+       file))
      (t
-      (and file (concat (dired-current-directory localp) file))))))
+      (concat (dired-current-directory localp) file)))))
 
 (defun dired-string-replace-match (regexp string newtext
                                          &optional literal global)
@@ -1483,35 +1528,38 @@ DIR must be a directory name, not a file name."
 (defvar dired-move-to-filename-regexp
   (let* ((l "\\([A-Za-z]\\|[^\0-\177]\\)")
         ;; In some locales, month abbreviations are as short as 2 letters,
-        ;; and they can be padded on the right with spaces.
-        ;; weiand: changed: month ends potentially with . or , or .,
-;;old   (month (concat l l "+ *"))
-        (month (concat l l "+[.]?,? *"))
-        ;; Recognize any non-ASCII character.  
-        ;; The purpose is to match a Kanji character.
-        (k "[^\0-\177]")
-        ;; (k "[^\x00-\x7f\x80-\xff]")
+        ;; and they can be followed by ".".
+        (month (concat l l "+\\.?"))
         (s " ")
         (yyyy "[0-9][0-9][0-9][0-9]")
-        (mm "[ 0-1][0-9]")
-;;old   (dd "[ 0-3][0-9]")
-        (dd "[ 0-3][0-9][.]?")
+        (dd "[ 0-3][0-9]")
         (HH:MM "[ 0-2][0-9]:[0-5][0-9]")
-        (western (concat "\\(" month s dd "\\|" dd s month "\\)"
-         ;; weiand: changed: year potentially unaligned
-;;old                    s "\\(" HH:MM "\\|" s yyyy "\\|" yyyy s "\\)"))
-                         s "\\(" HH:MM 
-                                 "\\|" yyyy s s "?"
-                                 "\\|" s "?" yyyy
-                            "\\)"))
-        (japanese (concat mm k s dd k s "\\(" s HH:MM "\\|" yyyy k "\\)")))
+        (seconds "[0-6][0-9]\\([.,][0-9]+\\)?")
+        (zone "[-+][0-2][0-9][0-5][0-9]")
+        (iso-mm-dd "[01][0-9]-[0-3][0-9]")
+        (iso-time (concat HH:MM "\\(:" seconds "\\( ?" zone "\\)?\\)?"))
+        (iso (concat "\\(\\(" yyyy "-\\)?" iso-mm-dd "[ T]" iso-time
+                     "\\|" yyyy "-" iso-mm-dd "\\)"))
+        (western (concat "\\(" month s "+" dd "\\|" dd "\\.?" s month "\\)"
+                         s "+"
+                         "\\(" HH:MM "\\|" yyyy "\\)"))
+        (western-comma (concat month s "+" dd "," s "+" yyyy))
+        ;; Japanese MS-Windows ls-lisp has one-digit months, and
+        ;; omits the Kanji characters after month and day-of-month.
+        (mm "[ 0-1]?[0-9]")
+        (japanese
+         (concat mm l "?" s dd l "?" s "+"
+                 "\\(" HH:MM "\\|" yyyy l "?" "\\)")))
         ;; The "[0-9]" below requires the previous column to end in a digit.
         ;; This avoids recognizing `1 may 1997' as a date in the line:
         ;; -r--r--r--   1 may      1997        1168 Oct 19 16:49 README
+        ;; The "[kMGTPEZY]?" below supports "ls -alh" output.
         ;; The ".*" below finds the last match if there are multiple matches.
         ;; This avoids recognizing `jservice  10  1024' as a date in the line:
         ;; drwxr-xr-x  3 jservice  10  1024 Jul  2  1997 esg-host
-    (concat ".*[0-9]" s "\\(" western "\\|" japanese "\\)" s))
+    (concat ".*[0-9][kMGTPEZY]?" s
+           "\\(" western "\\|" western-comma "\\|" japanese "\\|" iso "\\)"
+           s "+"))
   "Regular expression to match up to the file name in a directory listing.
 The default value is designed to recognize dates and times
 regardless of the language.")
@@ -1596,6 +1644,37 @@ regardless of the language.")
        nil
       (point))))
 
+\f
+;;; COPY NAMES OF MARKED FILES INTO KILL-RING.
+
+(defun dired-copy-filename-as-kill (&optional arg)
+  "Copy names of marked (or next ARG) files into the kill ring.
+The names are separated by a space.
+With a zero prefix arg, use the complete pathname of each marked file.
+With \\[universal-argument], use the relative pathname of each marked file.
+
+If on a subdir headerline, use subdirname instead; prefix arg is ignored
+in this case.
+
+You can then feed the file name(s) to other commands with \\[yank]."
+  (interactive "P")
+  (let ((string
+         (or (dired-get-subdir)
+             (mapconcat (function identity)
+                        (if arg
+                            (cond ((zerop (prefix-numeric-value arg))
+                                   (dired-get-marked-files))
+                                  ((integerp arg)
+                                   (dired-get-marked-files 'no-dir arg))
+                                  (t    ; else a raw arg
+                                   (dired-get-marked-files t)))
+                          (dired-get-marked-files 'no-dir))
+                        " "))))
+    (if (eq last-command 'kill-region)
+       (kill-append string nil)
+      (kill-new string))
+    (message "%s" string)))
+
 \f
 ;; Keeping Dired buffers in sync with the filesystem and with each other
 
@@ -1756,15 +1835,24 @@ regardless of the language.")
          nil                           ; return nil if not found
        (error "%s directory" (if (> arg 0) "Last" "First"))))))
 
-(defun dired-build-subdir-alist ()
+(defun dired-build-subdir-alist (&optional switches)
   "Build `dired-subdir-alist' by parsing the buffer.
-Returns the new value of the alist."
+Returns the new value of the alist.
+If optional arg SWITCHES is non-nil, use its value
+instead of `dired-actual-switches'."
   (interactive)
   (dired-clear-alist)
   (save-excursion
-    (let ((count 0)
-         (buffer-read-only nil)
-         new-dir-name)
+    (let* ((count 0)
+          (buffer-read-only nil)
+          (switches (or switches dired-actual-switches))
+          new-dir-name
+          (R-ftp-base-dir-regex
+           ;; Used to expand subdirectory names correctly in recursive
+           ;; ange-ftp listings.
+           (and (string-match "R" switches)
+                (string-match "\\`/.*:\\(/.*\\)" default-directory)
+                (concat "\\`" (match-string 1 default-directory)))))
       (goto-char (point-min))
       (setq dired-subdir-alist nil)
       (while (and (re-search-forward dired-subdir-regexp nil t)
@@ -1778,7 +1866,15 @@ Returns the new value of the alist."
        (save-excursion
          (goto-char (match-beginning 1))
          (setq new-dir-name
-               (expand-file-name (buffer-substring (point) (match-end 1))))
+               (buffer-substring-no-properties (point) (match-end 1))
+               new-dir-name
+               (save-match-data
+                 (if (and R-ftp-base-dir-regex
+                          (not (string= new-dir-name default-directory))
+                          (string-match R-ftp-base-dir-regex new-dir-name))
+                     (concat default-directory
+                             (substring new-dir-name (match-end 0)))
+                   (expand-file-name new-dir-name))))
          (delete-region (point) (match-end 1))
          (insert new-dir-name))
        (setq count (1+ count))
@@ -1910,7 +2006,7 @@ Optional argument means return a file name relative to `default-directory'."
 
 (defcustom dired-recursive-deletes nil ; Default only delete empty directories.
   "*Decide whether recursive deletes are allowed.
-Nil means no recursive deletes.
+nil means no recursive deletes.
 `always' means delete recursively without asking.  This is DANGEROUS!
 `top' means ask for each directory at top level, but delete its subdirectories
 without asking.
@@ -1953,7 +2049,7 @@ Anything else, ask for each sub-directory."
       (delete-directory file))))
 
 (defun dired-do-flagged-delete (&optional nomessage)
-  "In dired, delete the files flagged for deletion.
+  "In Dired, delete the files flagged for deletion.
 If NOMESSAGE is non-nil, we don't display any message
 if there are no flagged files."
   (interactive)
@@ -2011,9 +2107,9 @@ if there are no flagged files."
                      ;; if we get here, removing worked
                      (setq succ (1+ succ))
                      (message "%s of %s deletions" succ count)
-                     (delete-region (progn (beginning-of-line) (point))
-                                    (progn (forward-line 1) (point)))
-                     (dired-clean-up-after-deletion fn))
+                     (dired-fun-in-all-buffers
+                      (file-name-directory fn) (file-name-nondirectory fn)
+                      (function dired-delete-entry) fn))
                  (error;; catch errors from failed deletions
                   (dired-log "%s\n" err)
                   (setq failures (cons (car (car l)) failures)))))
@@ -2028,6 +2124,29 @@ if there are no flagged files."
       (message "(No deletions performed)")))
   (dired-move-to-filename))
 
+(defun dired-fun-in-all-buffers (directory file fun &rest args)
+  ;; In all buffers dired'ing DIRECTORY, run FUN with ARGS.
+  ;; If the buffer has a wildcard pattern, check that it matches FILE.
+  ;; (FILE does not include a directory component.)
+  ;; FILE may be nil, in which case ignore it.
+  ;; Return list of buffers where FUN succeeded (i.e., returned non-nil).
+  (let (success-list)
+    (dolist (buf (dired-buffers-for-dir (expand-file-name directory)
+                                       file))
+      (with-current-buffer buf
+       (if (apply fun args)
+           (setq success-list (cons (buffer-name buf) success-list)))))
+    success-list))
+
+;; Delete the entry for FILE from 
+(defun dired-delete-entry (file)
+  (save-excursion
+    (and (dired-goto-file file)
+        (let (buffer-read-only)
+          (delete-region (progn (beginning-of-line) (point))
+                         (save-excursion (forward-line 1) (point))))))
+  (dired-clean-up-after-deletion file))
+
 ;; This is a separate function for the sake of dired-x.el.
 (defun dired-clean-up-after-deletion (fn)
   ;; Clean up after a deleted file or directory FN.
@@ -2066,7 +2185,7 @@ if there are no flagged files."
     ;; let window shrink to fit:
     (let ((window (selected-window))
          target-lines w2)
-      (cond ;; if split-window-threshold is enabled, use the largest window
+      (cond ;; if split-height-threshold is enabled, use the largest window
             ((and (> (window-height (setq w2 (get-largest-window)))
                     split-height-threshold)
                  (= (frame-width) (window-width w2)))
@@ -2106,25 +2225,25 @@ Command symbols are `byte-compile', `chgrp', `chmod', `chown', `compress',
 `uncompress'.")
 
 (defun dired-mark-pop-up (bufname op-symbol files function &rest args)
-  ;;"Args BUFNAME OP-SYMBOL FILES FUNCTION &rest ARGS.
-  ;;Return FUNCTION's result on ARGS after popping up a window (in a buffer
-  ;;named BUFNAME, nil gives \" *Marked Files*\") showing the marked
-  ;;files.  Uses function `dired-pop-to-buffer' to do that.
 ;; FUNCTION should not manipulate files.
 ;; It should only read input (an argument or confirmation).
-  ;;The window is not shown if there is just one file or
 ;; OP-SYMBOL is a member of the list in `dired-no-confirm'.
-  ;;FILES is the list of marked files."
+  "Args BUFNAME OP-SYMBOL FILES FUNCTION &rest ARGS.
+Return FUNCTION's result on ARGS after popping up a window (in a buffer
+named BUFNAME, nil gives \" *Marked Files*\") showing the marked
+files.  Uses function `dired-pop-to-buffer' to do that.
+ FUNCTION should not manipulate files.
+ It should only read input (an argument or confirmation).
+The window is not shown if there is just one file or
+ OP-SYMBOL is a member of the list in `dired-no-confirm'.
+FILES is the list of marked files."
   (or bufname (setq bufname  " *Marked Files*"))
   (if (or (eq dired-no-confirm t)
          (memq op-symbol dired-no-confirm)
          (= (length files) 1))
       (apply function args)
-    (save-excursion
-      (set-buffer (get-buffer-create bufname))
+    (with-current-buffer (get-buffer-create bufname)
       (erase-buffer)
       (dired-format-columns-of-files files)
-      (remove-text-properties (point-min) (point-max) '(mouse-face)))
+      (remove-text-properties (point-min) (point-max)
+                             '(mouse-face nil help-echo nil)))
     (save-window-excursion
       (dired-pop-to-buffer bufname)
       (apply function args))))
@@ -2186,7 +2305,7 @@ Command symbols are `byte-compile', `chgrp', `chmod', `chown', `compress',
   ;; Point must be at beginning of line
   ;; Should be equivalent to (save-excursion (not (dired-move-to-filename)))
   ;; but is about 1.5..2.0 times as fast. (Actually that's not worth it)
-  (or (looking-at "^$\\|^. *$\\|^. total\\|^. wildcard\\|^. used")
+  (or (looking-at "^$\\|^. *$\\|^. total\\|^. wildcard\\|^. used\\|^. find")
       (and (looking-at dired-subdir-regexp)
           (save-excursion (not (dired-move-to-filename))))))
 
@@ -2260,7 +2379,7 @@ If looking at a subdir, unmark all its files except `.' and `..'."
     (dired-mark arg)))
 
 (defun dired-flag-file-deletion (arg)
-  "In dired, flag the current line's file for deletion.
+  "In Dired, flag the current line's file for deletion.
 With prefix arg, repeat over several lines.
 
 If on a subdir headerline, mark all its files except `.' and `..'."
@@ -2269,14 +2388,13 @@ If on a subdir headerline, mark all its files except `.' and `..'."
     (dired-mark arg)))
 
 (defun dired-unmark-backward (arg)
-  "In dired, move up lines and remove deletion flag there.
+  "In Dired, move up lines and remove deletion flag there.
 Optional prefix ARG says how many lines to unflag; default is one line."
   (interactive "p")
   (dired-unmark (- arg)))
 
-(defun dired-do-toggle ()
-  "Toggle marks.
-That is, currently marked files become unmarked and vice versa.
+(defun dired-toggle-marks ()
+  "Toggle marks: marked files become unmarked, and vice versa.
 Files marked with other flags (such as `D') are not affected.
 `.' and `..' are never toggled.
 As always, hidden subdirs are not affected."
@@ -2356,7 +2474,7 @@ A prefix argument means to unmark them instead.
      "matching file")))
 
 (defun dired-flag-files-regexp (regexp)
-  "In dired, flag all files containing the specified REGEXP for deletion.
+  "In Dired, flag all files containing the specified REGEXP for deletion.
 The match is against the non-directory part of the filename.  Use `^'
   and `$' to anchor matches.  Exclude subdirs by hiding them.
 `.' and `..' are never flagged."
@@ -2616,6 +2734,8 @@ With a prefix argument you can edit the current listing switches instead."
   (dired-sort-set-modeline)
   (revert-buffer))
 
+;; Some user code loads dired especially for this.
+;; Don't do that--use replace-regexp-in-string instead.
 (defun dired-replace-in-string (regexp newtext string)
   ;; Replace REGEXP with NEWTEXT everywhere in STRING and return result.
   ;; NEWTEXT is taken literally---no \\DIGIT escapes will be recognized.
@@ -2678,7 +2798,8 @@ To be called first in body of `dired-sort-other', etc."
 
 (autoload 'dired-diff "dired-aux"
   "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'."
   t)
 
@@ -2724,18 +2845,33 @@ If no files are marked or a specific 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.
 
-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.
+
+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 `?'.
 
-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.
+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."
   t)
 
 (autoload 'dired-do-kill-lines "dired-aux"
@@ -2886,6 +3022,10 @@ Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
 If FILE is a symbolic link and the optional argument DEREF-SYMLINKS is
 true then the type of the file linked to by FILE is printed instead." 
   t)
+
+(autoload 'dired-run-shell-command "dired-aux")
+
+(autoload 'dired-query "dired-aux")
 \f
 (if (eq system-type 'vax-vms)
     (load "dired-vms"))