The truename of a file is found by chasing all links
both at the file level and at the levels of the containing directories.")
-(defvar buffer-file-truename nil
- "The abbreviated truename of the file visited in the current buffer.
-That is, (abbreviate-file-name (file-truename buffer-file-name)).
-This variable is automatically local in all buffers, when non-nil.")
-(make-variable-buffer-local 'buffer-file-truename)
-(put 'buffer-file-truename 'permanent-local t)
-
(defvar buffer-file-number nil
"The device number and file number of the file visited in the current buffer.
The value is a list of the form (FILENUM DEVNUM).
"Make DIR become the current buffer's default directory.
If your environment includes a `CDPATH' variable, try each one of that
colon-separated list of directories when resolving a relative directory name."
- (interactive "FChange default directory: ")
+ (interactive
+ (list (read-file-name "Change default directory: "
+ default-directory default-directory)))
(if (file-name-absolute-p dir)
(cd-absolute (expand-file-name dir))
(if (null cd-path)
(onum buffer-file-number)
(otrue buffer-file-truename)
(oname (buffer-name)))
+ (if (get-buffer " **lose**")
+ (kill-buffer " **lose**"))
(rename-buffer " **lose**")
(setq buffer-file-name nil)
(setq buffer-file-number nil)
(setq list (cdr list))))
found))))
-(defun find-file-noselect (filename &optional nowarn)
+(defun insert-file-contents-literally (filename &optional visit beg end replace)
+ "Like `insert-file-contents', q.v., but only reads in the file.
+A buffer may be modified in several ways after reading into the buffer due
+to advanced Emacs features, such as file-name-handlers, format decoding,
+find-file-hooks, etc.
+ This function ensures that none of these modifications will take place."
+ (let ((file-name-handler-alist nil)
+ (format-alist nil)
+ (after-insert-file-functions nil)
+ (find-buffer-file-type-function
+ (if (fboundp 'find-buffer-file-type)
+ (symbol-function 'find-buffer-file-type)
+ nil)))
+ (unwind-protect
+ (progn
+ (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)
+ (fmakunbound 'find-buffer-file-type)))))
+
+(defun find-file-noselect (filename &optional nowarn rawfile)
"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.
(set-buffer-major-mode buf)
(set-buffer buf)
(erase-buffer)
- (condition-case ()
- (insert-file-contents filename t)
- (file-error
- ;; Run find-file-not-found-hooks until one returns non-nil.
- (or (run-hook-with-args-until-success 'find-file-not-found-hooks)
- ;; If they fail too, set error.
- (setq error t))))
+ (if rawfile
+ (condition-case ()
+ (insert-file-contents-literally filename t)
+ (file-error
+ ;; Unconditionally set error
+ (setq error t)))
+ (condition-case ()
+ (insert-file-contents filename t)
+ (file-error
+ ;; Run find-file-not-found-hooks until one returns non-nil.
+ (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)
(progn
(make-local-variable 'backup-inhibited)
(setq backup-inhibited t)))
- (after-find-file error (not nowarn))))
+ (if rawfile
+ nil
+ (after-find-file error (not nowarn)))))
buf)))
\f
(defvar after-find-file-from-revert-buffer nil)
("\\.p\\'" . pascal-mode)
("\\.pas\\'" . pascal-mode)
("\\.mss\\'" . scribe-mode)
- ("\\.ada\\'" . ada-mode)
+ ("\\.ad[abs]\\'" . ada-mode)
("\\.icn\\'" . icon-mode)
- ("\\.pl\\'" . prolog-mode)
+ ("\\.pl\\'" . perl-mode)
("\\.cc\\'" . c++-mode)
("\\.hh\\'" . c++-mode)
("\\.C\\'" . c++-mode)
("\\.hxx\\'" . c++-mode)
("\\.c\\+\\+\\'" . c++-mode)
("\\.h\\+\\+\\'" . c++-mode)
-;;; ("\\.mk\\'" . makefile-mode)
-;;; ("[Mm]akefile" . makefile-mode)
+ ("\\.mk\\'" . makefile-mode)
+ ("[Mm]akefile\\(.in\\)?\\'" . makefile-mode)
;;; Less common extensions come here
;;; so more common ones above are found faster.
("\\.texinfo\\'" . texinfo-mode)
("changelo\\'" . change-log-mode)
("ChangeLog.[0-9]+\\'" . change-log-mode)
("\\$CHANGE_LOG\\$\\.TXT" . change-log-mode)
-;; The following should come after the ChangeLog pattern
-;; for the sake of ChangeLog.1, etc.
+ ("\\.scm\\.[0-9]*\\'" . scheme-mode)
+;;; The following should come after the ChangeLog pattern
+;;; for the sake of ChangeLog.1, etc.
+;;; and after the .scm.[0-9] pattern too.
("\\.[12345678]\\'" . nroff-mode)
("\\.TeX\\'" . tex-mode)
("\\.sty\\'" . latex-mode)
("\\.article\\'" . text-mode)
("\\.letter\\'" . text-mode)
("\\.tcl\\'" . tcl-mode)
+ ("\\.f90\\'" . f90-mode)
("\\.lsp\\'" . lisp-mode)
("\\.awk\\'" . awk-mode)
("\\.prolog\\'" . prolog-mode)
("\\.tar\\'" . tar-mode)
+ ("\\.\\(arc\\|zip\\|lzh\\|zoo\\)\\'" . archive-mode)
;; Mailer puts message to be edited in
;; /tmp/Re.... or Message
("^/tmp/Re" . text-mode)
("\\.y\\'" . c-mode)
("\\.lex\\'" . c-mode)
("\\.oak\\'" . scheme-mode)
- ("\\.scm.[0-9]*\\'" . scheme-mode)
("\\.sgm\\'" . sgml-mode)
("\\.sgml\\'" . sgml-mode)
("\\.dtd\\'" . sgml-mode)
(length name))
(if keep-backup-version
(length name)
- (or (string-match "\\.~[0-9]+~\\'" name)
+ (or (string-match "\\.~[0-9.]+~\\'" name)
(string-match "~\\'" name)
(length name))))))))
(file-error nil))
(set-buffer-auto-saved))))
+(defvar after-save-hook nil
+ "Normal hook that is run after a buffer is saved to its file.")
+
(defun basic-save-buffer ()
- "Save the current buffer in its visited file, if it has been modified."
+ "Save the current buffer in its visited file, if it has been modified.
+After saving the buffer, run `after-save-hook'."
(interactive)
(save-excursion
;; In an indirect buffer, save its base buffer instead.
(rename-buffer buffer-new-name)))
;; If buffer has no file name, ask user for one.
(or buffer-file-name
- (set-visited-file-name
- (expand-file-name (read-file-name "File to save in: ") nil)))
+ (let ((filename
+ (expand-file-name
+ (read-file-name "File to save in: ") nil)))
+ (and (file-exists-p filename)
+ (or (y-or-n-p (format "File `%s' exists; overwrite? "
+ filename))
+ (error "Canceled")))
+ (set-visited-file-name filename)))
(or (verify-visited-file-modtime (current-buffer))
(not (file-exists-p buffer-file-name))
(yes-or-no-p
;; If the auto-save file was recent before this command,
;; delete it now.
(delete-auto-save-file-if-necessary recent-save)
+ ;; Support VC `implicit' locking.
+ (vc-after-save)
(run-hooks 'after-save-hook))
(message "(No changes need to be saved)"))))
(unwind-protect
(progn (clear-visited-file-modtime)
(write-region (point-min) (point-max)
- tempname nil realname)
+ tempname nil realname
+ buffer-file-truename)
(setq succeed t))
;; If writing the temp file fails,
;; delete the temp file.
(setq setmodes (file-modes buffer-file-name))
(set-file-modes buffer-file-name 511)))
(write-region (point-min) (point-max)
- buffer-file-name nil t)))
+ buffer-file-name nil t buffer-file-truename)))
setmodes))
(defun save-some-buffers (&optional arg exiting)
(error "%s is an auto-save file" file))
(let ((file-name (let ((buffer-file-name file))
(make-auto-save-file-name))))
- (cond ((not (file-newer-than-file-p file-name file))
+ (cond ((if (file-exists-p file)
+ (not (file-newer-than-file-p file-name file))
+ (not (file-exists-p file-name)))
(error "Auto-save file %s not current" file-name))
((save-window-excursion
(if (not (eq system-type 'vax-vms))
(goto-char (point-min))
(or (looking-at "Move to the session you want to recover,")
(let ((inhibit-read-only t))
- (insert "Move to the session you want to recover,\n")
- (insert "then type C-c C-c to select it.\n\n")))
+ (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))
;; Get the name of the session file to recover from.
(let ((file (dired-get-filename))
(buffer (get-buffer-create " *recover*")))
+ (dired-do-flagged-delete t)
(unwind-protect
(save-excursion
;; Read in the auto-save-list file.
(set-buffer buffer)
(erase-buffer)
(insert-file-contents file)
+ ;; The file contains a pair of line for each auto-saved buffer.
+ ;; The first line of the pair contains the visited file name
+ ;; or is empty if the buffer was not visiting a file.
+ ;; The second line is the auto-save file name.
(map-y-or-n-p "Recover %s? "
- (lambda (file) (save-excursion (recover-file file)))
+ (lambda (file)
+ (condition-case nil
+ (save-excursion (recover-file file))
+ (error
+ "Failed to recover `%s'" file)))
(lambda ()
(if (eobp)
nil
(prog1
- (buffer-substring-no-properties
- (point) (progn (end-of-line) (point)))
+ (if (eolp)
+ ;; If the first line of the pair is empty,
+ ;; it means this was a non-file buffer
+ ;; that was autosaved.
+ ;; Make a file name from
+ ;; the auto-save file name.
+ (let ((autofile
+ (buffer-substring-no-properties
+ (save-excursion
+ (forward-line 1)
+ (point))
+ (save-excursion
+ (forward-line 1)
+ (end-of-line)
+ (point)))))
+ (expand-file-name
+ (concat "temp"
+ (substring
+ (file-name-nondirectory autofile)
+ 1 -1))
+ (file-name-directory autofile)))
+ ;; This pair of lines is a file-visiting
+ ;; buffer. Use the visited file name.
+ (buffer-substring-no-properties
+ (point) (progn (end-of-line) (point))))
(while (and (eolp) (not (eobp)))
(forward-line 2)))))
'("file" "files" "recover")))
(terpri)
(save-excursion
(set-buffer "*Directory*")
+ (setq default-directory (file-name-directory dirname))
(let ((wildcard (not (file-directory-p dirname))))
(insert-directory dirname switches wildcard (not wildcard)))))))