(Fwindow_end): Don't call temp_set_pt_both with
[bpt/emacs.git] / lisp / files.el
index aa0047b..d92313e 100644 (file)
@@ -1,7 +1,7 @@
 ;;; files.el --- file input and output commands for Emacs
 
 ;; Copyright (C) 1985, 86, 87, 92, 93,
-;;              94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+;;              94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 
@@ -84,8 +84,9 @@ names that the old file had will now refer to the new (edited) file.
 The file's owner and group are unchanged.
 
 The choice of renaming or copying is controlled by the variables
-`backup-by-copying', `backup-by-copying-when-linked' and
-`backup-by-copying-when-mismatch'.  See also `backup-inhibited'."
+`backup-by-copying', `backup-by-copying-when-linked',
+`backup-by-copying-when-mismatch' and
+`backup-by-copying-when-privileged-mismatch'.  See also `backup-inhibited'."
   :type 'boolean
   :group 'backup)
 
@@ -120,6 +121,18 @@ This variable is relevant only if `backup-by-copying' is nil."
   :type 'boolean
   :group 'backup)
 
+(defcustom backup-by-copying-when-privileged-mismatch 200
+  "*Non-nil means create backups by copying to preserve a privileged owner.
+Renaming may still be used (subject to control of other variables)
+when it would not result in changing the owner of the file or if the owner
+has a user id greater than the value of this variable.  This is useful
+when low-numbered uid's are used for special system users (such as root)
+that must maintain ownership of certain files.
+This variable is relevant only if `backup-by-copying' and
+`backup-by-copying-when-mismatch' are nil."
+  :type '(choice (const nil) integer)
+  :group 'backup)
+
 (defvar backup-enable-predicate
   '(lambda (name)
      (or (< (length name) 5)
@@ -285,7 +298,8 @@ functions are called.")
 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.
+So any buffer-local binding of `write-file-hooks' is
+discarded if you change the visited file name with \\[set-visited-file-name].
 
 Don't make this variable buffer-local; instead, use `local-write-file-hooks'.
 See also `write-contents-hooks'.")
@@ -326,9 +340,12 @@ See also `write-file-hooks'.")
 The value can be t, nil or something else.
 A value of t means file local variables specifications are obeyed;
 nil means they are ignored; anything else means query.
+This variable also controls use of major modes specified in
+a -*- line.
 
-The command \\[normal-mode] always obeys file local variable
-specifications and ignores this variable."
+The command \\[normal-mode], when used interactively,
+always obeys file local variable specifications and the -*- line,
+and ignores this variable."
   :type '(choice (const :tag "Obey" t)
                 (const :tag "Ignore" nil)
                 (other :tag "Query" other))
@@ -336,8 +353,12 @@ specifications and ignores this variable."
 
 (defvar local-enable-local-variables t
   "Like `enable-local-variables' but meant for buffer-local bindings.
+The meaningful values are nil and non-nil.  The default is non-nil.
 If a major mode sets this to nil, buffer-locally, then any local
-variables list in the file will be ignored.")
+variables list in the file will be ignored.
+
+This variable does not affect the use of major modes
+specified in a -*- line.")
 
 (defcustom enable-local-eval 'maybe
   "*Control processing of the \"variable\" `eval' in a file's local variables.
@@ -373,6 +394,13 @@ and ignores this variable."
          (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") "/tmp"))))
   "The directory for writing temporary files.")
 
+(defvar small-temporary-file-directory
+  (if (eq system-type 'ms-dos) (getenv "TMPDIR"))
+  "The directory for writing small temporary files.
+If non-nil, this directory is used instead of `temporary-file-directory'
+by programs that create small temporary files.  This is for systems that
+have fast storage with limited space, such as a RAM disk.")
+
 ;; The system null device. (Should reference NULL_DEVICE from C.)
 (defvar null-device "/dev/null" "The system null device.")
 
@@ -474,10 +502,12 @@ This is an interface to the function `load'."
   (interactive "sLoad library: ")
   (load library))
 
-(defun file-local-copy (file &optional buffer)
+(defun file-local-copy (file)
   "Copy the file FILE into a temporary file on this machine.
 Returns the name of the local copy, or nil, if FILE is directly
 accessible."
+  ;; This formerly had an optional BUFFER argument that wasn't used by
+  ;; anything.
   (let ((handler (find-file-name-handler file 'file-local-copy)))
     (if handler
        (funcall handler 'file-local-copy file)
@@ -639,51 +669,73 @@ do not put this buffer at the front of the list of recently selected ones."
     (pop-to-buffer buffer t norecord)
     (raise-frame (window-frame (selected-window)))))
 
-(defun find-file (filename)
+(defun find-file (filename &optional wildcards)
   "Edit file FILENAME.
 Switch to a buffer visiting file FILENAME,
-creating one if none already exists."
-  (interactive "FFind file: ")
-  (switch-to-buffer (find-file-noselect filename)))
-
-(defun find-file-other-window (filename)
+creating one if none already exists.
+Interactively, or if WILDCARDS is non-nil in a call from Lisp,
+expand wildcards (if any) and visit multiple files.  Wildcard expansion
+can be suppressed by setting `find-file-wildcards'."
+  (interactive "FFind file: \np")
+  (let ((value (find-file-noselect filename nil nil wildcards)))
+    (if (listp value)
+       (mapcar 'switch-to-buffer (nreverse value))
+      (switch-to-buffer value))))
+
+(defun find-file-other-window (filename &optional wildcards)
   "Edit file FILENAME, in another window.
 May create a new window, or reuse an existing one.
-See the function `display-buffer'."
-  (interactive "FFind file in other window: ")
-  (switch-to-buffer-other-window (find-file-noselect filename)))
+See the function `display-buffer'.
+Interactively, or if WILDCARDS is non-nil in a call from Lisp,
+expand wildcards (if any) and visit multiple files."
+  (interactive "FFind file in other window: \np")
+  (let ((value (find-file-noselect filename nil nil wildcards)))
+    (if (listp value)
+       (progn
+         (setq value (nreverse value))
+         (switch-to-buffer-other-window (car value))
+         (mapcar 'switch-to-buffer (cdr value)))
+      (switch-to-buffer-other-window value))))
 
-(defun find-file-other-frame (filename)
+(defun find-file-other-frame (filename &optional wildcards)
   "Edit file FILENAME, in another frame.
 May create a new frame, or reuse an existing one.
-See the function `display-buffer'."
-  (interactive "FFind file in other frame: ")
-  (switch-to-buffer-other-frame (find-file-noselect filename)))
+See the function `display-buffer'.
+Interactively, or if WILDCARDS is non-nil in a call from Lisp,
+expand wildcards (if any) and visit multiple files."
+  (interactive "FFind file in other frame: \np")
+  (let ((value (find-file-noselect filename nil nil wildcards)))
+    (if (listp value)
+       (progn
+         (setq value (nreverse value))
+         (switch-to-buffer-other-frame (car value))
+         (mapcar 'switch-to-buffer (cdr value)))
+      (switch-to-buffer-other-frame value))))
 
-(defun find-file-read-only (filename)
+(defun find-file-read-only (filename &optional wildcards)
   "Edit file FILENAME but don't allow changes.
 Like \\[find-file] but marks buffer as read-only.
 Use \\[toggle-read-only] to permit editing."
-  (interactive "fFind file read-only: ")
-  (find-file filename)
+  (interactive "fFind file read-only: \np")
+  (find-file filename wildcards)
   (toggle-read-only 1)
   (current-buffer))
 
-(defun find-file-read-only-other-window (filename)
+(defun find-file-read-only-other-window (filename &optional wildcards)
   "Edit file FILENAME in another window but don't allow changes.
 Like \\[find-file-other-window] but marks buffer as read-only.
 Use \\[toggle-read-only] to permit editing."
-  (interactive "fFind file read-only other window: ")
-  (find-file-other-window filename)
+  (interactive "fFind file read-only other window: \np")
+  (find-file-other-window filename wildcards)
   (toggle-read-only 1)
   (current-buffer))
 
-(defun find-file-read-only-other-frame (filename)
+(defun find-file-read-only-other-frame (filename &optional wildcards)
   "Edit file FILENAME in another frame but don't allow changes.
 Like \\[find-file-other-frame] but marks buffer as read-only.
 Use \\[toggle-read-only] to permit editing."
-  (interactive "fFind file read-only other frame: ")
-  (find-file-other-frame filename)
+  (interactive "fFind file read-only other frame: \np")
+  (find-file-other-frame filename wildcards)
   (toggle-read-only 1)
   (current-buffer))
 
@@ -767,7 +819,7 @@ Choose the buffer's name using `generate-new-buffer-name'."
   "Regexp to match the automounter prefix in a directory name.")
 
 (defvar abbreviated-home-dir nil
-  "The user's homedir abbreviated according to `directory-abbrev-list'.")
+  "The user's homedir abbreviated according to `directory-abbrev-alist'.")
 
 (defun abbreviate-file-name (filename)
   "Return a version of FILENAME shortened using `directory-abbrev-alist'.
@@ -867,13 +919,17 @@ whose names match the pattern."
   :group 'files
   :type 'boolean)
 
-(defun find-file-noselect (filename &optional nowarn rawfile)
+(defun find-file-noselect (filename &optional nowarn rawfile wildcards)
   "Read file FILENAME into a buffer and return the buffer.
 If a buffer exists visiting FILENAME, return that one, but
 verify that the file has not changed since visited or saved.
 The buffer is not selected, just returned to the caller.
 Optional first arg NOWARN non-nil means suppress any warning messages.
-Optional second arg RAWFILE non-nil means the file is read literally."
+Optional second arg RAWFILE non-nil means the file is read literally.
+Optional third arg WILDCARDS non-nil means do wildcard processing
+and visit all the matching files.  When wildcards are actually
+used and expanded, the value is a list of buffers
+that are visiting the various files."
   (setq filename
        (abbreviate-file-name
         (expand-file-name filename)))
@@ -883,12 +939,18 @@ Optional second arg RAWFILE non-nil means the file is read literally."
                              (abbreviate-file-name (file-truename filename))
                            filename))
        (error "%s is a directory" filename))
-    (if (and find-file-wildcards
+    (if (and wildcards
+            find-file-wildcards
+            (not (string-match "\\`/:" filename))
             (string-match "[[*?]" filename))
-       (let ((files (file-expand-wildcards filename t))
+       (let ((files (condition-case nil
+                        (file-expand-wildcards filename t)
+                      (error (list filename))))
              (find-file-wildcards nil))
-         (car (mapcar #'(lambda (fn) (find-file-noselect fn))
-                      files)))
+         (if (null files)
+             (find-file-noselect filename)
+           (car (mapcar #'(lambda (fn) (find-file-noselect fn))
+                        files))))
       (let* ((buf (get-file-buffer filename))
             (truename (abbreviate-file-name (file-truename filename)))
             (number (nthcdr 10 (file-attributes truename)))
@@ -1010,8 +1072,11 @@ Optional second arg RAWFILE non-nil means the file is read literally."
           (or (run-hook-with-args-until-success 'find-file-not-found-hooks)
               ;; If they fail too, set error.
               (setq error t)))))
-      ;; Find the file's truename, and maybe use that as visited name.
-      (setq buffer-file-truename truename)
+      ;; Record the file's truename, and maybe use that as visited name.
+      (if (equal filename buffer-file-name)
+         (setq buffer-file-truename truename)
+       (setq buffer-file-truename
+             (abbreviate-file-name (file-truename buffer-file-name))))
       (setq buffer-file-number number)
       ;; On VMS, we may want to remember which directory in a search list
       ;; the file was found in.
@@ -1027,7 +1092,7 @@ Optional second arg RAWFILE non-nil means the file is read literally."
                (setq filename
                      (expand-file-name buffer-file-truename))))
       ;; Set buffer's default directory to that of the file.
-      (setq default-directory (file-name-directory filename))
+      (setq default-directory (file-name-directory buffer-file-name))
       ;; Turn off backup files for certain file names.  Since
       ;; this is a permanent local, the major mode won't eliminate it.
       (and (not (funcall backup-enable-predicate buffer-file-name))
@@ -1127,7 +1192,7 @@ unless NOMODES is non-nil."
           (msg
            (cond ((and error (file-attributes buffer-file-name))
                   (setq buffer-read-only t)
-                  "File exists, but cannot be read.")
+                  "File exists, but cannot be read")
                  ((not buffer-read-only)
                   (if (and warn
                            (file-newer-than-file-p (make-auto-save-file-name)
@@ -1146,16 +1211,22 @@ unless NOMODES is non-nil."
                  (t
                   (setq buffer-read-only nil)
                   (if (file-exists-p (file-name-directory (directory-file-name (file-name-directory buffer-file-name))))
-                      "Use M-x make-dir RET RET to create the directory"
-                    "Use C-u M-x make-dir RET RET to create directory and its parents")))))
+                      "Use M-x make-directory RET RET to create the directory"
+                    "Use C-u M-x make-directory RET RET to create directory and its parents")))))
       (if msg
          (progn
            (message msg)
            (or not-serious (sit-for 1 nil t)))))
     (if (and auto-save-default (not noauto))
        (auto-save-mode t)))
+  ;; Make people do a little extra work (C-x C-q)
+  ;; before altering a backup file.
+  (if (backup-file-name-p buffer-file-name)
+      (setq buffer-read-only t))
   (if nomodes
       nil
+    (and view-read-only view-mode
+        (view-mode-disable))
     (normal-mode t)
     (if (and buffer-read-only view-read-only
             (not (eq (get major-mode 'mode-class) 'special)))
@@ -1168,10 +1239,15 @@ Also sets up any specified local variables of the file.
 Uses the visited file name, the -*- line, and the local variables spec.
 
 This function is called automatically from `find-file'.  In that case,
-we may set up specified local variables depending on the value of
-`enable-local-variables': if it is t, we do; if it is nil, we don't;
-otherwise, we query.  `enable-local-variables' is ignored if you
-run `normal-mode' explicitly."
+we may set up the file-specified mode and local variables,
+depending on the value of `enable-local-variables': if it is t, we do;
+if it is nil, we don't; otherwise, we query.
+In addition, if `local-enable-local-variables' is nil, we do
+not set local variables (though we do notice a mode specified with -*-.)
+
+`enable-local-variables' is ignored if you run `normal-mode' interactively,
+or from Lisp without specifying the optional argument FIND-FILE;
+in that case, this function acts as if `enable-local-variables' were t."
   (interactive)
   (or find-file (funcall (or default-major-mode 'fundamental-mode)))
   (condition-case err
@@ -1238,10 +1314,12 @@ run `normal-mode' explicitly."
     ("\\(/\\|\\`\\)\\.\\(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)
+    ("\\.m?spec$" . sh-mode)
     ("\\.mm\\'" . nroff-mode)
     ("\\.me\\'" . nroff-mode)
     ("\\.ms\\'" . nroff-mode)
     ("\\.man\\'" . nroff-mode)
+    ("\\.\\(u?lpc\\|pike\\|pmod\\)\\'" . pike-mode)
 ;;; The following should come after the ChangeLog pattern
 ;;; for the sake of ChangeLog.1, etc.
 ;;; and after the .scm.[0-9] pattern too.
@@ -1252,6 +1330,7 @@ run `normal-mode' explicitly."
     ("\\.clo\\'" . latex-mode)         ;LaTeX 2e class option
     ("\\.bbl\\'" . latex-mode)
     ("\\.bib\\'" . bibtex-mode)
+    ("\\.sql\\'" . sql-mode)
     ("\\.m4\\'" . m4-mode)
     ("\\.mc\\'" . m4-mode)
     ("\\.mf\\'" . metafont-mode)
@@ -1296,13 +1375,16 @@ run `normal-mode' explicitly."
     ;; _emacs following a directory delimiter
     ;; in MsDos syntax
     ("[:/]_emacs\\'" . emacs-lisp-mode)
+    ("/crontab\\.X*[0-9]+\\'" . shell-script-mode)
     ("\\.ml\\'" . lisp-mode)
     ("\\.asn$" . snmp-mode)
     ("\\.mib$" . snmp-mode)
     ("\\.smi$" . snmp-mode)
     ("\\.as2$" . snmpv2-mode)
     ("\\.mi2$" . snmpv2-mode)
-    ("\\.sm2$" . snmpv2-mode))
+    ("\\.sm2$" . snmpv2-mode)
+    ("\\.\\(diffs?\\|patch\\|rej\\)\\'" . diff-mode)
+    ("\\.[eE]?[pP][sS]$" . ps-mode))
   "\
 Alist of filename patterns vs corresponding major mode functions.
 Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
@@ -1339,6 +1421,7 @@ REGEXP and search the list again for another match.")
     ("oash" . sh-mode)
     ("pdksh" . sh-mode)
     ("rc" . sh-mode)
+    ("rpm" . sh-mode)
     ("sh" . sh-mode)
     ("sh5" . sh-mode)
     ("tcsh" . sh-mode)
@@ -1348,7 +1431,10 @@ REGEXP and search the list again for another match.")
     ("tail" . text-mode)
     ("more" . text-mode)
     ("less" . text-mode)
-    ("pg" . text-mode))
+    ("pg" . text-mode)
+    ("make" . makefile-mode)           ; Debian uses this
+    ("guile" . scheme-mode)
+    ("clisp" . lisp-mode))
   "Alist mapping interpreter names to major modes.
 This alist applies to files whose first line starts with `#!'.
 Each element looks like (INTERPRETER . MODE).
@@ -1389,7 +1475,6 @@ and we don't even do that unless it would come from the file name."
       (goto-char (point-min))
       (skip-chars-forward " \t\n")
       (and enable-local-variables
-          local-enable-local-variables
           ;; Don't look for -*- if this file name matches any
           ;; of the regexps in inhibit-first-line-modes-regexps.
           (let ((temp inhibit-first-line-modes-regexps)
@@ -1510,7 +1595,9 @@ and we don't even do that unless it would come from the file name."
   (save-excursion
     (goto-char (point-min))
     (let ((result nil)
-         (end (save-excursion (end-of-line (and (looking-at "^#!") 2)) (point))))
+         (end (save-excursion (end-of-line (and (looking-at "^#!") 2)) (point)))
+         (enable-local-variables
+          (and local-enable-local-variables enable-local-variables)))
       ;; Parse the -*- line into the `result' alist.
       (cond ((not (search-forward "-*-" end t))
             ;; doesn't have one.
@@ -1582,7 +1669,9 @@ is specified, returning t if it is specified."
   (unless mode-only
     (hack-local-variables-prop-line))
   ;; Look for "Local variables:" line in last page.
-  (let (mode-specified)
+  (let (mode-specified
+       (enable-local-variables
+        (and local-enable-local-variables enable-local-variables)))
     (save-excursion
       (goto-char (point-max))
       (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
@@ -1731,13 +1820,15 @@ is specified, returning t if it is specified."
                                   (beginning-of-line)
                                   (set-window-start (selected-window) (point)))
                                 (setq enable-local-eval
-                                      (y-or-n-p (format "Process `eval' or hook local variables in file %s? "
-                                                        (file-name-nondirectory buffer-file-name)))))))))
+                                      (y-or-n-p (format "Process `eval' or hook local variables in %s? "
+                                                        (if buffer-file-name
+                                                            (concat "file " (file-name-nondirectory buffer-file-name))
+                                                          (concat "buffer " (buffer-name)))))))))))
             (if (eq var 'eval)
                 (save-excursion (eval val))
               (make-local-variable var)
               (set var val))
-          (message "Ignoring `eval:' in file's local variables")))
+          (message "Ignoring `eval:' in the local variables list")))
        ;; Ordinary variable, really set it.
        (t (make-local-variable var)
           (set var val))))
@@ -1862,31 +1953,37 @@ the old visited file has been renamed to the new name FILENAME."
 
 (defun write-file (filename &optional confirm)
   "Write current buffer into file FILENAME.
-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.
+This makes the buffer visit that file, and marks it as not modified.
+
+If you specify just a directory name as FILENAME, that means to use
+the default file name but in that directory.  You can also yank
+the default file name into the minibuffer to edit it, using M-n.
 
-If optional second arg CONFIRM is non-nil,
-ask for confirmation for overwriting an existing file.
+If the buffer is not already visiting a file, the default file name
+for the output file is the buffer name.
+
+If optional second arg CONFIRM is non-nil, this function
+asks for confirmation before overwriting an existing file.
 Interactively, confirmation is required unless you supply a prefix argument."
 ;;  (interactive "FWrite file: ")
   (interactive
    (list (if buffer-file-name
             (read-file-name "Write file: "
                                 nil nil nil nil)
-          (read-file-name "Write file: "
-                              (cdr (assq 'default-directory
-                                         (buffer-local-variables)))
-                              nil nil (file-name-nondirectory (buffer-name))))
+          (read-file-name "Write file: " default-directory
+                          (expand-file-name
+                           (file-name-nondirectory (buffer-name))
+                           default-directory)
+                          nil nil))
         (not current-prefix-arg)))
   (or (null filename) (string-equal filename "")
       (progn
        ;; If arg is just a directory,
-       ;; use same file name, but in that directory.
-       (if (and (file-directory-p filename) buffer-file-name)
+       ;; use the default file name, but in that directory.
+       (if (file-directory-p filename)
            (setq filename (concat (file-name-as-directory filename)
-                                  (file-name-nondirectory buffer-file-name))))
+                                  (file-name-nondirectory
+                                   (or buffer-file-name (buffer-name))))))
        (and confirm
             (file-exists-p filename)
             (or (y-or-n-p (format "File `%s' exists; overwrite? " filename))
@@ -1938,14 +2035,19 @@ no longer accessible under its old name."
                  ;; Actually write the back up file.
                  (condition-case ()
                      (if (or file-precious-flag
-    ;                    (file-symlink-p buffer-file-name)
+    ;                        (file-symlink-p buffer-file-name)
                              backup-by-copying
                              (and backup-by-copying-when-linked
                                   (> (file-nlinks real-file-name) 1))
-                             (and backup-by-copying-when-mismatch
+                             (and (or backup-by-copying-when-mismatch 
+                                      (integerp backup-by-copying-when-privileged-mismatch))
                                   (let ((attr (file-attributes real-file-name)))
-                                    (or (nth 9 attr)
-                                        (not (file-ownership-preserved-p real-file-name))))))
+                                    (and (or backup-by-copying-when-mismatch 
+                                             (and (integerp (nth 2 attr))
+                                                  (integerp backup-by-copying-when-privileged-mismatch)
+                                                  (<= (nth 2 attr) backup-by-copying-when-privileged-mismatch)))
+                                         (or (nth 9 attr)
+                                             (not (file-ownership-preserved-p real-file-name)))))))
                          (condition-case ()
                              (copy-file real-file-name backupname t t)
                            (file-error
@@ -2076,9 +2178,8 @@ You may need to redefine `file-name-sans-versions' as well."
 (defvar backup-extract-version-start)
 
 ;; This is used in various files.
-;; The usage of bv-length is not very clean,
-;; but I can't see a good alternative,
-;; so as of now I am leaving it alone.
+;; The usage of backup-extract-version-start is not very clean,
+;; but I can't see a good alternative, so as of now I am leaving it alone.
 (defun backup-extract-version (fn)
   "Given the name of a numeric backup file, return the backup number.
 Uses the free variable `backup-extract-version-start', whose value should be
@@ -2235,6 +2336,9 @@ the last real save, but optional arg FORCE non-nil means delete anyway."
           (file-error nil))
         (set-buffer-auto-saved))))
 
+(defvar auto-save-hook nil
+  "Normal hook run just before auto-saving.")
+
 (defvar after-save-hook nil
   "Normal hook that is run after a buffer is saved to its file.")
 
@@ -2595,7 +2699,9 @@ which are the arguments that `revert-buffer' received.")
 (defvar revert-buffer-insert-file-contents-function nil
   "Function to use to insert contents when reverting this buffer.
 Gets two args, first the nominal file name to use,
-and second, t if reading the auto-save file.")
+and second, t if reading the auto-save file.
+
+The function you specify is responsible for updating (or preserving) point.")
 
 (defvar before-revert-hook nil
   "Normal hook for `revert-buffer' to run before reverting.
@@ -2611,6 +2717,8 @@ hook functions.
 If `revert-buffer-function' is used to override the normal revert
 mechanism, this hook is not used.")
 
+(defvar revert-buffer-internal-hook)
+
 (defun revert-buffer (&optional ignore-auto noconfirm preserve-modes)
   "Replace current buffer text with the text of the visited file on disk.
 This undoes all changes since the file was visited or saved.
@@ -2629,7 +2737,8 @@ sake of backward compatibility.  IGNORE-AUTO is optional, defaulting
 to nil.
 
 Optional second argument NOCONFIRM means don't ask for confirmation at
-all.
+all.  (The local variable `revert-without-query', if non-nil, prevents 
+confirmation.)
 
 Optional third argument PRESERVE-MODES non-nil means don't alter
 the files modes.  Normally we reinitialize them using `normal-mode'.
@@ -2649,8 +2758,7 @@ non-nil, it is called instead of rereading visited file contents."
   (interactive (list (not current-prefix-arg)))
   (if revert-buffer-function
       (funcall revert-buffer-function ignore-auto noconfirm)
-    (let* ((opoint (point))
-          (auto-save-p (and (not ignore-auto)
+    (let* ((auto-save-p (and (not ignore-auto)
                             (recent-auto-save-p)
                             buffer-auto-save-file-name
                             (file-readable-p buffer-auto-save-file-name)
@@ -2706,9 +2814,9 @@ non-nil, it is called instead of rereading visited file contents."
                          ;; any code conversion.
                          (if auto-save-p 'no-conversion
                            coding-system-for-read)))
+                    ;; Note that this preserves point in an intelligent way.
                     (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.
               (setq buffer-file-truename
@@ -2749,10 +2857,13 @@ non-nil, it is called instead of rereading visited file contents."
             (yes-or-no-p (format "Recover auto save file %s? " file-name)))
           (switch-to-buffer (find-file-noselect file t))
           (let ((buffer-read-only nil)
+                ;; Keep the current buffer-file-coding-system.
+                (coding-system buffer-file-coding-system)
                 ;; Auto-saved file shoule be read without any code conversion.
                 (coding-system-for-read 'no-conversion))
             (erase-buffer)
-            (insert-file-contents file-name nil))
+            (insert-file-contents file-name nil)
+            (set-buffer-file-coding-system coding-system))
           (after-find-file nil nil t))
          (t (error "Recover-file cancelled")))))
 
@@ -2768,15 +2879,16 @@ Then you'll be asked about a number of files to recover."
   (let ((ls-lisp-support-shell-wildcards t))
     (dired (concat auto-save-list-file-prefix "*")
           (concat dired-listing-switches "t")))
-  (goto-char (point-min))
-  (or (looking-at "Move to the session you want to recover,")
-      (let ((inhibit-read-only t))
-       ;; Each line starts with a space
-       ;; so that Font Lock mode won't highlight the first character.
-       (insert " Move to the session you want to recover,\n"
-               " then type C-c C-c to select it.\n\n"
-               " You can also delete some of these files;\n"
-               " type d on a line to mark that file for deletion.\n\n")))
+  (save-excursion
+    (goto-char (point-min))
+    (or (looking-at " Move to the session you want to recover,")
+       (let ((inhibit-read-only t))
+         ;; Each line starts with a space
+         ;; so that Font Lock mode won't highlight the first character.
+         (insert " Move to the session you want to recover,\n"
+                 " then type C-c C-c to select it.\n\n"
+                 " You can also delete some of these files;\n"
+                 " type d on a line to mark that file for deletion.\n\n"))))
   (use-local-map (nconc (make-sparse-keymap) (current-local-map)))
   (define-key (current-local-map) "\C-c\C-c" 'recover-session-finish))
 
@@ -3042,9 +3154,46 @@ by `sh' are supported."
 
 (defun file-expand-wildcards (pattern &optional full)
   "Expand wildcard pattern PATTERN.
-This returns a list of file names which match the pattern."
-  (directory-files (file-name-directory pattern) full
-                  (wildcard-to-regexp (file-name-nondirectory pattern))))
+This returns a list of file names which match the pattern.
+
+If PATTERN is written as an absolute relative file name,
+the values are absolute also.
+
+If PATTERN is written as a relative file name, it is interpreted
+relative to the current default directory, `default-directory'.
+The file names returned are normally also relative to the current
+default directory.  However, if FULL is non-nil, they are absolute."
+  (let* ((nondir (file-name-nondirectory pattern))
+        (dirpart (file-name-directory pattern))
+        ;; A list of all dirs that DIRPART specifies.
+        ;; This can be more than one dir
+        ;; if DIRPART contains wildcards.
+        (dirs (if (and dirpart (string-match "[[*?]" dirpart))
+                  (mapcar 'file-name-as-directory
+                          (file-expand-wildcards (directory-file-name dirpart)))
+                (list dirpart)))
+        contents)
+    (while dirs
+      (when (or (null (car dirs))      ; Possible if DIRPART is not wild.
+               (file-directory-p (directory-file-name (car dirs))))
+       (let ((this-dir-contents
+              ;; Filter out "." and ".."
+              (delq nil
+                    (mapcar #'(lambda (name)
+                                (unless (string-match "\\`\\.\\.?\\'"
+                                                      (file-name-nondirectory name))
+                                  name))
+                            (directory-files (or (car dirs) ".") full
+                                             (wildcard-to-regexp nondir))))))
+         (setq contents
+               (nconc
+                (if (and (car dirs) (not full))
+                    (mapcar (function (lambda (name) (concat (car dirs) name)))
+                            this-dir-contents)
+                  this-dir-contents)
+                contents))))
+      (setq dirs (cdr dirs)))
+    contents))
 
 (defun list-directory (dirname &optional verbose)
   "Display a list of files in or matching DIRNAME, a la `ls'.
@@ -3210,6 +3359,7 @@ With prefix arg, silently save all file-visiting buffers, then kill."
                    (setq active t))
               (setq processes (cdr processes)))
             (or (not active)
+                (list-processes)
                 (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)