]> code.delx.au - gnu-emacs/blobdiff - lisp/files.el
(recover-file): Call auto-save-file-name-p correctly.
[gnu-emacs] / lisp / files.el
index 8eb4ff490e2bd6bf78c2b2edfa9a7aa683ae6f21..5673aeac8b593b4d7426854f46407ee887216d5c 100644 (file)
@@ -789,6 +789,8 @@ run `normal-mode' explicitly."
 ;;;                              ("[Mm]akefile" . makefile-mode)
 ;;; Less common extensions come here
 ;;; so more common ones above are found faster.
+                                 ("\\.texinfo\\'" . texinfo-mode)
+                                 ("\\.texi\\'" . texinfo-mode)
                                  ("\\.s\\'" . asm-mode)
                                  ("ChangeLog\\'" . change-log-mode)
                                  ("change.log\\'" . change-log-mode)
@@ -804,8 +806,7 @@ run `normal-mode' explicitly."
                                  ("\\.bib\\'" . bibtex-mode)
                                  ("\\.article\\'" . text-mode)
                                  ("\\.letter\\'" . text-mode)
-                                 ("\\.texinfo\\'" . texinfo-mode)
-                                 ("\\.texi\\'" . texinfo-mode)
+                                 ("\\.tcl\\'" . tcl-mode)
                                  ("\\.lsp\\'" . lisp-mode)
                                  ("\\.awk\\'" . awk-mode)
                                  ("\\.prolog\\'" . prolog-mode)
@@ -838,6 +839,20 @@ If the element has the form (REGEXP FUNCTION), then after calling
 FUNCTION, we delete the suffix that matched REGEXP and search the list
 again for another match.")
 
+(defconst interpreter-mode-alist
+  '(("perl" . perl-mode)
+    ("scope" . tcl-mode)
+    ("wish" . tcl-mode)
+    ("shell" . tcl-mode)
+    ("form" . tcl-mode)
+    ("tcl" . tcl-mode))
+  "Alist mapping interpreter names to major modes.
+This alist applies to files whose first line starts with `#!'.
+Each element looks like (INTERPRETER . MODE).
+The car of each element is compared with
+the name of the interpreter specified in the first line.
+If it matches, mode MODE is selected.")
+
 (defconst inhibit-local-variables-regexps '("\\.tar$")
   "List of regexps; if one matches a file name, don't look for local vars.")
 
@@ -927,7 +942,25 @@ If `enable-local-variables' is nil, this function does not check for a
                        (setq mode (cdr (car alist))
                              keep-going nil)))
                  (setq alist (cdr alist)))
-               (if mode (funcall mode)))))))))
+               (if mode
+                   (funcall mode)
+                 ;; If we can't deduce a mode from the file name,
+                 ;; look for an interpreter specified in the first line.
+                 (let ((interpreter
+                        (save-excursion
+                          (goto-char (point-min))
+                          (if (looking-at "#! *")
+                              (progn
+                                (goto-char (match-end 0))
+                                (buffer-substring (point)
+                                                  (progn (end-of-line) (point))))
+                            "")))
+                       elt)
+                   ;; Map interpreter name to a mode.
+                   (setq elt (assoc (file-name-nondirectory interpreter)
+                                    interpreter-mode-alist))
+                   (if elt
+                       (funcall (cdr elt))))))))))))
 
 (defun hack-local-variables-prop-line ()
   ;; Set local variables specified in the -*- line.
@@ -1382,22 +1415,16 @@ Value is a list whose car is the name for the backup file
   "Return number of names file FILENAME has."
   (car (cdr (file-attributes filename))))
 
-(defun file-relative-name-1 (directory)
-  (cond ((string= directory "/")
-        filename)
-       ((string-match (concat "^" (regexp-quote directory))
-                      filename)
-        (substring filename (match-end 0)))
-       (t
-        (file-relative-name-1
-         (file-name-directory (substring directory 0 -1))))))
-
 (defun file-relative-name (filename &optional directory)
   "Convert FILENAME to be relative to DIRECTORY (default: default-directory)."
   (setq filename (expand-file-name filename)
        directory (file-name-as-directory (expand-file-name
                                           (or directory default-directory))))
-  (file-relative-name-1 directory))
+  (let ((ancestor ""))
+    (while (not (string-match (concat "^" (regexp-quote directory)) filename))
+      (setq directory (file-name-directory (substring directory 0 -1))
+           ancestor (concat "../" ancestor)))
+    (concat ancestor (substring filename (match-end 0)))))
 \f
 (defun save-buffer (&optional args)
   "Save current buffer in visited file if modified.  Versions described below.
@@ -1795,7 +1822,8 @@ beginning and `after-revert-hook' at the end."
      (list (read-file-name "Recover file: "
                               file-dir nil nil file-name))))
   (setq file (expand-file-name file))
-  (if (auto-save-file-name-p file) (error "%s is an auto-save file" file))
+  (if (auto-save-file-name-p (file-name-nondirectory file))
+      (error "%s is an auto-save file" file))
   (let ((file-name (let ((buffer-file-name file))
                     (make-auto-save-file-name))))
     (cond ((not (file-newer-than-file-p file-name file))