(syms_of_frame): Fix typo.
[bpt/emacs.git] / lisp / dired-aux.el
index 0af40a0..878e5c5 100644 (file)
@@ -1,6 +1,6 @@
 ;;; dired-aux.el --- all of dired except what people usually use
 
-;; Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1992, 1994 Free Software Foundation, Inc.
 
 ;; Author: Sebastian Kremer <sk@thp.uni-koeln.de>.
 
 
 ;;; Commentary:
 
+;; The parts of dired mode not normally used.  This is a space-saving hack
+;; to avoid having to load a large mode when all that's wanted are a few
+;; functions.
+
 ;; Rewritten in 1990/1991 to add tree features, file marking and
 ;; sorting by Sebastian Kremer <sk@thp.uni-koeln.de>.
 ;; Finished up by rms in 1992.
 (defun dired-diff (file &optional switches)
   "Compare file at point with file FILE using `diff'.
 FILE defaults to the file at the mark.
-The prompted-for file is the first file given to `diff'."
+The prompted-for file is the first file given to `diff'.
+With prefix arg, prompt for second argument SWITCHES,
+ which is options for `diff'."
   (interactive
-   (let ((default (if (mark)
-                     (save-excursion (goto-char (mark))
+   (let ((default (if (mark t)
+                     (save-excursion (goto-char (mark t))
                                      (dired-get-filename t t)))))
+     (require 'diff)
      (list (read-file-name (format "Diff %s with: %s"
                                   (dired-get-filename t)
                                   (if default
                                       (concat "(default " default ") ")
                                     ""))
                           (dired-current-directory) default t)
-          (if (fboundp 'diff-read-switches)
-              (diff-read-switches "Options for diff: ")))))
-  (if switches                         ; Emacs 19's diff has but two
-      (diff file (dired-get-filename t) switches) ; args (yet ;-)
-    (diff file (dired-get-filename t))))
+          (if current-prefix-arg
+              (read-string "Options for diff: "
+                           (if (stringp diff-switches)
+                               diff-switches
+                             (mapconcat 'identity diff-switches " ")))))))
+  (diff file (dired-get-filename t) switches))
 
 ;;;###autoload
 (defun dired-backup-diff (&optional switches)
   "Diff this file with its backup file or vice versa.
 Uses the latest backup, if there are several numerical backups.
 If this file is a backup, diff it with its original.
-The backup file is the first file given to `diff'."
-  (interactive (list (if (fboundp 'diff-read-switches)
-                        (diff-read-switches "Diff with switches: "))))
-  (if switches
-      (diff-backup (dired-get-filename) switches)
-    (diff-backup (dired-get-filename))))
+The backup file is the first file given to `diff'.
+With prefix arg, prompt for argument SWITCHES which is options for `diff'."
+  (interactive
+    (if current-prefix-arg
+       (list (read-string "Options for diff: "
+                          (if (stringp diff-switches)
+                              diff-switches
+                            (mapconcat 'identity diff-switches " "))))
+      nil))
+  (diff-backup (dired-get-filename) switches))
 
 (defun dired-do-chxxx (attribute-name program op-symbol arg)
   ;; Change file attributes (mode, group, owner) of marked files and
@@ -152,7 +164,8 @@ Uses the shell command coming from variables `lpr-command' and
   (let* ((file-list (dired-get-marked-files t arg))
         (command (dired-mark-read-string
                   "Print %s with: "
-                  (apply 'concat lpr-command " " lpr-switches)
+                  (mapconcat 'concat (append (list lpr-command)
+                                             lpr-switches) " ")
                   'print arg file-list)))
     (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
 
@@ -265,9 +278,9 @@ with a prefix argument."
 (defun dired-shell-quote (filename)
   "Quote a file name for inferior shell (see variable `shell-file-name')."
   ;; Quote everything except POSIX filename characters.
-  ;; This should be safe enough even for really wierd shells.
+  ;; This should be safe enough even for really weird shells.
   (let ((result "") (start 0) end)
-    (while (string-match "[^---0-9a-zA-Z_./]" filename start)
+    (while (string-match "[^-0-9a-zA-Z_./]" filename start)
       (setq end (match-beginning 0)
            result (concat result (substring filename start end)
                           "\\" (substring filename end (1+ end)))
@@ -469,27 +482,57 @@ and use this command with a prefix argument (the value does not matter)."
         (from-file (dired-get-filename))
         (new-file (dired-compress-file from-file)))
     (if new-file
-       (progn (dired-update-file-line new-file) nil)
+       (let ((start (point)))
+         ;; Remove any preexisting entry for the name NEW-FILE.
+         (condition-case nil
+             (dired-remove-entry new-file)
+           (error nil))
+         (goto-char start)
+         ;; Now replace the current line with an entry for NEW-FILE.
+         (dired-update-file-line new-file) nil)
       (dired-log (concat "Failed to compress" from-file))
       from-file)))
 
+;;;###autoload
 (defun dired-compress-file (file)
   ;; Compress or uncompress FILE.
   ;; Return the name of the compressed or uncompressed file.
-  ;; Rerurn nil if no change in files.
-  (let ((handler (find-file-name-handler file)))
+  ;; Return nil if no change in files.
+  (let ((handler (find-file-name-handler file 'dired-compress-file)))
     (cond (handler
           (funcall handler 'dired-compress-file file))
          ((file-symlink-p file)
           nil)
-         ((string-match "\\.Z$" file)
-          (if (dired-check-process (concat "Uncompressing " file)
-                                   "uncompress" file)
+         ((let (case-fold-search)
+            (string-match "\\.Z$" file))
+          (if (not (dired-check-process (concat "Uncompressing " file)
+                                        "uncompress" file))
+              (substring file 0 -2)))
+         ((let (case-fold-search)
+            (string-match "\\.gz$" file))
+          (if (not (dired-check-process (concat "Uncompressing " file)
+                                        "gunzip" file))
+              (substring file 0 -3)))
+         ;; For .z, try gunzip.  It might be an old gzip file,
+         ;; or it might be from compact? pack? (which?) but gunzip handles
+         ;; both.
+         ((let (case-fold-search)
+            (string-match "\\.z$" file))
+          (if (not (dired-check-process (concat "Uncompressing " file)
+                                        "gunzip" file))
               (substring file 0 -2)))
          (t
-          (if (dired-check-process (concat "Compressing " file)
-                                   "compress" "-f" file)
-              (concat name ".Z"))))))
+          ;;; Try gzip; if we don't have that, use compress.
+          (condition-case nil
+              (if (not (dired-check-process (concat "Compressing " file)
+                                            "gzip" "-f" file))
+                  (cond ((file-exists-p (concat file ".gz"))
+                         (concat file ".gz"))
+                        (t (concat file ".z"))))
+            (file-error
+             (if (not (dired-check-process (concat "Compressing " file)
+                                           "compress" "-f" file))
+                 (concat file ".Z"))))))))
 \f
 (defun dired-mark-confirm (op-symbol arg)
   ;; Request confirmation from the user that the operation described
@@ -586,15 +629,12 @@ and use this command with a prefix argument (the value does not matter)."
 (defun dired-byte-compile ()
   ;; Return nil for success, offending file name else.
   (let* ((filename (dired-get-filename))
-        (elc-file
-         (if (eq system-type 'vax-vms)
-             (concat (substring filename 0 (string-match ";" filename)) "c")
-           (concat filename "c")))
-        buffer-read-only failure)
+        elc-file buffer-read-only failure)
     (condition-case err
        (save-excursion (byte-compile-file filename))
       (error
        (setq failure err)))
+    (setq elc-file (byte-compile-dest-file filename))
     (if failure
        (progn
          (dired-log "Byte compile error for %s:\n%s\n" filename failure)
@@ -668,7 +708,7 @@ a prefix arg lets you edit the `ls' switches used for the new listing."
 (defun dired-fun-in-all-buffers (directory fun &rest args)
   ;; In all buffers dired'ing DIRECTORY, run FUN with ARGS.
   ;; Return list of buffers where FUN succeeded (i.e., returned non-nil).
-  (let ((buf-list (dired-buffers-for-dir directory))
+  (let ((buf-list (dired-buffers-for-dir (expand-file-name directory)))
        (obuf (current-buffer))
        buf success-list)
     (while buf-list
@@ -682,6 +722,7 @@ a prefix arg lets you edit the `ls' switches used for the new listing."
        (set-buffer obuf)))
     success-list))
 
+;;;###autoload
 (defun dired-add-file (filename &optional marker-char)
   (dired-fun-in-all-buffers
    (file-name-directory filename)
@@ -725,20 +766,16 @@ a prefix arg lets you edit the `ls' switches used for the new listing."
                    (dired-goto-next-nontrivial-file))
                ;; not found
                (throw 'not-found "Subdir not found")))
-           ;; found and point is at The Right Place:
-           (let (buffer-read-only)
+           (let (buffer-read-only opoint)
              (beginning-of-line)
+             (setq opoint (point))
              (dired-add-entry-do-indentation marker-char)
-             ;; don't expand `.' !
-             (insert-directory (dired-make-absolute filename directory)
-                               (concat dired-actual-switches "d"))
+             ;; don't expand `.'.  Show just the file name within directory.
+             (let ((default-directory directory))
+               (insert-directory filename
+                                 (concat dired-actual-switches "d")))
+             (dired-insert-set-properties opoint (point))
              (forward-line -1)
-             ;; We want to have the non-directory part, only:
-             (let* ((beg (dired-move-to-filename t)) ; error for strange output
-                    (end (dired-move-to-end-of-filename)))
-               (setq filename (buffer-substring beg end))
-               (delete-region beg end)
-               (insert (file-name-nondirectory filename)))
              (if dired-after-readin-hook;; the subdir-alist is not affected...
                  (save-excursion;; ...so we can run it right now:
                    (save-restriction
@@ -751,7 +788,7 @@ a prefix arg lets you edit the `ls' switches used for the new listing."
            nil))
     (if reason                         ; don't move away on failure
        (goto-char opoint))
-    (not reason)))                     ; return t on succes, nil else
+    (not reason)))                     ; return t on success, nil else
 
 ;; This is a separate function for the sake of nested dired format.
 (defun dired-add-entry-do-indentation (marker-char)
@@ -775,6 +812,7 @@ a prefix arg lets you edit the `ls' switches used for the new listing."
        (forward-line 1))
     (point)))
 
+;;;###autoload
 (defun dired-remove-file (file)
   (dired-fun-in-all-buffers
    (file-name-directory file) (function dired-remove-entry) file))
@@ -786,6 +824,7 @@ a prefix arg lets you edit the `ls' switches used for the new listing."
           (delete-region (progn (beginning-of-line) (point))
                          (save-excursion (forward-line 1) (point)))))))
 
+;;;###autoload
 (defun dired-relist-file (file)
   (dired-fun-in-all-buffers (file-name-directory file)
                            (function dired-relist-entry) file))
@@ -827,10 +866,12 @@ Special value `always' suppresses confirmation.")
        (rename-file to backup 0)       ; confirm overwrite of old backup
        (dired-relist-entry backup))))
 
+;;;###autoload
 (defun dired-copy-file (from to ok-flag)
   (dired-handle-overwrite to)
   (copy-file from to ok-flag dired-copy-preserve-time))
 
+;;;###autoload
 (defun dired-rename-file (from to ok-flag)
   (dired-handle-overwrite to)
   (rename-file from to ok-flag)                ; error is caught in -create-files
@@ -851,12 +892,13 @@ Special value `always' suppresses confirmation.")
   (dired-fun-in-all-buffers from-dir
                            (function dired-rename-subdir-1) from-dir to-dir)
   ;; Update visited file name of all affected buffers
-  (let ((blist (buffer-list)))
+  (let ((expanded-from-dir (expand-file-name from-dir))
+       (blist (buffer-list)))
     (while blist
       (save-excursion
-        (set-buffer (car blist))
+       (set-buffer (car blist))
        (if (and buffer-file-name
-                (dired-in-this-tree buffer-file-name from-dir))
+                (dired-in-this-tree buffer-file-name expanded-from-dir))
            (let ((modflag (buffer-modified-p))
                  (to-file (dired-replace-in-string
                            (concat "^" (regexp-quote from-dir))
@@ -869,12 +911,13 @@ Special value `always' suppresses confirmation.")
 (defun dired-rename-subdir-1 (dir to)
   ;; Rename DIR to TO in headerlines and dired-subdir-alist, if DIR or
   ;; one of its subdirectories is expanded in this buffer.
-  (let ((alist dired-subdir-alist)
+  (let ((expanded-dir (expand-file-name dir))
+       (alist dired-subdir-alist)
        (elt nil))
     (while alist
       (setq elt (car alist)
            alist (cdr alist))
-      (if (dired-in-this-tree (car elt) dir)
+      (if (dired-in-this-tree (car elt) expanded-dir)
          ;; ELT's subdir is affected by the rename
          (dired-rename-subdir-2 elt dir to)))
     (if (equal dir default-directory)
@@ -1084,7 +1127,7 @@ ESC or `q' to not overwrite any of the remaining files,
   ;;   the new files.  Target may be a plain file if only one marked
   ;;   file exists.
   ;; OP-SYMBOL is the symbol for the operation.  Function `dired-mark-pop-up'
-  ;;   will determine wether pop-ups are appropriate for this OP-SYMBOL.
+  ;;   will determine whether pop-ups are appropriate for this OP-SYMBOL.
   ;; FILE-CREATOR and OPERATION as in dired-create-files.
   ;; ARG as in dired-get-marked-files.
   ;; Optional arg OP1 is an alternate form for OPERATION if there is
@@ -1459,7 +1502,7 @@ This function takes some pains to conform to `ls -lR' output."
 (defun dired-insert-subdir-validate (dirname &optional switches)
   ;; Check that it is valid to insert DIRNAME with SWITCHES.
   ;; Signal an error if invalid (e.g. user typed `i' on `..').
-  (or (dired-in-this-tree dirname default-directory)
+  (or (dired-in-this-tree dirname (expand-file-name default-directory))
       (error  "%s: not in this directory tree" dirname))
   (if switches
       (let (case-fold-search)
@@ -1490,6 +1533,7 @@ This function takes some pains to conform to `ls -lR' output."
   ;;"Kill all proper subdirs of DIRNAME, excluding DIRNAME itself.
   ;; With optional arg REMEMBER-MARKS, return an alist of marked files."
   (interactive "DKill tree below directory: ")
+  (setq dirname (expand-file-name dirname))
   (let ((s-alist dired-subdir-alist) dir m-alist)
     (while s-alist
       (setq dir (car (car s-alist))
@@ -1545,7 +1589,9 @@ This function takes some pains to conform to `ls -lR' output."
       (if (equal dirname (car (car (reverse dired-subdir-alist))))
          ;; top level directory may contain wildcards:
          (dired-readin-insert dired-directory)
-       (insert-directory dirname dired-actual-switches nil t)))
+       (let ((opoint (point)))
+         (insert-directory dirname dired-actual-switches nil t)
+         (dired-insert-set-properties opoint (point)))))
     (message "Reading directory %s...done" dirname)
     (setq end (point-marker))
     (indent-rigidly begin end 2)
@@ -1688,7 +1734,7 @@ The next char is either \\n, or \\r if DIR is hidden."
 ;;;###autoload
 (defun dired-mark-subdir-files ()
   "Mark all files except `.' and `..'."
-  (interactive "P")
+  (interactive)
   (let ((p-min (dired-subdir-min)))
     (dired-mark-files-in-region p-min (dired-subdir-max))))
 
@@ -1811,4 +1857,28 @@ Use \\[dired-hide-subdir] to (un)hide a particular subdirectory."
 
 ;;;###end dired-ins.el
 
+\f
+;; Functions for searching in tags style among marked files.
+
+;;;###autoload
+(defun dired-do-tags-search (regexp)
+  "Search through all marked files for a match for REGEXP.
+Stops when a match is found.
+To continue searching for next match, use command \\[tags-loop-continue]."
+  (interactive "sSearch marked files (regexp): ")
+  (tags-search regexp '(dired-get-marked-files)))
+
+;;;###autoload
+(defun dired-do-tags-query-replace (from to &optional delimited)
+  "Query-replace-regexp FROM with TO through all marked files.
+Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
+If you exit (\\[keyboard-quit] or ESC), you can resume the query-replace
+with the command \\[tags-loop-continue]."
+  (interactive
+   "sQuery replace in marked files (regexp): \nsQuery replace %s by: \nP")
+  (tags-query-replace from to delimited '(dired-get-marked-files)))
+\f
+
+(provide 'dired-aux)
+
 ;;; dired-aux.el ends here