(compilation-error-regexp-alist): Fix previous change.
[bpt/emacs.git] / lisp / dired.el
index 4cdc1da..705c1b8 100644 (file)
@@ -1,9 +1,9 @@
 ;;; dired.el --- directory-browsing commands
 
-;; Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
 
-;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>.
-;; Version: 6
+;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>
+;; Maintainer: FSF
 
 ;; This file is part of GNU Emacs.
 
@@ -38,7 +38,8 @@
 (defvar dired-listing-switches "-al"
   "*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'.")
+may contain even `F', `b', `i' and `s'.  See also the variable
+`dired-ls-F-marks-symlinks' concerning the `F' switch.")
 
 ; Don't use absolute paths as /bin should be in any PATH and people
 ; may prefer /usr/local/gnu/bin or whatever.  However, chown is
@@ -46,9 +47,9 @@ may contain even `F', `b', `i' and `s'.")
 
 ;;;###autoload
 (defvar dired-chown-program
-  (if (memq system-type '(hpux dgux usg-unix-v silicon-graphics-unix))
+  (if (memq system-type '(hpux dgux usg-unix-v irix linux))
       "chown" "/etc/chown")
-  "Name of chown command (usully `chown' or `/etc/chown').")
+  "Name of chown command (usually `chown' or `/etc/chown').")
 
 ;;;###autoload
 (defvar dired-ls-F-marks-symlinks nil
@@ -184,6 +185,7 @@ directory name and the cdr is the actual files to list.")
               "-[-r][-w].[-r][-w][xs][-r][-w]."
               "-[-r][-w].[-r][-w].[-r][-w][xst]")
             "\\|"))
+(defvar dired-re-perms "-[-r][-w].[-r][-w].[-r][-w].")
 (defvar dired-re-dot "^.* \\.\\.?$")
 
 (defvar dired-subdir-alist nil
@@ -192,7 +194,7 @@ Each subdirectory has an element: (DIRNAME . STARTMARKER).
 The order of elements is the reverse of the order in the buffer.
 In simple cases, this list contains one element.")
 
-(defvar dired-subdir-regexp "^. \\([^ \n\r]+\\)\\(:\\)[\n\r]"
+(defvar dired-subdir-regexp "^. \\([^\n\r]+\\)\\(:\\)[\n\r]"
   "Regexp matching a maybe hidden subdirectory line in `ls -lR' output.
 Subexpression 1 is the subdirectory proper, no trailing colon.
 The match starts at the beginning of the line and ends after the end
@@ -363,7 +365,8 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
     (if (consp dir-or-list)
        (setq dirname (car dir-or-list))
       (setq dirname dir-or-list))
-    (setq dirname (expand-file-name (directory-file-name dirname)))
+    (setq dirname (abbreviate-file-name
+                  (expand-file-name (directory-file-name dirname))))
     (if (file-directory-p dirname)
        (setq dirname (file-name-as-directory dirname)))
     (if (consp dir-or-list)
@@ -396,11 +399,21 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
     (set-buffer buffer)
     (if (not new-buffer-p)             ; existing buffer ...
        (if switches                    ; ... but new switches
-           (dired-sort-other switches))        ; this calls dired-revert
+           (dired-sort-other switches) ; this calls dired-revert
+         ;; If directory has changed on disk, offer to revert.
+         (if (let ((attributes (file-attributes dirname))
+                   (modtime (visited-file-modtime)))
+               (or (eq modtime 0)
+                   (not (eq (car attributes) t))
+                   (and (= (car (nth 5 attributes)) (car modtime))
+                        (= (nth 1 (nth 5 attributes)) (cdr modtime)))))
+             nil
+           (message "Directory has changed on disk; type `g' to update Dired")))
       ;; Else a new buffer
-      (setq default-directory (if (file-directory-p dirname)
-                                 dirname
-                               (file-name-directory dirname)))
+      (setq default-directory
+           (if (file-directory-p dirname)
+               dirname
+             (file-name-directory dirname)))
       (or switches (setq switches dired-listing-switches))
       (dired-mode dirname switches)
       ;; default-directory and dired-actual-switches are set now
@@ -474,11 +487,14 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
        ;; alist to be OK.
        )
       (message "Reading directory %s...done" dirname)
-      (set-buffer-modified-p nil)
       ;; Must first make alist buffer local and set it to nil because
       ;; dired-build-subdir-alist will call dired-clear-alist first
       (set (make-local-variable 'dired-subdir-alist) nil)
-      (dired-build-subdir-alist))))
+      (dired-build-subdir-alist)
+      (let ((attributes (file-attributes dirname)))
+       (if (eq (car attributes) t)
+           (set-visited-file-modtime (nth 5 attributes))))
+      (set-buffer-modified-p nil))))
 
 ;; Subroutines of dired-readin
 
@@ -489,13 +505,19 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
     (if (consp dir-or-list)
        (setq dirname (car dir-or-list))
       (setq dirname dir-or-list))
-    (if (equal default-directory dirname)      ;; i.e., (file-directory-p dirname)
+    ;; Expand before comparing in case one or both have been abbreviated.
+    (if (and (equal (expand-file-name default-directory)
+                   (expand-file-name dirname))
+            (not (consp dir-or-list)))
+       ;; If we are reading a whole single directory...
        (dired-insert-directory dir-or-list dired-actual-switches nil t)
       (if (not (file-readable-p
                (directory-file-name (file-name-directory dirname))))
          (error "Directory %s inaccessible or nonexistent" dirname)
-       ;; else assume it contains wildcards:
-       (dired-insert-directory dir-or-list dired-actual-switches t)
+       ;; Else assume it contains wildcards,
+       ;; unless it is an explicit list of files.
+       (dired-insert-directory dir-or-list dired-actual-switches
+                               (not (listp dir-or-list)))
        (save-excursion         ;; insert wildcard instead of total line:
          (goto-char (point-min))
          (insert "wildcard " (file-name-nondirectory dirname) "\n"))))))
@@ -503,15 +525,29 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
 (defun dired-insert-directory (dir-or-list switches &optional wildcard full-p)
   ;; Do the right thing whether dir-or-list is atomic or not.  If it is,
   ;; inset all files listed in the cdr (the car is the passed-in directory
-  ;; list.
-  (if (consp dir-or-list)
-      (progn
-      (mapcar
-       (function (lambda (x) (insert-directory x switches wildcard full-p)))
-       (cdr dir-or-list)))
-    (insert-directory dir-or-list switches wildcard full-p))
+  ;; list).
+  (let ((opoint (point)))
+    (if (consp dir-or-list)
+       (progn
+         (mapcar
+          (function (lambda (x) (insert-directory x switches wildcard full-p)))
+          (cdr dir-or-list)))
+      (insert-directory dir-or-list switches wildcard full-p))
+    (dired-insert-set-properties opoint (point)))
   (setq dired-directory dir-or-list))
 
+(defun dired-insert-set-properties (beg end)
+  (save-excursion
+    (goto-char beg)
+    (while (< (point) end)
+      (if (dired-move-to-filename)
+         (put-text-property (point)
+                            (save-excursion
+                              (dired-move-to-end-of-filename)
+                              (point))
+                            'mouse-face 'highlight))
+      (forward-line 1))))
+
 (defun dired-insert-headerline (dir);; also used by dired-insert-subdir
   ;; Insert DIR's headerline with no trailing slash, exactly like ls
   ;; would, and put cursor where dired-build-subdir-alist puts subdir
@@ -623,7 +659,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
 
 ;; Remove directory DIR from any directory cache.
 (defun dired-uncache (dir)
-  (let ((handler (find-file-name-handler dir)))
+  (let ((handler (find-file-name-handler dir 'dired-uncache)))
     (if handler
        (funcall handler 'dired-uncache dir))))
 \f
@@ -632,13 +668,12 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
 (defvar dired-mode-map nil "Local keymap for dired-mode buffers.")
 (if dired-mode-map
     nil
-  ;; Force `f' rather than `e' in the mode doc:
-  (defalias 'dired-advertised-find-file 'dired-find-file)
   ;; This looks ugly when substitute-command-keys uses C-d instead d:
   ;;  (define-key dired-mode-map "\C-d" 'dired-flag-file-deletion)
 
   (setq dired-mode-map (make-keymap))
   (suppress-keymap dired-mode-map)
+  (define-key dired-mode-map [mouse-2] 'dired-mouse-find-file-other-window)
   ;; Commands to mark or flag certain categories of files
   (define-key dired-mode-map "#" 'dired-flag-auto-save-files)
   (define-key dired-mode-map "*" 'dired-mark-executables)
@@ -674,8 +709,10 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
   (define-key dired-mode-map "\M-{" 'dired-prev-marked-file)
   (define-key dired-mode-map "\M-}" 'dired-next-marked-file)
   ;; Make all regexp commands share a `%' prefix:
-  (defalias 'dired-regexp-prefix (make-sparse-keymap))
-  (define-key dired-mode-map "%" 'dired-regexp-prefix)
+  ;; We used to get to the submap via a symbol dired-regexp-prefix,
+  ;; but that seems to serve little purpose, and copy-keymap
+  ;; does a better job without it.
+  (define-key dired-mode-map "%" nil)
   (define-key dired-mode-map "%u" 'dired-upcase)
   (define-key dired-mode-map "%l" 'dired-downcase)
   (define-key dired-mode-map "%d" 'dired-flag-files-regexp)
@@ -722,14 +759,133 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
   (define-key dired-mode-map "\C-_" 'dired-undo)
   (define-key dired-mode-map "\C-xu" 'dired-undo)
   )
-
-(or (member '(dired-sort-mode dired-sort-mode) minor-mode-alist)
-    ;; Test whether this has already been done in case dired is reloaded
-    ;; There may be several elements with dired-sort-mode as car.
-    (setq minor-mode-alist
-         (cons '(dired-sort-mode dired-sort-mode)
-               ;; dired-sort-mode is nil outside dired
-               minor-mode-alist)))
+\f
+;; Make menu bar items.
+
+;; Get rid of the Edit menu bar item to save space.
+(define-key dired-mode-map [menu-bar edit] 'undefined)
+
+(define-key dired-mode-map [menu-bar subdir]
+  (cons "Subdir" (make-sparse-keymap "Subdir")))
+
+(define-key dired-mode-map [menu-bar subdir hide-all]
+  '("Hide All" . dired-hide-all))
+(define-key dired-mode-map [menu-bar subdir hide-subdir]
+  '("Hide Subdir" . dired-hide-subdir))
+(define-key dired-mode-map [menu-bar subdir tree-down]
+  '("Tree Down" . dired-tree-down))
+(define-key dired-mode-map [menu-bar subdir tree-up]
+  '("Tree Up" . dired-tree-up))
+(define-key dired-mode-map [menu-bar subdir up]
+  '("Up Directory" . dired-up-directory))
+(define-key dired-mode-map [menu-bar subdir prev-subdir]
+  '("Prev Subdir" . dired-prev-subdir))
+(define-key dired-mode-map [menu-bar subdir next-subdir]
+  '("Next Subdir" . dired-next-subdir))
+(define-key dired-mode-map [menu-bar subdir prev-dirline]
+  '("Prev Dirline" . dired-prev-dirline))
+(define-key dired-mode-map [menu-bar subdir next-dirline]
+  '("Next Dirline" . dired-next-dirline))
+(define-key dired-mode-map [menu-bar subdir insert]
+  '("Insert This Subdir" . dired-maybe-insert-subdir))
+
+(define-key dired-mode-map [menu-bar immediate]
+  (cons "Immediate" (make-sparse-keymap "Immediate")))
+
+(define-key dired-mode-map [menu-bar immediate backup-diff]
+  '("Compare with Backup" . dired-backup-diff))
+(define-key dired-mode-map [menu-bar immediate diff]
+  '("Diff" . dired-diff))
+(define-key dired-mode-map [menu-bar immediate view]
+  '("View This File" . dired-view-file))
+(define-key dired-mode-map [menu-bar immediate display]
+  '("Display in Other Window" . dired-display-file))
+(define-key dired-mode-map [menu-bar immediate find-file-other-window]
+  '("Find in Other Window" . dired-find-file-other-window))
+(define-key dired-mode-map [menu-bar immediate find-file]
+  '("Find This File" . dired-find-file))
+(define-key dired-mode-map [menu-bar immediate create-directory]
+  '("Create Directory..." . dired-create-directory))
+
+(define-key dired-mode-map [menu-bar regexp]
+  (cons "Regexp" (make-sparse-keymap "Regexp")))
+
+(define-key dired-mode-map [menu-bar regexp downcase]
+  '("Downcase" . dired-downcase))
+(define-key dired-mode-map [menu-bar regexp upcase]
+  '("Upcase" . dired-upcase))
+(define-key dired-mode-map [menu-bar regexp hardlink]
+  '("Hardlink..." . dired-do-hardlink-regexp))
+(define-key dired-mode-map [menu-bar regexp symlink]
+  '("Symlink..." . dired-do-symlink-regexp))
+(define-key dired-mode-map [menu-bar regexp rename]
+  '("Rename..." . dired-do-rename-regexp))
+(define-key dired-mode-map [menu-bar regexp copy]
+  '("Copy..." . dired-do-copy-regexp))
+(define-key dired-mode-map [menu-bar regexp flag]
+  '("Flag..." . dired-flag-files-regexp))
+(define-key dired-mode-map [menu-bar regexp mark]
+  '("Mark..." . dired-mark-files-regexp))
+
+(define-key dired-mode-map [menu-bar mark]
+  (cons "Mark" (make-sparse-keymap "Mark")))
+
+(define-key dired-mode-map [menu-bar mark prev]
+  '("Previous Marked" . dired-prev-marked-file))
+(define-key dired-mode-map [menu-bar mark next]
+  '("Next Marked" . dired-next-marked-file))
+(define-key dired-mode-map [menu-bar mark marks]
+  '("Change Marks..." . dired-change-marks))
+(define-key dired-mode-map [menu-bar mark unmark-all]
+  '("Unmark All" . dired-unmark-all-files-no-query))
+(define-key dired-mode-map [menu-bar mark symlinks]
+  '("Mark Symlinks" . dired-mark-symlinks))
+(define-key dired-mode-map [menu-bar mark directories]
+  '("Mark Directories" . dired-mark-directories))
+(define-key dired-mode-map [menu-bar mark directory]
+  '("Mark Old Backups" . dired-clean-directory))
+(define-key dired-mode-map [menu-bar mark executables]
+  '("Mark Executables" . dired-mark-executables))
+(define-key dired-mode-map [menu-bar mark backup-files]
+  '("Flag Backup Files" . dired-flag-backup-files))
+(define-key dired-mode-map [menu-bar mark auto-save-files]
+  '("Flag Auto-save Files" . dired-flag-auto-save-files))
+(define-key dired-mode-map [menu-bar mark deletion]
+  '("Flag" . dired-flag-file-deletion))
+(define-key dired-mode-map [menu-bar mark unmark]
+  '("Unmark" . dired-unmark))
+(define-key dired-mode-map [menu-bar mark mark]
+  '("Mark" . dired-mark))
+
+(define-key dired-mode-map [menu-bar operate]
+  (cons "Operate" (make-sparse-keymap "Operate")))
+
+(define-key dired-mode-map [menu-bar operate chown]
+  '("Change Owner..." . dired-do-chown))
+(define-key dired-mode-map [menu-bar operate chgrp]
+  '("Change Group..." . dired-do-chgrp))
+(define-key dired-mode-map [menu-bar operate chmod]
+  '("Change Mode..." . dired-do-chmod))
+(define-key dired-mode-map [menu-bar operate load]
+  '("Load" . dired-do-load))
+(define-key dired-mode-map [menu-bar operate compile]
+  '("Byte-compile" . dired-do-byte-compile))
+(define-key dired-mode-map [menu-bar operate compress]
+  '("Compress" . dired-do-compress))
+(define-key dired-mode-map [menu-bar operate print]
+  '("Print" . dired-do-print))
+(define-key dired-mode-map [menu-bar operate hardlink]
+  '("Hardlink to..." . dired-do-hardlink))
+(define-key dired-mode-map [menu-bar operate symlink]
+  '("Symlink to..." . dired-do-symlink))
+(define-key dired-mode-map [menu-bar operate command]
+  '("Shell Command..." . dired-do-shell-command))
+(define-key dired-mode-map [menu-bar operate delete]
+  '("Delete" . dired-do-delete))
+(define-key dired-mode-map [menu-bar operate rename]
+  '("Rename to..." . dired-do-rename))
+(define-key dired-mode-map [menu-bar operate copy]
+  '("Copy to..." . dired-do-copy))
 \f
 ;; Dired mode is suitable only for specially formatted data.
 (put 'dired-mode 'mode-class 'special)
@@ -805,7 +961,7 @@ Keybindings:
   (dired-advertise)                    ; default-directory is already set
   (setq major-mode 'dired-mode
        mode-name "Dired"
-       case-fold-search nil
+;;     case-fold-search nil
        buffer-read-only t
        selective-display t             ; for subdirectory hiding
        mode-line-buffer-identification '("Dired: %17b"))
@@ -820,11 +976,10 @@ Keybindings:
        dired-directory)
   (set (make-local-variable 'dired-actual-switches)
        (or switches dired-listing-switches))
-  (make-local-variable 'dired-sort-mode)
   (dired-sort-other dired-actual-switches t)
   (run-hooks 'dired-mode-hook))
 \f
-;; Ideosyncratic dired commands that don't deal with marks.
+;; Idiosyncratic dired commands that don't deal with marks.
 
 (defun dired-quit ()
   "Bury the current dired buffer."
@@ -837,7 +992,7 @@ Keybindings:
   (dired-why)
   ;>> this should check the key-bindings and use substitute-command-keys if non-standard
   (message
-   "d-elete, u-ndelete, x-punge, f-ind, o-ther window, r-ename, C-opy, h-elp"))
+   "d-elete, u-ndelete, x-punge, f-ind, o-ther window, R-ename, C-opy, h-elp"))
 
 (defun dired-undo ()
   "Undo in a dired buffer.
@@ -896,11 +1051,25 @@ Creates a buffer if necessary."
 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."
   (interactive)
   (find-file (file-name-sans-versions (dired-get-filename) t)))
 
+(defun dired-mouse-find-file-other-window (event)
+  "In dired, visit the file or directory name you click on."
+  (interactive "e")
+  (let (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)))
+    (find-file-other-window (file-name-sans-versions file t))))
+
 (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;
@@ -938,7 +1107,7 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
       (if (setq p1 (dired-move-to-filename (not no-error-if-not-filep)))
          (setq p2 (dired-move-to-end-of-filename no-error-if-not-filep))))
     ;; nil if no file on this line, but no-error-if-not-filep is t:
-    (if (setq file (and p1 p2 (buffer-substring p1 p2)))
+    (if (setq file (and p1 p2 (format "%s" (buffer-substring p1 p2))))
        ;; Check if ls quoted the names, and unquote them.
        ;; Using read to unquote is much faster than substituting
        ;; \007 (4 chars) -> ^G  (1 char) etc. in a lisp loop.
@@ -978,6 +1147,10 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
   ;; DIR must be file-name-as-directory, as with all directory args in
   ;; Emacs Lisp code.
   (or dir (setq dir default-directory))
+  ;; This case comes into play if default-directory is set to
+  ;; use ~.
+  (if (and (> (length dir) 0) (= (aref dir 0) ?~))
+      (setq dir (expand-file-name dir)))
   (if (string-match (concat "^" (regexp-quote dir)) file)
       (substring file (match-end 0))
     (if no-error
@@ -986,28 +1159,20 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
 \f
 ;;; Functions for finding the file name in a dired buffer line.
 
+(defvar dired-move-to-filename-regexp
+  "\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\)[ ]+[0-9]+ [ 0-9][0-9][:0-9][0-9][ 0-9] "
+  "Regular expression to match a month abbreviation followed by a number.")
+
 ;; Move to first char of filename on this line.
 ;; Returns position (point) or nil if no filename on this line."
 (defun dired-move-to-filename (&optional raise-error eol)
   ;; This is the UNIX version.
   (or eol (setq eol (progn (end-of-line) (point))))
   (beginning-of-line)
-  (if (re-search-forward
-       "\\(Jan\\|Feb\\|Mar\\|Apr\\|May\\|Jun\\|Jul\\|Aug\\|Sep\\|Oct\\|Nov\\|Dec\\)[ ]+[0-9]+"
-       eol t)
-      (progn
-       (skip-chars-forward " ")        ; there is one SPC after day of month
-       (skip-chars-forward "^ " eol)   ; move after time of day (or year)
-       (skip-chars-forward " " eol)    ; there is space before the file name
-       ;; Actually, if the year instead of clock time is displayed,
-       ;; there are (only for some ls programs?) two spaces instead
-       ;; of one before the name.
-       ;; If we could depend on ls inserting exactly one SPC we
-       ;; would not bomb on names _starting_ with SPC.
-       (point))
+  (if (re-search-forward dired-move-to-filename-regexp eol t)
+      (goto-char (match-end 0))
     (if raise-error
-       (error "No file on this line")
-      nil)))
+       (error "No file on this line"))))
 
 (defun dired-move-to-end-of-filename (&optional no-error)
   ;; Assumes point is at beginning of filename,
@@ -1129,7 +1294,7 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
 (defun dired-in-this-tree (file dir)
   ;;"Is FILE part of the directory tree starting at DIR?"
   (let (case-fold-search)
-    (string-match (concat "^" (regexp-quote dir)) file)))
+    (string-match (concat "^" (regexp-quote (expand-file-name dir))) file)))
 
 (defun dired-normalize-subdir (dir)
   ;; Prepend default-directory to DIR if relative path name.
@@ -1203,18 +1368,32 @@ Returns the new value of the alist."
   (interactive)
   (dired-clear-alist)
   (save-excursion
-    (let ((count 0))
+    (let ((count 0)
+         (buffer-read-only nil)
+         new-dir-name)
       (goto-char (point-min))
       (setq dired-subdir-alist nil)
-      (while (re-search-forward dired-subdir-regexp nil t)
+      (while (and (re-search-forward dired-subdir-regexp nil t)
+                 ;; Avoid taking a file name ending in a colon
+                 ;; as a subdir name.
+                 (not (save-excursion
+                        (goto-char (match-beginning 0))
+                        (beginning-of-line)
+                        (forward-char 2)
+                        (save-match-data (looking-at dired-re-perms)))))
+       (save-excursion
+         (goto-char (match-beginning 1))
+         (setq new-dir-name
+               (expand-file-name (buffer-substring (point) (match-end 1))))
+         (delete-region (point) (match-end 1))
+         (insert new-dir-name))
        (setq count (1+ count))
-       (dired-alist-add-1 (buffer-substring (match-beginning 1)
-                                            (match-end 1))
-                        ;; Put subdir boundary between lines:
-                        (save-excursion
-                          (goto-char (match-beginning 0))
-                          (beginning-of-line)
-                          (point-marker))))
+       (dired-alist-add-1 new-dir-name
+                          ;; Place a sub directory boundary between lines.
+                          (save-excursion
+                            (goto-char (match-beginning 0))
+                            (beginning-of-line)
+                            (point-marker))))
       (if (> count 1)
          (message "Buffer includes %d directories" count))
       ;; We don't need to sort it because it is in buffer order per
@@ -1263,7 +1442,7 @@ Returns the new value of the alist."
     (save-excursion
       ;; The hair here is to get the result of dired-goto-subdir
       ;; without really calling it if we don't have any subdirs.
-      (if (if (string= dir default-directory)
+      (if (if (string= dir (expand-file-name default-directory))
              (goto-char (point-min))
            (and (cdr dired-subdir-alist)
                 (dired-goto-subdir dir)))
@@ -1281,7 +1460,10 @@ Returns the new value of the alist."
                    ;; correct) match could have been elsewhere on the
                    ;; ;; line (e.g. "-" would match somewhere in the
                    ;; permission bits).
-                 (setq found (dired-move-to-filename)))))))
+                 (setq found (dired-move-to-filename))
+               ;; If this isn't the right line, move forward to avoid
+               ;; trying this line again.
+               (forward-line 1))))))
     (and found
         ;; return value of point (i.e., FOUND):
         (goto-char found))))
@@ -1506,7 +1688,8 @@ Optional argument means return a file name relative to `default-directory'."
     (save-excursion
       (set-buffer (get-buffer-create bufname))
       (erase-buffer)
-      (dired-format-columns-of-files files))
+      (dired-format-columns-of-files files)
+      (remove-text-properties (point-min) (point-max) '(mouse-face)))
     (save-window-excursion
       (dired-pop-to-buffer bufname)
       (apply function args))))
@@ -1542,28 +1725,35 @@ Optional argument means return a file name relative to `default-directory'."
 
 (defun dired-repeat-over-lines (arg function)
   ;; This version skips non-file lines.
-  (beginning-of-line)
-  (while (and (> arg 0) (not (eobp)))
-    (setq arg (1- arg))
-    (beginning-of-line)
-    (while (and (not (eobp)) (dired-between-files)) (forward-line 1))
-    (save-excursion (funcall function))
-    (forward-line 1))
-  (while (and (< arg 0) (not (bobp)))
-    (setq arg (1+ arg))
-    (forward-line -1)
-    (while (and (not (bobp)) (dired-between-files)) (forward-line -1))
+  (let ((pos (make-marker)))
     (beginning-of-line)
-    (save-excursion (funcall function))
-    (dired-move-to-filename))
-  (dired-move-to-filename))
+    (while (and (> arg 0) (not (eobp)))
+      (setq arg (1- arg))
+      (beginning-of-line)
+      (while (and (not (eobp)) (dired-between-files)) (forward-line 1))
+      (save-excursion
+       (forward-line 1)
+       (move-marker pos (1+ (point))))
+      (save-excursion (funcall function))
+      ;; Advance to the next line--actually, to the line that *was* next.
+      ;; (If FUNCTION inserted some new lines in between, skip them.)
+      (goto-char pos))
+    (while (and (< arg 0) (not (bobp)))
+      (setq arg (1+ arg))
+      (forward-line -1)
+      (while (and (not (bobp)) (dired-between-files)) (forward-line -1))
+      (beginning-of-line)
+      (save-excursion (funcall function)))
+    (move-marker pos nil)
+    (dired-move-to-filename)))
 
 (defun dired-between-files ()
   ;; 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")
-      (looking-at dired-subdir-regexp)))
+      (and (looking-at dired-subdir-regexp)
+          (save-excursion (not (dired-move-to-filename))))))
 
 (defun dired-next-marked-file (arg &optional wrap opoint)
   "Move to the next marked file, wrapping around the end of the buffer."
@@ -1716,10 +1906,19 @@ A prefix argument says to unflag those files instead."
   (interactive "P")
   (let ((dired-marker-char (if unflag-p ?\040 dired-del-marker)))
     (dired-mark-if
-     ;; It is less than general to check for ~ here,
+     ;; It is less than general to check for # here,
      ;; but it's the only way this runs fast enough.
      (and (save-excursion (end-of-line)
-                         (eq (preceding-char) ?#))
+                          (or
+                           (eq (preceding-char) ?#)
+                           ;; Handle executables in case of -F option.
+                           ;; We need not worry about the other kinds
+                           ;; of markings that -F makes, since they won't
+                           ;; appear on real auto-save files.
+                           (if (eq (preceding-char) ?*)
+                               (progn
+                                 (forward-char -1)
+                                 (eq (preceding-char) ?#)))))
          (not (looking-at dired-re-dir))
          (let ((fn (dired-get-filename t t)))
            (if fn (auto-save-file-name-p
@@ -1735,16 +1934,16 @@ With prefix argument, unflag these files."
      ;; It is less than general to check for ~ here,
      ;; but it's the only way this runs fast enough.
      (and (save-excursion (end-of-line)
-                            (or
-                             (eq (preceding-char) ?~)
-                            ;; Handle executables in case of -F option.
-                            ;; We need not worry about the other kinds
-                            ;; of markings that -F makes, since they won't
-                            ;; appear on real backup files.
-                             (if (eq (preceding-char) ?*)
-                                 (progn
-                                   (forward-char -1)
-                                   (eq (preceding-char) ?~)))))
+                         (or
+                          (eq (preceding-char) ?~)
+                          ;; Handle executables in case of -F option.
+                          ;; We need not worry about the other kinds
+                          ;; of markings that -F makes, since they won't
+                          ;; appear on real backup files.
+                          (if (eq (preceding-char) ?*)
+                              (progn
+                                (forward-char -1)
+                                (eq (preceding-char) ?~)))))
          (not (looking-at dired-re-dir))
          (let ((fn (dired-get-filename t t)))
            (if fn (backup-file-name-p fn))))
@@ -1769,6 +1968,11 @@ OLD and NEW are both characters used to mark files."
          (subst-char-in-region (match-beginning 0)
                                (match-end 0) old new))))))
 
+(defun dired-unmark-all-files-no-query ()
+  "Remove all marks from all files in the Dired buffer."
+  (interactive)
+  (dired-unmark-all-files ?\r))
+
 (defun dired-unmark-all-files (mark &optional arg)
   "Remove a specific mark (or any mark) from every file.
 After this command, type the mark character to remove, 
@@ -1865,23 +2069,19 @@ Thus, use \\[backward-page] to find the beginning of a group of errors."
   (concat "^-[^t" dired-ls-sorting-switches "]+$")
   "Regexp recognized by dired to set `by name' mode.")
 
-(defvar dired-sort-mode nil
-  "Whether Dired sorts by name, date etc. (buffer-local).")
-;; This is nil outside dired buffers so it can be used in the modeline
-
 (defun dired-sort-set-modeline ()
   ;; Set modeline display according to dired-actual-switches.
   ;; Modeline display of "by name" or "by date" guarantees the user a
   ;; match with the corresponding regexps.  Non-matching switches are
   ;; shown literally.
-  (setq dired-sort-mode
+  (setq mode-name
        (let (case-fold-search)
          (cond ((string-match dired-sort-by-name-regexp dired-actual-switches)
-                " by name")
+                "Dired by name")
                ((string-match dired-sort-by-date-regexp dired-actual-switches)
-                " by date")
+                "Dired by date")
                (t
-                (concat " " dired-actual-switches)))))
+                (concat "Dired " dired-actual-switches)))))
   ;; update mode line:
   (set-buffer-modified-p (buffer-modified-p)))
 
@@ -1900,7 +2100,7 @@ With a prefix argument you can edit the current listing switches instead."
        (let (case-fold-search)
          (concat
           "-l"
-          (dired-replace-in-string (concat "[---lt"
+          (dired-replace-in-string (concat "[-lt"
                                            dired-ls-sorting-switches "]")
                                    ""
                                    dired-actual-switches)
@@ -2150,8 +2350,8 @@ Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
 (if (eq system-type 'vax-vms)
     (load "dired-vms"))
 
-(run-hooks 'dired-load-hook)           ; for your customizations
-
 (provide 'dired)
 
+(run-hooks 'dired-load-hook)           ; for your customizations
+
 ;;; dired.el ends here