]> code.delx.au - gnu-emacs/blobdiff - lisp/dired.el
Add `auth-source-search' integration for LDAP searches.
[gnu-emacs] / lisp / dired.el
index b88c217c4158064a6b1262ca1ff8051a74a73467..c4374503a6f3ea6bb5cc9f8018d4d0a9f504b75b 100644 (file)
@@ -1,7 +1,6 @@
 ;;; dired.el --- directory-browsing commands
 
 ;;; dired.el --- directory-browsing commands
 
-;; Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995, 1996, 1997, 2000,
-;;   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Copyright (C) 1985-1986, 1992-1997, 2000-2011
 ;;   Free Software Foundation, Inc.
 
 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>
 ;;   Free Software Foundation, Inc.
 
 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>
@@ -250,9 +249,19 @@ Local to each dired buffer.  May be a list, in which case the car is the
 directory name and the cdr is the list of files to mention.
 The directory name must be absolute, but need not be fully expanded.")
 
 directory name and the cdr is the list of files to mention.
 The directory name must be absolute, but need not be fully expanded.")
 
+;; Beware of "-l;reboot" etc.  See bug#3230.
+(defun dired-safe-switches-p (switches)
+  "Return non-nil if string SWITCHES does not look risky for dired."
+  (or (not switches)
+      (and (stringp switches)
+           (< (length switches) 100)    ; arbitrary
+           (string-match "\\` *-[- [:alnum:]]+\\'" switches))))
+
 (defvar dired-actual-switches nil
   "The value of `dired-listing-switches' used to make this buffer's text.")
 
 (defvar dired-actual-switches nil
   "The value of `dired-listing-switches' used to make this buffer's text.")
 
+(put 'dired-actual-switches 'safe-local-variable 'dired-safe-switches-p)
+
 (defvar dired-re-inode-size "[0-9 \t]*"
   "Regexp for optional initial inode and file size as made by `ls -i -s'.")
 
 (defvar dired-re-inode-size "[0-9 \t]*"
   "Regexp for optional initial inode and file size as made by `ls -i -s'.")
 
@@ -602,9 +611,12 @@ Don't use that together with FILTER."
            (if current-prefix-arg
                (read-string "Dired listing switches: "
                             dired-listing-switches))
            (if current-prefix-arg
                (read-string "Dired listing switches: "
                             dired-listing-switches))
-           ;; If a dialog is about to be used, call read-directory-name so
-           ;; the dialog code knows we want directories.  Some dialogs can
-           ;; only select directories or files when popped up, not both.
+           ;; If a dialog is used, call `read-directory-name' so the
+           ;; dialog code knows we want directories.  Some dialogs
+           ;; can only select directories or files when popped up,
+           ;; not both.  If no dialog is used, call `read-file-name'
+           ;; because the user may want completion of file names for
+           ;; use in a wildcard pattern.
            (if (next-read-file-uses-dialog-p)
                (read-directory-name (format "Dired %s(directory): " str)
                                     nil default-directory nil)
            (if (next-read-file-uses-dialog-p)
                (read-directory-name (format "Dired %s(directory): " str)
                                     nil default-directory nil)
@@ -848,28 +860,47 @@ periodically reverts at specified time intervals."
   ;; killed buffer, it is removed from this list.
   "Alist of expanded directories and their associated dired buffers.")
 
   ;; killed buffer, it is removed from this list.
   "Alist of expanded directories and their associated dired buffers.")
 
+(defvar dired-find-subdir)
+
+;; FIXME add a doc-string, and document dired-x extensions.
 (defun dired-find-buffer-nocreate (dirname &optional mode)
   ;; This differs from dired-buffers-for-dir in that it does not consider
   ;; subdirs of default-directory and searches for the first match only.
   ;; Also, the major mode must be MODE.
 (defun dired-find-buffer-nocreate (dirname &optional mode)
   ;; This differs from dired-buffers-for-dir in that it does not consider
   ;; subdirs of default-directory and searches for the first match only.
   ;; Also, the major mode must be MODE.
-  (setq dirname (expand-file-name dirname))
-  (let (found (blist dired-buffers))    ; was (buffer-list)
-    (or mode (setq mode 'dired-mode))
-    (while blist
-      (if (null (buffer-name (cdr (car blist))))
-         (setq blist (cdr blist))
-       (with-current-buffer (cdr (car blist))
-         (if (and (eq major-mode mode)
-                  dired-directory  ;; nil during find-alternate-file
-                  (equal dirname
-                         (expand-file-name
-                          (if (consp dired-directory)
-                              (car dired-directory)
-                            dired-directory))))
-             (setq found (cdr (car blist))
-                   blist nil)
-           (setq blist (cdr blist))))))
-    found))
+  (if (and (featurep 'dired-x)
+           dired-find-subdir
+           ;; Don't try to find a wildcard as a subdirectory.
+          (string-equal dirname (file-name-directory dirname)))
+      (let* ((cur-buf (current-buffer))
+            (buffers (nreverse
+                      (dired-buffers-for-dir (expand-file-name dirname))))
+            (cur-buf-matches (and (memq cur-buf buffers)
+                                  ;; Wildcards must match, too:
+                                  (equal dired-directory dirname))))
+       ;; We don't want to switch to the same buffer---
+       (setq buffers (delq cur-buf buffers))
+       (or (car (sort buffers #'dired-buffer-more-recently-used-p))
+           ;; ---unless it's the only possibility:
+           (and cur-buf-matches cur-buf)))
+    ;; No dired-x, or dired-find-subdir nil.
+    (setq dirname (expand-file-name dirname))
+    (let (found (blist dired-buffers))    ; was (buffer-list)
+      (or mode (setq mode 'dired-mode))
+      (while blist
+        (if (null (buffer-name (cdr (car blist))))
+            (setq blist (cdr blist))
+          (with-current-buffer (cdr (car blist))
+            (if (and (eq major-mode mode)
+                     dired-directory  ;; nil during find-alternate-file
+                     (equal dirname
+                            (expand-file-name
+                             (if (consp dired-directory)
+                                 (car dired-directory)
+                               dired-directory))))
+                (setq found (cdr (car blist))
+                      blist nil)
+              (setq blist (cdr blist))))))
+      found)))
 
 \f
 ;; Read in a new dired buffer
 
 \f
 ;; Read in a new dired buffer
@@ -1053,6 +1084,8 @@ BEG..END is the line where the file info is located."
        (set-marker file nil)))))
 
 
        (set-marker file nil)))))
 
 
+(defvar ls-lisp-use-insert-directory-program)
+
 (defun dired-insert-directory (dir switches &optional file-list wildcard hdr)
   "Insert a directory listing of DIR, Dired style.
 Use SWITCHES to make the listings.
 (defun dired-insert-directory (dir switches &optional file-list wildcard hdr)
   "Insert a directory listing of DIR, Dired style.
 Use SWITCHES to make the listings.
@@ -1064,14 +1097,20 @@ If HDR is non-nil, insert a header line with the directory name."
   (let ((opoint (point))
        (process-environment (copy-sequence process-environment))
        end)
   (let ((opoint (point))
        (process-environment (copy-sequence process-environment))
        end)
-    (if (or (if (eq dired-use-ls-dired 'unspecified)
-               ;; Check whether "ls --dired" gives exit code 0, and
-               ;; save the answer in `dired-use-ls-dired'.
-               (setq dired-use-ls-dired
-                     (eq (call-process insert-directory-program nil nil nil "--dired")
-                         0))
-             dired-use-ls-dired)
-           (file-remote-p dir))
+    (if (and
+        ;; Don't try to invoke `ls' if we are on DOS/Windows where
+        ;; ls-lisp emulation is used, except if they want to use `ls'
+        ;; as indicated by `ls-lisp-use-insert-directory-program'.
+        (not (and (featurep 'ls-lisp)
+                  (null ls-lisp-use-insert-directory-program)))
+        (or (if (eq dired-use-ls-dired 'unspecified)
+                ;; Check whether "ls --dired" gives exit code 0, and
+                ;; save the answer in `dired-use-ls-dired'.
+                (setq dired-use-ls-dired
+                      (eq (call-process insert-directory-program nil nil nil "--dired")
+                          0))
+              dired-use-ls-dired)
+            (file-remote-p dir)))
        (setq switches (concat "--dired " switches)))
     ;; We used to specify the C locale here, to force English month names;
     ;; but this should not be necessary any more,
        (setq switches (concat "--dired " switches)))
     ;; We used to specify the C locale here, to force English month names;
     ;; but this should not be necessary any more,
@@ -1146,7 +1185,10 @@ If HDR is non-nil, insert a header line with the directory name."
   "Reread the dired buffer.
 Must also be called after `dired-actual-switches' have changed.
 Should not fail even on completely garbaged buffers.
   "Reread the dired buffer.
 Must also be called after `dired-actual-switches' have changed.
 Should not fail even on completely garbaged buffers.
-Preserves old cursor, marks/flags, hidden-p."
+Preserves old cursor, marks/flags, hidden-p.
+
+Dired sets `revert-buffer-function' to this function.  The args
+ARG and NOCONFIRM, passed from `revert-buffer', are ignored."
   (widen)                              ; just in case user narrowed
   (let ((modflag (buffer-modified-p))
        (positions (dired-save-positions))
   (widen)                              ; just in case user narrowed
   (let ((modflag (buffer-modified-p))
        (positions (dired-save-positions))
@@ -1292,7 +1334,7 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
   ;; This looks ugly when substitute-command-keys uses C-d instead d:
   ;;  (define-key dired-mode-map "\C-d" 'dired-flag-file-deletion)
   (let ((map (make-keymap)))
   ;; This looks ugly when substitute-command-keys uses C-d instead d:
   ;;  (define-key dired-mode-map "\C-d" 'dired-flag-file-deletion)
   (let ((map (make-keymap)))
-    (suppress-keymap map)
+    (set-keymap-parent map special-mode-map)
     (define-key map [mouse-2] 'dired-mouse-find-file-other-window)
     (define-key map [follow-link] 'mouse-face)
     ;; Commands to mark or flag certain categories of files
     (define-key map [mouse-2] 'dired-mouse-find-file-other-window)
     (define-key map [follow-link] 'mouse-face)
     ;; Commands to mark or flag certain categories of files
@@ -1371,7 +1413,6 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
     (define-key map "\C-m" 'dired-find-file)
     (put 'dired-find-file :advertised-binding "\C-m")
     (define-key map "g" 'revert-buffer)
     (define-key map "\C-m" 'dired-find-file)
     (put 'dired-find-file :advertised-binding "\C-m")
     (define-key map "g" 'revert-buffer)
-    (define-key map "h" 'describe-mode)
     (define-key map "i" 'dired-maybe-insert-subdir)
     (define-key map "j" 'dired-goto-file)
     (define-key map "k" 'dired-do-kill-lines)
     (define-key map "i" 'dired-maybe-insert-subdir)
     (define-key map "j" 'dired-goto-file)
     (define-key map "k" 'dired-do-kill-lines)
@@ -1381,7 +1422,6 @@ Do so according to the former subdir alist OLD-SUBDIR-ALIST."
     (define-key map "o" 'dired-find-file-other-window)
     (define-key map "\C-o" 'dired-display-file)
     (define-key map "p" 'dired-previous-line)
     (define-key map "o" 'dired-find-file-other-window)
     (define-key map "\C-o" 'dired-display-file)
     (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-toggle-marks)
     (define-key map "u" 'dired-unmark)
     (define-key map "s" 'dired-sort-toggle-or-edit)
     (define-key map "t" 'dired-toggle-marks)
     (define-key map "u" 'dired-unmark)
@@ -1833,6 +1873,7 @@ Keybindings:
   (set (make-local-variable 'desktop-save-buffer)
        'dired-desktop-buffer-misc-data)
   (setq dired-switches-alist nil)
   (set (make-local-variable 'desktop-save-buffer)
        'dired-desktop-buffer-misc-data)
   (setq dired-switches-alist nil)
+  (hack-dir-local-variables-non-file-buffer) ; before sorting
   (dired-sort-other dired-actual-switches t)
   (when (featurep 'dnd)
     (set (make-local-variable 'dnd-protocol-alist)
   (dired-sort-other dired-actual-switches t)
   (when (featurep 'dnd)
     (set (make-local-variable 'dnd-protocol-alist)
@@ -2025,7 +2066,7 @@ Otherwise, an error occurs in these cases."
           ;; with quotation marks in their names.
          (while (string-match "\\(?:[^\\]\\|\\`\\)\\(\"\\)" file)
            (setq file (replace-match "\\\"" nil t file 1)))
           ;; with quotation marks in their names.
          (while (string-match "\\(?:[^\\]\\|\\`\\)\\(\"\\)" file)
            (setq file (replace-match "\\\"" nil t file 1)))
-         
+
          (when (eq system-type 'windows-nt)
            (save-match-data
              (let ((start 0))
          (when (eq system-type 'windows-nt)
            (save-match-data
              (let ((start 0))
@@ -2536,11 +2577,15 @@ instead of `dired-actual-switches'."
         ;; return value of point (i.e., FOUND):
         (goto-char found))))
 
         ;; return value of point (i.e., FOUND):
         (goto-char found))))
 
+(defvar dired-find-subdir)
+
+;; FIXME document whatever dired-x is doing.
 (defun dired-initial-position (dirname)
 (defun dired-initial-position (dirname)
-  ;; Where point should go in a new listing of DIRNAME.
-  ;; Point assumed at beginning of new subdir line.
-  ;; You may redefine this function as you wish, e.g. like in dired-x.el.
+  "Where point should go in a new listing of DIRNAME.
+Point assumed at beginning of new subdir line."
   (end-of-line)
   (end-of-line)
+  (and (featurep 'dired-x) dired-find-subdir
+       (dired-goto-subdir dirname))
   (if dired-trivial-filenames (dired-goto-next-nontrivial-file)))
 \f
 ;; These are hooks which make tree dired work.
   (if dired-trivial-filenames (dired-goto-next-nontrivial-file)))
 \f
 ;; These are hooks which make tree dired work.
@@ -2737,12 +2782,32 @@ non-empty directories is allowed."
                          (save-excursion (forward-line 1) (point))))))
   (dired-clean-up-after-deletion file))
 
                          (save-excursion (forward-line 1) (point))))))
   (dired-clean-up-after-deletion file))
 
-;; This is a separate function for the sake of dired-x.el.
+(defvar dired-clean-up-buffers-too)
+
 (defun dired-clean-up-after-deletion (fn)
 (defun dired-clean-up-after-deletion (fn)
-  ;; Clean up after a deleted file or directory FN.
+  "Clean up after a deleted file or directory FN.
+Removes any expanded subdirectory of deleted directory.
+If `dired-x' is loaded and `dired-clean-up-buffers-too' is non-nil,
+also offers to kill buffers visiting deleted files and directories."
   (save-excursion (and (cdr dired-subdir-alist)
                       (dired-goto-subdir fn)
   (save-excursion (and (cdr dired-subdir-alist)
                       (dired-goto-subdir fn)
-                      (dired-kill-subdir))))
+                      (dired-kill-subdir)))
+  ;; Offer to kill buffer of deleted file FN.
+  (when (and (featurep 'dired-x) dired-clean-up-buffers-too)
+    (let ((buf (get-file-buffer fn)))
+      (and buf
+           (funcall #'y-or-n-p
+                    (format "Kill buffer of %s, too? "
+                            (file-name-nondirectory fn)))
+           (kill-buffer buf)))
+    (let ((buf-list (dired-buffers-for-dir (expand-file-name fn))))
+      (and buf-list
+           (y-or-n-p (format "Kill dired buffer%s of %s, too? "
+                             (dired-plural-s (length buf-list))
+                             (file-name-nondirectory fn)))
+           (dolist (buf buf-list)
+             (kill-buffer buf))))))
+
 \f
 ;; Confirmation
 
 \f
 ;; Confirmation
 
@@ -3562,7 +3627,7 @@ Ask means pop up a menu for the user to select one of copy, move or link."
 ;;;;;;  dired-run-shell-command dired-do-shell-command dired-do-async-shell-command
 ;;;;;;  dired-clean-directory dired-do-print dired-do-touch dired-do-chown
 ;;;;;;  dired-do-chgrp dired-do-chmod dired-compare-directories dired-backup-diff
 ;;;;;;  dired-run-shell-command dired-do-shell-command dired-do-async-shell-command
 ;;;;;;  dired-clean-directory dired-do-print dired-do-touch dired-do-chown
 ;;;;;;  dired-do-chgrp dired-do-chmod dired-compare-directories dired-backup-diff
-;;;;;;  dired-diff) "dired-aux" "dired-aux.el" "db61da0d98435f468e41e92c12f99d3b")
+;;;;;;  dired-diff) "dired-aux" "dired-aux.el" "154cdfbf451aedec60c5012b625ff329")
 ;;; Generated autoloads from dired-aux.el
 
 (autoload 'dired-diff "dired-aux" "\
 ;;; Generated autoloads from dired-aux.el
 
 (autoload 'dired-diff "dired-aux" "\
@@ -4020,8 +4085,8 @@ true then the type of the file linked to by FILE is printed instead.
 
 ;;;***
 \f
 
 ;;;***
 \f
-;;;### (autoloads (dired-do-relsymlink dired-jump) "dired-x" "dired-x.el"
-;;;;;;  "27c312d6d5d40d8cb4ef8d62e30d5f4a")
+;;;### (autoloads (dired-do-relsymlink dired-jump-other-window dired-jump)
+;;;;;;  "dired-x" "dired-x.el" "87fd4ae2fdade7e0f11c4a0b1cfdeda2")
 ;;; Generated autoloads from dired-x.el
 
 (autoload 'dired-jump "dired-x" "\
 ;;; Generated autoloads from dired-x.el
 
 (autoload 'dired-jump "dired-x" "\
@@ -4036,6 +4101,11 @@ move to its line in dired.
 
 \(fn &optional OTHER-WINDOW FILE-NAME)" t nil)
 
 
 \(fn &optional OTHER-WINDOW FILE-NAME)" t nil)
 
+(autoload 'dired-jump-other-window "dired-x" "\
+Like \\[dired-jump] (`dired-jump') but in other window.
+
+\(fn &optional FILE-NAME)" t nil)
+
 (autoload 'dired-do-relsymlink "dired-x" "\
 Relative symlink all marked (or next ARG) files into a directory.
 Otherwise make a relative symbolic link to the current file.
 (autoload 'dired-do-relsymlink "dired-x" "\
 Relative symlink all marked (or next ARG) files into a directory.
 Otherwise make a relative symbolic link to the current file.