aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2013-01-25 14:15:22 +0100
committerMichael Albinus2013-01-25 14:15:22 +0100
commitef3544f6a6cd1cea6a415d58e39d3a4bebd450f5 (patch)
tree3d536f0b5c1dab62369ccf06a31b0717e435f714
parent69bb66c12e42e8196cdf440b83e367635f901bff (diff)
downloademacs-ef3544f6a6cd1cea6a415d58e39d3a4bebd450f5.tar.gz
emacs-ef3544f6a6cd1cea6a415d58e39d3a4bebd450f5.zip
* autorevert.el (auto-revert-remote-files)
(auto-revert-notify-exclude-dir-regexp): New defcustoms. (auto-revert-notify-enabled, auto-revert-use-notify) (auto-revert-notify-watch-descriptor-hash-list) (auto-revert-notify-modified-p, auto-revert-notify-event-p) (auto-revert-notify-event-descriptor) (auto-revert-notify-event-action) (auto-revert-notify-event-file-name): Doc fix. (global-auto-revert-mode): Reorder checks. (auto-revert-notify-rm-watch): Respect changed values of `auto-revert-notify-watch-descriptor-hash-list'. (auto-revert-notify-add-watch): Check for `auto-revert-notify-exclude-dir-regexp'. Adapt filters for `inotify-add-watch'. Watch `default-directory' instead of `buffer-file-name'. `auto-revert-notify-watch-descriptor-hash-list' has a changed meaning now. (Bug#13540) (auto-revert-notify-handler): Change implementation wrt events returning from a directory. (auto-revert-handler): Reorder implementation for checks of remote files. (auto-revert-buffers): Fix parentheses error.
-rw-r--r--lisp/ChangeLog24
-rw-r--r--lisp/autorevert.el178
2 files changed, 138 insertions, 64 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1fc7b5d49ce..7c600ca7e6f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,27 @@
12013-01-25 Michael Albinus <michael.albinus@gmx.de>
2
3 * autorevert.el (auto-revert-remote-files)
4 (auto-revert-notify-exclude-dir-regexp): New defcustoms.
5 (auto-revert-notify-enabled, auto-revert-use-notify)
6 (auto-revert-notify-watch-descriptor-hash-list)
7 (auto-revert-notify-modified-p, auto-revert-notify-event-p)
8 (auto-revert-notify-event-descriptor)
9 (auto-revert-notify-event-action)
10 (auto-revert-notify-event-file-name): Doc fix.
11 (global-auto-revert-mode): Reorder checks.
12 (auto-revert-notify-rm-watch): Respect changed values of
13 `auto-revert-notify-watch-descriptor-hash-list'.
14 (auto-revert-notify-add-watch): Check for
15 `auto-revert-notify-exclude-dir-regexp'. Adapt filters for
16 `inotify-add-watch'. Watch `default-directory' instead of
17 `buffer-file-name'. `auto-revert-notify-watch-descriptor-hash-list'
18 has a changed meaning now. (Bug#13540)
19 (auto-revert-notify-handler): Change implementation wrt events
20 returning from a directory.
21 (auto-revert-handler): Reorder implementation for checks of remote
22 files.
23 (auto-revert-buffers): Fix parentheses error.
24
12013-01-25 Fabián Ezequiel Gallina <fgallina@cuca> 252013-01-25 Fabián Ezequiel Gallina <fgallina@cuca>
2 26
3 * progmodes/python.el: Enhancements to header documentation about 27 * progmodes/python.el: Enhancements to header documentation about
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 1b5460ff2cf..25a953e1719 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -39,8 +39,11 @@
39;; Auto-Revert Mode applies to all file buffers. (If the user option 39;; Auto-Revert Mode applies to all file buffers. (If the user option
40;; `global-auto-revert-non-file-buffers' is non-nil, it also applies 40;; `global-auto-revert-non-file-buffers' is non-nil, it also applies
41;; to some non-file buffers. This option is disabled by default.) 41;; to some non-file buffers. This option is disabled by default.)
42;; Since checking a remote file is too slow, these modes do not check 42;;
43;; or revert remote files. 43;; Since checking a remote file is slow, these modes check or revert
44;; remote files only if the user option `auto-revert-remote-files' is
45;; non-nil. It is recommended to disable version control for remote
46;; files.
44;; 47;;
45;; Both modes operate by checking the time stamp of all files at 48;; Both modes operate by checking the time stamp of all files at
46;; intervals of `auto-revert-interval'. The default is every five 49;; intervals of `auto-revert-interval'. The default is every five
@@ -48,10 +51,12 @@
48;; Emacs. You should never even notice that this package is active 51;; Emacs. You should never even notice that this package is active
49;; (except that your buffers will be reverted, of course). 52;; (except that your buffers will be reverted, of course).
50;; 53;;
51;; If Emacs is compiled with file watch support, notifications are 54;; If Emacs is compiled with file notification support, notifications
52;; used instead of checking the time stamp of the files. You can 55;; are used instead of checking the time stamp of the files. You can
53;; disable this by setting the user option `auto-revert-use-notify' to 56;; disable this by setting the user option `auto-revert-use-notify' to
54;; nil. 57;; nil. Alternatively, a regular expression of directories to be
58;; excluded from file notifications can be specified by
59;; `auto-revert-notify-exclude-dir-regexp'.
55;; 60;;
56;; After reverting a file buffer, Auto Revert Mode normally puts point 61;; After reverting a file buffer, Auto Revert Mode normally puts point
57;; at the same position that a regular manual revert would. However, 62;; at the same position that a regular manual revert would. However,
@@ -70,7 +75,6 @@
70;; change by growing at the end. It only appends the new output, 75;; change by growing at the end. It only appends the new output,
71;; instead of reverting the entire buffer. It does so even if the 76;; instead of reverting the entire buffer. It does so even if the
72;; buffer contains unsaved changes. (Because they will not be lost.) 77;; buffer contains unsaved changes. (Because they will not be lost.)
73;; Auto Revert Tail Mode works also for remote files.
74 78
75;; Usage: 79;; Usage:
76;; 80;;
@@ -260,15 +264,21 @@ buffers. CPU usage depends on the version control system."
260This variable becomes buffer local when set in any fashion.") 264This variable becomes buffer local when set in any fashion.")
261(make-variable-buffer-local 'global-auto-revert-ignore-buffer) 265(make-variable-buffer-local 'global-auto-revert-ignore-buffer)
262 266
267(defcustom auto-revert-remote-files nil
268 "If non-nil remote files are also reverted."
269 :group 'auto-revert
270 :type 'boolean
271 :version "24.4")
272
263(defconst auto-revert-notify-enabled 273(defconst auto-revert-notify-enabled
264 (or (featurep 'inotify) (featurep 'w32notify)) 274 (or (featurep 'inotify) (featurep 'w32notify))
265 "Non-nil when Emacs has been compiled with file watch support.") 275 "Non-nil when Emacs has been compiled with file notification support.")
266 276
267(defcustom auto-revert-use-notify auto-revert-notify-enabled 277(defcustom auto-revert-use-notify auto-revert-notify-enabled
268 "If non-nil Auto Revert Mode uses file watch functions. 278 "If non-nil Auto Revert Mode uses file notification functions.
269This requires Emacs being compiled with file watch support (see 279This requires Emacs being compiled with file notification
270`auto-revert-notify-enabled'). You should set this variable 280support (see `auto-revert-notify-enabled'). You should set this
271through Custom only." 281variable through Custom only."
272 :group 'auto-revert 282 :group 'auto-revert
273 :type 'boolean 283 :type 'boolean
274 :set (lambda (variable value) 284 :set (lambda (variable value)
@@ -281,6 +291,17 @@ through Custom only."
281 (auto-revert-notify-rm-watch))))))) 291 (auto-revert-notify-rm-watch)))))))
282 :version "24.4") 292 :version "24.4")
283 293
294(defcustom auto-revert-notify-exclude-dir-regexp
295 (concat
296 ;; No mounted file systems.
297 "^" (regexp-opt '("/afs/" "/media/" "/mnt" "/net/" "/tmp_mnt/"))
298 ;; No remote files.
299 (unless auto-revert-remote-files "\\|^/[^/|:][^/|]+:"))
300 "Regular expression of directories to be excluded from file notifications."
301 :group 'auto-revert
302 :type 'regexp
303 :version "24.4")
304
284;; Internal variables: 305;; Internal variables:
285 306
286(defvar auto-revert-buffer-list () 307(defvar auto-revert-buffer-list ()
@@ -306,7 +327,9 @@ the list of old buffers.")
306(defvar auto-revert-notify-watch-descriptor-hash-list 327(defvar auto-revert-notify-watch-descriptor-hash-list
307 (make-hash-table :test 'equal) 328 (make-hash-table :test 'equal)
308 "A hash table collecting all file watch descriptors. 329 "A hash table collecting all file watch descriptors.
309Hash key is a watch descriptor, hash value is the corresponding buffer.") 330Hash key is a watch descriptor, hash value is a list of buffers
331which are related to files being watched and carrying the same
332default directory.")
310 333
311(defvar auto-revert-notify-watch-descriptor nil 334(defvar auto-revert-notify-watch-descriptor nil
312 "The file watch descriptor active for the current buffer.") 335 "The file watch descriptor active for the current buffer.")
@@ -315,7 +338,7 @@ Hash key is a watch descriptor, hash value is the corresponding buffer.")
315 338
316(defvar auto-revert-notify-modified-p nil 339(defvar auto-revert-notify-modified-p nil
317 "Non-nil when file has been modified on the file system. 340 "Non-nil when file has been modified on the file system.
318This has been reported by a file watch event.") 341This has been reported by a file notification event.")
319(make-variable-buffer-local 'auto-revert-notify-modified-p) 342(make-variable-buffer-local 'auto-revert-notify-modified-p)
320 343
321;; Functions: 344;; Functions:
@@ -444,9 +467,9 @@ specifies in the mode line."
444 (auto-revert-set-timer) 467 (auto-revert-set-timer)
445 (if global-auto-revert-mode 468 (if global-auto-revert-mode
446 (auto-revert-buffers) 469 (auto-revert-buffers)
447 (when auto-revert-use-notify 470 (dolist (buf (buffer-list))
448 (dolist (buf (buffer-list)) 471 (with-current-buffer buf
449 (with-current-buffer buf 472 (when auto-revert-use-notify
450 (auto-revert-notify-rm-watch)))))) 473 (auto-revert-notify-rm-watch))))))
451 474
452(defun auto-revert-set-timer () 475(defun auto-revert-set-timer ()
@@ -465,85 +488,106 @@ will use an up-to-date value of `auto-revert-interval'"
465 'auto-revert-buffers)))) 488 'auto-revert-buffers))))
466 489
467(defun auto-revert-notify-rm-watch () 490(defun auto-revert-notify-rm-watch ()
468 "Disable file watch for current buffer's associated file." 491 "Disable file notification for current buffer's associated file."
469 (when auto-revert-notify-watch-descriptor 492 (when auto-revert-notify-watch-descriptor
470 (ignore-errors 493 (maphash
471 (funcall (if (fboundp 'inotify-rm-watch) 494 (lambda (key value)
472 'inotify-rm-watch 'w32notify-rm-watch) 495 (when (equal key auto-revert-notify-watch-descriptor)
473 auto-revert-notify-watch-descriptor)) 496 (setq value (delete (current-buffer) value))
474 (remhash auto-revert-notify-watch-descriptor 497 (if value
475 auto-revert-notify-watch-descriptor-hash-list) 498 (puthash key value auto-revert-notify-watch-descriptor-hash-list)
499 (remhash key auto-revert-notify-watch-descriptor-hash-list)
500 (ignore-errors
501 (funcall (if (fboundp 'inotify-rm-watch)
502 'inotify-rm-watch 'w32notify-rm-watch)
503 auto-revert-notify-watch-descriptor)))))
504 auto-revert-notify-watch-descriptor-hash-list)
476 (remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch)) 505 (remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch))
477 (setq auto-revert-notify-watch-descriptor nil 506 (setq auto-revert-notify-watch-descriptor nil
478 auto-revert-notify-modified-p nil)) 507 auto-revert-notify-modified-p nil))
479 508
480(defun auto-revert-notify-add-watch () 509(defun auto-revert-notify-add-watch ()
481 "Enable file watch for current buffer's associated file." 510 "Enable file notification for current buffer's associated file."
511 (when (string-match auto-revert-notify-exclude-dir-regexp
512 (expand-file-name default-directory))
513 ;; Fallback to file checks.
514 (set (make-local-variable 'auto-revert-use-notify) nil))
515
482 (when (and buffer-file-name auto-revert-use-notify 516 (when (and buffer-file-name auto-revert-use-notify
483 (not auto-revert-notify-watch-descriptor)) 517 (not auto-revert-notify-watch-descriptor))
484 (let ((func (if (fboundp 'inotify-add-watch) 518 (let ((func (if (fboundp 'inotify-add-watch)
485 'inotify-add-watch 'w32notify-add-watch)) 519 'inotify-add-watch 'w32notify-add-watch))
486 (aspect (if (fboundp 'inotify-add-watch) 520 (aspect (if (fboundp 'inotify-add-watch)
487 '(modify) '(size last-write-time)))) 521 '(create modify moved-to) '(size last-write-time))))
488 (setq auto-revert-notify-watch-descriptor 522 (setq auto-revert-notify-watch-descriptor
489 (ignore-errors 523 (ignore-errors
490 (funcall 524 (funcall
491 func buffer-file-name aspect 'auto-revert-notify-handler))) 525 func (directory-file-name (expand-file-name default-directory))
526 aspect 'auto-revert-notify-handler)))
492 (if auto-revert-notify-watch-descriptor 527 (if auto-revert-notify-watch-descriptor
493 (progn 528 (progn
494 (puthash auto-revert-notify-watch-descriptor 529 (puthash
495 (current-buffer) 530 auto-revert-notify-watch-descriptor
496 auto-revert-notify-watch-descriptor-hash-list) 531 (cons (current-buffer)
532 (gethash auto-revert-notify-watch-descriptor
533 auto-revert-notify-watch-descriptor-hash-list))
534 auto-revert-notify-watch-descriptor-hash-list)
497 (add-hook (make-local-variable 'kill-buffer-hook) 535 (add-hook (make-local-variable 'kill-buffer-hook)
498 'auto-revert-notify-rm-watch)) 536 'auto-revert-notify-rm-watch))
499 ;; Fallback to file checks. 537 ;; Fallback to file checks.
500 (set (make-local-variable 'auto-revert-use-notify) nil))))) 538 (set (make-local-variable 'auto-revert-use-notify) nil)))))
501 539
502(defun auto-revert-notify-event-p (event) 540(defun auto-revert-notify-event-p (event)
503 "Check that event is a file watch event." 541 "Check that event is a file notification event."
504 (cond ((featurep 'inotify) 542 (cond ((featurep 'inotify)
505 (and (listp event) (= (length event) 4))) 543 (and (listp event) (= (length event) 4)))
506 ((featurep 'w32notify) 544 ((featurep 'w32notify)
507 (and (listp event) (= (length event) 3) (stringp (nth 2 event)))))) 545 (and (listp event) (= (length event) 3) (stringp (nth 2 event))))))
508 546
509(defun auto-revert-notify-event-descriptor (event) 547(defun auto-revert-notify-event-descriptor (event)
510 "Return watch descriptor of notification event, or nil." 548 "Return watch descriptor of file notification event, or nil."
511 (and (auto-revert-notify-event-p event) (car event))) 549 (and (auto-revert-notify-event-p event) (car event)))
512 550
513(defun auto-revert-notify-event-action (event) 551(defun auto-revert-notify-event-action (event)
514 "Return action of notification event, or nil." 552 "Return action of file notification event, or nil."
515 (and (auto-revert-notify-event-p event) (nth 1 event))) 553 (and (auto-revert-notify-event-p event) (nth 1 event)))
516 554
517(defun auto-revert-notify-event-file-name (event) 555(defun auto-revert-notify-event-file-name (event)
518 "Return file name of notification event, or nil." 556 "Return file name of file notification event, or nil."
519 (and (auto-revert-notify-event-p event) 557 (and (auto-revert-notify-event-p event)
520 (cond ((featurep 'inotify) (nth 3 event)) 558 (cond ((featurep 'inotify) (nth 3 event))
521 ((featurep 'w32notify) (nth 2 event))))) 559 ((featurep 'w32notify) (nth 2 event)))))
522 560
523(defun auto-revert-notify-handler (event) 561(defun auto-revert-notify-handler (event)
524 "Handle an event returned from file watch." 562 "Handle an event returned from file notification."
525 (when (auto-revert-notify-event-p event) 563 (when (auto-revert-notify-event-p event)
526 (let* ((descriptor (auto-revert-notify-event-descriptor event)) 564 (let* ((descriptor (auto-revert-notify-event-descriptor event))
527 (action (auto-revert-notify-event-action event)) 565 (action (auto-revert-notify-event-action event))
528 (file (auto-revert-notify-event-file-name event)) 566 (file (auto-revert-notify-event-file-name event))
529 (buffer (gethash descriptor 567 (buffers (gethash descriptor
530 auto-revert-notify-watch-descriptor-hash-list))) 568 auto-revert-notify-watch-descriptor-hash-list)))
531 (ignore-errors 569 (ignore-errors
532 ;; Check, that event is meant for us. 570 ;; Check, that event is meant for us.
533 ;; TODO: Filter events which stop watching, like `move' or `removed'. 571 ;; TODO: Filter events which stop watching, like `move' or `removed'.
534 (cl-assert descriptor) 572 (cl-assert descriptor)
535 (when (featurep 'inotify) (cl-assert (memq 'modify action))) 573 (when (featurep 'inotify)
574 (cl-assert (or (memq 'create action)
575 (memq 'modify action)
576 (memq 'moved-to action))))
536 (when (featurep 'w32notify) (cl-assert (eq 'modified action))) 577 (when (featurep 'w32notify) (cl-assert (eq 'modified action)))
537 (cl-assert (bufferp buffer)) 578 ;; Since we watch a directory, a file name must be returned.
538 (with-current-buffer buffer 579 (cl-assert (stringp file))
539 (when (and (stringp file) (stringp buffer-file-name)) 580 (dolist (buffer buffers)
540 ;; w32notify returns the basename of the file without its 581 (when (buffer-live-p buffer)
541 ;; leading directories; inotify returns its full absolute 582 (with-current-buffer buffer
542 ;; file name. 583 (when (and (stringp buffer-file-name)
543 (cl-assert (file-equal-p file buffer-file-name))) 584 (string-equal
544 585 (file-name-nondirectory file)
545 ;; Mark buffer modified. 586 (file-name-nondirectory buffer-file-name)))
546 (setq auto-revert-notify-modified-p t)))))) 587 ;; Mark buffer modified.
588 (setq auto-revert-notify-modified-p t)
589 ;; No need to check other buffers.
590 (cl-return)))))))))
547 591
548(defun auto-revert-active-p () 592(defun auto-revert-active-p ()
549 "Check if auto-revert is active (in current buffer or globally)." 593 "Check if auto-revert is active (in current buffer or globally)."
@@ -560,23 +604,29 @@ will use an up-to-date value of `auto-revert-interval'"
560This is an internal function used by Auto-Revert Mode." 604This is an internal function used by Auto-Revert Mode."
561 (when (or auto-revert-tail-mode (not (buffer-modified-p))) 605 (when (or auto-revert-tail-mode (not (buffer-modified-p)))
562 (let* ((buffer (current-buffer)) size 606 (let* ((buffer (current-buffer)) size
607 ;; Tramp caches the file attributes. Setting
608 ;; `remote-file-name-inhibit-cache' forces Tramp to reread
609 ;; the values.
610 (remote-file-name-inhibit-cache t)
563 (revert 611 (revert
564 (or (and buffer-file-name 612 (or (and buffer-file-name
565 (or (not auto-revert-use-notify) 613 (or auto-revert-remote-files
566 auto-revert-notify-modified-p) 614 (not (file-remote-p buffer-file-name)))
567 (if auto-revert-tail-mode 615 (if auto-revert-tail-mode
568 ;; Tramp caches the file attributes. Setting 616 (and (or (not auto-revert-use-notify)
569 ;; `remote-file-name-inhibit-cache' forces Tramp 617 auto-revert-notify-modified-p)
570 ;; to reread the values. 618 (file-readable-p buffer-file-name)
571 (let ((remote-file-name-inhibit-cache t)) 619 (/= auto-revert-tail-pos
572 (and (file-readable-p buffer-file-name) 620 (setq size
573 (/= auto-revert-tail-pos 621 (nth 7 (file-attributes
574 (setq size 622 buffer-file-name)))))
575 (nth 7 (file-attributes 623 ;; When `auto-revert-use-notify' is set, we do
576 buffer-file-name)))))) 624 ;; not apply further checks for performance
577 (and (not (file-remote-p buffer-file-name)) 625 ;; reasons.
578 (file-readable-p buffer-file-name) 626 (if auto-revert-use-notify
579 (not (verify-visited-file-modtime buffer))))) 627 auto-revert-notify-modified-p
628 (and (file-readable-p buffer-file-name)
629 (not (verify-visited-file-modtime buffer))))))
580 (and (or auto-revert-mode 630 (and (or auto-revert-mode
581 global-auto-revert-non-file-buffers) 631 global-auto-revert-non-file-buffers)
582 revert-buffer-function 632 revert-buffer-function
@@ -692,10 +742,10 @@ the timer when no buffers need to be checked."
692 (setq auto-revert-buffer-list 742 (setq auto-revert-buffer-list
693 (delq buf auto-revert-buffer-list))) 743 (delq buf auto-revert-buffer-list)))
694 (when (auto-revert-active-p) 744 (when (auto-revert-active-p)
695 ;; Enable file watches. 745 ;; Enable file notification.
696 (when (and auto-revert-use-notify buffer-file-name 746 (when (and auto-revert-use-notify buffer-file-name
697 (not auto-revert-notify-watch-descriptor) 747 (not auto-revert-notify-watch-descriptor))
698 (auto-revert-notify-add-watch))) 748 (auto-revert-notify-add-watch))
699 (auto-revert-handler))) 749 (auto-revert-handler)))
700 ;; Remove dead buffer from `auto-revert-buffer-list'. 750 ;; Remove dead buffer from `auto-revert-buffer-list'.
701 (setq auto-revert-buffer-list 751 (setq auto-revert-buffer-list