comparison lisp/files.el @ 90070:95879cc1ed20

Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-81 Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-748 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-749 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-750 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-751 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-753 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-754 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-755 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-757 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-78 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-79 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-80 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-81 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-82 Update from CVS
author Miles Bader <miles@gnu.org>
date Sun, 02 Jan 2005 09:13:19 +0000
parents fb79180b618d e4a2eb7b1ae5
children f6b4d0ebf147
comparison
equal deleted inserted replaced
90069:fa0a5c4db2c8 90070:95879cc1ed20
271 Includes the new backup. Must be > 0" 271 Includes the new backup. Must be > 0"
272 :type 'integer 272 :type 'integer
273 :group 'backup) 273 :group 'backup)
274 274
275 (defcustom require-final-newline nil 275 (defcustom require-final-newline nil
276 "*Value of t says silently ensure a file ends in a newline when it is saved. 276 "*Whether to add a newline automatically at the end of the file.
277 Non-nil but not t says ask user whether to add a newline when there isn't one. 277
278 nil means don't add newlines." 278 A value of t means do this only when the file is about to be saved.
279 :type '(choice (const :tag "Off" nil) 279 A value of `visit' means do this right after the file is visited.
280 (const :tag "Add" t) 280 A value of `visit-save' means do it at both of those times.
281 Any other non-nil value means ask user whether to add a newline, when saving.
282 nil means don't add newlines.
283
284 Certain major modes set this locally to the value obtained
285 from `mode-require-final-newline'."
286 :type '(choice (const :tag "When visiting" visit)
287 (const :tag "When saving" t)
288 (const :tag "When visiting or saving" visit-save)
289 (const :tag "Never" nil)
281 (other :tag "Ask" ask)) 290 (other :tag "Ask" ask))
282 :group 'editing-basics) 291 :group 'editing-basics)
292
293 (defcustom mode-require-final-newline t
294 "*Whether to add a newline at the end of the file, in certain major modes.
295 Those modes set `require-final-newline' to this value when you enable them.
296 They do so because they are used for files that are supposed
297 to end in newlines, and the question is how to arrange that.
298
299 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.
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."
303 :type '(choice (const :tag "When visiting" visit)
304 (const :tag "When saving" t)
305 (const :tag "When visiting or saving" visit-save)
306 (other :tag "Ask" ask))
307 :group 'editing-basics
308 :version "21.4")
283 309
284 (defcustom auto-save-default t 310 (defcustom auto-save-default t
285 "*Non-nil says by default do auto-saving of every file-visiting buffer." 311 "*Non-nil says by default do auto-saving of every file-visiting buffer."
286 :type 'boolean 312 :type 'boolean
287 :group 'auto-save) 313 :group 'auto-save)
1198 1224
1199 (defun find-buffer-visiting (filename &optional predicate) 1225 (defun find-buffer-visiting (filename &optional predicate)
1200 "Return the buffer visiting file FILENAME (a string). 1226 "Return the buffer visiting file FILENAME (a string).
1201 This is like `get-file-buffer', except that it checks for any buffer 1227 This is like `get-file-buffer', except that it checks for any buffer
1202 visiting the same file, possibly under a different name. 1228 visiting the same file, possibly under a different name.
1203 If PREDICATE is non-nil, only a buffer satisfying it can be returned. 1229 If PREDICATE is non-nil, only buffers satisfying it are eligible,
1230 and others are ignored.
1204 If there is no such live buffer, return nil." 1231 If there is no such live buffer, return nil."
1205 (let ((predicate (or predicate #'identity)) 1232 (let ((predicate (or predicate #'identity))
1206 (truename (abbreviate-file-name (file-truename filename)))) 1233 (truename (abbreviate-file-name (file-truename filename))))
1207 (or (let ((buf (get-file-buffer filename))) 1234 (or (let ((buf (get-file-buffer filename)))
1208 (when (and buf (funcall predicate buf)) buf)) 1235 (when (and buf (funcall predicate buf)) buf))
1624 (setq buffer-read-only t)) 1651 (setq buffer-read-only t))
1625 (unless nomodes 1652 (unless nomodes
1626 (when (and view-read-only view-mode) 1653 (when (and view-read-only view-mode)
1627 (view-mode-disable)) 1654 (view-mode-disable))
1628 (normal-mode t) 1655 (normal-mode t)
1656 ;; If requested, add a newline at the end of the file.
1657 (and (memq require-final-newline '(visit visit-save))
1658 (> (point-max) (point-min))
1659 (/= (char-after (1- (point-max))) ?\n)
1660 (not (and (eq selective-display t)
1661 (= (char-after (1- (point-max))) ?\r)))
1662 (save-excursion
1663 (goto-char (point-max))
1664 (insert "\n")))
1629 (when (and buffer-read-only 1665 (when (and buffer-read-only
1630 view-read-only 1666 view-read-only
1631 (not (eq (get major-mode 'mode-class) 'special))) 1667 (not (eq (get major-mode 'mode-class) 'special)))
1632 (view-mode-enter)) 1668 (view-mode-enter))
1633 (run-hooks 'find-file-hook))) 1669 (run-hooks 'find-file-hook)))
2180 (if buffer-file-name 2216 (if buffer-file-name
2181 (file-name-nondirectory 2217 (file-name-nondirectory
2182 buffer-file-name) 2218 buffer-file-name)
2183 (concat "buffer " 2219 (concat "buffer "
2184 (buffer-name)))))))))) 2220 (buffer-name))))))))))
2185 (let (prefix prefixlen suffix beg 2221 (let (prefix suffix beg
2186 (enable-local-eval enable-local-eval)) 2222 (enable-local-eval enable-local-eval))
2187 ;; The prefix is what comes before "local variables:" in its line. 2223 ;; The prefix is what comes before "local variables:" in its line.
2188 ;; The suffix is what comes after "local variables:" in its line. 2224 ;; The suffix is what comes after "local variables:" in its line.
2189 (skip-chars-forward " \t") 2225 (skip-chars-forward " \t")
2190 (or (eolp) 2226 (or (eolp)
2194 (or (bolp) 2230 (or (bolp)
2195 (setq prefix 2231 (setq prefix
2196 (buffer-substring (point) 2232 (buffer-substring (point)
2197 (progn (beginning-of-line) (point))))) 2233 (progn (beginning-of-line) (point)))))
2198 2234
2199 (if prefix (setq prefixlen (length prefix) 2235 (setq prefix (if prefix (regexp-quote prefix) "^"))
2200 prefix (regexp-quote prefix)))
2201 (if suffix (setq suffix (concat (regexp-quote suffix) "$"))) 2236 (if suffix (setq suffix (concat (regexp-quote suffix) "$")))
2202 (forward-line 1) 2237 (forward-line 1)
2203 (let ((startpos (point)) 2238 (let ((startpos (point))
2204 endpos 2239 endpos
2205 (thisbuf (current-buffer))) 2240 (thisbuf (current-buffer)))
3192 (not find-file-literally) 3227 (not find-file-literally)
3193 (/= (char-after (1- (point-max))) ?\n) 3228 (/= (char-after (1- (point-max))) ?\n)
3194 (not (and (eq selective-display t) 3229 (not (and (eq selective-display t)
3195 (= (char-after (1- (point-max))) ?\r))) 3230 (= (char-after (1- (point-max))) ?\r)))
3196 (or (eq require-final-newline t) 3231 (or (eq require-final-newline t)
3232 (eq require-final-newline 'visit-save)
3197 (and require-final-newline 3233 (and require-final-newline
3198 (y-or-n-p 3234 (y-or-n-p
3199 (format "Buffer %s does not end in newline. Add one? " 3235 (format "Buffer %s does not end in newline. Add one? "
3200 (buffer-name))))) 3236 (buffer-name)))))
3201 (save-excursion 3237 (save-excursion
3236 ;; It returns a value (MODES . BACKUPNAME), like backup-buffer. 3272 ;; It returns a value (MODES . BACKUPNAME), like backup-buffer.
3237 (defun basic-save-buffer-1 () 3273 (defun basic-save-buffer-1 ()
3238 (if save-buffer-coding-system 3274 (if save-buffer-coding-system
3239 (let ((coding-system-for-write save-buffer-coding-system)) 3275 (let ((coding-system-for-write save-buffer-coding-system))
3240 (basic-save-buffer-2)) 3276 (basic-save-buffer-2))
3241 (basic-save-buffer-2))) 3277 (basic-save-buffer-2))
3278 (setq buffer-file-coding-system-explicit last-coding-system-used))
3242 3279
3243 ;; This returns a value (MODES . BACKUPNAME), like backup-buffer. 3280 ;; This returns a value (MODES . BACKUPNAME), like backup-buffer.
3244 (defun basic-save-buffer-2 () 3281 (defun basic-save-buffer-2 ()
3245 (let (tempsetmodes setmodes) 3282 (let (tempsetmodes setmodes)
3246 (if (not (file-writable-p buffer-file-name)) 3283 (if (not (file-writable-p buffer-file-name))
3361 (?d diff-buffer-with-file 3398 (?d diff-buffer-with-file
3362 "show difference to last saved version")) 3399 "show difference to last saved version"))
3363 "ACTION-ALIST argument used in call to `map-y-or-n-p'.") 3400 "ACTION-ALIST argument used in call to `map-y-or-n-p'.")
3364 (put 'save-some-buffers-action-alist 'risky-local-variable t) 3401 (put 'save-some-buffers-action-alist 'risky-local-variable t)
3365 3402
3403 (defvar buffer-save-without-query nil
3404 "Non-nil means `save-some-buffers' should save this buffer without asking.")
3405 (make-variable-buffer-local 'buffer-save-without-query)
3406
3366 (defun save-some-buffers (&optional arg pred) 3407 (defun save-some-buffers (&optional arg pred)
3367 "Save some modified file-visiting buffers. Asks user about each one. 3408 "Save some modified file-visiting buffers. Asks user about each one.
3368 You can answer `y' to save, `n' not to save, `C-r' to look at the 3409 You can answer `y' to save, `n' not to save, `C-r' to look at the
3369 buffer in question with `view-buffer' before deciding or `d' to 3410 buffer in question with `view-buffer' before deciding or `d' to
3370 view the differences using `diff-buffer-to-file'. 3411 view the differences using `diff-buffer-to-file'.
3378 3419
3379 See `save-some-buffers-action-alist' if you want to 3420 See `save-some-buffers-action-alist' if you want to
3380 change the additional actions you can take on files." 3421 change the additional actions you can take on files."
3381 (interactive "P") 3422 (interactive "P")
3382 (save-window-excursion 3423 (save-window-excursion
3383 (let* ((queried nil) 3424 (let* (queried some-automatic
3384 (files-done 3425 files-done abbrevs-done)
3426 (dolist (buffer (buffer-list))
3427 ;; First save any buffers that we're supposed to save unconditionally.
3428 ;; That way the following code won't ask about them.
3429 (with-current-buffer buffer
3430 (when (and buffer-save-without-query (buffer-modified-p))
3431 (setq some-automatic t)
3432 (save-buffer))))
3433 ;; Ask about those buffers that merit it,
3434 ;; and record the number thus saved.
3435 (setq files-done
3385 (map-y-or-n-p 3436 (map-y-or-n-p
3386 (function 3437 (function
3387 (lambda (buffer) 3438 (lambda (buffer)
3388 (and (buffer-modified-p buffer) 3439 (and (buffer-modified-p buffer)
3389 (not (buffer-base-buffer buffer)) 3440 (not (buffer-base-buffer buffer))
3408 (set-buffer buffer) 3459 (set-buffer buffer)
3409 (save-buffer))) 3460 (save-buffer)))
3410 (buffer-list) 3461 (buffer-list)
3411 '("buffer" "buffers" "save") 3462 '("buffer" "buffers" "save")
3412 save-some-buffers-action-alist)) 3463 save-some-buffers-action-alist))
3413 (abbrevs-done 3464 ;; Maybe to save abbrevs, and record whether
3414 (and save-abbrevs abbrevs-changed 3465 ;; we either saved them or asked to.
3415 (progn 3466 (and save-abbrevs abbrevs-changed
3416 (if (or arg 3467 (progn
3417 (eq save-abbrevs 'silently) 3468 (if (or arg
3418 (y-or-n-p (format "Save abbrevs in %s? " 3469 (eq save-abbrevs 'silently)
3419 abbrev-file-name))) 3470 (y-or-n-p (format "Save abbrevs in %s? "
3420 (write-abbrev-file nil)) 3471 abbrev-file-name)))
3421 ;; Don't keep bothering user if he says no. 3472 (write-abbrev-file nil))
3422 (setq abbrevs-changed nil) 3473 ;; Don't keep bothering user if he says no.
3423 t)))) 3474 (setq abbrevs-changed nil)
3475 (setq abbrevs-done t)))
3424 (or queried (> files-done 0) abbrevs-done 3476 (or queried (> files-done 0) abbrevs-done
3425 (message "(No files need saving)"))))) 3477 (message (if some-automatic
3478 "(Some special files were saved without asking)"
3479 "(No files need saving)"))))))
3426 3480
3427 (defun not-modified (&optional arg) 3481 (defun not-modified (&optional arg)
3428 "Mark current buffer as unmodified, not needing to be saved. 3482 "Mark current buffer as unmodified, not needing to be saved.
3429 With prefix arg, mark buffer as modified, so \\[save-buffer] will save. 3483 With prefix arg, mark buffer as modified, so \\[save-buffer] will save.
3430 3484
3689 (let ((buffer-file-name nil)) 3743 (let ((buffer-file-name nil))
3690 (or auto-save-p 3744 (or auto-save-p
3691 (unlock-buffer))) 3745 (unlock-buffer)))
3692 (widen) 3746 (widen)
3693 (let ((coding-system-for-read 3747 (let ((coding-system-for-read
3694 ;; Auto-saved file shoule be read without 3748 ;; Auto-saved file shoule be read by Emacs'
3695 ;; any code conversion. 3749 ;; internal coding.
3696 (if auto-save-p 'utf-8-emacs 3750 (if auto-save-p 'auto-save-coding
3697 (or coding-system-for-read 3751 (or coding-system-for-read
3698 buffer-file-coding-system)))) 3752 buffer-file-coding-system-explicit))))
3699 ;; This force after-insert-file-set-coding 3753 ;; This force after-insert-file-set-coding
3700 ;; (called from insert-file-contents) to set 3754 ;; (called from insert-file-contents) to set
3701 ;; buffer-file-coding-system to a proper value. 3755 ;; buffer-file-coding-system to a proper value.
3702 (kill-local-variable 'buffer-file-coding-system) 3756 (kill-local-variable 'buffer-file-coding-system)
3703 3757
4307 (let ((end (point))) 4361 (let ((end (point)))
4308 (forward-word -1) 4362 (forward-word -1)
4309 (buffer-substring (point) end))))))))) 4363 (buffer-substring (point) end)))))))))
4310 4364
4311 4365
4366 (defvar insert-directory-ls-version 'unknown)
4367
4312 ;; insert-directory 4368 ;; insert-directory
4313 ;; - must insert _exactly_one_line_ describing FILE if WILDCARD and 4369 ;; - must insert _exactly_one_line_ describing FILE if WILDCARD and
4314 ;; FULL-DIRECTORY-P is nil. 4370 ;; FULL-DIRECTORY-P is nil.
4315 ;; The single line of output must display FILE's name as it was 4371 ;; The single line of output must display FILE's name as it was
4316 ;; given, namely, an absolute path name. 4372 ;; given, namely, an absolute path name.
4416 (list 4472 (list
4417 (if full-directory-p 4473 (if full-directory-p
4418 (concat (file-name-as-directory file) ".") 4474 (concat (file-name-as-directory file) ".")
4419 file)))))))) 4475 file))))))))
4420 4476
4477 ;; If we got "//DIRED//" in the output, it means we got a real
4478 ;; directory listing, even if `ls' returned nonzero.
4479 ;; So ignore any errors.
4480 (when (if (stringp switches)
4481 (string-match "--dired\\>" switches)
4482 (member "--dired" switches))
4483 (save-excursion
4484 (forward-line -2)
4485 (when (looking-at "//SUBDIRED//")
4486 (forward-line -1))
4487 (if (looking-at "//DIRED//")
4488 (setq result 0))))
4489
4490 (when (and (not (eq 0 result))
4491 (eq insert-directory-ls-version 'unknown))
4492 ;; The first time ls returns an error,
4493 ;; find the version numbers of ls,
4494 ;; and set insert-directory-ls-version
4495 ;; to > if it is more than 5.2.1, < if it is less, nil if it
4496 ;; is equal or if the info cannot be obtained.
4497 ;; (That can mean it isn't GNU ls.)
4498 (let ((version-out
4499 (with-temp-buffer
4500 (call-process "ls" nil t nil "--version")
4501 (buffer-string))))
4502 (if (string-match "ls (.*utils) \\([0-9.]*\\)$" version-out)
4503 (let* ((version (match-string 1 version-out))
4504 (split (split-string version "[.]"))
4505 (numbers (mapcar 'string-to-int split))
4506 (min '(5 2 1))
4507 comparison)
4508 (while (and (not comparison) (or numbers min))
4509 (cond ((null min)
4510 (setq comparison '>))
4511 ((null numbers)
4512 (setq comparison '<))
4513 ((> (car numbers) (car min))
4514 (setq comparison '>))
4515 ((< (car numbers) (car min))
4516 (setq comparison '<))
4517 (t
4518 (setq numbers (cdr numbers)
4519 min (cdr min)))))
4520 (setq insert-directory-ls-version (or comparison '=)))
4521 (setq insert-directory-ls-version nil))))
4522
4523 ;; For GNU ls versions 5.2.2 and up, ignore minor errors.
4524 (when (and (eq 1 result) (eq insert-directory-ls-version '>))
4525 (setq result 0))
4526
4421 ;; If `insert-directory-program' failed, signal an error. 4527 ;; If `insert-directory-program' failed, signal an error.
4422 (unless (eq 0 result) 4528 (unless (eq 0 result)
4423 ;; Delete the error message it may have output. 4529 ;; Delete the error message it may have output.
4424 (delete-region beg (point)) 4530 (delete-region beg (point))
4425 ;; On non-Posix systems, we cannot open a directory, so 4531 ;; On non-Posix systems, we cannot open a directory, so
4442 (member "--dired" switches)) 4548 (member "--dired" switches))
4443 (forward-line -2) 4549 (forward-line -2)
4444 (when (looking-at "//SUBDIRED//") 4550 (when (looking-at "//SUBDIRED//")
4445 (delete-region (point) (progn (forward-line 1) (point))) 4551 (delete-region (point) (progn (forward-line 1) (point)))
4446 (forward-line -1)) 4552 (forward-line -1))
4447 (if (looking-at "//DIRED//") 4553 (when (looking-at "//DIRED//")
4448 (let ((end (line-end-position))) 4554 (let ((end (line-end-position))
4449 (forward-word 1) 4555 (linebeg (point))
4450 (forward-char 3) 4556 error-lines)
4451 (while (< (point) end) 4557 ;; Find all the lines that are error messages,
4452 (let ((start (+ beg (read (current-buffer)))) 4558 ;; and record the bounds of each one.
4453 (end (+ beg (read (current-buffer))))) 4559 (goto-char (point-min))
4454 (if (memq (char-after end) '(?\n ?\ )) 4560 (while (< (point) linebeg)
4455 ;; End is followed by \n or by " -> ". 4561 (or (eql (following-char) ?\s)
4456 (put-text-property start end 'dired-filename t) 4562 (push (list (point) (line-end-position)) error-lines))
4457 ;; It seems that we can't trust ls's output as to 4563 (forward-line 1))
4458 ;; byte positions of filenames. 4564 (setq error-lines (nreverse error-lines))
4459 (put-text-property beg (point) 'dired-filename nil) 4565 ;; Now read the numeric positions of file names.
4460 (end-of-line)))) 4566 (goto-char linebeg)
4461 (goto-char end) 4567 (forward-word 1)
4462 (beginning-of-line) 4568 (forward-char 3)
4463 (delete-region (point) (progn (forward-line 2) (point)))) 4569 (while (< (point) end)
4570 (let ((start (insert-directory-adj-pos
4571 (+ beg (read (current-buffer)))
4572 error-lines))
4573 (end (insert-directory-adj-pos
4574 (+ beg (read (current-buffer)))
4575 error-lines)))
4576 (if (memq (char-after end) '(?\n ?\ ))
4577 ;; End is followed by \n or by " -> ".
4578 (put-text-property start end 'dired-filename t)
4579 ;; It seems that we can't trust ls's output as to
4580 ;; byte positions of filenames.
4581 (put-text-property beg (point) 'dired-filename nil)
4582 (end-of-line))))
4583 (goto-char end)
4584 (beginning-of-line)
4585 (delete-region (point) (progn (forward-line 2) (point))))
4464 (forward-line 1) 4586 (forward-line 1)
4465 (if (looking-at "//DIRED-OPTIONS//") 4587 (if (looking-at "//DIRED-OPTIONS//")
4466 (delete-region (point) (progn (forward-line 1) (point))) 4588 (delete-region (point) (progn (forward-line 1) (point)))
4467 (forward-line 1)))) 4589 (forward-line 1))))
4468 4590
4509 (when available 4631 (when available
4510 ;; Replace "total" with "used", to avoid confusion. 4632 ;; Replace "total" with "used", to avoid confusion.
4511 (replace-match "total used in directory" nil nil nil 1) 4633 (replace-match "total used in directory" nil nil nil 1)
4512 (end-of-line) 4634 (end-of-line)
4513 (insert " available " available))))))))))) 4635 (insert " available " available)))))))))))
4636
4637 (defun insert-directory-adj-pos (pos error-lines)
4638 "Convert `ls --dired' file name position value POS to a buffer position.
4639 File name position values returned in ls --dired output
4640 count only stdout; they don't count the error messages sent to stderr.
4641 So this function converts to them to real buffer positions.
4642 ERROR-LINES is a list of buffer positions of error message lines,
4643 of the form (START END)."
4644 (while (and error-lines (< (caar error-lines) pos))
4645 (setq pos (+ pos (- (nth 1 (car error-lines)) (nth 0 (car error-lines)))))
4646 (pop error-lines))
4647 pos)
4514 4648
4515 (defun insert-directory-safely (file switches 4649 (defun insert-directory-safely (file switches
4516 &optional wildcard full-directory-p) 4650 &optional wildcard full-directory-p)
4517 "Insert directory listing for FILE, formatted according to SWITCHES. 4651 "Insert directory listing for FILE, formatted according to SWITCHES.
4518 4652