Continue gfilenotify.c implementation of missing parts
* lisp/filenotify.el (file-notify-add-watch): Append `flags' to `gfile-add-watch' call. (file-notify-rm-watch): Modify `file-notify-descriptors' only after calling the low level functions. * src/gfilenotify.c (dir_monitor_callback): Check, whether event_type is expected. (Fgfile_add_watch): Allow also `change'and `attribute-change' for FLAGS. (Fgfile_rm_watch): Fix typo. (syms_of_gfilenotify): Declare Qchange and Qattribute_change.
This commit is contained in:
@@ -291,7 +291,7 @@ FILE is the name of the file whose event is being reported."
|
||||
|
||||
;; Determine respective flags.
|
||||
(if (eq file-notify--library 'gfilenotify)
|
||||
(setq l-flags '(watch-mounts send-moved))
|
||||
(setq l-flags (append '(watch-mounts send-moved) flags))
|
||||
(when (memq 'change flags)
|
||||
(setq
|
||||
l-flags
|
||||
@@ -330,7 +330,21 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
|
||||
handler registered)
|
||||
|
||||
(when (stringp dir)
|
||||
;; Call low-level function.
|
||||
(setq handler (find-file-name-handler dir 'file-notify-rm-watch))
|
||||
(condition-case nil
|
||||
(if handler
|
||||
;; A file name handler could exist even if there is no
|
||||
;; local file notification support.
|
||||
(funcall handler 'file-notify-rm-watch desc)
|
||||
|
||||
(funcall
|
||||
(cond
|
||||
((eq file-notify--library 'gfilenotify) 'gfile-rm-watch)
|
||||
((eq file-notify--library 'inotify) 'inotify-rm-watch)
|
||||
((eq file-notify--library 'w32notify) 'w32notify-rm-watch))
|
||||
desc))
|
||||
(file-notify-error nil))
|
||||
|
||||
;; Modify `file-notify-descriptors'.
|
||||
(if (not file)
|
||||
@@ -341,23 +355,7 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'."
|
||||
(delete (assoc file (cdr registered)) (cdr registered)))
|
||||
(if (null (cdr registered))
|
||||
(remhash desc file-notify-descriptors)
|
||||
(puthash desc registered file-notify-descriptors)))
|
||||
|
||||
;; Call low-level function.
|
||||
(when (null (cdr registered))
|
||||
(condition-case nil
|
||||
(if handler
|
||||
;; A file name handler could exist even if there is no local
|
||||
;; file notification support.
|
||||
(funcall handler 'file-notify-rm-watch desc)
|
||||
|
||||
(funcall
|
||||
(cond
|
||||
((eq file-notify--library 'gfilenotify) 'gfile-rm-watch)
|
||||
((eq file-notify--library 'inotify) 'inotify-rm-watch)
|
||||
((eq file-notify--library 'w32notify) 'w32notify-rm-watch))
|
||||
desc))
|
||||
(file-notify-error nil))))))
|
||||
(puthash desc registered file-notify-descriptors))))))
|
||||
|
||||
(defun file-notify-valid-p (descriptor)
|
||||
"Check a watch specified by its DESCRIPTOR.
|
||||
|
||||
@@ -29,7 +29,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "process.h"
|
||||
|
||||
|
||||
/* This is a list, elements are triples (DESCRIPTOR FILE CALLBACK) */
|
||||
/* This is a list, elements are triples (DESCRIPTOR FILE FLAGS CALLBACK) */
|
||||
static Lisp_Object watch_list;
|
||||
|
||||
/* This is the callback function for arriving signals from
|
||||
@@ -42,7 +42,7 @@ dir_monitor_callback (GFileMonitor *monitor,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
Lisp_Object symbol, monitor_object, watch_object;
|
||||
Lisp_Object symbol, monitor_object, watch_object, flags;
|
||||
char *name = g_file_get_parse_name (file);
|
||||
char *oname = other_file ? g_file_get_parse_name (other_file) : NULL;
|
||||
|
||||
@@ -84,26 +84,35 @@ dir_monitor_callback (GFileMonitor *monitor,
|
||||
|
||||
if (CONSP (watch_object))
|
||||
{
|
||||
/* Construct an event. */
|
||||
struct input_event event;
|
||||
Lisp_Object otail = oname ? list1 (build_string (oname)) : Qnil;
|
||||
EVENT_INIT (event);
|
||||
event.kind = FILE_NOTIFY_EVENT;
|
||||
event.frame_or_window = Qnil;
|
||||
event.arg = list2 (Fcons (monitor_object,
|
||||
Fcons (symbol,
|
||||
Fcons (build_string (name),
|
||||
otail))),
|
||||
XCAR (XCDR (XCDR (watch_object))));
|
||||
|
||||
/* Store it into the input event queue. */
|
||||
kbd_buffer_store_event (&event);
|
||||
/* Check, whether event_type is expected. */
|
||||
flags = XCAR (XCDR (XCDR (watch_object)));
|
||||
if ((!NILP (Fmember (Qchange, flags)) &&
|
||||
!NILP (Fmember (symbol, list5 (Qchanged, Qchanges_done_hint,
|
||||
Qdeleted, Qcreated, Qmoved)))) ||
|
||||
(!NILP (Fmember (Qattribute_change, flags)) &&
|
||||
((EQ (symbol, Qattribute_changed)))))
|
||||
{
|
||||
/* Construct an event. */
|
||||
EVENT_INIT (event);
|
||||
event.kind = FILE_NOTIFY_EVENT;
|
||||
event.frame_or_window = Qnil;
|
||||
event.arg = list2 (Fcons (monitor_object,
|
||||
Fcons (symbol,
|
||||
Fcons (build_string (name),
|
||||
otail))),
|
||||
XCAR (XCDR (XCDR (XCDR (watch_object)))));
|
||||
|
||||
/* Store it into the input event queue. */
|
||||
kbd_buffer_store_event (&event);
|
||||
// XD_DEBUG_MESSAGE ("%s", XD_OBJECT_TO_STRING (event.arg));
|
||||
}
|
||||
|
||||
/* Cancel monitor if file or directory is deleted. */
|
||||
if (((event_type == G_FILE_MONITOR_EVENT_DELETED) ||
|
||||
(event_type == G_FILE_MONITOR_EVENT_MOVED)) &&
|
||||
(strcmp (name, SSDATA (XCAR (XCDR (watch_object)))) == 0) &&
|
||||
(!g_file_monitor_is_cancelled (monitor)))
|
||||
if (!NILP (Fmember (symbol, list2 (Qdeleted, Qmoved))) &&
|
||||
!g_file_monitor_is_cancelled (monitor))
|
||||
g_file_monitor_cancel (monitor);
|
||||
}
|
||||
|
||||
@@ -127,9 +136,13 @@ watched for some reason, this function signals a `file-notify-error' error.
|
||||
FLAGS is a list of conditions to set what will be watched for. It can
|
||||
include the following symbols:
|
||||
|
||||
`watch-mounts' -- watch for mount events
|
||||
`send-moved' -- pair `deleted' and `created' events caused by file
|
||||
renames and send a single `renamed' event instead
|
||||
`change' -- watch for file changes
|
||||
`attribute-change' -- watch for file attributes changes, like
|
||||
permissions or modification time
|
||||
`watch-mounts' -- watch for mount events
|
||||
`send-moved' -- pair `deleted' and `created' events caused by
|
||||
file renames and send a single `renamed' event
|
||||
instead
|
||||
|
||||
When any event happens, Emacs will call the CALLBACK function passing
|
||||
it a single argument EVENT, which is of the form
|
||||
@@ -206,13 +219,13 @@ will be reported only in case of the `moved' event. */)
|
||||
(GCallback) dir_monitor_callback, NULL);
|
||||
|
||||
/* Store watch object in watch list. */
|
||||
watch_object = list3 (watch_descriptor, file, callback);
|
||||
watch_object = list4 (watch_descriptor, file, flags, callback);
|
||||
watch_list = Fcons (watch_object, watch_list);
|
||||
|
||||
return watch_descriptor;
|
||||
}
|
||||
|
||||
DEFUN ("gfile-rm-watc", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
|
||||
DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
|
||||
doc: /* Remove an existing WATCH-DESCRIPTOR.
|
||||
|
||||
WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */)
|
||||
@@ -279,6 +292,8 @@ syms_of_gfilenotify (void)
|
||||
defsubr (&Sgfile_valid_p);
|
||||
|
||||
/* Filter objects. */
|
||||
DEFSYM (Qchange, "change");
|
||||
DEFSYM (Qattribute_change, "attribute-change");
|
||||
DEFSYM (Qwatch_mounts, "watch-mounts"); /* G_FILE_MONITOR_WATCH_MOUNTS */
|
||||
DEFSYM (Qsend_moved, "send-moved"); /* G_FILE_MONITOR_SEND_MOVED */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user