aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2013-01-10 15:27:48 +0100
committerMichael Albinus2013-01-10 15:27:48 +0100
commited9112575ebdf0fefec530d7b2687f83eea7bb8a (patch)
tree78b09a1fe52b4460f1a4039f2af158f1d66dcbe6
parent58cc0a010b7e16dfcf03d7e858ea27eba5dece65 (diff)
downloademacs-ed9112575ebdf0fefec530d7b2687f83eea7bb8a.tar.gz
emacs-ed9112575ebdf0fefec530d7b2687f83eea7bb8a.zip
* autorevert.el: Add file watch support.
(auto-revert-notify-enabled): New defconst. (auto-revert-notify-watch-descriptor-hash-list) (auto-revert-notify-watch-descriptor) (auto-revert-notify-modified-p): New defvars. (auto-revert-notify-rm-watch, auto-revert-notify-add-watch) (auto-revert-notify-handler): New defuns. (auto-revert-mode, global-auto-revert-mode): Remove file watches when mode is disabled. (auto-revert-handler): Check for `auto-revert-notify-modified-p'. (auto-revert-buffers): Add file watches for active buffers.
-rw-r--r--lisp/ChangeLog14
-rw-r--r--lisp/autorevert.el84
2 files changed, 91 insertions, 7 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 19968c46aa8..507550dbec0 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,17 @@
12013-01-10 Michael Albinus <michael.albinus@gmx.de>
2
3 * autorevert.el: Add file watch support.
4 (auto-revert-notify-enabled): New defconst.
5 (auto-revert-notify-watch-descriptor-hash-list)
6 (auto-revert-notify-watch-descriptor)
7 (auto-revert-notify-modified-p): New defvars.
8 (auto-revert-notify-rm-watch, auto-revert-notify-add-watch)
9 (auto-revert-notify-handler): New defuns.
10 (auto-revert-mode, global-auto-revert-mode): Remove file watches
11 when mode is disabled.
12 (auto-revert-handler): Check for `auto-revert-notify-modified-p'.
13 (auto-revert-buffers): Add file watches for active buffers.
14
12013-01-10 Dmitry Antipov <dmantipov@yandex.ru> 152013-01-10 Dmitry Antipov <dmantipov@yandex.ru>
2 16
3 * cus-start.el (toplevel): Only allow float values for 17 * cus-start.el (toplevel): Only allow float values for
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index f491f2427be..395323a074a 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -48,6 +48,9 @@
48;; Emacs. You should never even notice that this package is active 48;; Emacs. You should never even notice that this package is active
49;; (except that your buffers will be reverted, of course). 49;; (except that your buffers will be reverted, of course).
50;; 50;;
51;; If Emacs is compiled with file watch support, notifications are
52;; used instead of checking the time stamp of the files.
53;;
51;; After reverting a file buffer, Auto Revert Mode normally puts point 54;; After reverting a file buffer, Auto Revert Mode normally puts point
52;; at the same position that a regular manual revert would. However, 55;; at the same position that a regular manual revert would. However,
53;; there is one exception to this rule. If point is at the end of the 56;; there is one exception to this rule. If point is at the end of the
@@ -276,6 +279,27 @@ the list of old buffers.")
276 (set (make-local-variable 'auto-revert-tail-pos) 279 (set (make-local-variable 'auto-revert-tail-pos)
277 (nth 7 (file-attributes buffer-file-name))))) 280 (nth 7 (file-attributes buffer-file-name)))))
278 281
282(defconst auto-revert-notify-enabled
283 (or (featurep 'inotify) (featurep 'w32notify))
284 "Non-nil when Emacs has been compiled with file watch support.")
285
286(when auto-revert-notify-enabled
287 (add-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch))
288
289(defvar auto-revert-notify-watch-descriptor-hash-list
290 (make-hash-table :test 'equal)
291 "A hash table collecting all file watch descriptors.
292Hash key is a watch descriptor, hash value is the corresponding buffer.")
293
294(defvar auto-revert-notify-watch-descriptor nil
295 "The file watch descriptor active for the current buffer.")
296(make-variable-buffer-local 'auto-revert-notify-watch-descriptor)
297
298(defvar auto-revert-notify-modified-p nil
299 "Non-nil when file has been modified on the file system.
300This has been reported by a file watch event.")
301(make-variable-buffer-local 'auto-revert-notify-modified-p)
302
279;; Functions: 303;; Functions:
280 304
281;;;###autoload 305;;;###autoload
@@ -296,6 +320,7 @@ without being changed in the part that is already in the buffer."
296 (if auto-revert-mode 320 (if auto-revert-mode
297 (if (not (memq (current-buffer) auto-revert-buffer-list)) 321 (if (not (memq (current-buffer) auto-revert-buffer-list))
298 (push (current-buffer) auto-revert-buffer-list)) 322 (push (current-buffer) auto-revert-buffer-list))
323 (when auto-revert-notify-enabled (auto-revert-notify-rm-watch))
299 (setq auto-revert-buffer-list 324 (setq auto-revert-buffer-list
300 (delq (current-buffer) auto-revert-buffer-list))) 325 (delq (current-buffer) auto-revert-buffer-list)))
301 (auto-revert-set-timer) 326 (auto-revert-set-timer)
@@ -399,9 +424,12 @@ It displays the text that `global-auto-revert-mode-text'
399specifies in the mode line." 424specifies in the mode line."
400 :global t :group 'auto-revert :lighter global-auto-revert-mode-text 425 :global t :group 'auto-revert :lighter global-auto-revert-mode-text
401 (auto-revert-set-timer) 426 (auto-revert-set-timer)
402 (when global-auto-revert-mode 427 (if global-auto-revert-mode
403 (auto-revert-buffers))) 428 (auto-revert-buffers)
404 429 (when auto-revert-notify-enabled
430 (dolist (buf (buffer-list))
431 (with-current-buffer buf
432 (auto-revert-notify-rm-watch))))))
405 433
406(defun auto-revert-set-timer () 434(defun auto-revert-set-timer ()
407 "Restart or cancel the timer used by Auto-Revert Mode. 435 "Restart or cancel the timer used by Auto-Revert Mode.
@@ -418,6 +446,39 @@ will use an up-to-date value of `auto-revert-interval'"
418 auto-revert-interval 446 auto-revert-interval
419 'auto-revert-buffers)))) 447 'auto-revert-buffers))))
420 448
449(defun auto-revert-notify-rm-watch ()
450 "Disable file watch for current buffer's associated file."
451 (when auto-revert-notify-watch-descriptor
452 (funcall (if (fboundp 'inotify-rm-watch) 'inotify-rm-watch 'w32-rm-watch)
453 auto-revert-notify-watch-descriptor)
454 (remhash auto-revert-notify-watch-descriptor
455 auto-revert-notify-watch-descriptor-hash-list))
456 (setq auto-revert-notify-watch-descriptor nil
457 auto-revert-notify-modified-p nil))
458
459(defun auto-revert-notify-add-watch ()
460 "Enable file watch for current buffer's associated file."
461 (when (and buffer-file-name auto-revert-notify-enabled)
462 (auto-revert-notify-rm-watch)
463 (let ((func (if (fboundp 'inotify-add-watch)
464 'inotify-add-watch 'w32-add-watch))
465 (aspect (if (fboundp 'inotify-add-watch)
466 '(close-write) '(last-write-time))))
467 (setq auto-revert-notify-watch-descriptor
468 (funcall func buffer-file-name aspect 'auto-revert-notify-handler))
469 (puthash auto-revert-notify-watch-descriptor
470 (current-buffer)
471 auto-revert-notify-watch-descriptor-hash-list))))
472
473(defun auto-revert-notify-handler (event)
474 "Handle an event returned from file watch."
475 (when (listp event)
476 (let ((buffer
477 (gethash (car event) auto-revert-notify-watch-descriptor-hash-list)))
478 (when (bufferp buffer)
479 (with-current-buffer buffer
480 (setq auto-revert-notify-modified-p t))))))
481
421(defun auto-revert-active-p () 482(defun auto-revert-active-p ()
422 "Check if auto-revert is active (in current buffer or globally)." 483 "Check if auto-revert is active (in current buffer or globally)."
423 (or auto-revert-mode 484 (or auto-revert-mode
@@ -445,9 +506,12 @@ This is an internal function used by Auto-Revert Mode."
445 (setq size 506 (setq size
446 (nth 7 (file-attributes 507 (nth 7 (file-attributes
447 buffer-file-name)))))) 508 buffer-file-name))))))
448 (and (not (file-remote-p buffer-file-name)) 509 (if auto-revert-notify-enabled
449 (file-readable-p buffer-file-name) 510 ;; There are file watches.
450 (not (verify-visited-file-modtime buffer))))) 511 auto-revert-notify-modified-p
512 (and (not (file-remote-p buffer-file-name))
513 (file-readable-p buffer-file-name)
514 (not (verify-visited-file-modtime buffer))))))
451 (and (or auto-revert-mode 515 (and (or auto-revert-mode
452 global-auto-revert-non-file-buffers) 516 global-auto-revert-non-file-buffers)
453 revert-buffer-function 517 revert-buffer-function
@@ -456,6 +520,7 @@ This is an internal function used by Auto-Revert Mode."
456 (funcall buffer-stale-function t)))) 520 (funcall buffer-stale-function t))))
457 eob eoblist) 521 eob eoblist)
458 (when revert 522 (when revert
523 (setq auto-revert-notify-modified-p nil)
459 (when (and auto-revert-verbose 524 (when (and auto-revert-verbose
460 (not (eq revert 'fast))) 525 (not (eq revert 'fast)))
461 (message "Reverting buffer `%s'." (buffer-name))) 526 (message "Reverting buffer `%s'." (buffer-name)))
@@ -561,7 +626,12 @@ the timer when no buffers need to be checked."
561 (memq buf auto-revert-buffer-list)) 626 (memq buf auto-revert-buffer-list))
562 (setq auto-revert-buffer-list 627 (setq auto-revert-buffer-list
563 (delq buf auto-revert-buffer-list))) 628 (delq buf auto-revert-buffer-list)))
564 (when (auto-revert-active-p) (auto-revert-handler))) 629 (when (auto-revert-active-p)
630 ;; Enable file watches.
631 (when (and auto-revert-notify-enabled buffer-file-name
632 (not auto-revert-notify-watch-descriptor)
633 (auto-revert-notify-add-watch)))
634 (auto-revert-handler)))
565 ;; Remove dead buffer from `auto-revert-buffer-list'. 635 ;; Remove dead buffer from `auto-revert-buffer-list'.
566 (setq auto-revert-buffer-list 636 (setq auto-revert-buffer-list
567 (delq buf auto-revert-buffer-list)))) 637 (delq buf auto-revert-buffer-list))))