(replace_buffer_in_all_windows):
[bpt/emacs.git] / lisp / files.el
index 603195b..102f0d3 100644 (file)
@@ -153,7 +153,7 @@ The value is a list of regular expressions.
 If the file name matches one of these regular expressions,
 then `revert-buffer' reverts the file without querying
 if the file has changed on disk and you have not edited the buffer."
-  :type 'boolean
+  :type '(repeat regexp)
   :group 'find-file)
 
 (defvar buffer-file-number nil
@@ -481,6 +481,33 @@ Do not specify them in other calls."
           (let ((tem (copy-sequence file-name-handler-alist)))
             (delq (rassq 'ange-ftp-completion-hook-function tem) tem)))))
     (or prev-dirs (setq prev-dirs (list nil)))
+
+    ;; andrewi@harlequin.co.uk - none of the following code (except for
+    ;; invoking the file-name handler) currently applies on Windows
+    ;; (ie. there are no native symlinks), but there is an issue with
+    ;; case differences being ignored by the OS, and short "8.3 DOS"
+    ;; name aliases existing for all files.  (The short names are not
+    ;; reported by directory-files, but can be used to refer to files.)
+    ;; It seems appropriate for file-truename to resolve these issues in
+    ;; the most natural way, which on Windows is to call the function
+    ;; `w32-long-file-name' - this returns the exact name of a file as
+    ;; it is stored on disk (expanding short name aliases with the full
+    ;; name in the process).
+    (if (eq system-type 'windows-nt)
+      (let ((handler (find-file-name-handler filename 'file-truename))
+           newname)
+       ;; For file name that has a special handler, call handler.
+       ;; This is so that ange-ftp can save time by doing a no-op.
+       (if handler
+           (setq filename (funcall handler 'file-truename filename))
+         ;; If filename contains a wildcard, newname will be the old name.
+         (if (string-match "[*?]" filename)
+             (setq newname filename)
+           ;; If filename doesn't exist, newname will be nil.
+           (setq newname (w32-long-file-name filename)))
+         (setq filename (or newname filename)))
+       (setq done t)))
+
     ;; If this file directly leads to a link, process that iteratively
     ;; so that we don't use lots of stack.
     (while (not done)
@@ -688,7 +715,7 @@ If the current buffer now contains an empty file that you just visited
             (rename-buffer oname))))
     (or (eq (current-buffer) obuf)
        (kill-buffer obuf))))
-
+\f
 (defun create-file-buffer (filename)
   "Create a suitably named buffer for visiting FILENAME, and return it.
 FILENAME (sans directory) is used unchanged if that name is free;
@@ -799,33 +826,7 @@ If there is no such live buffer, return nil."
                       (setq found (car list))))
                 (setq list (cdr list))))
          found))))
-
-(defun insert-file-contents-literally (filename &optional visit beg end replace)
-  "Like `insert-file-contents', q.v., but only reads in the file.
-A buffer may be modified in several ways after reading into the buffer due
-to advanced Emacs features, such as file-name-handlers, format decoding,
-find-file-hooks, etc.
-  This function ensures that none of these modifications will take place.
-
-This function does not work for remote files, because it turns off
-file name handlers and remote file access uses a file name handler."
-  (let ((format-alist nil)
-       (after-insert-file-functions nil)
-       (coding-system-for-read 'no-conversion)
-       (coding-system-for-write 'no-conversion)
-       (jka-compr-compression-info-list nil)
-       (find-buffer-file-type-function
-        (if (fboundp 'find-buffer-file-type)
-            (symbol-function 'find-buffer-file-type)
-          nil)))
-    (unwind-protect
-       (progn
-         (fset 'find-buffer-file-type (lambda (filename) t))
-         (insert-file-contents filename visit beg end replace))
-      (if find-buffer-file-type-function
-         (fset 'find-buffer-file-type find-buffer-file-type-function)
-       (fmakunbound 'find-buffer-file-type)))))
-
+\f
 (defun find-file-noselect (filename &optional nowarn rawfile)
   "Read file FILENAME into a buffer and return the buffer.
 If a buffer exists visiting FILENAME, return that one, but
@@ -892,7 +893,11 @@ Optional second arg RAWFILE non-nil means the file is read literally."
                         (file-name-nondirectory filename)
                         (buffer-name buf))))
                     (with-current-buffer buf
-                      (revert-buffer t t)))))
+                      (revert-buffer t t)))
+                   ((not (eq rawfile (not (null find-file-literally))))
+                    (if rawfile
+                        (message "File is already visited, and not literally")
+                      (message "File is already visited, and visited literally")))))
        (save-excursion
 ;;; The truename stuff makes this obsolete.
 ;;;      (let* ((link-name (car (file-attributes filename)))
@@ -943,10 +948,55 @@ Optional second arg RAWFILE non-nil means the file is read literally."
                 (make-local-variable 'backup-inhibited)
                 (setq backup-inhibited t)))
          (if rawfile
-             nil
+             (progn
+               (setq enable-multibyte-characters nil)
+               (make-local-variable 'find-file-literally)
+               (setq find-file-literally t))
            (after-find-file error (not nowarn))
            (setq buf (current-buffer)))))
       buf)))
+\f
+(defun insert-file-contents-literally (filename &optional visit beg end replace)
+  "Like `insert-file-contents', but only reads in the file literally.
+A buffer may be modified in several ways after reading into the buffer,
+to Emacs features such as format decoding, character code
+conversion, find-file-hooks, automatic uncompression, etc.
+
+This function ensures that none of these modifications will take place."
+  (let ((format-alist nil)
+       (after-insert-file-functions nil)
+       (coding-system-for-read 'no-conversion)
+       (coding-system-for-write 'no-conversion)
+       (jka-compr-compression-info-list nil)
+       (find-buffer-file-type-function
+        (if (fboundp 'find-buffer-file-type)
+            (symbol-function 'find-buffer-file-type)
+          nil)))
+    (unwind-protect
+       (progn
+         (fset 'find-buffer-file-type (lambda (filename) t))
+         (insert-file-contents filename visit beg end replace))
+      (if find-buffer-file-type-function
+         (fset 'find-buffer-file-type find-buffer-file-type-function)
+       (fmakunbound 'find-buffer-file-type)))))
+
+(defun insert-file-literally (filename)
+  "Insert contents of file FILENAME into buffer after point with no conversion.
+
+This function is meant for the user to run interactively.
+Don't call it from programs!  Use `insert-file-contents-literally' instead.
+\(Its calling sequence is different; see its documentation)."
+  (interactive "*fInsert file literally: ")
+  (if (file-directory-p filename)
+      (signal 'file-error (list "Opening input file" "file is a directory"
+                               filename)))
+  (let ((tem (insert-file-contents-literally filename)))
+    (push-mark (+ (point) (car (cdr tem))))))
+
+(defvar find-file-literally nil
+  "Non-nil if this buffer was made by `find-file-literally' or equivalent.
+This is a permanent local.")
+(put 'find-file-literally 'permanent-local t)
 
 (defun find-file-literally (filename) 
   "Visit file FILENAME with no conversion of any kind.
@@ -954,11 +1004,18 @@ Format conversion and character code conversion are both disabled,
 and multibyte characters are disabled in the resulting buffer.
 The major mode used is Fundamental mode regardless of the file name,
 and local variable specifications in the file are ignored.
-Automatic uncompression is also disabled."
+Automatic uncompression is also disabled.
+
+You cannot absolutely rely on this function to result in
+visiting the file literally.  If Emacs already has a buffer
+which is visiting the file, you get the existing buffer,
+regardless of whether it was created literally or not.
+
+In a Lisp program, if you want to be sure of accessing a file's
+contents literally, you should create a temporary buffer and then read
+the file contents into it using `insert-file-contents-literally'."
   (interactive "FFind file literally: ")
-  (prog1
-      (switch-to-buffer (find-file-noselect filename nil t))
-    (setq enable-multibyte-characters nil)))
+  (switch-to-buffer (find-file-noselect filename nil t)))
 \f
 (defvar after-find-file-from-revert-buffer nil)
 
@@ -1108,6 +1165,8 @@ run `normal-mode' explicitly."
     ("\\.clo\\'" . latex-mode)         ;LaTeX 2e class option
     ("\\.bbl\\'" . latex-mode)
     ("\\.bib\\'" . bibtex-mode)
+    ("\\.m4\\'" . m4-mode)
+    ("\\.mc\\'" . m4-mode)
     ("\\.mf\\'" . metafont-mode)
     ("\\.mp\\'" . metapost-mode)
     ("\\.article\\'" . text-mode)
@@ -1124,8 +1183,8 @@ run `normal-mode' explicitly."
     ("\\.awk\\'" . awk-mode)
     ("\\.prolog\\'" . prolog-mode)
     ("\\.tar\\'" . tar-mode)
-    ("\\.\\(arc\\|zip\\|lzh\\|zoo\\)\\'" . archive-mode)
-    ("\\.\\(ARC\\|ZIP\\|LZH\\|ZOO\\)\\'" . archive-mode)
+    ("\\.\\(arc\\|zip\\|lzh\\|zoo\\|jar\\)\\'" . archive-mode)
+    ("\\.\\(ARC\\|ZIP\\|LZH\\|ZOO\\|JAR\\)\\'" . archive-mode)
     ;; Mailer puts message to be edited in
     ;; /tmp/Re.... or Message
     ("\\`/tmp/Re" . text-mode)
@@ -1339,8 +1398,9 @@ and we don't even do that unless it would come from the file name."
 
 (defun hack-local-variables-prop-line ()
   ;; Set local variables specified in the -*- line.
-  ;; Ignore any specification for `mode:';
-  ;; set-auto-mode should already have handled that.
+  ;; Ignore any specification for `mode:' and `coding:';
+  ;; set-auto-mode should already have handled `mode:',
+  ;; set-auto-coding should already have handled `coding:'.
   (save-excursion
     (goto-char (point-min))
     (let ((result nil)
@@ -1376,7 +1436,9 @@ and we don't even do that unless it would come from the file name."
                 ;; case when checking for `mode' in set-auto-mode,
                 ;; so we must do that here as well.
                 ;; That is inconsistent, but we're stuck with it.
+                ;; The same can be said for `coding' in set-auto-coding.
                 (or (equal (downcase (symbol-name key)) "mode")
+                    (equal (downcase (symbol-name key)) "coding")
                     (setq result (cons (cons key val) result)))
                 (skip-chars-forward " \t;")))
             (setq result (nreverse result))))
@@ -1528,6 +1590,9 @@ is specified, returning t if it is specified."
   (cond ((eq var 'mode)
         (funcall (intern (concat (downcase (symbol-name val))
                                  "-mode"))))
+       ((eq var 'coding)
+        ;; We have already handled coding: tag in set-auto-coding.
+        nil)
        ((memq var ignored-local-variables)
         nil)
        ;; "Setting" eval means either eval it or do nothing.
@@ -2307,8 +2372,7 @@ Don't call it from programs!  Use `insert-file-contents' instead.
   "Append the contents of the region to the end of file FILENAME.
 When called from a function, expects three arguments,
 START, END and FILENAME.  START and END are buffer positions
-saying what text to write.
-A prefix argument enables user to specify the coding-system interactively."
+saying what text to write."
   (interactive "r\nFAppend to file: ")
   (write-region start end filename t))
 
@@ -2495,8 +2559,13 @@ non-nil, it is called instead of rereading visited file contents."
                     (or auto-save-p
                         (unlock-buffer)))
                   (widen)
-                  (insert-file-contents file-name (not auto-save-p)
-                                        nil nil t)))
+                  (let ((coding-system-for-read
+                         ;; Auto-saved file shoule be read without
+                         ;; any code conversion.
+                         (if auto-save-p 'no-conversion
+                           coding-system-for-read)))
+                    (insert-file-contents file-name (not auto-save-p)
+                                          nil nil t))))
               (goto-char (min opoint (point-max)))
               ;; Recompute the truename in case changes in symlinks
               ;; have changed the truename.
@@ -2529,7 +2598,7 @@ non-nil, it is called instead of rereading visited file contents."
             (not (file-exists-p file-name)))
           (error "Auto-save file %s not current" file-name))
          ((save-window-excursion
-            (if (not (eq system-type 'vax-vms))
+            (if (not (memq system-type '(vax-vms windows-nt)))
                 (with-output-to-temp-buffer "*Directory*"
                   (buffer-disable-undo standard-output)
                   (call-process "ls" nil standard-output nil
@@ -2702,7 +2771,7 @@ See also `auto-save-file-name-p'."
       (if (and (eq system-type 'ms-dos)
               (not (msdos-long-file-names)))
          (let ((fn (file-name-nondirectory buffer-file-name)))
-               (string-match "\\`\\([^.]+\\)\\(\\.\\(..?\\)?.?\\|\\)\\'" fn)
+           (string-match "\\`\\([^.]+\\)\\(\\.\\(..?\\)?.?\\|\\)\\'" fn)
            (concat (file-name-directory buffer-file-name)
                    "#" (match-string 1 fn) 
                    "." (match-string 3 fn) "#"))
@@ -2916,14 +2985,16 @@ If WILDCARD, it also runs the shell specified by `shell-file-name'."
                                     (substring pattern (match-beginning 0)))
                             beg (1+ (match-end 0))))
                     (call-process shell-file-name nil t nil
-                                  "-c" (concat "\\"  ;; Disregard shell aliases!
+                                  "-c" (concat "\\" ;; Disregard shell aliases!
                                                insert-directory-program
                                                " -d "
                                                (if (stringp switches)
                                                    switches
                                                  (mapconcat 'identity switches " "))
                                                " -- "
-                                               pattern)))
+                                               (encode-coding-string
+                                                pattern
+                                                file-name-coding-system t))))
                 ;; SunOS 4.1.3, SVr4 and others need the "." to list the
                 ;; directory if FILE is a symbolic link.
                 (apply 'call-process
@@ -2944,9 +3015,11 @@ If WILDCARD, it also runs the shell specified by `shell-file-name'."
                                  ;; Avoid lossage if FILE starts with `-'.
                                  '("--")
                                  (list
-                                  (if full-directory-p
-                                      (concat (file-name-as-directory file) ".")
-                                    file)))))))
+                                  (encode-coding-string
+                                   (if full-directory-p
+                                       (concat (file-name-as-directory file) ".")
+                                     file)
+                                   file-name-coding-system t)))))))
            ;; We get here if ls failed.
            ;; Access the file to get a suitable error.
            (access-file file "Reading directory"))))))