diff options
| author | Michael Albinus | 2013-07-05 15:34:01 +0200 |
|---|---|---|
| committer | Michael Albinus | 2013-07-05 15:34:01 +0200 |
| commit | ddbdfd6f90c513e15ad5896dea156110f048322f (patch) | |
| tree | d850b54117c1d98f5ce8f32db3b7424958f3dbe1 | |
| parent | 96eb829aa781926a66524237b266de44c564bf60 (diff) | |
| download | emacs-ddbdfd6f90c513e15ad5896dea156110f048322f.tar.gz emacs-ddbdfd6f90c513e15ad5896dea156110f048322f.zip | |
* net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch): Support
both "gvfs-monitor-dir" and "inotifywait".
(tramp-sh-file-inotifywait-process-filter): Renamed from
`tramp-sh-file-notify-process-filter'.
(tramp-sh-file-gvfs-monitor-dir-process-filter)
(tramp-get-remote-gvfs-monitor-dir): New defuns.
| -rw-r--r-- | lisp/ChangeLog | 9 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 105 |
2 files changed, 88 insertions, 26 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d0c53d4d023..3dfa2f4a11b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2013-07-05 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch): Support | ||
| 4 | both "gvfs-monitor-dir" and "inotifywait". | ||
| 5 | (tramp-sh-file-inotifywait-process-filter): Renamed from | ||
| 6 | `tramp-sh-file-notify-process-filter'. | ||
| 7 | (tramp-sh-file-gvfs-monitor-dir-process-filter) | ||
| 8 | (tramp-get-remote-gvfs-monitor-dir): New defuns. | ||
| 9 | |||
| 1 | 2013-07-05 Leo Liu <sdl.web@gmail.com> | 10 | 2013-07-05 Leo Liu <sdl.web@gmail.com> |
| 2 | 11 | ||
| 3 | * autoinsert.el (auto-insert-alist): Default to lexical-binding. | 12 | * autoinsert.el (auto-insert-alist): Default to lexical-binding. |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index f402e2b2774..f0423cbfa68 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -3378,32 +3378,79 @@ Fall back to normal file name handler if no Tramp handler exists." | |||
| 3378 | ;; Default file name handlers, we don't care. | 3378 | ;; Default file name handlers, we don't care. |
| 3379 | (t (tramp-run-real-handler operation args))))))) | 3379 | (t (tramp-run-real-handler operation args))))))) |
| 3380 | 3380 | ||
| 3381 | ;; We use inotify for implementation. It is more likely to exist than glib. | ||
| 3382 | (defun tramp-sh-handle-file-notify-add-watch (file-name flags callback) | 3381 | (defun tramp-sh-handle-file-notify-add-watch (file-name flags callback) |
| 3383 | "Like `file-notify-add-watch' for Tramp files." | 3382 | "Like `file-notify-add-watch' for Tramp files." |
| 3384 | (setq file-name (expand-file-name file-name)) | 3383 | (setq file-name (expand-file-name file-name)) |
| 3385 | (with-parsed-tramp-file-name file-name nil | 3384 | (with-parsed-tramp-file-name file-name nil |
| 3386 | (let* ((default-directory (file-name-directory file-name)) | 3385 | (let* ((default-directory (file-name-directory file-name)) |
| 3387 | (command (tramp-get-remote-inotifywait v)) | 3386 | command events filter p) |
| 3388 | (events | 3387 | (cond |
| 3389 | (cond | 3388 | ;; gvfs-monitor-dir. |
| 3390 | ((and (memq 'change flags) (memq 'attribute-change flags)) | 3389 | ((setq command (tramp-get-remote-gvfs-monitor-dir v)) |
| 3391 | "create,modify,move,delete,attrib") | 3390 | (setq filter 'tramp-sh-file-gvfs-monitor-dir-process-filter |
| 3392 | ((memq 'change flags) "create,modify,move,delete") | 3391 | p (start-file-process |
| 3393 | ((memq 'attribute-change flags) "attrib"))) | 3392 | "gvfs-monitor-dir" (generate-new-buffer " *gvfs-monitor-dir*") |
| 3394 | (p (and command | 3393 | command localname))) |
| 3395 | (start-file-process | 3394 | ;; inotifywait. |
| 3396 | "inotifywait" (generate-new-buffer " *inotifywait*") | 3395 | ((setq command (tramp-get-remote-inotifywait v)) |
| 3397 | command "-mq" "-e" events localname)))) | 3396 | (setq filter 'tramp-sh-file-inotifywait-process-filter |
| 3397 | events | ||
| 3398 | (cond | ||
| 3399 | ((and (memq 'change flags) (memq 'attribute-change flags)) | ||
| 3400 | "create,modify,move,delete,attrib") | ||
| 3401 | ((memq 'change flags) "create,modify,move,delete") | ||
| 3402 | ((memq 'attribute-change flags) "attrib")) | ||
| 3403 | p (start-file-process | ||
| 3404 | "inotifywait" (generate-new-buffer " *inotifywait*") | ||
| 3405 | command "-mq" "-e" events localname))) | ||
| 3406 | ;; None. | ||
| 3407 | (t (tramp-error | ||
| 3408 | v 'file-notify-error | ||
| 3409 | "No file notification program found on %s" | ||
| 3410 | (file-remote-p file-name)))) | ||
| 3398 | ;; Return the process object as watch-descriptor. | 3411 | ;; Return the process object as watch-descriptor. |
| 3399 | (if (not (processp p)) | 3412 | (if (not (processp p)) |
| 3400 | (tramp-error | 3413 | (tramp-error |
| 3401 | v 'file-notify-error "`inotifywait' not found on remote host") | 3414 | v 'file-notify-error "`%s' failed to start on remote host" command) |
| 3402 | (tramp-compat-set-process-query-on-exit-flag p nil) | 3415 | (tramp-compat-set-process-query-on-exit-flag p nil) |
| 3403 | (set-process-filter p 'tramp-sh-file-notify-process-filter) | 3416 | (set-process-filter p filter) |
| 3404 | p)))) | 3417 | p)))) |
| 3405 | 3418 | ||
| 3406 | (defun tramp-sh-file-notify-process-filter (proc string) | 3419 | (defun tramp-sh-file-gvfs-monitor-dir-process-filter (proc string) |
| 3420 | "Read output from \"gvfs-monitor-dir\" and add corresponding file-notify events." | ||
| 3421 | (tramp-message proc 6 (format "%S\n%s" proc string)) | ||
| 3422 | (with-current-buffer (process-buffer proc) | ||
| 3423 | (dolist | ||
| 3424 | (line | ||
| 3425 | (split-string string "Directory Monitor Event:[\n\r]+" 'omit-nulls)) | ||
| 3426 | ;; Attribute change is returned in unused wording. | ||
| 3427 | (setq line | ||
| 3428 | (replace-regexp-in-string | ||
| 3429 | "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" line)) | ||
| 3430 | ;; Check, whether there is a problem. | ||
| 3431 | (unless | ||
| 3432 | (string-match | ||
| 3433 | "^Child = \\([^[:blank:]]+\\)[\n\r]+\\(Other = \\([^[:blank:]]+\\)[\n\r]+\\)?Event = \\([^[:blank:]]+\\)[\n\r]+$" line) | ||
| 3434 | (tramp-error proc 'file-notify-error "%s" line)) | ||
| 3435 | |||
| 3436 | (let* ((remote-prefix (file-remote-p default-directory)) | ||
| 3437 | (object | ||
| 3438 | (list | ||
| 3439 | proc | ||
| 3440 | (intern-soft | ||
| 3441 | (replace-regexp-in-string | ||
| 3442 | "_" "-" (downcase (match-string 4 line)))) | ||
| 3443 | ;; File names are returned as absolute paths. We must | ||
| 3444 | ;; add the remote prefix. | ||
| 3445 | (concat remote-prefix (match-string 1 line)) | ||
| 3446 | (when (match-string 3 line) | ||
| 3447 | (concat remote-prefix (match-string 3 line)))))) | ||
| 3448 | ;; Usually, we would add an Emacs event now. Unfortunately, | ||
| 3449 | ;; `unread-command-events' does not accept several events at | ||
| 3450 | ;; once. Therefore, we apply the callback directly. | ||
| 3451 | (tramp-compat-funcall 'file-notify-callback object))))) | ||
| 3452 | |||
| 3453 | (defun tramp-sh-file-inotifywait-process-filter (proc string) | ||
| 3407 | "Read output from \"inotifywait\" and add corresponding file-notify events." | 3454 | "Read output from \"inotifywait\" and add corresponding file-notify events." |
| 3408 | (tramp-message proc 6 (format "%S\n%s" proc string)) | 3455 | (tramp-message proc 6 (format "%S\n%s" proc string)) |
| 3409 | (dolist (line (split-string string "[\n\r]+" 'omit-nulls)) | 3456 | (dolist (line (split-string string "[\n\r]+" 'omit-nulls)) |
| @@ -3413,17 +3460,17 @@ Fall back to normal file name handler if no Tramp handler exists." | |||
| 3413 | "^[^[:blank:]]+[[:blank:]]+\\([^[:blank:]]+\\)+\\([[:blank:]]+\\([^[:blank:]]+\\)\\)?[[:blank:]]*$" line) | 3460 | "^[^[:blank:]]+[[:blank:]]+\\([^[:blank:]]+\\)+\\([[:blank:]]+\\([^[:blank:]]+\\)\\)?[[:blank:]]*$" line) |
| 3414 | (tramp-error proc 'file-notify-error "%s" line)) | 3461 | (tramp-error proc 'file-notify-error "%s" line)) |
| 3415 | 3462 | ||
| 3416 | ;; Usually, we would add an Emacs event now. Unfortunately, | 3463 | (let ((object |
| 3417 | ;; `unread-command-events' does not accept several events at once. | 3464 | (list |
| 3418 | ;; Therefore, we apply the callback directly. | 3465 | proc |
| 3419 | (let* ((object | 3466 | (mapcar |
| 3420 | (list | 3467 | (lambda (x) |
| 3421 | proc | 3468 | (intern-soft (replace-regexp-in-string "_" "-" (downcase x)))) |
| 3422 | (mapcar | 3469 | (split-string (match-string 1 line) "," 'omit-nulls)) |
| 3423 | (lambda (x) | 3470 | (match-string 3 line)))) |
| 3424 | (intern-soft (replace-regexp-in-string "_" "-" (downcase x)))) | 3471 | ;; Usually, we would add an Emacs event now. Unfortunately, |
| 3425 | (split-string (match-string 1 line) "," 'omit-nulls)) | 3472 | ;; `unread-command-events' does not accept several events at |
| 3426 | (match-string 3 line)))) | 3473 | ;; once. Therefore, we apply the callback directly. |
| 3427 | (tramp-compat-funcall 'file-notify-callback object)))) | 3474 | (tramp-compat-funcall 'file-notify-callback object)))) |
| 3428 | 3475 | ||
| 3429 | (defvar file-notify-descriptors) | 3476 | (defvar file-notify-descriptors) |
| @@ -4923,6 +4970,12 @@ Return ATTR." | |||
| 4923 | (tramp-message vec 5 "Finding a suitable `trash' command") | 4970 | (tramp-message vec 5 "Finding a suitable `trash' command") |
| 4924 | (tramp-find-executable vec "trash" (tramp-get-remote-path vec)))) | 4971 | (tramp-find-executable vec "trash" (tramp-get-remote-path vec)))) |
| 4925 | 4972 | ||
| 4973 | (defun tramp-get-remote-gvfs-monitor-dir (vec) | ||
| 4974 | (with-tramp-connection-property vec "gvfs-monitor-dir" | ||
| 4975 | (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command") | ||
| 4976 | (tramp-find-executable | ||
| 4977 | vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t))) | ||
| 4978 | |||
| 4926 | (defun tramp-get-remote-inotifywait (vec) | 4979 | (defun tramp-get-remote-inotifywait (vec) |
| 4927 | (with-tramp-connection-property vec "inotifywait" | 4980 | (with-tramp-connection-property vec "inotifywait" |
| 4928 | (tramp-message vec 5 "Finding a suitable `inotifywait' command") | 4981 | (tramp-message vec 5 "Finding a suitable `inotifywait' command") |