]> code.delx.au - gnu-emacs/blobdiff - lisp/files.el
Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
[gnu-emacs] / lisp / files.el
index 132ebced1c077aa18c35ea938f7a6bca86f2212d..4610c0a11e06dd4caecd288ad006873a82a704ec 100644 (file)
@@ -2316,14 +2316,21 @@ not set local variables (though we do notice a mode specified with -*-.)
 or from Lisp without specifying the optional argument FIND-FILE;
 in that case, this function acts as if `enable-local-variables' were t."
   (interactive)
-  (fundamental-mode)
+  (kill-all-local-variables)
+  (unless delay-mode-hooks
+    (run-hooks 'change-major-mode-after-body-hook
+               'after-change-major-mode-hook))
   (let ((enable-local-variables (or (not find-file) enable-local-variables)))
     ;; FIXME this is less efficient than it could be, since both
     ;; s-a-m and h-l-v may parse the same regions, looking for "mode:".
     (with-demoted-errors "File mode specification error: %s"
       (set-auto-mode))
-    (with-demoted-errors "File local-variables error: %s"
-      (hack-local-variables)))
+    ;; `delay-mode-hooks' being non-nil will have prevented the major
+    ;; mode's call to `run-mode-hooks' from calling
+    ;; `hack-local-variables'.  In that case, call it now.
+    (when delay-mode-hooks
+      (with-demoted-errors "File local-variables error: %s"
+        (hack-local-variables 'no-mode))))
   ;; Turn font lock off and on, to make sure it takes account of
   ;; whatever file local variables are relevant to it.
   (when (and font-lock-mode
@@ -3297,11 +3304,15 @@ DIR-NAME is the name of the associated directory.  Otherwise it is nil."
 ;; TODO?  Warn once per file rather than once per session?
 (defvar hack-local-variables--warned-lexical nil)
 
-(defun hack-local-variables (&optional mode-only)
+(defun hack-local-variables (&optional handle-mode)
   "Parse and put into effect this buffer's local variables spec.
 Uses `hack-local-variables-apply' to apply the variables.
 
-If MODE-ONLY is non-nil, all we do is check whether a \"mode:\"
+If HANDLE-MODE is nil, we apply all the specified local
+variables.  If HANDLE-MODE is neither nil nor t, we do the same,
+except that any settings of `mode' are ignored.
+
+If HANDLE-MODE is t, all we do is check whether a \"mode:\"
 is specified, and return the corresponding mode symbol, or nil.
 In this case, we try to ignore minor-modes, and only return a
 major-mode.
@@ -3319,7 +3330,7 @@ local variables, but directory-local variables may still be applied."
   (let ((enable-local-variables
         (and local-enable-local-variables enable-local-variables))
        result)
-    (unless mode-only
+    (unless (eq handle-mode t)
       (setq file-local-variables-alist nil)
       (with-demoted-errors "Directory-local variables error: %s"
        ;; Note this is a no-op if enable-local-variables is nil.
@@ -3327,18 +3338,19 @@ local variables, but directory-local variables may still be applied."
     ;; This entire function is basically a no-op if enable-local-variables
     ;; is nil.  All it does is set file-local-variables-alist to nil.
     (when enable-local-variables
-      ;; This part used to ignore enable-local-variables when mode-only
-      ;; was non-nil.  That was inappropriate, eg consider the
+      ;; This part used to ignore enable-local-variables when handle-mode
+      ;; was t.  That was inappropriate, eg consider the
       ;; (artificial) example of:
       ;; (setq local-enable-local-variables nil)
       ;; Open a file foo.txt that contains "mode: sh".
       ;; It correctly opens in text-mode.
       ;; M-x set-visited-file name foo.c, and it incorrectly stays in text-mode.
       (unless (or (inhibit-local-variables-p)
-                 ;; If MODE-ONLY is non-nil, and the prop line specifies a
+                 ;; If HANDLE-MODE is t, and the prop line specifies a
                  ;; mode, then we're done, and have no need to scan further.
-                 (and (setq result (hack-local-variables-prop-line mode-only))
-                      mode-only))
+                 (and (setq result (hack-local-variables-prop-line
+                                     (eq handle-mode t)))
+                      (eq handle-mode t)))
        ;; Look for "Local variables:" line in last page.
        (save-excursion
          (goto-char (point-max))
@@ -3393,7 +3405,7 @@ local variables, but directory-local variables may still be applied."
                  (goto-char (point-min))
 
                  (while (not (or (eobp)
-                                  (and mode-only result)))
+                                  (and (eq handle-mode t) result)))
                    ;; Find the variable name;
                    (unless (looking-at hack-local-variable-regexp)
                       (error "Malformed local variable line: %S"
@@ -3410,7 +3422,7 @@ local variables, but directory-local variables may still be applied."
                      (forward-char 1)
                      (let ((read-circle nil))
                        (setq val (read (current-buffer))))
-                     (if mode-only
+                     (if (eq handle-mode t)
                          (and (eq var 'mode)
                               ;; Specifying minor-modes via mode: is
                               ;; deprecated, but try to reject them anyway.
@@ -3432,6 +3444,7 @@ local variables, but directory-local variables may still be applied."
                                     ;; to use 'thisbuf's name in the
                                     ;; warning message.
                                     (or (buffer-file-name thisbuf) ""))))))
+                              ((and (eq var 'mode) handle-mode))
                              (t
                               (ignore-errors
                                 (push (cons (if (eq var 'eval)
@@ -3440,8 +3453,8 @@ local variables, but directory-local variables may still be applied."
                                             val) result))))))
                    (forward-line 1))))))))
       ;; Now we've read all the local variables.
-      ;; If MODE-ONLY is non-nil, return whether the mode was specified.
-      (if mode-only result
+      ;; If HANDLE-MODE is t, return whether the mode was specified.
+      (if (eq handle-mode t) result
        ;; Otherwise, set the variables.
        (hack-local-variables-filter result nil)
        (hack-local-variables-apply)))))
@@ -3804,8 +3817,10 @@ This function returns either:
                   ;; The entry MTIME should match the most recent
                   ;; MTIME among matching files.
                   (and cached-files
-                       (= (time-to-seconds (nth 2 dir-elt))
-                          (apply #'max (mapcar (lambda (f) (time-to-seconds (nth 5 (file-attributes f))))
+                       (= (float-time (nth 2 dir-elt))
+                          (apply #'max (mapcar (lambda (f)
+                                                 (float-time
+                                                  (nth 5 (file-attributes f))))
                                                cached-files))))))
             ;; This cache entry is OK.
             dir-elt
@@ -3847,7 +3862,7 @@ Return the new class name, which is a symbol named DIR."
      (seconds-to-time
       (if success
           (apply #'max (mapcar (lambda (file)
-                                 (time-to-seconds (nth 5 (file-attributes file))))
+                                 (float-time (nth 5 (file-attributes file))))
                                files))
         ;; If there was a problem, use the values we could get but
         ;; don't let the cache prevent future reads.
@@ -4305,8 +4320,8 @@ the group would be preserved too."
 
 (defun file-name-sans-extension (filename)
   "Return FILENAME sans final \"extension\".
-The extension, in a file name, is the part that follows the last `.',
-except that a leading `.', if any, doesn't count."
+The extension, in a file name, is the part that begins with the last `.',
+except that a leading `.' of the file name, if there is one, doesn't count."
   (save-match-data
     (let ((file (file-name-sans-versions (file-name-nondirectory filename)))
          directory)
@@ -4321,15 +4336,16 @@ except that a leading `.', if any, doesn't count."
 
 (defun file-name-extension (filename &optional period)
   "Return FILENAME's final \"extension\".
-The extension, in a file name, is the part that follows the last `.',
-excluding version numbers and backup suffixes,
-except that a leading `.', if any, doesn't count.
+The extension, in a file name, is the part that begins with the last `.',
+excluding version numbers and backup suffixes, except that a leading `.'
+of the file name, if there is one, doesn't count.
 Return nil for extensionless file names such as `foo'.
 Return the empty string for file names such as `foo.'.
 
-If PERIOD is non-nil, then the returned value includes the period
-that delimits the extension, and if FILENAME has no extension,
-the value is \"\"."
+By default, the returned value excludes the period that starts the
+extension, but if the optional argument PERIOD is non-nil, the period
+is included in the value, and in that case, if FILENAME has no
+extension, the value is \"\"."
   (save-match-data
     (let ((file (file-name-sans-versions (file-name-nondirectory filename))))
       (if (and (string-match "\\.[^.]*\\'" file)
@@ -6194,7 +6210,7 @@ and `list-directory-verbose-switches'."
 
 PATTERN is assumed to represent a file-name wildcard suitable for the
 underlying filesystem.  For Unix and GNU/Linux, each character from the
-set [ \\t\\n;<>&|()`'\"#$] is quoted with a backslash; for DOS/Windows, all
+set [ \\t\\n;<>&|()\\=`\\='\"#$] is quoted with a backslash; for DOS/Windows, all
 the parts of the pattern which don't include wildcard characters are
 quoted with double quotes.