]> code.delx.au - gnu-emacs/blobdiff - lisp/files.el
(c-macro-expansion): Delete ??! trigraph in uniquestring.
[gnu-emacs] / lisp / files.el
index 17a3f4c7a610a21ef11421bb32ace03afd7266fd..1aaf22348bdbe5334f9a506ae86500ee963c5fa7 100644 (file)
@@ -1,6 +1,7 @@
 ;;; files.el --- file input and output commands for Emacs
 
-;; Copyright (C) 1985, 86, 87, 92, 93, 94, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 86, 87, 92, 93,
+;;              94, 95, 1996 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 
@@ -17,8 +18,9 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
 
 ;;; Commentary:
 
@@ -194,15 +196,21 @@ If one of them returns non-nil, the file is considered already written
 and the rest are not called.
 These hooks are considered to pertain to the visited file.
 So this list is cleared if you change the visited file name.
-See also `write-contents-hooks'.
-Don't make this variable buffer-local; instead, use `local-write-file-hooks'.")
+
+Don't make this variable buffer-local; instead, use `local-write-file-hooks'.
+See also `write-contents-hooks'.")
 ;;; However, in case someone does make it local...
 (put 'write-file-hooks 'permanent-local t)
 
 (defvar local-write-file-hooks nil
   "Just like `write-file-hooks', except intended for per-buffer use.
 The functions in this list are called before the ones in
-`write-file-hooks'.")
+`write-file-hooks'.
+
+This variable is meant to be used for hooks that have to do with a
+particular visited file.  Therefore, it is a permanent local, so that
+changing the major mode does not clear it.  However, calling
+`set-visited-file-name' does clear it.")
 (make-variable-buffer-local 'local-write-file-hooks)
 (put 'local-write-file-hooks 'permanent-local t)
 
@@ -210,10 +218,18 @@ The functions in this list are called before the ones in
   "List of functions to be called before writing out a buffer to a file.
 If one of them returns non-nil, the file is considered already written
 and the rest are not called.
-These hooks are considered to pertain to the buffer's contents,
-not to the particular visited file; thus, `set-visited-file-name' does
-not clear this variable, but changing the major mode does clear it.
+
+This variable is meant to be used for hooks that pertain to the
+buffer's contents, not to the particular visited file; thus,
+`set-visited-file-name' does not clear this variable; but changing the
+major mode does clear it.
+
+This variable automatically becomes buffer-local whenever it is set.
+If you use `add-hooks' to add elements to the list, use nil for the
+LOCAL argument.
+
 See also `write-file-hooks'.")
+(make-variable-buffer-local 'write-contents-hooks)
 
 (defconst enable-local-variables t
   "*Control use of local-variables lists in files you visit.
@@ -724,7 +740,7 @@ The buffer is not selected, just returned to the caller."
          (dired-noselect (if find-file-visit-truename
                              (abbreviate-file-name (file-truename filename))
                            filename))
-       (error "%s is a directory." filename))
+       (error "%s is a directory" filename))
     (let* ((buf (get-file-buffer filename))
           (truename (abbreviate-file-name (file-truename filename)))
           (number (nthcdr 10 (file-attributes truename)))
@@ -814,7 +830,8 @@ The buffer is not selected, just returned to the caller."
                 (setq backup-inhibited t)))
          (if rawfile
              nil
-           (after-find-file error (not nowarn)))))
+           (after-find-file error (not nowarn))
+           (setq buf (current-buffer)))))
       buf)))
 \f
 (defvar after-find-file-from-revert-buffer nil)
@@ -845,7 +862,8 @@ unless NOMODES is non-nil."
                   (if (and warn
                            (file-newer-than-file-p (make-auto-save-file-name)
                                                    buffer-file-name))
-                      "Auto save file is newer; consider M-x recover-file"
+                      (format "%s has auto save data; consider M-x recover-file"
+                              (file-name-nondirectory buffer-file-name))
                     (setq not-serious t)
                     (if error "(New file)" nil)))
                  ((not error)
@@ -909,6 +927,7 @@ run `normal-mode' explicitly."
     ("\\.l\\'" . lisp-mode)
     ("\\.lisp\\'" . lisp-mode)
     ("\\.f\\'" . fortran-mode)
+    ("\\.F\\'" . fortran-mode)
     ("\\.for\\'" . fortran-mode)
     ("\\.p\\'" . pascal-mode)
     ("\\.pas\\'" . pascal-mode)
@@ -925,8 +944,9 @@ run `normal-mode' explicitly."
     ("\\.hxx\\'" . c++-mode)
     ("\\.c\\+\\+\\'" . c++-mode)
     ("\\.h\\+\\+\\'" . c++-mode)
+    ("\\.java\\'" . java-mode)
     ("\\.mk\\'" . makefile-mode)
-    ("[Mm]akefile\\(.in\\)?\\'" . makefile-mode)
+    ("\\(M\\|m\\|GNUm\\)akefile\\(.in\\)?\\'" . makefile-mode)
 ;;; Less common extensions come here
 ;;; so more common ones above are found faster.
     ("\\.texinfo\\'" . texinfo-mode)
@@ -940,6 +960,10 @@ run `normal-mode' explicitly."
     ("ChangeLog.[0-9]+\\'" . change-log-mode)
     ("\\$CHANGE_LOG\\$\\.TXT" . change-log-mode)
     ("\\.scm\\.[0-9]*\\'" . scheme-mode)
+    ("\\.[ck]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode)
+    ("/\\.\\(bash_profile\\|z?login\\|bash_login\\|z?logout\\)\\'" . sh-mode)
+    ("/\\.\\(bash_logout\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode)
+    ("/\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode)
 ;;; The following should come after the ChangeLog pattern
 ;;; for the sake of ChangeLog.1, etc.
 ;;; and after the .scm.[0-9] pattern too.
@@ -952,6 +976,9 @@ run `normal-mode' explicitly."
     ("\\.article\\'" . text-mode)
     ("\\.letter\\'" . text-mode)
     ("\\.tcl\\'" . tcl-mode)
+    ("\\.exp\\'" . tcl-mode)
+    ("\\.itcl\\'" . tcl-mode)
+    ("\\.itk\\'" . tcl-mode)
     ("\\.f90\\'" . f90-mode)
     ("\\.lsp\\'" . lisp-mode)
     ("\\.awk\\'" . awk-mode)
@@ -960,17 +987,17 @@ run `normal-mode' explicitly."
     ("\\.\\(arc\\|zip\\|lzh\\|zoo\\)\\'" . archive-mode)
     ;; Mailer puts message to be edited in
     ;; /tmp/Re.... or Message
-    ("^/tmp/Re" . text-mode)
+    ("\\`/tmp/Re" . text-mode)
     ("/Message[0-9]*\\'" . text-mode)
     ("/drafts/[0-9]+\\'" . mh-letter-mode)
     ;; some news reader is reported to use this
-    ("^/tmp/fol/" . text-mode)
+    ("\\`/tmp/fol/" . text-mode)
     ("\\.y\\'" . c-mode)
     ("\\.lex\\'" . c-mode)
     ("\\.oak\\'" . scheme-mode)
-    ("\\.sgm\\'" . sgml-mode)
-    ("\\.sgml\\'" . sgml-mode)
+    ("\\.sgml?\\'" . sgml-mode)
     ("\\.dtd\\'" . sgml-mode)
+    ("\\.s?html?\\'" . html-mode)
     ;; .emacs following a directory delimiter
     ;; in either Unix or VMS syntax.
     ("[]>:/]\\..*emacs\\'" . emacs-lisp-mode)
@@ -991,14 +1018,37 @@ REGEXP and search the list again for another match.")
 
 (defconst interpreter-mode-alist
   '(("perl" . perl-mode)
+    ("perl5" . perl-mode)
     ("wish" . tcl-mode)
     ("wishx" . tcl-mode)
     ("tcl" . tcl-mode)
     ("tclsh" . tcl-mode)
     ("awk" . awk-mode)
+    ("mawk" . awk-mode)
     ("nawk" . awk-mode)
     ("gawk" . awk-mode)
-    ("scm" . scheme-mode))
+    ("scm" . scheme-mode)
+    ("ash" . sh-mode)
+    ("bash" . sh-mode)
+    ("csh" . sh-mode)
+    ("dtksh" . sh-mode)
+    ("es" . sh-mode)
+    ("itcsh" . sh-mode)
+    ("jsh" . sh-mode)
+    ("ksh" . sh-mode)
+    ("oash" . sh-mode)
+    ("pdksh" . sh-mode)
+    ("rc" . sh-mode)
+    ("sh" . sh-mode)
+    ("sh5" . sh-mode)
+    ("tcsh" . sh-mode)
+    ("wksh" . sh-mode)
+    ("wsh" . sh-mode)
+    ("zsh" . sh-mode)
+    ("tail" . text-mode)
+    ("more" . text-mode)
+    ("less" . text-mode)
+    ("pg" . text-mode))
   "Alist mapping interpreter names to major modes.
 This alist applies to files whose first line starts with `#!'.
 Each element looks like (INTERPRETER . MODE).
@@ -1129,7 +1179,7 @@ If `enable-local-variables' is nil, this function does not check for a
                (let ((interpreter
                       (save-excursion
                         (goto-char (point-min))
-                        (if (looking-at "#! *\\([^ \t\n]*/bin/env +\\)?\\([^ \t\n]+\\)")
+                        (if (looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)")
                             (buffer-substring (match-beginning 2)
                                               (match-end 2))
                           "")))
@@ -1322,7 +1372,7 @@ in order to initialize other data structure based on them.")
              (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$"
                            (symbol-name var))
              (not (get var 'safe-local-variable))))
-        ;; Permit evaling a put of a harmless property
+        ;; Permit evalling a put of a harmless property.
         ;; if the args do nothing tricky.
         (if (or (and (eq var 'eval)
                      (consp val)
@@ -1377,6 +1427,11 @@ if you wish to pass an empty string as the argument."
          (setq truename (file-truename filename))
          (if find-file-visit-truename
              (setq filename truename))))
+    (let ((buffer (and filename (find-buffer-visiting filename))))
+      (and buffer (not (eq buffer (current-buffer)))
+          (not (y-or-n-p (message "A buffer is visiting %s; proceed? "
+                                  filename)))
+          (error "Aborted")))
     (or (equal filename buffer-file-name)
        (progn
          (and filename (lock-buffer filename))
@@ -1446,8 +1501,10 @@ Makes buffer visit that file, and marks it not modified.
 If the buffer is already visiting a file, you can specify
 a directory name as FILENAME, to write a file of the same
 old name in that directory.
+
 If optional second arg CONFIRM is non-nil,
-ask for confirmation for overwriting an existing file."
+ask for confirmation for overwriting an existing file.
+Interactively, confirmation is required unless you supply a prefix argument."
 ;;  (interactive "FWrite file: ")
   (interactive
    (list (if buffer-file-name
@@ -1457,7 +1514,7 @@ ask for confirmation for overwriting an existing file."
                               (cdr (assq 'default-directory
                                          (buffer-local-variables)))
                               nil nil (buffer-name)))
-        t))
+        (not current-prefix-arg)))
   (or (null filename) (string-equal filename "")
       (progn
        ;; If arg is just a directory,
@@ -2005,13 +2062,17 @@ saying what text to write."
         (file (file-name-nondirectory filename))
         (dir  (file-name-directory    filename))
         (comp (file-name-all-completions file dir))
-        newest)
+         (newest nil)
+         tem)
     (while comp
-      (setq file (concat dir (car comp))
+      (setq tem (car comp)
            comp (cdr comp))
-      (if (and (backup-file-name-p file)
-              (or (null newest) (file-newer-than-file-p file newest)))
-         (setq newest file)))
+      (cond ((and (backup-file-name-p tem)
+                  (string= (file-name-sans-versions tem) file))
+             (setq tem (concat dir tem))
+             (if (or (null newest)
+                     (file-newer-than-file-p tem newest))
+                 (setq newest tem)))))
     newest))
 
 (defun rename-uniquely ()
@@ -2040,7 +2101,7 @@ or multiple mail buffers, etc."
   "Create the directory DIR and any nonexistent parent dirs.
 Interactively, the default choice of directory to create
 is the current default directory for file names.
-That is useful when you have visited a file in a nonexistint directory.
+That is useful when you have visited a file in a nonexistent directory.
 
 Noninteractively, the second (optional) argument PARENTS says whether
 to create parent directories if they don't exist."
@@ -2495,7 +2556,10 @@ and `list-directory-verbose-switches'."
       (terpri)
       (save-excursion
        (set-buffer "*Directory*")
-       (setq default-directory (file-name-directory dirname))
+       (setq default-directory
+             (if (file-directory-p dirname)
+                 (file-name-as-directory dirname)
+               (file-name-directory dirname)))
        (let ((wildcard (not (file-directory-p dirname))))
          (insert-directory dirname switches wildcard (not wildcard)))))))