Spelling fixes.
[bpt/emacs.git] / lisp / files.el
index 8849e26..40b6e7d 100644 (file)
@@ -151,6 +151,7 @@ Automatically local in all buffers."
   :type 'boolean
   :group 'backup)
 (make-variable-buffer-local 'buffer-offer-save)
+(put 'buffer-offer-save 'permanent-local t)
 
 (defcustom find-file-existing-other-name t
   "Non-nil means find a file under alternative names, in existing buffers.
@@ -278,7 +279,7 @@ The value `never' means do not make them."
   :group 'backup
   :group 'vc)
 (put 'version-control 'safe-local-variable
-     '(lambda (x) (or (booleanp x) (equal x 'never))))
+     (lambda (x) (or (booleanp x) (equal x 'never))))
 
 (defcustom dired-kept-versions 2
   "When cleaning directory, number of versions to keep."
@@ -635,22 +636,22 @@ the value of `default-directory'."
   "Value of the CDPATH environment variable, as a list.
 Not actually set up until the first time you use it.")
 
-(defun parse-colon-path (cd-path)
+(defun parse-colon-path (search-path)
   "Explode a search path into a list of directory names.
 Directories are separated by occurrences of `path-separator'
 \(which is colon in GNU and GNU-like systems)."
   ;; We could use split-string here.
-  (and cd-path
+  (and search-path
        (let (cd-list (cd-start 0) cd-colon)
-        (setq cd-path (concat cd-path path-separator))
-        (while (setq cd-colon (string-match path-separator cd-path cd-start))
+        (setq search-path (concat search-path path-separator))
+        (while (setq cd-colon (string-match path-separator search-path cd-start))
           (setq cd-list
                 (nconc cd-list
                        (list (if (= cd-start cd-colon)
                                   nil
                                (substitute-in-file-name
                                 (file-name-as-directory
-                                 (substring cd-path cd-start cd-colon)))))))
+                                 (substring search-path cd-start cd-colon)))))))
           (setq cd-start (+ cd-colon 1)))
         cd-list)))
 
@@ -866,11 +867,10 @@ and return the directory.  Return nil if not found."
   ;; `name' in /home or in /.
   (setq file (abbreviate-file-name file))
   (let ((root nil)
-        (prev-file file)
         ;; `user' is not initialized outside the loop because
         ;; `file' may not exist, so we may have to walk up part of the
-        ;; hierarchy before we find the "initial UID".
-        (user nil)
+        ;; hierarchy before we find the "initial UID".  Note: currently unused
+        ;; (user nil)
         try)
     (while (not (or root
                     (null file)
@@ -887,8 +887,7 @@ and return the directory.  Return nil if not found."
                     (string-match locate-dominating-stop-dir-regexp file)))
       (setq try (file-exists-p (expand-file-name name file)))
       (cond (try (setq root file))
-            ((equal file (setq prev-file file
-                               file (file-name-directory
+            ((equal file (setq file (file-name-directory
                                      (directory-file-name file))))
              (setq file nil))))
     root))
@@ -958,10 +957,10 @@ reasonable to let-bind this variable to a value less then the
 time period between two checks.
 Example:
 
-  \(defun display-time-file-nonempty-p \(file)
-    \(let \(\(remote-file-name-inhibit-cache \(- display-time-interval 5)))
-      \(and \(file-exists-p file)
-           \(< 0 \(nth 7 \(file-attributes \(file-chase-links file)))))))"
+  (defun display-time-file-nonempty-p (file)
+    (let ((remote-file-name-inhibit-cache (- display-time-interval 5)))
+      (and (file-exists-p file)
+           (< 0 (nth 7 (file-attributes (file-chase-links file)))))))"
   :group 'files
   :version "24.1"
   :type `(choice
@@ -983,7 +982,8 @@ accessible."
       nil)))
 
 (defun file-truename (filename &optional counter prev-dirs)
-  "Return the truename of FILENAME, which should be absolute.
+  "Return the truename of FILENAME.
+If FILENAME is not absolute, first expands it against `default-directory'.
 The truename of a file name is found by chasing symbolic links
 both at the level of the file and at the level of the directories
 containing it, until no links are left at any level.
@@ -1139,6 +1139,37 @@ it means chase no more than that many links and then stop."
        (setq count (1+ count))))
     newname))
 
+;; A handy function to display file sizes in human-readable form.
+;; See http://en.wikipedia.org/wiki/Kibibyte for the reference.
+(defun file-size-human-readable (file-size &optional flavor)
+  "Produce a string showing FILE-SIZE in human-readable form.
+
+Optional second argument FLAVOR controls the units and the display format:
+
+ If FLAVOR is nil or omitted, each kilobyte is 1024 bytes and the produced
+    suffixes are \"k\", \"M\", \"G\", \"T\", etc.
+ If FLAVOR is `si', each kilobyte is 1000 bytes and the produced suffixes
+    are \"k\", \"M\", \"G\", \"T\", etc.
+ If FLAVOR is `iec', each kilobyte is 1024 bytes and the produced suffixes
+    are \"KiB\", \"MiB\", \"GiB\", \"TiB\", etc."
+  (let ((power (if (or (null flavor) (eq flavor 'iec))
+                  1024.0
+                1000.0))
+       (post-fixes
+        ;; none, kilo, mega, giga, tera, peta, exa, zetta, yotta
+        (list "" "k" "M" "G" "T" "P" "E" "Z" "Y")))
+    (while (and (>= file-size power) (cdr post-fixes))
+      (setq file-size (/ file-size power)
+           post-fixes (cdr post-fixes)))
+    (format (if (> (mod file-size 1.0) 0.05)
+               "%.1f%s%s"
+             "%.0f%s%s")
+           file-size
+           (if (and (eq flavor 'iec) (string= (car post-fixes) "k"))
+               "K"
+             (car post-fixes))
+           (if (eq flavor 'iec) "iB" ""))))
+
 (defun make-temp-file (prefix &optional dir-flag suffix)
   "Create a temporary file.
 The returned file name (created by appending some random characters at the end
@@ -1258,100 +1289,6 @@ return value, which may be passed as the REQUIRE-MATCH arg to
         'confirm)
        (t nil)))
 
-(defun read-buffer-to-switch (prompt)
-  "Read the name of a buffer to switch to and return as a string.
-It is intended for `switch-to-buffer' family of commands since they
-need to omit the name of current buffer from the list of completions
-and default values."
-  (let ((rbts-completion-table (internal-complete-buffer-except)))
-    (minibuffer-with-setup-hook
-        (lambda ()
-          (setq minibuffer-completion-table rbts-completion-table)
-          ;; Since rbts-completion-table is built dynamically, we
-          ;; can't just add it to the default value of
-          ;; icomplete-with-completion-tables, so we add it
-          ;; here manually.
-          (if (and (boundp 'icomplete-with-completion-tables)
-                   (listp icomplete-with-completion-tables))
-              (set (make-local-variable 'icomplete-with-completion-tables)
-                   (cons rbts-completion-table
-                         icomplete-with-completion-tables))))
-      (read-buffer prompt (other-buffer (current-buffer))
-                   (confirm-nonexistent-file-or-buffer)))))
-
-(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
-  "Select the buffer specified by BUFFER-OR-NAME in another window.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil.  Return the buffer switched to.
-
-If called interactively, prompt for the buffer name using the
-minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name.  If BUFFER-OR-NAME is
-nil, switch to the buffer returned by `other-buffer'.
-
-Optional second argument NORECORD non-nil means do not put this
-buffer at the front of the list of recently selected ones.
-
-This uses the function `display-buffer' as a subroutine; see its
-documentation for additional customization information."
-  (interactive
-   (list (read-buffer-to-switch "Switch to buffer in other window: ")))
-  (let ((pop-up-windows t)
-       same-window-buffer-names same-window-regexps)
-    (pop-to-buffer buffer-or-name t norecord)))
-
-(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
-  "Switch to buffer BUFFER-OR-NAME in another frame.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil.  Return the buffer switched to.
-
-If called interactively, prompt for the buffer name using the
-minibuffer.  The variable `confirm-nonexistent-file-or-buffer'
-determines whether to request confirmation before creating a new
-buffer.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name.  If BUFFER-OR-NAME is
-nil, switch to the buffer returned by `other-buffer'.
-
-Optional second arg NORECORD non-nil means do not put this
-buffer at the front of the list of recently selected ones.
-
-This uses the function `display-buffer' as a subroutine; see its
-documentation for additional customization information."
-  (interactive
-   (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
-  (let ((pop-up-frames t)
-       same-window-buffer-names same-window-regexps)
-    (pop-to-buffer buffer-or-name t norecord)))
-
-(defun display-buffer-other-frame (buffer)
-  "Display buffer BUFFER in another frame.
-This uses the function `display-buffer' as a subroutine; see
-its documentation for additional customization information."
-  (interactive "BDisplay buffer in other frame: ")
-  (let ((pop-up-frames t)
-       same-window-buffer-names same-window-regexps
-        (old-window (selected-window))
-       new-window)
-    (setq new-window (display-buffer buffer t))
-    ;; This may have been here in order to prevent the new frame from hiding
-    ;; the old frame.  But it does more harm than good.
-    ;; Maybe we should call `raise-window' on the old-frame instead?  --Stef
-    ;;(lower-frame (window-frame new-window))
-
-    ;; This may have been here in order to make sure the old-frame gets the
-    ;; focus.  But not only can it cause an annoying flicker, with some
-    ;; window-managers it just makes the window invisible, with no easy
-    ;; way to recover it.  --Stef
-    ;;(make-frame-invisible (window-frame old-window))
-    ;;(make-frame-visible (window-frame old-window))
-    ))
-
 (defmacro minibuffer-with-setup-hook (fun &rest body)
   "Temporarily add FUN to `minibuffer-setup-hook' while executing BODY.
 BODY should use the minibuffer at most once.
@@ -1543,6 +1480,8 @@ expand wildcards (if any) and replace the file with multiple files."
       (other-window 1)
       (find-alternate-file filename wildcards))))
 
+(defvar kill-buffer-hook)  ; from buffer.c
+
 (defun find-alternate-file (filename &optional wildcards)
   "Find file FILENAME, select its buffer, kill previous buffer.
 If the current buffer now contains an empty file that you just visited
@@ -1700,11 +1639,6 @@ home directory is a root directory) and removes automounter prefixes
                        (substring filename (match-end 0)))))
       filename)))
 
-(defcustom find-file-not-true-dirname-list nil
-  "List of logical names for which visiting shouldn't save the true dirname."
-  :type '(repeat (string :tag "Name"))
-  :group 'find-file)
-
 (defun find-buffer-visiting (filename &optional predicate)
   "Return the buffer visiting file FILENAME (a string).
 This is like `get-file-buffer', except that it checks for any buffer
@@ -1893,8 +1827,8 @@ the various files."
                           (not nonexistent)
                           ;; It is confusing to ask whether to visit
                           ;; non-literally if they have the file in
-                          ;; hexl-mode.
-                          (not (eq major-mode 'hexl-mode)))
+                          ;; hexl-mode or image-mode.
+                          (not (memq major-mode '(hexl-mode image-mode))))
                  (if (buffer-modified-p)
                      (if (y-or-n-p
                           (format
@@ -2041,7 +1975,7 @@ This function ensures that none of these modifications will take place."
         (inhibit-file-name-operation 'insert-file-contents))
     (unwind-protect
          (progn
-           (fset 'find-buffer-file-type (lambda (filename) t))
+           (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)
@@ -2099,10 +2033,8 @@ the file contents into it using `insert-file-contents-literally'."
          (confirm-nonexistent-file-or-buffer))))
   (switch-to-buffer (find-file-noselect filename nil t)))
 \f
-(defvar after-find-file-from-revert-buffer nil)
-
 (defun after-find-file (&optional error warn noauto
-                                 after-find-file-from-revert-buffer
+                                 _after-find-file-from-revert-buffer
                                  nomodes)
   "Called after finding a file and by the default revert function.
 Sets buffer mode, parses local variables.
@@ -2110,8 +2042,8 @@ Optional args ERROR, WARN, and NOAUTO: ERROR non-nil means there was an
 error in reading the file.  WARN non-nil means warn if there
 exists an auto-save file more recent than the visited file.
 NOAUTO means don't mess with auto-save mode.
-Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil
- means this call was from `revert-buffer'.
+Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER is ignored
+\(see `revert-buffer-in-progress-p' for similar functionality).
 Fifth arg NOMODES non-nil means don't alter the file's modes.
 Finishes by calling the functions in `find-file-hook'
 unless NOMODES is non-nil."
@@ -2124,7 +2056,11 @@ unless NOMODES is non-nil."
             ((not warn) nil)
             ((and error (file-attributes buffer-file-name))
              (setq buffer-read-only t)
-             "File exists, but cannot be read")
+             (if (and (file-symlink-p buffer-file-name)
+                      (not (file-exists-p
+                            (file-chase-links buffer-file-name))))
+                 "Symbolic link that points to nonexistent file"
+               "File exists, but cannot be read"))
             ((not buffer-read-only)
              (if (and warn
                       ;; No need to warn if buffer is auto-saved
@@ -2152,7 +2088,7 @@ unless NOMODES is non-nil."
        (message "%s" msg)
        (or not-serious (sit-for 1 t))))
     (when (and auto-save-default (not noauto))
-      (auto-save-mode t)))
+      (auto-save-mode 1)))
   ;; Make people do a little extra work (C-x C-q)
   ;; before altering a backup file.
   (when (backup-file-name-p buffer-file-name)
@@ -2211,6 +2147,8 @@ in that case, this function acts as if `enable-local-variables' were t."
   (interactive)
   (funcall (or (default-value 'major-mode) 'fundamental-mode))
   (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:".
     (report-errors "File mode specification error: %s"
       (set-auto-mode))
     (report-errors "File local-variables error: %s"
@@ -2330,7 +2268,12 @@ since only a single case-insensitive search through the alist is made."
      ("\\.icn\\'" . icon-mode)
      ("\\.sim\\'" . simula-mode)
      ("\\.mss\\'" . scribe-mode)
+     ;; The Fortran standard does not say anything about file extensions.
+     ;; .f90 was widely used for F90, now we seem to be trapped into
+     ;; using a different extension for each language revision.
+     ;; Anyway, the following extensions are supported by gfortran.
      ("\\.f9[05]\\'" . f90-mode)
+     ("\\.f0[38]\\'" . f90-mode)
      ("\\.indent\\.pro\\'" . fundamental-mode) ; to avoid idlwave-mode
      ("\\.\\(pro\\|PRO\\)\\'" . idlwave-mode)
      ("\\.srt\\'" . srecode-template-mode)
@@ -2356,6 +2299,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
      ("\\.dtd\\'" . sgml-mode)
      ("\\.ds\\(ss\\)?l\\'" . dsssl-mode)
      ("\\.js\\'" . js-mode)            ; javascript-mode would be better
+     ("\\.json\\'" . js-mode)
      ("\\.[ds]?vh?\\'" . verilog-mode)
      ;; .emacs or .gnus or .viper following a directory delimiter in
      ;; Unix, MSDOG or VMS syntax.
@@ -2394,6 +2338,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
      ("\\.ebrowse\\'" . ebrowse-tree-mode)
      ("#\\*mail\\*" . mail-mode)
      ("\\.g\\'" . antlr-mode)
+     ("\\.mod\\'" . m2-mode)
      ("\\.ses\\'" . ses-mode)
      ("\\.docbook\\'" . sgml-mode)
      ("\\.com\\'" . dcl-mode)
@@ -2404,8 +2349,6 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
      ("\\.ppd\\'" . conf-ppd-mode)
      ("java.+\\.conf\\'" . conf-javaprop-mode)
      ("\\.properties\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-javaprop-mode)
-     ;; *.cf, *.cfg, *.conf, *.config[.local|.de_DE.UTF8|...], */config
-     ("[/.]c\\(?:on\\)?f\\(?:i?g\\)?\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-mode-maybe)
      ("\\`/etc/\\(?:DIR_COLORS\\|ethers\\|.?fstab\\|.*hosts\\|lesskey\\|login\\.?de\\(?:fs\\|vperm\\)\\|magic\\|mtab\\|pam\\.d/.*\\|permissions\\(?:\\.d/.+\\)?\\|protocols\\|rpc\\|services\\)\\'" . conf-space-mode)
      ("\\`/etc/\\(?:acpid?/.+\\|aliases\\(?:\\.d/.+\\)?\\|default/.+\\|group-?\\|hosts\\..+\\|inittab\\|ksysguarddrc\\|opera6rc\\|passwd-?\\|shadow-?\\|sysconfig/.+\\)\\'" . conf-mode)
      ;; ChangeLog.old etc.  Other change-log-mode entries are above;
@@ -2427,11 +2370,14 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
      ;; Using mode nil rather than `ignore' would let the search continue
      ;; through this list (with the shortened name) rather than start over.
      ("\\.~?[0-9]+\\.[0-9][-.0-9]*~?\\'" nil t)
+     ("\\.\\(?:orig\\|in\\|[bB][aA][kK]\\)\\'" nil t)
+     ;; This should come after "in" stripping (e.g. config.h.in).
+     ;; *.cf, *.cfg, *.conf, *.config[.local|.de_DE.UTF8|...], */config
+     ("[/.]c\\(?:on\\)?f\\(?:i?g\\)?\\(?:\\.[a-zA-Z0-9._-]+\\)?\\'" . conf-mode-maybe)
      ;; The following should come after the ChangeLog pattern
      ;; for the sake of ChangeLog.1, etc.
      ;; and after the .scm.[0-9] and CVS' <file>.<rev> patterns too.
-     ("\\.[1-9]\\'" . nroff-mode)
-     ("\\.\\(?:orig\\|in\\|[bB][aA][kK]\\)\\'" nil t)))
+     ("\\.[1-9]\\'" . nroff-mode)))
   "Alist of filename patterns vs corresponding major mode functions.
 Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
 \(NON-NIL stands for anything that is not nil; the value does not matter.)
@@ -2490,6 +2436,7 @@ and `magic-mode-alist', which determines modes based on file contents.")
      ("ksh" . sh-mode)
      ("oash" . sh-mode)
      ("pdksh" . sh-mode)
+     ("rbash" . sh-mode)
      ("rc" . sh-mode)
      ("rpm" . sh-mode)
      ("sh" . sh-mode)
@@ -2514,7 +2461,9 @@ of a script, mode MODE is enabled.
 
 See also `auto-mode-alist'.")
 
-(defvar inhibit-first-line-modes-regexps (mapcar 'purecopy '("\\.tar\\'" "\\.tgz\\'"))
+(defvar inhibit-first-line-modes-regexps
+  (mapcar 'purecopy '("\\.tar\\'" "\\.tgz\\'" "\\.tiff?\\'"
+                     "\\.gif\\'" "\\.png\\'" "\\.jpe?g\\'"))
   "List of regexps; if one matches a file name, don't look for `-*-'.")
 
 (defvar inhibit-first-line-modes-suffixes nil
@@ -2585,23 +2534,24 @@ Also applies to `magic-fallback-mode-alist'.")
   "Select major mode appropriate for current buffer.
 
 To find the right major mode, this function checks for a -*- mode tag,
+checks for a `mode:' entry in the Local Variables section of the file,
 checks if it uses an interpreter listed in `interpreter-mode-alist',
 matches the buffer beginning against `magic-mode-alist',
 compares the filename against the entries in `auto-mode-alist',
 then matches the buffer beginning against `magic-fallback-mode-alist'.
 
-It does not check for the `mode:' local variable in the
-Local Variables section of the file; for that, use `hack-local-variables'.
-
-If `enable-local-variables' is nil, this function does not check for a
--*- mode tag.
+If `enable-local-variables' is nil, this function does not check for
+any mode: tag anywhere in the file.
 
 If the optional argument KEEP-MODE-IF-SAME is non-nil, then we
 set the major mode only if that would change it.  In other words
 we don't actually set it to the same mode the buffer already has."
   ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
   (let (end done mode modes)
-    ;; Find a -*- mode tag
+    ;; Once we drop the deprecated feature where mode: is also allowed to
+    ;; specify minor-modes (ie, there can be more than one "mode:"), we can
+    ;; remove this section and just let (hack-local-variables t) handle it.
+    ;; Find a -*- mode tag.
     (save-excursion
       (goto-char (point-min))
       (skip-chars-forward " \t\n")
@@ -2636,6 +2586,14 @@ we don't actually set it to the same mode the buffer already has."
              (or (set-auto-mode-0 mode keep-mode-if-same)
                  ;; continuing would call minor modes again, toggling them off
                  (throw 'nop nil))))))
+    (and (not done)
+        enable-local-variables
+        (setq mode (hack-local-variables t))
+        (not (memq mode modes))        ; already tried and failed
+        (if (not (functionp mode))
+            (message "Ignoring unknown mode `%s'" mode)
+          (setq done t)
+          (set-auto-mode-0 mode keep-mode-if-same)))
     ;; If we didn't, look for an interpreter specified in the first line.
     ;; As a special case, allow for things like "#!/bin/env perl", which
     ;; finds the interpreter anywhere in $PATH.
@@ -2645,7 +2603,7 @@ we don't actually set it to the same mode the buffer already has."
                   (if (looking-at auto-mode-interpreter-regexp)
                       (match-string 2)
                     ""))
-           ;; Map interpreter name to a mode, signalling we're done at the
+           ;; Map interpreter name to a mode, signaling we're done at the
            ;; same time.
            done (assoc (file-name-nondirectory mode)
                        interpreter-mode-alist))
@@ -2661,7 +2619,7 @@ we don't actually set it to the same mode the buffer already has."
                                           (min (point-max)
                                                (+ (point-min) magic-mode-regexp-match-limit)))
                         (assoc-default nil magic-mode-alist
-                                       (lambda (re dummy)
+                                       (lambda (re _dummy)
                                          (if (functionp re)
                                              (funcall re)
                                            (looking-at re)))))))
@@ -2671,12 +2629,12 @@ we don't actually set it to the same mode the buffer already has."
       (if buffer-file-name
          (let ((name buffer-file-name)
                (remote-id (file-remote-p buffer-file-name)))
+           ;; Remove backup-suffixes from file name.
+           (setq name (file-name-sans-versions name))
            ;; Remove remote file name identification.
            (when (and (stringp remote-id)
                       (string-match (regexp-quote remote-id) name))
              (setq name (substring name (match-end 0))))
-           ;; Remove backup-suffixes from file name.
-           (setq name (file-name-sans-versions name))
            (while name
              ;; Find first matching alist entry.
              (setq mode
@@ -2714,7 +2672,7 @@ we don't actually set it to the same mode the buffer already has."
                                           (min (point-max)
                                                (+ (point-min) magic-mode-regexp-match-limit)))
                         (assoc-default nil magic-fallback-mode-alist
-                                       (lambda (re dummy)
+                                       (lambda (re _dummy)
                                          (if (functionp re)
                                              (funcall re)
                                            (looking-at re)))))))
@@ -2868,18 +2826,19 @@ asking you for confirmation."
 ;;
 ;; For variables defined in the C source code the declaration should go here:
 
-(mapc (lambda (pair)
-       (put (car pair) 'safe-local-variable (cdr pair)))
-      '((buffer-read-only        . booleanp)   ;; C source code
-       (default-directory       . stringp)    ;; C source code
-       (fill-column             . integerp)   ;; C source code
-       (indent-tabs-mode        . booleanp)   ;; C source code
-       (left-margin             . integerp)   ;; C source code
-       (no-update-autoloads     . booleanp)
-       (tab-width               . integerp)   ;; C source code
-       (truncate-lines          . booleanp)   ;; C source code
-       (word-wrap               . booleanp) ;; C source code
-       (bidi-display-reordering . booleanp))) ;; C source code
+(dolist (pair
+        '((buffer-read-only        . booleanp) ;; C source code
+          (default-directory       . stringp)  ;; C source code
+          (fill-column             . integerp) ;; C source code
+          (indent-tabs-mode        . booleanp) ;; C source code
+          (left-margin             . integerp) ;; C source code
+          (no-update-autoloads     . booleanp)
+          (lexical-binding      . booleanp)      ;; C source code
+          (tab-width               . integerp)   ;; C source code
+          (truncate-lines          . booleanp)   ;; C source code
+          (word-wrap               . booleanp)   ;; C source code
+          (bidi-display-reordering . booleanp))) ;; C source code
+  (put (car pair) 'safe-local-variable (cdr pair)))
 
 (put 'bidi-paragraph-direction 'safe-local-variable
      (lambda (v) (memq v '(nil right-to-left left-to-right))))
@@ -2986,74 +2945,71 @@ n  -- to ignore the local variables list.")
            (setq char nil)))
        (kill-buffer buf)
        (when (and offer-save (= char ?!) unsafe-vars)
-         (dolist (elt unsafe-vars)
-           (add-to-list 'safe-local-variable-values elt))
-         ;; When this is called from desktop-restore-file-buffer,
-         ;; coding-system-for-read may be non-nil.  Reset it before
-         ;; writing to .emacs.
-         (if (or custom-file user-init-file)
-             (let ((coding-system-for-read nil))
-               (customize-save-variable
-                'safe-local-variable-values
-                safe-local-variable-values))))
+         (customize-push-and-save 'safe-local-variable-values unsafe-vars))
        (memq char '(?! ?\s ?y))))))
 
 (defun hack-local-variables-prop-line (&optional mode-only)
   "Return local variables specified in the -*- line.
-Ignore any specification for `mode:' and `coding:';
-`set-auto-mode' should already have handled `mode:',
-`set-auto-coding' should already have handled `coding:'.
-
-If MODE-ONLY is non-nil, all we do is check whether the major
-mode is specified, returning t if it is specified.  Otherwise,
-return an alist of elements (VAR . VAL), where VAR is a variable
-and VAL is the specified value."
-  (save-excursion
-    (goto-char (point-min))
-    (let ((end (set-auto-mode-1))
-         result mode-specified)
-      ;; Parse the -*- line into the RESULT alist.
-      ;; Also set MODE-SPECIFIED if we see a spec or `mode'.
-      (cond ((not end)
-            nil)
-           ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)")
-            ;; Simple form: "-*- MODENAME -*-".  Already handled.
-            (setq mode-specified t)
-            nil)
-           (t
-            ;; Hairy form: '-*-' [ <variable> ':' <value> ';' ]* '-*-'
-            ;; (last ";" is optional).
-            (while (< (point) end)
-              (or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*")
-                  (error "Malformed -*- line"))
-              (goto-char (match-end 0))
-              ;; There used to be a downcase here,
-              ;; but the manual didn't say so,
-              ;; and people want to set var names that aren't all lc.
-              (let ((key (intern (match-string 1)))
-                    (val (save-restriction
-                           (narrow-to-region (point) end)
-                           (let ((read-circle nil))
-                             (read (current-buffer))))))
-                ;; It is traditional to ignore
-                ;; 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 (and (equal (downcase (symbol-name key)) "mode")
-                         (setq mode-specified t))
-                    (equal (downcase (symbol-name key)) "coding")
-                    (condition-case nil
-                        (push (cons (if (eq key 'eval)
-                                        'eval
-                                      (indirect-variable key))
-                                    val) result)
-                      (error nil)))
-                (skip-chars-forward " \t;")))))
-
-      (if mode-only
-         mode-specified
-       result))))
+Returns an alist of elements (VAR . VAL), where VAR is a variable
+and VAL is the specified value.  Ignores any specification for
+`mode:' and `coding:' (which should have already been handled
+by `set-auto-mode' and `set-auto-coding', respectively).
+Return nil if the -*- line is malformed.
+
+If MODE-ONLY is non-nil, just returns the symbol specifying the
+mode, if there is one, otherwise nil."
+  (catch 'malformed-line
+    (save-excursion
+      (goto-char (point-min))
+      (let ((end (set-auto-mode-1))
+           result)
+       (cond ((not end)
+              nil)
+             ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)")
+              ;; Simple form: "-*- MODENAME -*-".
+              (if mode-only
+                  (intern (concat (match-string 1) "-mode"))))
+             (t
+              ;; Hairy form: '-*-' [ <variable> ':' <value> ';' ]* '-*-'
+              ;; (last ";" is optional).
+              ;; If MODE-ONLY, just check for `mode'.
+              ;; Otherwise, parse the -*- line into the RESULT alist.
+              (while (and (or (not mode-only)
+                              (not result))
+                          (< (point) end))
+                (unless (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*")
+                  (message "Malformed mode-line")
+                  (throw 'malformed-line nil))
+                (goto-char (match-end 0))
+                ;; There used to be a downcase here,
+                ;; but the manual didn't say so,
+                ;; and people want to set var names that aren't all lc.
+                (let* ((key (intern (match-string 1)))
+                       (val (save-restriction
+                              (narrow-to-region (point) end)
+                              (let ((read-circle nil))
+                                (read (current-buffer)))))
+                       ;; It is traditional to ignore
+                       ;; 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.
+                       (keyname (downcase (symbol-name key))))
+                  (if mode-only
+                      (and (equal keyname "mode")
+                           (setq result
+                                 (intern (concat (downcase (symbol-name val))
+                                                 "-mode"))))
+                    (or (equal keyname "coding")
+                        (condition-case nil
+                            (push (cons (cond ((eq key 'eval) 'eval)
+                                              ;; Downcase "Mode:".
+                                              ((equal keyname "mode") 'mode)
+                                              (t (indirect-variable key)))
+                                        val) result)
+                          (error nil))))
+                  (skip-chars-forward " \t;")))
+              result))))))
 
 (defun hack-local-variables-filter (variables dir-name)
   "Filter local variable settings, querying the user if necessary.
@@ -3112,8 +3068,12 @@ DIR-NAME is the name of the associated directory.  Otherwise it is nil."
 
 (defun hack-local-variables (&optional mode-only)
   "Parse and put into effect this buffer's local variables spec.
-If MODE-ONLY is non-nil, all we do is check whether the major mode
-is specified, returning t if it is specified."
+Uses `hack-local-variables-apply' to apply the variables.
+
+If MODE-ONLY is non-nil, 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."
   (let ((enable-local-variables
         (and local-enable-local-variables enable-local-variables))
        result)
@@ -3122,88 +3082,100 @@ is specified, returning t if it is specified."
       (report-errors "Directory-local variables error: %s"
        (hack-dir-local-variables)))
     (when (or mode-only enable-local-variables)
-      (setq result (hack-local-variables-prop-line mode-only))
-      ;; Look for "Local variables:" line in last page.
-      (save-excursion
-       (goto-char (point-max))
-       (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
-                        'move)
-       (when (let ((case-fold-search t))
-               (search-forward "Local Variables:" nil t))
-         (skip-chars-forward " \t")
-         ;; suffix is what comes after "local variables:" in its line.
-         ;; prefix is what comes before "local variables:" in its line.
-         (let ((suffix
-                (concat
-                 (regexp-quote (buffer-substring (point)
-                                                 (line-end-position)))
-                 "$"))
-               (prefix
-                (concat "^" (regexp-quote
-                             (buffer-substring (line-beginning-position)
-                                               (match-beginning 0)))))
-               beg)
-
-           (forward-line 1)
-           (let ((startpos (point))
-                 endpos
-                 (thisbuf (current-buffer)))
-             (save-excursion
-               (unless (let ((case-fold-search t))
-                         (re-search-forward
-                          (concat prefix "[ \t]*End:[ \t]*" suffix)
-                          nil t))
-                  ;; This used to be an error, but really all it means is
-                  ;; that this may simply not be a local-variables section,
-                  ;; so just ignore it.
-                 (message "Local variables list is not properly terminated"))
-               (beginning-of-line)
-               (setq endpos (point)))
-
-             (with-temp-buffer
-               (insert-buffer-substring thisbuf startpos endpos)
-               (goto-char (point-min))
-               (subst-char-in-region (point) (point-max) ?\^m ?\n)
-               (while (not (eobp))
-                 ;; Discard the prefix.
-                 (if (looking-at prefix)
-                     (delete-region (point) (match-end 0))
-                   (error "Local variables entry is missing the prefix"))
-                 (end-of-line)
-                 ;; Discard the suffix.
-                 (if (looking-back suffix)
-                     (delete-region (match-beginning 0) (point))
-                   (error "Local variables entry is missing the suffix"))
-                 (forward-line 1))
-               (goto-char (point-min))
-
-               (while (not (eobp))
-                 ;; Find the variable name; strip whitespace.
-                 (skip-chars-forward " \t")
-                 (setq beg (point))
-                 (skip-chars-forward "^:\n")
-                 (if (eolp) (error "Missing colon in local variables entry"))
-                 (skip-chars-backward " \t")
-                 (let* ((str (buffer-substring beg (point)))
-                        (var (let ((read-circle nil))
-                               (read str)))
-                        val)
-                   ;; Read the variable value.
-                   (skip-chars-forward "^:")
-                   (forward-char 1)
-                   (let ((read-circle nil))
-                     (setq val (read (current-buffer))))
-                   (if mode-only
-                       (if (eq var 'mode)
-                           (setq result t))
-                     (unless (eq var 'coding)
-                       (condition-case nil
-                           (push (cons (if (eq var 'eval)
-                                           'eval
-                                         (indirect-variable var))
-                                       val) result)
-                         (error nil)))))
-                 (forward-line 1))))))))
+      ;; If MODE-ONLY is non-nil, and the prop line specifies a mode,
+      ;; then we're done, and have no need to scan further.
+      (unless (and (setq result (hack-local-variables-prop-line mode-only))
+                  mode-only)
+       ;; Look for "Local variables:" line in last page.
+       (save-excursion
+         (goto-char (point-max))
+         (search-backward "\n\^L" (max (- (point-max) 3000) (point-min))
+                          'move)
+         (when (let ((case-fold-search t))
+                 (search-forward "Local Variables:" nil t))
+           (skip-chars-forward " \t")
+           ;; suffix is what comes after "local variables:" in its line.
+           ;; prefix is what comes before "local variables:" in its line.
+           (let ((suffix
+                  (concat
+                   (regexp-quote (buffer-substring (point)
+                                                   (line-end-position)))
+                   "$"))
+                 (prefix
+                  (concat "^" (regexp-quote
+                               (buffer-substring (line-beginning-position)
+                                                 (match-beginning 0)))))
+                 beg)
+
+             (forward-line 1)
+             (let ((startpos (point))
+                   endpos
+                   (thisbuf (current-buffer)))
+               (save-excursion
+                 (unless (let ((case-fold-search t))
+                           (re-search-forward
+                            (concat prefix "[ \t]*End:[ \t]*" suffix)
+                            nil t))
+                   ;; This used to be an error, but really all it means is
+                   ;; that this may simply not be a local-variables section,
+                   ;; so just ignore it.
+                   (message "Local variables list is not properly terminated"))
+                 (beginning-of-line)
+                 (setq endpos (point)))
+
+               (with-temp-buffer
+                 (insert-buffer-substring thisbuf startpos endpos)
+                 (goto-char (point-min))
+                 (subst-char-in-region (point) (point-max) ?\^m ?\n)
+                 (while (not (eobp))
+                   ;; Discard the prefix.
+                   (if (looking-at prefix)
+                       (delete-region (point) (match-end 0))
+                     (error "Local variables entry is missing the prefix"))
+                   (end-of-line)
+                   ;; Discard the suffix.
+                   (if (looking-back suffix)
+                       (delete-region (match-beginning 0) (point))
+                     (error "Local variables entry is missing the suffix"))
+                   (forward-line 1))
+                 (goto-char (point-min))
+
+                 (while (and (not (eobp))
+                             (or (not mode-only)
+                                 (not result)))
+                   ;; Find the variable name; strip whitespace.
+                   (skip-chars-forward " \t")
+                   (setq beg (point))
+                   (skip-chars-forward "^:\n")
+                   (if (eolp) (error "Missing colon in local variables entry"))
+                   (skip-chars-backward " \t")
+                   (let* ((str (buffer-substring beg (point)))
+                          (var (let ((read-circle nil))
+                                 (read str)))
+                          val val2)
+                     (and (equal (downcase (symbol-name var)) "mode")
+                          (setq var 'mode))
+                     ;; Read the variable value.
+                     (skip-chars-forward "^:")
+                     (forward-char 1)
+                     (let ((read-circle nil))
+                       (setq val (read (current-buffer))))
+                     (if mode-only
+                         (and (eq var 'mode)
+                              ;; Specifying minor-modes via mode: is
+                              ;; deprecated, but try to reject them anyway.
+                              (not (string-match
+                                    "-minor\\'"
+                                    (setq val2 (downcase (symbol-name val)))))
+                              (setq result (intern (concat val2 "-mode"))))
+                       (unless (eq var 'coding)
+                         (condition-case nil
+                             (push (cons (if (eq var 'eval)
+                                             'eval
+                                           (indirect-variable var))
+                                         val) result)
+                           (error nil)))))
+                   (forward-line 1)))))))))
     ;; Now we've read all the local variables.
     ;; If MODE-ONLY is non-nil, return whether the mode was specified.
     (cond (mode-only result)
@@ -3213,6 +3185,14 @@ is specified, returning t if it is specified."
           (hack-local-variables-apply)))))
 
 (defun hack-local-variables-apply ()
+  "Apply the elements of `file-local-variables-alist'.
+If there are any elements, runs `before-hack-local-variables-hook',
+then calls `hack-one-local-variable' to apply the alist elements one by one.
+Finishes by running `hack-local-variables-hook', regardless of whether
+the alist is empty or not.
+
+Note that this function ignores a `mode' entry if it specifies the same
+major mode as the buffer already has."
   (when file-local-variables-alist
     ;; Any 'evals must run in the Right sequence.
     (setq file-local-variables-alist
@@ -3238,7 +3218,7 @@ It is safe if any of these conditions are met:
              ;; can't assure us that the value is safe.
              (with-demoted-errors (funcall safep val))))))
 
-(defun risky-local-variable-p (sym &optional ignored)
+(defun risky-local-variable-p (sym &optional _ignored)
   "Non-nil if SYM could be dangerous as a file-local variable.
 It is dangerous if either of these conditions are met:
 
@@ -3295,21 +3275,25 @@ It is dangerous if either of these conditions are met:
       ;; Certain functions can be allowed with safe arguments
       ;; or can specify verification functions to try.
       (and (symbolp (car exp))
-          (let ((prop (get (car exp) 'safe-local-eval-function)))
-            (cond ((eq prop t)
-                   (let ((ok t))
-                     (dolist (arg (cdr exp))
-                       (unless (hack-one-local-variable-constantp arg)
-                         (setq ok nil)))
-                     ok))
-                  ((functionp prop)
-                   (funcall prop exp))
-                  ((listp prop)
-                   (let ((ok nil))
-                     (dolist (function prop)
-                       (if (funcall function exp)
-                           (setq ok t)))
-                     ok)))))))
+          ;; Allow (minor)-modes calls with no arguments.
+          ;; This obsoletes the use of "mode:" for such things.  (Bug#8613)
+          (or (and (member (cdr exp) '(nil (1) (-1)))
+                   (string-match "-mode\\'" (symbol-name (car exp))))
+              (let ((prop (get (car exp) 'safe-local-eval-function)))
+                (cond ((eq prop t)
+                       (let ((ok t))
+                         (dolist (arg (cdr exp))
+                           (unless (hack-one-local-variable-constantp arg)
+                             (setq ok nil)))
+                         ok))
+                      ((functionp prop)
+                       (funcall prop exp))
+                      ((listp prop)
+                       (let ((ok nil))
+                         (dolist (function prop)
+                           (if (funcall function exp)
+                               (setq ok t)))
+                         ok))))))))
 
 (defun hack-one-local-variable (var val)
   "Set local variable VAR with value VAL.
@@ -3698,7 +3682,11 @@ the old visited file has been renamed to the new name FILENAME."
          (get major-mode 'mode-class)
          ;; Don't change the mode if the local variable list specifies it.
          (hack-local-variables t)
-         (set-auto-mode t))
+         ;; TODO consider making normal-mode handle this case.
+         (let ((old major-mode))
+           (set-auto-mode t)
+           (or (eq old major-mode)
+               (hack-local-variables))))
     (error nil)))
 
 (defun write-file (filename &optional confirm)
@@ -3868,7 +3856,9 @@ BACKUPNAME is the backup file name, which is the old file renamed."
        (set-file-selinux-context to-name context)))
 
 (defvar file-name-version-regexp
-  "\\(?:~\\|\\.~[-[:alnum:]:#@^._]+~\\)"
+  "\\(?:~\\|\\.~[-[:alnum:]:#@^._]+\\(?:~[[:digit:]]+\\)?~\\)"
+  ;; The last ~[[:digit]]+ matches relative versions in git,
+  ;; e.g. `foo.js.~HEAD~1~'.
   "Regular expression matching the backup/version part of a file name.
 Used by `file-name-sans-versions'.")
 
@@ -3892,11 +3882,17 @@ See also `file-name-version-regexp'."
   (let ((handler (find-file-name-handler file 'file-ownership-preserved-p)))
     (if handler
        (funcall handler 'file-ownership-preserved-p file)
-      (let ((attributes (file-attributes file)))
+      (let ((attributes (file-attributes file 'integer)))
        ;; Return t if the file doesn't exist, since it's true that no
        ;; information would be lost by an (attempted) delete and create.
        (or (null attributes)
-           (= (nth 2 attributes) (user-uid)))))))
+           (= (nth 2 attributes) (user-uid))
+           ;; Files created on Windows by Administrator (RID=500)
+           ;; have the Administrators group (RID=544) recorded as
+           ;; their owner.  Rewriting them will still preserve the
+           ;; owner.
+           (and (eq system-type 'windows-nt)
+                (= (user-uid) 500) (= (nth 2 attributes) 544)))))))
 
 (defun file-name-sans-extension (filename)
   "Return FILENAME sans final \"extension\".
@@ -4473,6 +4469,7 @@ Before and after saving the buffer, this function runs
            (dir-writable (file-writable-p dir)))
       (if (or (and file-precious-flag dir-writable)
               (and break-hardlink-on-save
+                   (file-exists-p buffer-file-name)
                    (> (file-nlinks buffer-file-name) 1)
                    (or dir-writable
                        (error (concat (format
@@ -4597,6 +4594,9 @@ You can answer `y' to save, `n' not to save, `C-r' to look at the
 buffer in question with `view-buffer' before deciding or `d' to
 view the differences using `diff-buffer-with-file'.
 
+This command first saves any buffers where `buffer-save-without-query' is
+non-nil, without asking.
+
 Optional argument (the prefix) non-nil means save all with no questions.
 Optional second argument PRED determines which buffers are considered:
 If PRED is nil, all the file-visiting buffers are considered.
@@ -4608,14 +4608,14 @@ See `save-some-buffers-action-alist' if you want to
 change the additional actions you can take on files."
   (interactive "P")
   (save-window-excursion
-    (let* (queried some-automatic
+    (let* (queried autosaved-buffers
           files-done abbrevs-done)
       (dolist (buffer (buffer-list))
        ;; First save any buffers that we're supposed to save unconditionally.
        ;; That way the following code won't ask about them.
        (with-current-buffer buffer
          (when (and buffer-save-without-query (buffer-modified-p))
-           (setq some-automatic t)
+           (push (buffer-name) autosaved-buffers)
            (save-buffer))))
       ;; Ask about those buffers that merit it,
       ;; and record the number thus saved.
@@ -4661,9 +4661,15 @@ change the additional actions you can take on files."
             (setq abbrevs-changed nil)
             (setq abbrevs-done t)))
       (or queried (> files-done 0) abbrevs-done
-         (message (if some-automatic
-                      "(Some special files were saved without asking)"
-                    "(No files need saving)"))))))
+         (cond
+          ((null autosaved-buffers)
+           (message "(No files need saving)"))
+          ((= (length autosaved-buffers) 1)
+           (message "(Saved %s)" (car autosaved-buffers)))
+          (t
+           (message "(Saved %d files: %s)"
+                    (length autosaved-buffers)
+                    (mapconcat 'identity autosaved-buffers ", "))))))))
 \f
 (defun not-modified (&optional arg)
   "Mark current buffer as unmodified, not needing to be saved.
@@ -4680,7 +4686,15 @@ prints a message in the minibuffer.  Instead, use `set-buffer-modified-p'."
   "Change whether this buffer is read-only.
 With prefix argument ARG, make the buffer read-only if ARG is
 positive, otherwise make it writable.  If buffer is read-only
-and `view-read-only' is non-nil, enter view mode."
+and `view-read-only' is non-nil, enter view mode.
+
+This function is usually the wrong thing to use in a Lisp program.
+It can have side-effects beyond changing the read-only status of a buffer
+\(e.g., enabling view mode), and does not affect read-only regions that
+are caused by text properties.  To make a buffer read-only in Lisp code,
+set `buffer-read-only'.  To ignore read-only status (whether due to text
+properties or buffer state) and make changes, temporarily bind
+`inhibit-read-only'."
   (interactive "P")
   (if (and arg
            (if (> (prefix-numeric-value arg) 0) buffer-read-only
@@ -4698,11 +4712,7 @@ and `view-read-only' is non-nil, enter view mode."
            (not (eq (get major-mode 'mode-class) 'special)))
       (view-mode-enter))
      (t (setq buffer-read-only (not buffer-read-only))
-        (force-mode-line-update)))
-    (if (vc-backend buffer-file-name)
-        (message "%s" (substitute-command-keys
-                  (concat "File is under version-control; "
-                          "use \\[vc-next-action] to check in/out"))))))
+        (force-mode-line-update)))))
 
 (defun insert-file (filename)
   "Insert contents of file FILENAME into buffer after point.
@@ -4779,7 +4789,10 @@ visited a file in a nonexistent directory.
 
 Noninteractively, the second (optional) argument PARENTS, if
 non-nil, says whether to create parent directories that don't
-exist.  Interactively, this happens by default."
+exist.  Interactively, this happens by default.
+
+If creating the directory or directories fail, an error will be
+raised."
   (interactive
    (list (read-file-name "Make directory: " default-directory default-directory
                         nil nil)
@@ -4822,7 +4835,7 @@ given.  With a prefix argument, TRASH is nil."
    (let* ((trashing (and delete-by-moving-to-trash
                         (null current-prefix-arg)))
          (dir (expand-file-name
-               (read-file-name
+               (read-directory-name
                 (if trashing
                     "Move directory to trash: "
                   "Delete directory: ")
@@ -4853,7 +4866,7 @@ given.  With a prefix argument, TRASH is nil."
                directory 'full directory-files-no-dot-files-regexp))
          (error "Directory is not empty, not moving to trash")
        (move-file-to-trash directory)))
-     ;; Otherwise, call outselves recursively if needed.
+     ;; Otherwise, call ourselves recursively if needed.
      (t
       (if (and recursive (not (file-symlink-p directory)))
          (mapc (lambda (file)
@@ -4890,7 +4903,7 @@ directly into NEWNAME instead."
    (let ((dir (read-directory-name
               "Copy directory: " default-directory default-directory t nil)))
      (list dir
-          (read-file-name
+          (read-directory-name
            (format "Copy directory %s to: " dir)
            default-directory default-directory nil nil)
           current-prefix-arg t nil)))
@@ -4936,9 +4949,10 @@ directly into NEWNAME instead."
              (copy-file file target t keep-time)))))
 
       ;; Set directory attributes.
-      (set-file-modes newname (file-modes directory))
-      (if keep-time
-         (set-file-times newname (nth 5 (file-attributes directory)))))))
+      (let ((modes (file-modes directory))
+           (times (and keep-time (nth 5 (file-attributes directory)))))
+       (if modes (set-file-modes newname modes))
+       (if times (set-file-times newname times))))))
 \f
 (put 'revert-buffer-function 'permanent-local t)
 (defvar revert-buffer-function nil
@@ -4985,6 +4999,10 @@ hook functions.
 If `revert-buffer-function' is used to override the normal revert
 mechanism, this hook is not used.")
 
+(defvar revert-buffer-in-progress-p nil
+  "Non-nil if a `revert-buffer' operation is in progress, nil otherwise.
+This is true even if a `revert-buffer-function' is being used.")
+
 (defvar revert-buffer-internal-hook)
 
 (defun revert-buffer (&optional ignore-auto noconfirm preserve-modes)
@@ -5007,7 +5025,7 @@ sake of backward compatibility.  IGNORE-AUTO is optional, defaulting
 to nil.
 
 Optional second argument NOCONFIRM means don't ask for confirmation
-at all.  \(The variable `revert-without-query' offers another way to
+at all.  (The variable `revert-without-query' offers another way to
 revert buffers without querying for confirmation.)
 
 Optional third argument PRESERVE-MODES non-nil means don't alter
@@ -5027,10 +5045,12 @@ non-nil, it is called instead of rereading visited file contents."
   ;; interface, but leaving the programmatic interface the same.
   (interactive (list (not current-prefix-arg)))
   (if revert-buffer-function
-      (funcall revert-buffer-function ignore-auto noconfirm)
+      (let ((revert-buffer-in-progress-p t))
+        (funcall revert-buffer-function ignore-auto noconfirm))
     (with-current-buffer (or (buffer-base-buffer (current-buffer))
                             (current-buffer))
-      (let* ((auto-save-p (and (not ignore-auto)
+      (let* ((revert-buffer-in-progress-p t)
+             (auto-save-p (and (not ignore-auto)
                               (recent-auto-save-p)
                               buffer-auto-save-file-name
                               (file-readable-p buffer-auto-save-file-name)
@@ -5121,7 +5141,7 @@ non-nil, it is called instead of rereading visited file contents."
                 ;; have changed the truename.
                 (setq buffer-file-truename
                       (abbreviate-file-name (file-truename buffer-file-name)))
-                (after-find-file nil nil t t preserve-modes)
+                (after-find-file nil nil t nil preserve-modes)
                 ;; Run after-revert-hook as it was before we reverted.
                 (setq-default revert-buffer-internal-hook global-hook)
                 (if local-hook
@@ -5158,7 +5178,7 @@ non-nil, it is called instead of rereading visited file contents."
               (save-excursion
                 (let ((switches dired-listing-switches))
                   (if (file-symlink-p file)
-                      (setq switches (concat switches "L")))
+                      (setq switches (concat switches " -L")))
                   (set-buffer standard-output)
                   ;; Use insert-directory-safely, not insert-directory,
                   ;; because these files might not exist.  In particular,
@@ -5201,7 +5221,7 @@ Then you'll be asked about a number of files to recover."
       (error "No previous sessions to recover")))
   (let ((ls-lisp-support-shell-wildcards t))
     (dired (concat auto-save-list-file-prefix "*")
-          (concat dired-listing-switches "t")))
+          (concat dired-listing-switches " -t")))
   (save-excursion
     (goto-char (point-min))
     (or (looking-at " Move to the session you want to recover,")
@@ -5559,7 +5579,8 @@ default directory.  However, if FULL is non-nil, they are absolute."
           contents)
       (while dirs
        (when (or (null (car dirs))     ; Possible if DIRPART is not wild.
-                 (file-directory-p (directory-file-name (car dirs))))
+                 (and (file-directory-p (directory-file-name (car dirs)))
+                      (file-readable-p (car dirs))))
          (let ((this-dir-contents
                 ;; Filter out "." and ".."
                 (delq nil
@@ -5589,7 +5610,7 @@ Prefix arg (second arg if noninteractive) means supply -l switch to `ls'.
 Actions controlled by variables `list-directory-brief-switches'
 and `list-directory-verbose-switches'."
   (interactive (let ((pfx current-prefix-arg))
-                (list (read-file-name (if pfx "List directory (verbose): "
+                (list (read-directory-name (if pfx "List directory (verbose): "
                                         "List directory (brief): ")
                                       nil default-directory nil)
                       pfx)))
@@ -5769,7 +5790,7 @@ returns nil."
 
          ;; vc dired listings provide the state or blanks between file
          ;; permissions and date.  The state is always surrounded by
-         ;; parantheses:
+         ;; parentheses:
          ;; -rw-r--r-- (modified) 2005-10-22 21:25 files.el
          ;; This is not supported yet.
     (purecopy (concat "\\([0-9][BkKMGTPEZY]? " iso
@@ -6089,7 +6110,7 @@ message to that effect instead of signaling an error."
 
 (defvar kill-emacs-query-functions nil
   "Functions to call with no arguments to query about killing Emacs.
-If any of these functions returns nil, killing Emacs is cancelled.
+If any of these functions returns nil, killing Emacs is canceled.
 `save-buffers-kill-emacs' calls these functions, but `kill-emacs',
 the low level primitive, does not.  See also `kill-emacs-hook'.")
 
@@ -6123,8 +6144,8 @@ With prefix ARG, silently save all file-visiting buffers, then kill."
                    (setq active t))
               (setq processes (cdr processes)))
             (or (not active)
-                (list-processes t)
-                (yes-or-no-p "Active processes exist; kill them and exit anyway? "))))
+                (progn (list-processes t)
+                       (yes-or-no-p "Active processes exist; kill them and exit anyway? ")))))
        ;; Query the user for other things, perhaps.
        (run-hook-with-args-until-failure 'kill-emacs-query-functions)
        (or (null confirm-kill-emacs)
@@ -6293,7 +6314,7 @@ as in \"og+rX-w\"."
   "Convert symbolic file modes to numeric file modes.
 MODES is the string to convert, it should match
 \"[ugoa]*([+-=][rwxXstugo]*)+,...\".
-See (info \"(coreutils)File permissions\") for more information on this
+See Info node `(coreutils)File permissions' for more information on this
 notation.
 FROM (or 0 if nil) gives the mode bits on which to base permissions if
 MODES request to add, remove, or set permissions based on existing ones,
@@ -6479,7 +6500,7 @@ Otherwise, trash FILENAME using the freedesktop.org conventions,
                                 (setq tries 0 success t))
                             (file-already-exists nil))
                     (setq tries (1- tries))
-                    ;; Uniqify new-fn.  (Some file managers do not
+                    ;; Uniquify new-fn.  (Some file managers do not
                     ;; like Emacs-style backup file names---e.g. bug
                     ;; 170956 in Konqueror bug tracker.)
                     (setq new-fn (make-temp-name (concat base-fn "_")))))