diff options
| author | Michael Albinus | 2013-01-10 15:27:48 +0100 |
|---|---|---|
| committer | Michael Albinus | 2013-01-10 15:27:48 +0100 |
| commit | ed9112575ebdf0fefec530d7b2687f83eea7bb8a (patch) | |
| tree | 78b09a1fe52b4460f1a4039f2af158f1d66dcbe6 | |
| parent | 58cc0a010b7e16dfcf03d7e858ea27eba5dece65 (diff) | |
| download | emacs-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/ChangeLog | 14 | ||||
| -rw-r--r-- | lisp/autorevert.el | 84 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-01-10 Dmitry Antipov <dmantipov@yandex.ru> | 15 | 2013-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. | ||
| 292 | Hash 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. | ||
| 300 | This 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' | |||
| 399 | specifies in the mode line." | 424 | specifies 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)))) |