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))))
(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)
(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)
(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
(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.
("\\.p\\'" . pascal-mode)
("\\.pas\\'" . pascal-mode)
("\\.mss\\'" . scribe-mode)
+ ("\\.ada\\'" . ada-mode)
+ ("\\.icn\\'" . icon-mode)
("\\.pl\\'" . prolog-mode)
("\\.cc\\'" . c++-mode)
("\\.hh\\'" . c++-mode)
(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))))
;; "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)
(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."
(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 ()
;; 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.
(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.
(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)