]> code.delx.au - gnu-emacs/blobdiff - lisp/files.el
(save-buffers-kill-emacs): Use run-hook-with-args-until-failure.
[gnu-emacs] / lisp / files.el
index 9938c19b548f8dc6ff29e97d636b5978f0e3c75d..691d3dae790a4e401526b181123521512c738e65 100644 (file)
@@ -516,7 +516,7 @@ If the current buffer now contains an empty file that you just visited
                file-dir (file-name-directory file)))
      (list (read-file-name
            "Find alternate file: " file-dir nil nil file-name))))
-  (and (buffer-modified-p)
+  (and (buffer-modified-p) (buffer-file-name)
        ;; (not buffer-read-only)
        (not (yes-or-no-p (format "Buffer %s is modified; kill anyway? "
                                 (buffer-name))))
@@ -684,7 +684,7 @@ The buffer is not selected, just returned to the caller."
                      (format
                       (if (buffer-modified-p buf)
     "File %s changed on disk.  Discard your edits? "
-    "File %s changed on disk.  Read the new version? ")
+    "File %s changed on disk.  Reread from disk? ")
                       (file-name-nondirectory filename)))
                     (save-excursion
                       (set-buffer buf)
@@ -703,16 +703,10 @@ The buffer is not selected, just returned to the caller."
          (condition-case ()
              (insert-file-contents filename t)
            (file-error
-            (setq error t)
             ;; Run find-file-not-found-hooks until one returns non-nil.
-            (let ((hooks find-file-not-found-hooks))
-              (while (and hooks
-                          (not (and (funcall (car hooks))
-                                    ;; If a hook succeeded, clear error.
-                                    (progn (setq error nil)
-                                           ;; Also exit the loop.
-                                           t))))
-                (setq hooks (cdr hooks))))))
+            (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)
          (setq buffer-file-number number)
@@ -740,14 +734,18 @@ The buffer is not selected, just returned to the caller."
          (after-find-file error (not nowarn))))
       buf)))
 \f
-(defun after-find-file (&optional error warn noauto from-revert-buffer)
+(defvar after-find-file-from-revert-buffer nil)
+
+(defun after-find-file (&optional error warn noauto
+                                 after-find-file-from-revert-buffer)
   "Called after finding a file and by the default revert function.
 Sets buffer mode, parses local variables.
 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.
-FROM-REVERT-BUFFER means this call was from `revert-buffer'.
+Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil
+ means this call was from `revert-buffer'.
 Finishes by calling the functions in `find-file-hooks'."
   (setq buffer-read-only (not (file-writable-p buffer-file-name)))
   (if noninteractive
@@ -783,7 +781,7 @@ Finishes by calling the functions in `find-file-hooks'."
     (if (and auto-save-default (not noauto))
        (auto-save-mode t)))
   (normal-mode t)
-  (mapcar 'funcall find-file-hooks))
+  (run-hooks 'find-file-hooks))
 
 (defun normal-mode (&optional find-file)
   "Choose the major mode for this buffer automatically.
@@ -827,6 +825,8 @@ run `normal-mode' explicitly."
                                  ("\\.p\\'" . pascal-mode)
                                  ("\\.pas\\'" . pascal-mode)
                                  ("\\.mss\\'" . scribe-mode)
+                                 ("\\.ada\\'" . ada-mode)
+                                 ("\\.icn\\'" . icon-mode)
                                  ("\\.pl\\'" . prolog-mode)
                                  ("\\.cc\\'" . c++-mode)
                                  ("\\.hh\\'" . c++-mode)
@@ -1163,6 +1163,9 @@ If `enable-local-variables' is nil, this function does not check for a
 (put 'outline-level 'risky-local-variable t)
 (put 'rmail-output-file-alist 'risky-local-variable t)
 
+;; This one is safe because the user gets to check it before it is used.
+(put 'compile-command 'safe-local-variable t)
+
 (defun hack-one-local-variable-quotep (exp)
   (and (consp exp) (eq (car exp) 'quote) (consp (cdr exp))))
 
@@ -1177,8 +1180,10 @@ If `enable-local-variables' is nil, this function does not check for a
        ;; "Setting" eval means either eval it or do nothing.
        ;; Likewise for setting hook variables.
        ((or (get var 'risky-local-variable)
-            (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$"
-                          (symbol-name var)))
+            (and
+             (string-match "-hooks?$\\|-functions?$\\|-forms?$\\|-program$\\|-command$"
+                           (symbol-name var))
+             (not (get var 'safe-local-variable))))
         ;; Permit evaling a put of a harmless property
         ;; if the args do nothing tricky.
         (if (or (and (eq var 'eval)
@@ -1425,6 +1430,26 @@ we do not remove backup version numbers, only true file version numbers."
                         (string-match "~\\'" name)
                         (length name))))))))
 
+(defun file-ownership-preserved-p (file)
+  "Returns t if deleting FILE and rewriting it would preserve the owner."
+  (let ((handler (find-file-name-handler file 'file-ownership-preserved-p)))
+    (if handler
+       (funcall handler 'file-ownership-preserved-p file)
+      (= (nth 2 (file-attributes file)) (user-uid)))))
+
+(defun file-name-sans-extension (filename)
+  "Return FILENAME sans final \"extension\".
+The extension, in a file name, is the part that follows the last `.'."
+  (save-match-data
+    (let ((file (file-name-sans-versions (file-name-nondirectory filename)))
+         directory)
+      (if (string-match "\\.[^.]*\\'" file)
+         (if (setq directory (file-name-directory filename))
+             (expand-file-name (substring file 0 (match-beginning 0))
+                               directory)
+           (substring file 0 (match-beginning 0)))
+       filename))))
+
 (defun make-backup-file-name (file)
   "Create the non-numeric backup file name for FILE.
 This is a separate function so you can redefine it for customization."
@@ -1604,15 +1629,12 @@ the last real save, but optional arg FORCE non-nil means delete anyway."
               (save-excursion
                 (goto-char (point-max))
                 (insert ?\n)))
-         (let ((hooks (append write-contents-hooks local-write-file-hooks
-                              write-file-hooks))
-               (done nil))
-           (while (and hooks
-                       (not (setq done (funcall (car hooks)))))
-             (setq hooks (cdr hooks)))
-           ;; If a hook returned t, file is already "written".
-           (cond ((not done)
-                  (setq setmodes (basic-save-buffer-1)))))
+         (or (run-hook-with-args-until-success 'write-contents-hooks)
+             (run-hook-with-args-until-success 'local-write-file-hooks)
+             (run-hook-with-args-until-success 'write-file-hooks)
+             ;; If a hook returned t, file is already "written".
+             ;; Otherwise, write it the usual way now.
+             (setq setmodes (basic-save-buffer-1)))
          (setq buffer-file-number (nth 10 (file-attributes buffer-file-name)))
          (if setmodes
              (condition-case ()
@@ -1651,7 +1673,8 @@ the last real save, but optional arg FORCE non-nil means delete anyway."
          ;; This requires write access to the containing dir,
          ;; which is why we don't try it if we don't have that access.
          (let ((realname buffer-file-name)
-               tempname temp nogood i succeed)
+               tempname temp nogood i succeed
+               (old-modtime (visited-file-modtime)))
            (setq i 0)
            (setq nogood t)
            ;; Find the temporary name to write under.
@@ -1666,7 +1689,10 @@ the last real save, but optional arg FORCE non-nil means delete anyway."
                       (setq succeed t))
              ;; If writing the temp file fails,
              ;; delete the temp file.
-             (or succeed (delete-file tempname)))
+             (or succeed 
+                 (progn
+                   (delete-file tempname)
+                   (set-visited-file-modtime old-modtime))))
            ;; Since we have created an entirely new file
            ;; and renamed it, make sure it gets the
            ;; right permission bits set.
@@ -2194,12 +2220,7 @@ With prefix arg, silently save all file-visiting buffers, then kill."
             (or (not active)
                 (yes-or-no-p "Active processes exist; kill them and exit anyway? "))))
        ;; Query the user for other things, perhaps.
-       (let ((functions kill-emacs-query-functions)
-            (yes t))
-        (while (and functions yes)
-          (setq yes (and yes (funcall (car functions))))
-          (setq functions (cdr functions)))
-        yes)
+       (run-hook-with-args-until-failure 'kill-emacs-query-functions)
        (kill-emacs)))
 \f
 (define-key ctl-x-map "\C-f" 'find-file)