]> code.delx.au - gnu-emacs/blobdiff - lisp/dired.el
(shadow-parse-fullname): Renamed from shadow-parse-fullpath.
[gnu-emacs] / lisp / dired.el
index f8d5fc03883206f3c70448a52c2c25d3689edcba..db067c5da164b80059695c0019f9d0f4c6479f57 100644 (file)
@@ -1,6 +1,6 @@
 ;;; dired.el --- directory-browsing commands
 
-;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 1997, 2000, 2001
+;; Copyright (C) 1985, 86, 92, 93, 94, 95, 96, 1997, 2000, 2001, 2003
 ;;  Free Software Foundation, Inc.
 
 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>
@@ -59,13 +59,13 @@ some of the `ls' switches are not supported; see the doc string of
   :type 'string
   :group 'dired)
 
-; Don't use absolute paths as /bin should be in any PATH and people
+; Don't use absolute file names as /bin should be in any PATH and people
 ; may prefer /usr/local/gnu/bin or whatever.  However, chown is
 ; usually not in PATH.
 
 ;;;###autoload
 (defvar dired-chown-program
-  (if (memq system-type '(hpux dgux usg-unix-v irix linux gnu/linux))
+  (if (memq system-type '(hpux dgux usg-unix-v irix linux gnu/linux cygwin))
       "chown"
     (if (file-exists-p "/usr/sbin/chown")
        "/usr/sbin/chown"
@@ -219,6 +219,7 @@ This is what the `do' commands look for and what the `mark' commands store.")
 
 (defvar dired-file-version-alist)
 
+;;;###autoload
 (defvar dired-directory nil
   "The directory name or wildcard spec that this Dired directory lists.
 Local to each dired buffer.  May be a list, in which case the car is the
@@ -299,7 +300,7 @@ Subexpression 2 must end right before the \\n or \\r.")
         '(".+" (dired-move-to-filename) nil (0 font-lock-function-name-face)))
    ;;
    ;; Symbolic links.
-   (list dired-re-sym 
+   (list dired-re-sym
         '(".+" (dired-move-to-filename) nil (0 font-lock-keyword-face)))
    ;;
    ;; Files suffixed with `completion-ignored-extensions'.
@@ -530,11 +531,11 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
          (setq buffer (create-file-buffer (directory-file-name dirname)))))
     (set-buffer buffer)
     (if (not new-buffer-p)     ; existing buffer ...
-       (cond (switches        ; ... but new switches     
+       (cond (switches        ; ... but new switches
               ;; file list may have changed
               (setq dired-directory dir-or-list)
               ;; this calls dired-revert
-              (dired-sort-other switches))  
+              (dired-sort-other switches))
              ;; If directory has changed on disk, offer to revert.
              ((if (let ((attributes (file-attributes dirname))
                         (modtime (visited-file-modtime)))
@@ -589,6 +590,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
        (save-excursion
          (set-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)
@@ -654,6 +656,7 @@ If DIRNAME is already in a dired buffer, that buffer is used without refresh."
              file-list (cdr dired-directory))
       (setq dir dired-directory
            file-list nil))
+    (setq dir (expand-file-name dir))
     (if (and (equal "" (file-name-nondirectory dir))
             (not file-list))
        ;; If we are reading a whole single directory...
@@ -677,8 +680,7 @@ If HDR is non-nil, insert a header line with the directory name."
   (let ((opoint (point))
        (process-environment (copy-sequence process-environment))
        end)
-    (if (and dired-use-ls-dired
-            (not (file-remote-p dir)))
+    (if (or 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,
@@ -693,16 +695,22 @@ If HDR is non-nil, insert a header line with the directory name."
          (setq end (point-marker))
          (goto-char opoint)
          (while (search-forward "\\" end t)
-           (replace-match "\\\\" nil t))
+           (replace-match (apply #'propertize
+                                 "\\\\"
+                                 (text-properties-at (match-beginning 0)))
+                          nil t))
          (goto-char opoint)
          (while (search-forward "\^m" end t)
-           (replace-match "\\015" nil t))
+           (replace-match (apply #'propertize
+                                 "\\015"
+                                 (text-properties-at (match-beginning 0)))
+                          nil t))
          (set-marker end nil)))
     (dired-insert-set-properties opoint (point))
     ;; If we used --dired and it worked, the lines are already indented.
     ;; Otherwise, indent them.
     (unless (save-excursion
-             (forward-line -1)
+             (goto-char opoint)
              (looking-at "  "))
       (let ((indent-tabs-mode nil))
        (indent-rigidly opoint (point) 2)))
@@ -1454,16 +1462,17 @@ Optional arg NO-ERROR-IF-NOT-FILEP means return nil if no filename on
                         (or (dired-string-replace-match
                              "\\([^\\]\\|\\`\\)\"" file "\\1\\\\\"" nil t)
                             file)
-                        "\"")))))
+                        "\"")))
+         ;; The above `read' will return a unibyte string if FILE
+         ;; contains eight-bit-control/graphic characters.
+         (if (and enable-multibyte-characters
+                  (not (multibyte-string-p file)))
+             (setq file (string-to-multibyte 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)
@@ -1511,7 +1520,7 @@ Optional arg GLOBAL means to replace all matches."
       (replace-match newtext t literal string))))
 
 (defun dired-make-absolute (file &optional dir)
-  ;;"Convert FILE (a pathname relative to DIR) to an absolute pathname."
+  ;;"Convert FILE (a file name relative to DIR) to an absolute file name."
   ;; We can't always use expand-file-name as this would get rid of `.'
   ;; or expand in / instead default-directory if DIR=="".
   ;; This should be good enough for ange-ftp, but might easily be
@@ -1565,11 +1574,11 @@ DIR must be a directory name, not a file name."
         ;; 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 "[kKMGTPEZY]?" 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][kMGTPEZY]?" s
+    (concat ".*[0-9][kKMGTPEZY]?" s
            "\\(" western "\\|" western-comma "\\|" japanese "\\|" iso "\\)"
            s "+"))
   "Regular expression to match up to the file name in a directory listing.
@@ -1673,8 +1682,8 @@ regardless of the language.")
 (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.
+With a zero prefix arg, use the absolute file name of each marked file.
+With \\[universal-argument], use the file name sans directory of each marked file.
 
 If on a subdir headerline, use subdirname instead; prefix arg is ignored
 in this case.
@@ -1763,7 +1772,7 @@ You can then feed the file name(s) to other commands with \\[yank]."
             (substring pattern matched-in-pattern))
            "\\'")))
 
-                
+
 
 (defun dired-advertise ()
   ;;"Advertise in variable `dired-buffers' that we dired `default-directory'."
@@ -1793,8 +1802,8 @@ You can then feed the file name(s) to other commands with \\[yank]."
     (string-match (concat "^" (regexp-quote dir)) file)))
 
 (defun dired-normalize-subdir (dir)
-  ;; Prepend default-directory to DIR if relative path name.
-  ;; dired-get-filename must be able to make a valid filename from a
+  ;; Prepend default-directory to DIR if relative file name.
+  ;; dired-get-filename must be able to make a valid file name from a
   ;; file and its directory DIR.
   (file-name-as-directory
    (if (file-name-absolute-p dir)
@@ -1938,7 +1947,7 @@ instead of `dired-actual-switches'."
 (defun dired-goto-file (file)
   "Go to file line of FILE in this dired buffer."
   ;; Return value of point on success, else nil.
-  ;; FILE must be an absolute pathname.
+  ;; FILE must be an absolute file name.
   ;; Loses if FILE contains control chars like "\007" for which ls
   ;; either inserts "?" or "\\007" into the buffer, so we won't find
   ;; it in the buffer.
@@ -1951,7 +1960,7 @@ instead of `dired-actual-switches'."
   (setq file (directory-file-name file)) ; does no harm if no directory
   (let (found case-fold-search dir)
     (setq dir (or (file-name-directory file)
-                 (error "Need absolute pathname for %s" file)))
+                 (error "File name `%s' is not absolute" file)))
     (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.
@@ -1960,11 +1969,17 @@ instead of `dired-actual-switches'."
            (and (cdr dired-subdir-alist)
                 (dired-goto-subdir dir)))
          (let ((base (file-name-nondirectory file))
+               search-string
                (boundary (dired-subdir-max)))
+           (setq search-string
+                 (replace-regexp-in-string "\^m" "\\^m" base nil t))
+           (setq search-string
+                 (replace-regexp-in-string "\\\\" "\\\\" search-string nil t))
            (while (and (not found)
                        ;; filenames are preceded by SPC, this makes
                        ;; the search faster (e.g. for the filename "-"!).
-                       (search-forward (concat " " base) boundary 'move))
+                       (search-forward (concat " " search-string)
+                                       boundary 'move))
              ;; Match could have BASE just as initial substring or
              ;; or in permission bits or date or
              ;; not be a proper filename at all:
@@ -2034,13 +2049,14 @@ nil means no recursive deletes.
 `top' means ask for each directory at top level, but delete its subdirectories
 without asking.
 Anything else means ask for each directory."
-  :type '(choice :tag "Delete not empty directory"
-                (const :tag "No. Only empty directories" nil)
-                (const :tag "Ask for each directory" t)
-                (const :tag "Ask for each top directory only" top))
+  :type '(choice :tag "Delete non-empty directories"
+                (const :tag "Yes" always)
+                (const :tag "No--only delete empty directories" nil)
+                (const :tag "Confirm for each directory" t)
+                (const :tag "Confirm for each top directory only" top))
   :group 'dired)
 
-;; Match anything but `.' and `..'. 
+;; Match anything but `.' and `..'.
 (defvar dired-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")
 
 ;; Delete file, possibly delete a directory and all its files.
@@ -2161,7 +2177,7 @@ if there are no flagged files."
            (setq success-list (cons (buffer-name buf) success-list)))))
     success-list))
 
-;; Delete the entry for FILE from 
+;; Delete the entry for FILE from
 (defun dired-delete-entry (file)
   (save-excursion
     (and (dired-goto-file file)
@@ -2248,11 +2264,13 @@ Command symbols are `byte-compile', `chgrp', `chmod', `chown', `compress',
 `uncompress'.")
 
 (defun dired-mark-pop-up (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).
+  "Return FUNCTION's result on ARGS after showing which files are marked.
+Displays the file names in a buffer named BUFNAME;
+ nil gives \" *Marked Files*\".
+This uses function `dired-pop-to-buffer' to do that.
+
+FUNCTION should not manipulate files, just 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."
@@ -2555,7 +2573,9 @@ A prefix argument says to unflag those files instead."
      "auto save file")))
 
 (defvar dired-garbage-files-regexp
-  "\\.log$\\|\\.toc$\\|\\.dvi$\\|\\.bak$\\|\\.orig$\\|\\.rej$" 
+  (concat (regexp-opt
+          '(".log" ".toc" ".dvi" ".bak" ".orig" ".rej" ".aux"))
+         "\\'")
   "*Regular expression to match \"garbage\" files for `dired-flag-garbage-files'.")
 
 (defun dired-flag-garbage-files ()
@@ -2615,7 +2635,7 @@ OLD and NEW are both characters used to mark files."
 
 (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, 
+After this command, type the mark character to remove,
 or type RET to remove all marks.
 With prefix arg, query for each marked file.
 Type \\[help-command] at that time for help."
@@ -2666,7 +2686,7 @@ Thus, use \\[backward-page] to find the beginning of a group of errors."
   ;; Log a message or the contents of a buffer.
   ;; If LOG is a string and there are more args, it is formatted with
   ;; those ARGS.  Usually the LOG string ends with a \n.
-  ;; End each bunch of errors with (dired-log t): 
+  ;; End each bunch of errors with (dired-log t):
   ;; this inserts the current time and buffer at the start of the page,
   ;; and \f (formfeed) at the end.
   (let ((obuf (current-buffer)))
@@ -2721,6 +2741,10 @@ 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-inhibit nil
+  "Non-nil means the Dired sort command is disabled.
+The idea is to set this buffer-locally in special Dired buffers.")
+
 (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
@@ -2740,6 +2764,8 @@ Thus, use \\[backward-page] to find the beginning of a group of errors."
   "Toggle between sort by date/name and refresh the dired buffer.
 With a prefix argument you can edit the current listing switches instead."
   (interactive "P")
+  (when dired-sort-inhibit
+    (error "Cannot sort this Dired buffer"))
   (if arg
       (dired-sort-other
        (read-string "ls switches (must contain -l): " dired-actual-switches))
@@ -2969,9 +2995,8 @@ As each match is found, the user must type a character saying
   what to do with it.  For directions, type \\[help-command] at that time.
 NEWNAME may contain \\=\\<n> or \\& as in `query-replace-regexp'.
 REGEXP defaults to the last regexp used.
-With a zero prefix arg, renaming by regexp affects the complete
-  pathname - usually only the non-directory part of file names is used
-  and changed."
+With a zero prefix arg, renaming by regexp affects the full file name;
+usually only the non-directory part of file names is used and changed."
   t)
 
 (autoload 'dired-do-copy-regexp "dired-aux"
@@ -3054,7 +3079,7 @@ Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
 (autoload 'dired-show-file-type "dired-aux"
   "Print the type of FILE, according to the `file' command.
 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." 
+true then the type of the file linked to by FILE is printed instead."
   t)
 
 (autoload 'dired-run-shell-command "dired-aux")