Function: tramp-sh-gio-monitor-process-filter
tramp-sh-gio-monitor-process-filter is a byte-compiled function
defined in tramp-sh.el.gz.
Signature
(tramp-sh-gio-monitor-process-filter PROC STRING)
Documentation
Read output from "gio monitor" and add corresponding file-notify events.
Source Code
;; Defined in /usr/src/emacs/lisp/net/tramp-sh.el.gz
(defun tramp-sh-gio-monitor-process-filter (proc string)
"Read output from \"gio monitor\" and add corresponding `file-notify' events."
(let ((events (process-get proc 'events))
(remote-prefix
(with-current-buffer (process-buffer proc)
(file-remote-p default-directory)))
(rest-string (process-get proc 'rest-string))
pos)
(when rest-string
(tramp-message proc 10 "Previous string:\n%s" rest-string))
(tramp-message proc 6 "%S\n%s" proc string)
(setq string (concat rest-string string)
;; Fix action names.
string (tramp-compat-string-replace
"attributes changed" "attribute-changed" string)
string (tramp-compat-string-replace
"changes done" "changes-done-hint" string)
string (tramp-compat-string-replace
"renamed to" "moved" string))
(catch 'doesnt-work
;; https://bugs.launchpad.net/bugs/1742946
(when
(string-match-p "Monitoring not supported\\|No locations given" string)
(delete-process proc)
(throw 'doesnt-work nil))
;; Determine monitor name.
(unless (tramp-connection-property-p proc "gio-file-monitor")
(tramp-set-connection-property
proc "gio-file-monitor"
(cond
;; We have seen this on cygwin gio and on emba. Let's make
;; some assumptions.
((string-match
"Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string)
(setq pos (match-end 0))
(cond
((getenv "EMACS_EMBA_CI") 'GInotifyFileMonitor)
((eq system-type 'cygwin) 'GPollFileMonitor)
(t nil)))
;; TODO: What happens, if several monitor names are reported?
((string-match "\
Supported arguments for GIO_USE_FILE_MONITOR environment variable:
\\s-*\\([[:alpha:]]+\\) - 20" string)
(setq pos (match-end 0))
(intern
(format "G%sFileMonitor" (capitalize (match-string 1 string)))))
(t (setq pos (length string)) nil)))
(setq string (substring string pos)))
;; Delete empty lines.
(setq string (tramp-compat-string-replace "\n\n" "\n" string))
(while (string-match
(eval-when-compile
(concat "^[^:]+:"
"[[:space:]]\\([^:]+\\):"
"[[:space:]]" (regexp-opt tramp-gio-events t)
"\\([[:space:]]\\([^:]+\\)\\)?$"))
string)
(let* ((file (match-string 1 string))
(file1 (match-string 4 string))
(object
(list
proc
(list
(intern-soft (match-string 2 string)))
;; File names are returned as absolute paths. We
;; must add the remote prefix.
(concat remote-prefix file)
(when file1 (concat remote-prefix file1)))))
(setq string (replace-match "" nil nil string))
;; Usually, we would add an Emacs event now. Unfortunately,
;; `unread-command-events' does not accept several events at
;; once. Therefore, we apply the handler directly.
(when (member (cl-caadr object) events)
(tramp-compat-funcall
(lookup-key special-event-map [file-notify])
`(file-notify ,object file-notify-callback))))))
;; Save rest of the string.
(while (string-match "^\n" string)
(setq string (replace-match "" nil nil string)))
(when (zerop (length string)) (setq string nil))
(when string (tramp-message proc 10 "Rest string:\n%s" string))
(process-put proc 'rest-string string)))