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 'tramp-events))
	(rest-string (process-get proc 'tramp-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 (string-replace "attributes changed" "attribute-changed" string)
          string (string-replace "changes done" "changes-done-hint" string)
          string (string-replace "renamed to" "moved" string))

    (catch 'doesnt-work
      ;; https://bugs.launchpad.net/bugs/1742946
      (when (string-match-p
	     (rx (| "Monitoring not supported"
                    "No locations given"
                    "Unable to find default local file monitor type"))
             string)
        (delete-process proc)
        (throw 'doesnt-work nil))

      ;; Determine monitor name.
      (unless (tramp-connection-property-p proc "file-monitor")
        (tramp-set-connection-property
         proc "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)))
          ;; TODO: What happens, if several monitor names are reported?
          ((string-match
	    (rx "Supported arguments for "
		"GIO_USE_FILE_MONITOR environment variable:\n"
		(* blank) (group (+ 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 (string-replace "\n\n" "\n" string))

      (while (string-match
	      (rx
	       bol (+ (not ":")) ":" blank
	       (group (+ (not ":"))) ":" blank
	       (group (regexp (regexp-opt tramp-gio-events)))
	       (? blank (group (+ (not (any "\r\n:"))))) eol)
	      string)

        (let* ((file (match-string 1 string))
	       (file1 (match-string 3 string))
	       (object
                (list
                 proc
                 (list
		  (intern-soft (match-string 2 string)))
                 file file1)))
	  (setq string (replace-match "" nil nil string))
          ;; Add an Emacs event now.
	  ;; `insert-special-event' exists since Emacs 31.
	  (when (member (caadr object) events)
	    (tramp-compat-funcall
                (if (fboundp 'insert-special-event)
                    'insert-special-event
                  (lookup-key special-event-map [file-notify]))
	      `(file-notify ,object file-notify-callback))))))

    ;; Save rest of the string.
    (while (string-match (rx bol "\n") string)
      (setq string (replace-match "" nil nil string)))
    (when (string-empty-p string) (setq string nil))
    (when string (tramp-message proc 10 "Rest string:\n%s" string))
    (process-put proc 'tramp-rest-string string)))