diff options
| author | Richard M. Stallman | 2005-04-23 16:53:21 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2005-04-23 16:53:21 +0000 |
| commit | 44dce0fb4351151515b608e06f8a8b3e9df45019 (patch) | |
| tree | 66400b83ef6794390c77f0f3d17794b2db418caf | |
| parent | 2a4b921193df1594ab2ba05080d779e78abf6bd8 (diff) | |
| download | emacs-44dce0fb4351151515b608e06f8a8b3e9df45019.tar.gz emacs-44dce0fb4351151515b608e06f8a8b3e9df45019.zip | |
(read-directory-name): Always pass non-nil
DEFAULT-FILENAME arg to read-file-name.
(backup-buffer-copy, basic-save-buffer-2): Take care against
writing thru an unexpected existing symlink.
(revert-buffer): In indirect buffer, revert the base buffer.
(magic-mode-alist): Doc fix.
(buffer-stale-function): Doc fix.
(minibuffer-with-setup-hook): Avoid warning.
(mode-require-final-newline): Doc and custom fix.
| -rw-r--r-- | lisp/files.el | 310 |
1 files changed, 167 insertions, 143 deletions
diff --git a/lisp/files.el b/lisp/files.el index 407922082f1..1186a5fb8b4 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -300,16 +300,15 @@ A value of t means do this only when the file is about to be saved. | |||
| 300 | A value of `visit' means do this right after the file is visited. | 300 | A value of `visit' means do this right after the file is visited. |
| 301 | A value of `visit-save' means do it at both of those times. | 301 | A value of `visit-save' means do it at both of those times. |
| 302 | Any other non-nil value means ask user whether to add a newline, when saving. | 302 | Any other non-nil value means ask user whether to add a newline, when saving. |
| 303 | nil means don't add newlines. | 303 | nil means do not add newlines when saving. |
| 304 | 304 | ||
| 305 | You will have to be careful if you set this to nil: you will have | 305 | If you set this to nil, you must careful to manually add a final newline |
| 306 | to remember to manually add a final newline whenever you finish a | 306 | whenever you save a file that really needs one." |
| 307 | file that really needs one." | ||
| 308 | :type '(choice (const :tag "When visiting" visit) | 307 | :type '(choice (const :tag "When visiting" visit) |
| 309 | (const :tag "When saving" t) | 308 | (const :tag "When saving" t) |
| 310 | (const :tag "When visiting or saving" visit-save) | 309 | (const :tag "When visiting or saving" visit-save) |
| 311 | (const :tag "Never" nil) | 310 | (other :tag "Ask" ask) |
| 312 | (other :tag "Ask" ask)) | 311 | (const :tag "Don't add newlines" nil)) |
| 313 | :group 'editing-basics | 312 | :group 'editing-basics |
| 314 | :version "22.1") | 313 | :version "22.1") |
| 315 | 314 | ||
| @@ -529,8 +528,8 @@ See Info node `(elisp)Standard File Names' for more details." | |||
| 529 | Value is not expanded---you must call `expand-file-name' yourself. | 528 | Value is not expanded---you must call `expand-file-name' yourself. |
| 530 | Default name to DEFAULT-DIRNAME if user exits with the same | 529 | Default name to DEFAULT-DIRNAME if user exits with the same |
| 531 | non-empty string that was inserted by this function. | 530 | non-empty string that was inserted by this function. |
| 532 | (If DEFAULT-DIRNAME is omitted, the current buffer's directory is used, | 531 | (If DEFAULT-DIRNAME is omitted, DIR combined with INITIAL is used, |
| 533 | except that if INITIAL is specified, that combined with DIR is used.) | 532 | or just DIR if INITIAL is nil.) |
| 534 | If the user exits with an empty minibuffer, this function returns | 533 | If the user exits with an empty minibuffer, this function returns |
| 535 | an empty string. (This can only happen if the user erased the | 534 | an empty string. (This can only happen if the user erased the |
| 536 | pre-inserted contents or if `insert-default-directory' is nil.) | 535 | pre-inserted contents or if `insert-default-directory' is nil.) |
| @@ -544,7 +543,10 @@ the value of `default-directory'." | |||
| 544 | (unless default-dirname | 543 | (unless default-dirname |
| 545 | (setq default-dirname | 544 | (setq default-dirname |
| 546 | (if initial (concat dir initial) default-directory))) | 545 | (if initial (concat dir initial) default-directory))) |
| 547 | (read-file-name prompt dir default-dirname mustmatch initial | 546 | (read-file-name prompt dir (or default-dirname |
| 547 | (if initial (expand-file-name initial dir) | ||
| 548 | dir)) | ||
| 549 | mustmatch initial | ||
| 548 | 'file-directory-p)) | 550 | 'file-directory-p)) |
| 549 | 551 | ||
| 550 | 552 | ||
| @@ -940,12 +942,13 @@ BODY should use the minibuffer at most once. | |||
| 940 | Recursive uses of the minibuffer will not be affected." | 942 | Recursive uses of the minibuffer will not be affected." |
| 941 | (declare (indent 1) (debug t)) | 943 | (declare (indent 1) (debug t)) |
| 942 | (let ((hook (make-symbol "setup-hook"))) | 944 | (let ((hook (make-symbol "setup-hook"))) |
| 943 | `(let ((,hook | 945 | `(let (,hook) |
| 944 | (lambda () | 946 | (setq ,hook |
| 945 | ;; Clear out this hook so it does not interfere | 947 | (lambda () |
| 946 | ;; with any recursive minibuffer usage. | 948 | ;; Clear out this hook so it does not interfere |
| 947 | (remove-hook 'minibuffer-setup-hook ,hook) | 949 | ;; with any recursive minibuffer usage. |
| 948 | (,fun)))) | 950 | (remove-hook 'minibuffer-setup-hook ,hook) |
| 951 | (,fun))) | ||
| 949 | (unwind-protect | 952 | (unwind-protect |
| 950 | (progn | 953 | (progn |
| 951 | (add-hook 'minibuffer-setup-hook ,hook) | 954 | (add-hook 'minibuffer-setup-hook ,hook) |
| @@ -1973,8 +1976,13 @@ with that interpreter in `interpreter-mode-alist'.") | |||
| 1973 | ("%![^V]" . ps-mode) | 1976 | ("%![^V]" . ps-mode) |
| 1974 | ("# xmcd " . conf-unix-mode)) | 1977 | ("# xmcd " . conf-unix-mode)) |
| 1975 | "Alist of buffer beginnings vs. corresponding major mode functions. | 1978 | "Alist of buffer beginnings vs. corresponding major mode functions. |
| 1976 | Each element looks like (REGEXP . FUNCTION). FUNCTION will be | 1979 | Each element looks like (REGEXP . FUNCTION). After visiting a file, |
| 1977 | called, unless it is nil (to allow `auto-mode-alist' to override).") | 1980 | if REGEXP matches the text at the beginning of the buffer, |
| 1981 | `normal-mode' will call FUNCTION rather than allowing `auto-mode-alist' | ||
| 1982 | to decide the buffer's major mode. | ||
| 1983 | |||
| 1984 | If FUNCTION is nil, then it is not called. (That is a way of saying | ||
| 1985 | \"allow `auto-mode-alist' to decide for these files.") | ||
| 1978 | 1986 | ||
| 1979 | (defun set-auto-mode (&optional keep-mode-if-same) | 1987 | (defun set-auto-mode (&optional keep-mode-if-same) |
| 1980 | "Select major mode appropriate for current buffer. | 1988 | "Select major mode appropriate for current buffer. |
| @@ -2740,15 +2748,27 @@ BACKUPNAME is the backup file name, which is the old file renamed." | |||
| 2740 | (file-error nil)))))) | 2748 | (file-error nil)))))) |
| 2741 | 2749 | ||
| 2742 | (defun backup-buffer-copy (from-name to-name modes) | 2750 | (defun backup-buffer-copy (from-name to-name modes) |
| 2743 | (condition-case () | 2751 | (let ((umask (default-file-modes))) |
| 2744 | (copy-file from-name to-name t t) | 2752 | (unwind-protect |
| 2745 | (file-error | 2753 | (progn |
| 2746 | ;; If copying fails because file TO-NAME | 2754 | ;; Create temp files with strict access rights. It's easy to |
| 2747 | ;; is not writable, delete that file and try again. | 2755 | ;; loosen them later, whereas it's impossible to close the |
| 2748 | (if (and (file-exists-p to-name) | 2756 | ;; time-window of loose permissions otherwise. |
| 2749 | (not (file-writable-p to-name))) | 2757 | (set-default-file-modes ?\700) |
| 2750 | (delete-file to-name)) | 2758 | (while (condition-case () |
| 2751 | (copy-file from-name to-name t t))) | 2759 | (progn |
| 2760 | (condition-case nil | ||
| 2761 | (delete-file to-name) | ||
| 2762 | (file-error nil)) | ||
| 2763 | (write-region "" nil to-name nil 'silent nil 'excl) | ||
| 2764 | nil) | ||
| 2765 | (file-already-exists t)) | ||
| 2766 | ;; the file was somehow created by someone else between | ||
| 2767 | ;; `make-temp-name' and `write-region', let's try again. | ||
| 2768 | nil) | ||
| 2769 | (copy-file from-name to-name t t 'excl)) | ||
| 2770 | ;; Reset the umask. | ||
| 2771 | (set-default-file-modes umask))) | ||
| 2752 | (and modes | 2772 | (and modes |
| 2753 | (set-file-modes to-name (logand modes #o1777)))) | 2773 | (set-file-modes to-name (logand modes #o1777)))) |
| 2754 | 2774 | ||
| @@ -3331,39 +3351,41 @@ Before and after saving the buffer, this function runs | |||
| 3331 | ;; This requires write access to the containing dir, | 3351 | ;; This requires write access to the containing dir, |
| 3332 | ;; which is why we don't try it if we don't have that access. | 3352 | ;; which is why we don't try it if we don't have that access. |
| 3333 | (let ((realname buffer-file-name) | 3353 | (let ((realname buffer-file-name) |
| 3334 | tempname nogood i succeed | 3354 | tempname succeed |
| 3355 | (umask (default-file-modes)) | ||
| 3335 | (old-modtime (visited-file-modtime))) | 3356 | (old-modtime (visited-file-modtime))) |
| 3336 | (setq i 0) | 3357 | ;; Create temp files with strict access rights. It's easy to |
| 3337 | (setq nogood t) | 3358 | ;; loosen them later, whereas it's impossible to close the |
| 3338 | ;; Find the temporary name to write under. | 3359 | ;; time-window of loose permissions otherwise. |
| 3339 | (while nogood | ||
| 3340 | (setq tempname (format | ||
| 3341 | (if (and (eq system-type 'ms-dos) | ||
| 3342 | (not (msdos-long-file-names))) | ||
| 3343 | "%s#%d.tm#" ; MSDOS limits files to 8+3 | ||
| 3344 | (if (memq system-type '(vax-vms axp-vms)) | ||
| 3345 | "%s$tmp$%d" | ||
| 3346 | "%s#tmp#%d")) | ||
| 3347 | dir i)) | ||
| 3348 | (setq nogood (file-exists-p tempname)) | ||
| 3349 | (setq i (1+ i))) | ||
| 3350 | (unwind-protect | 3360 | (unwind-protect |
| 3351 | (progn (clear-visited-file-modtime) | 3361 | (progn |
| 3352 | (write-region (point-min) (point-max) | 3362 | (clear-visited-file-modtime) |
| 3353 | tempname nil realname | 3363 | (set-default-file-modes ?\700) |
| 3354 | buffer-file-truename) | 3364 | ;; Try various temporary names. |
| 3355 | (setq succeed t)) | 3365 | ;; This code follows the example of make-temp-file, |
| 3356 | ;; If writing the temp file fails, | 3366 | ;; but it calls write-region in the appropriate way |
| 3357 | ;; delete the temp file. | 3367 | ;; for saving the buffer. |
| 3358 | (or succeed | 3368 | (while (condition-case () |
| 3359 | (progn | 3369 | (progn |
| 3360 | (condition-case nil | 3370 | (setq tempname |
| 3361 | (delete-file tempname) | 3371 | (make-temp-name |
| 3362 | (file-error nil)) | 3372 | (expand-file-name "tmp" dir))) |
| 3363 | (set-visited-file-modtime old-modtime)))) | 3373 | (write-region (point-min) (point-max) |
| 3364 | ;; Since we have created an entirely new file | 3374 | tempname nil realname |
| 3365 | ;; and renamed it, make sure it gets the | 3375 | buffer-file-truename 'excl) |
| 3366 | ;; right permission bits set. | 3376 | nil) |
| 3377 | (file-already-exists t)) | ||
| 3378 | ;; The file was somehow created by someone else between | ||
| 3379 | ;; `make-temp-name' and `write-region', let's try again. | ||
| 3380 | nil) | ||
| 3381 | (setq succeed t)) | ||
| 3382 | ;; Reset the umask. | ||
| 3383 | (set-default-file-modes umask) | ||
| 3384 | ;; If we failed, restore the buffer's modtime. | ||
| 3385 | (unless succeed | ||
| 3386 | (set-visited-file-modtime old-modtime))) | ||
| 3387 | ;; Since we have created an entirely new file, | ||
| 3388 | ;; make sure it gets the right permission bits set. | ||
| 3367 | (setq setmodes (or setmodes (cons (file-modes buffer-file-name) | 3389 | (setq setmodes (or setmodes (cons (file-modes buffer-file-name) |
| 3368 | buffer-file-name))) | 3390 | buffer-file-name))) |
| 3369 | ;; We succeeded in writing the temp file, | 3391 | ;; We succeeded in writing the temp file, |
| @@ -3649,7 +3671,7 @@ The function you specify is responsible for updating (or preserving) point.") | |||
| 3649 | (defvar buffer-stale-function nil | 3671 | (defvar buffer-stale-function nil |
| 3650 | "Function to check whether a non-file buffer needs reverting. | 3672 | "Function to check whether a non-file buffer needs reverting. |
| 3651 | This should be a function with one optional argument NOCONFIRM. | 3673 | This should be a function with one optional argument NOCONFIRM. |
| 3652 | Auto Revert Mode sets NOCONFIRM to t. The function should return | 3674 | Auto Revert Mode passes t for NOCONFIRM. The function should return |
| 3653 | non-nil if the buffer should be reverted. A return value of | 3675 | non-nil if the buffer should be reverted. A return value of |
| 3654 | `fast' means that the need for reverting was not checked, but | 3676 | `fast' means that the need for reverting was not checked, but |
| 3655 | that reverting the buffer is fast. The buffer is current when | 3677 | that reverting the buffer is fast. The buffer is current when |
| @@ -3718,91 +3740,93 @@ non-nil, it is called instead of rereading visited file contents." | |||
| 3718 | (interactive (list (not current-prefix-arg))) | 3740 | (interactive (list (not current-prefix-arg))) |
| 3719 | (if revert-buffer-function | 3741 | (if revert-buffer-function |
| 3720 | (funcall revert-buffer-function ignore-auto noconfirm) | 3742 | (funcall revert-buffer-function ignore-auto noconfirm) |
| 3721 | (let* ((auto-save-p (and (not ignore-auto) | 3743 | (with-current-buffer (or (buffer-base-buffer (current-buffer)) |
| 3722 | (recent-auto-save-p) | 3744 | (current-buffer)) |
| 3723 | buffer-auto-save-file-name | 3745 | (let* ((auto-save-p (and (not ignore-auto) |
| 3724 | (file-readable-p buffer-auto-save-file-name) | 3746 | (recent-auto-save-p) |
| 3725 | (y-or-n-p | 3747 | buffer-auto-save-file-name |
| 3726 | "Buffer has been auto-saved recently. Revert from auto-save file? "))) | 3748 | (file-readable-p buffer-auto-save-file-name) |
| 3727 | (file-name (if auto-save-p | 3749 | (y-or-n-p |
| 3728 | buffer-auto-save-file-name | 3750 | "Buffer has been auto-saved recently. Revert from auto-save file? "))) |
| 3729 | buffer-file-name))) | 3751 | (file-name (if auto-save-p |
| 3730 | (cond ((null file-name) | 3752 | buffer-auto-save-file-name |
| 3731 | (error "Buffer does not seem to be associated with any file")) | 3753 | buffer-file-name))) |
| 3732 | ((or noconfirm | 3754 | (cond ((null file-name) |
| 3733 | (and (not (buffer-modified-p)) | 3755 | (error "Buffer does not seem to be associated with any file")) |
| 3734 | (let ((tail revert-without-query) | 3756 | ((or noconfirm |
| 3735 | (found nil)) | 3757 | (and (not (buffer-modified-p)) |
| 3736 | (while tail | 3758 | (let ((tail revert-without-query) |
| 3737 | (if (string-match (car tail) file-name) | 3759 | (found nil)) |
| 3738 | (setq found t)) | 3760 | (while tail |
| 3739 | (setq tail (cdr tail))) | 3761 | (if (string-match (car tail) file-name) |
| 3740 | found)) | 3762 | (setq found t)) |
| 3741 | (yes-or-no-p (format "Revert buffer from file %s? " | 3763 | (setq tail (cdr tail))) |
| 3742 | file-name))) | 3764 | found)) |
| 3743 | (run-hooks 'before-revert-hook) | 3765 | (yes-or-no-p (format "Revert buffer from file %s? " |
| 3744 | ;; If file was backed up but has changed since, | 3766 | file-name))) |
| 3745 | ;; we shd make another backup. | 3767 | (run-hooks 'before-revert-hook) |
| 3746 | (and (not auto-save-p) | 3768 | ;; If file was backed up but has changed since, |
| 3747 | (not (verify-visited-file-modtime (current-buffer))) | 3769 | ;; we shd make another backup. |
| 3748 | (setq buffer-backed-up nil)) | 3770 | (and (not auto-save-p) |
| 3749 | ;; Get rid of all undo records for this buffer. | 3771 | (not (verify-visited-file-modtime (current-buffer))) |
| 3750 | (or (eq buffer-undo-list t) | 3772 | (setq buffer-backed-up nil)) |
| 3751 | (setq buffer-undo-list nil)) | 3773 | ;; Get rid of all undo records for this buffer. |
| 3752 | ;; Effectively copy the after-revert-hook status, | 3774 | (or (eq buffer-undo-list t) |
| 3753 | ;; since after-find-file will clobber it. | 3775 | (setq buffer-undo-list nil)) |
| 3754 | (let ((global-hook (default-value 'after-revert-hook)) | 3776 | ;; Effectively copy the after-revert-hook status, |
| 3755 | (local-hook-p (local-variable-p 'after-revert-hook)) | 3777 | ;; since after-find-file will clobber it. |
| 3756 | (local-hook (and (local-variable-p 'after-revert-hook) | 3778 | (let ((global-hook (default-value 'after-revert-hook)) |
| 3757 | after-revert-hook))) | 3779 | (local-hook-p (local-variable-p 'after-revert-hook)) |
| 3758 | (let (buffer-read-only | 3780 | (local-hook (and (local-variable-p 'after-revert-hook) |
| 3759 | ;; Don't make undo records for the reversion. | 3781 | after-revert-hook))) |
| 3760 | (buffer-undo-list t)) | 3782 | (let (buffer-read-only |
| 3761 | (if revert-buffer-insert-file-contents-function | 3783 | ;; Don't make undo records for the reversion. |
| 3762 | (funcall revert-buffer-insert-file-contents-function | 3784 | (buffer-undo-list t)) |
| 3763 | file-name auto-save-p) | 3785 | (if revert-buffer-insert-file-contents-function |
| 3764 | (if (not (file-exists-p file-name)) | 3786 | (funcall revert-buffer-insert-file-contents-function |
| 3765 | (error (if buffer-file-number | 3787 | file-name auto-save-p) |
| 3766 | "File %s no longer exists!" | 3788 | (if (not (file-exists-p file-name)) |
| 3767 | "Cannot revert nonexistent file %s") | 3789 | (error (if buffer-file-number |
| 3768 | file-name)) | 3790 | "File %s no longer exists!" |
| 3769 | ;; Bind buffer-file-name to nil | 3791 | "Cannot revert nonexistent file %s") |
| 3770 | ;; so that we don't try to lock the file. | 3792 | file-name)) |
| 3771 | (let ((buffer-file-name nil)) | 3793 | ;; Bind buffer-file-name to nil |
| 3772 | (or auto-save-p | 3794 | ;; so that we don't try to lock the file. |
| 3773 | (unlock-buffer))) | 3795 | (let ((buffer-file-name nil)) |
| 3774 | (widen) | 3796 | (or auto-save-p |
| 3775 | (let ((coding-system-for-read | 3797 | (unlock-buffer))) |
| 3776 | ;; Auto-saved file shoule be read by Emacs' | 3798 | (widen) |
| 3777 | ;; internal coding. | 3799 | (let ((coding-system-for-read |
| 3778 | (if auto-save-p 'auto-save-coding | 3800 | ;; Auto-saved file shoule be read by Emacs' |
| 3779 | (or coding-system-for-read | 3801 | ;; internal coding. |
| 3780 | buffer-file-coding-system-explicit)))) | 3802 | (if auto-save-p 'auto-save-coding |
| 3781 | ;; This force after-insert-file-set-coding | 3803 | (or coding-system-for-read |
| 3782 | ;; (called from insert-file-contents) to set | 3804 | buffer-file-coding-system-explicit)))) |
| 3783 | ;; buffer-file-coding-system to a proper value. | 3805 | ;; This force after-insert-file-set-coding |
| 3784 | (kill-local-variable 'buffer-file-coding-system) | 3806 | ;; (called from insert-file-contents) to set |
| 3785 | 3807 | ;; buffer-file-coding-system to a proper value. | |
| 3786 | ;; Note that this preserves point in an intelligent way. | 3808 | (kill-local-variable 'buffer-file-coding-system) |
| 3787 | (if preserve-modes | 3809 | |
| 3788 | (let ((buffer-file-format buffer-file-format)) | 3810 | ;; Note that this preserves point in an intelligent way. |
| 3789 | (insert-file-contents file-name (not auto-save-p) | 3811 | (if preserve-modes |
| 3790 | nil nil t)) | 3812 | (let ((buffer-file-format buffer-file-format)) |
| 3791 | (insert-file-contents file-name (not auto-save-p) | 3813 | (insert-file-contents file-name (not auto-save-p) |
| 3792 | nil nil t))))) | 3814 | nil nil t)) |
| 3793 | ;; Recompute the truename in case changes in symlinks | 3815 | (insert-file-contents file-name (not auto-save-p) |
| 3794 | ;; have changed the truename. | 3816 | nil nil t))))) |
| 3795 | (setq buffer-file-truename | 3817 | ;; Recompute the truename in case changes in symlinks |
| 3796 | (abbreviate-file-name (file-truename buffer-file-name))) | 3818 | ;; have changed the truename. |
| 3797 | (after-find-file nil nil t t preserve-modes) | 3819 | (setq buffer-file-truename |
| 3798 | ;; Run after-revert-hook as it was before we reverted. | 3820 | (abbreviate-file-name (file-truename buffer-file-name))) |
| 3799 | (setq-default revert-buffer-internal-hook global-hook) | 3821 | (after-find-file nil nil t t preserve-modes) |
| 3800 | (if local-hook-p | 3822 | ;; Run after-revert-hook as it was before we reverted. |
| 3801 | (set (make-local-variable 'revert-buffer-internal-hook) | 3823 | (setq-default revert-buffer-internal-hook global-hook) |
| 3802 | local-hook) | 3824 | (if local-hook-p |
| 3803 | (kill-local-variable 'revert-buffer-internal-hook)) | 3825 | (set (make-local-variable 'revert-buffer-internal-hook) |
| 3804 | (run-hooks 'revert-buffer-internal-hook)) | 3826 | local-hook) |
| 3805 | t))))) | 3827 | (kill-local-variable 'revert-buffer-internal-hook)) |
| 3828 | (run-hooks 'revert-buffer-internal-hook)) | ||
| 3829 | t)))))) | ||
| 3806 | 3830 | ||
| 3807 | (defun recover-this-file () | 3831 | (defun recover-this-file () |
| 3808 | "Recover the visited file--get contents from its last auto-save file." | 3832 | "Recover the visited file--get contents from its last auto-save file." |