refactor: get zine watcher to build in flow
This commit is contained in:
parent
db4e3e1936
commit
b698fffd25
7 changed files with 90 additions and 30 deletions
|
|
@ -241,3 +241,22 @@ pub fn buffer_from_ref(self: *Self, buffer_ref: usize) ?*Buffer {
|
|||
pub fn buffer_to_ref(_: *Self, buffer: *Buffer) usize {
|
||||
return @intFromPtr(buffer);
|
||||
}
|
||||
|
||||
const watcher = @import("watcher");
|
||||
|
||||
pub fn watch_all_buffers(self: *Self) watcher.Error!void {
|
||||
var debouncer: watcher.Debouncer = .{};
|
||||
var buffers: std.ArrayList([]const u8) = .empty;
|
||||
var iter = self.buffers.keyIterator();
|
||||
while (iter.next()) |key| {
|
||||
(try buffers.addOne(self.allocator)).* = key.*;
|
||||
}
|
||||
|
||||
var watcher_: watcher.Watcher = try .init(
|
||||
self.allocator,
|
||||
&debouncer,
|
||||
&.{}, // dirs_to_watch.items,
|
||||
);
|
||||
|
||||
try watcher_.start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1401,6 +1401,15 @@ const cmds = struct {
|
|||
} else return error.InvalidSwapTabsArgument;
|
||||
}
|
||||
pub const place_next_tab_meta: Meta = .{ .arguments = &.{ .string, .integer } };
|
||||
|
||||
pub fn enable_file_watcher(self: *Self, _: Ctx) Result {
|
||||
self.buffer_manager.watch_all_buffers() catch |e| {
|
||||
const logger = log.logger("watcher");
|
||||
defer logger.deinit();
|
||||
logger.print_err("watcher", "failed to watch all buffes: {s}", .{@errorName(e)});
|
||||
};
|
||||
}
|
||||
pub const enable_file_watcher_meta: Meta = .{ .description = "Enable file watcher" };
|
||||
};
|
||||
|
||||
pub fn handle_editor_event(self: *Self, _: tp.pid_ref, m: tp.message) tp.result {
|
||||
|
|
|
|||
8
src/watcher/Debouncer.zig
Normal file
8
src/watcher/Debouncer.zig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
const std = @import("std");
|
||||
|
||||
const Debouncer = @This();
|
||||
|
||||
/// Thread-safe. To be called when a new event comes in
|
||||
pub fn newEvent(d: *Debouncer) void {
|
||||
_ = d;
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
const LinuxWatcher = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const fatal = @import("../../../fatal.zig");
|
||||
const Debouncer = @import("../../serve.zig").Debouncer;
|
||||
const Debouncer = @import("Debouncer.zig");
|
||||
const Error = @import("root.zig").Error;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const log = std.log.scoped(.watcher);
|
||||
|
|
@ -30,11 +30,7 @@ pub fn init(
|
|||
gpa: std.mem.Allocator,
|
||||
debouncer: *Debouncer,
|
||||
dir_paths: []const []const u8,
|
||||
) LinuxWatcher {
|
||||
errdefer |err| fatal.msg("error: unable to start the file watcher: {s}", .{
|
||||
@errorName(err),
|
||||
});
|
||||
|
||||
) Error!LinuxWatcher {
|
||||
const notify_fd = try std.posix.inotify_init1(0);
|
||||
var watcher: LinuxWatcher = .{
|
||||
.gpa = gpa,
|
||||
|
|
@ -300,7 +296,7 @@ pub fn listen(watcher: *LinuxWatcher) !void {
|
|||
|
||||
var event_data = buffer[0..len];
|
||||
while (event_data.len > 0) {
|
||||
const event: *Event = @alignCast(@ptrCast(event_data[0..event_size]));
|
||||
const event: *Event = @ptrCast(@alignCast(event_data[0..event_size]));
|
||||
const parent = watcher.watch_fds.get(event.wd).?;
|
||||
event_data = event_data[event_size + event.len ..];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
const MacosWatcher = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const fatal = @import("../../../fatal.zig");
|
||||
const Debouncer = @import("../../serve.zig").Debouncer;
|
||||
const Debouncer = @import("Debouncer.zig");
|
||||
|
||||
const c = @cImport({
|
||||
@cInclude("CoreServices/CoreServices.h");
|
||||
|
|
@ -31,11 +30,7 @@ pub fn start(watcher: *MacosWatcher) !void {
|
|||
t.detach();
|
||||
}
|
||||
|
||||
pub fn listen(watcher: *MacosWatcher) void {
|
||||
errdefer |err| switch (err) {
|
||||
error.OutOfMemory => fatal.oom(),
|
||||
};
|
||||
|
||||
pub fn listen(watcher: *MacosWatcher) error{ OutOfMemory, FSEventStreamError }!void {
|
||||
const macos_paths = try watcher.gpa.alloc(
|
||||
c.CFStringRef,
|
||||
watcher.dir_paths.len,
|
||||
|
|
@ -74,9 +69,8 @@ pub fn listen(watcher: *MacosWatcher) void {
|
|||
c.kCFRunLoopDefaultMode,
|
||||
);
|
||||
|
||||
if (c.FSEventStreamStart(stream) == 0) {
|
||||
fatal.msg("error: macos watcher FSEventStreamStart failed", .{});
|
||||
}
|
||||
if (c.FSEventStreamStart(stream) == 0)
|
||||
return error.FSEventStreamError;
|
||||
|
||||
c.CFRunLoopRun();
|
||||
|
||||
|
|
@ -98,9 +92,9 @@ pub fn macosCallback(
|
|||
_ = eventIds;
|
||||
_ = eventFlags;
|
||||
_ = streamRef;
|
||||
const watcher: *MacosWatcher = @alignCast(@ptrCast(clientCallBackInfo));
|
||||
const watcher: *MacosWatcher = @ptrCast(@alignCast(clientCallBackInfo));
|
||||
|
||||
const paths: [*][*:0]u8 = @alignCast(@ptrCast(eventPaths));
|
||||
const paths: [*][*:0]u8 = @ptrCast(@alignCast(eventPaths));
|
||||
for (paths[0..numEvents]) |p| {
|
||||
const path = std.mem.span(p);
|
||||
log.debug("Changed: {s}\n", .{path});
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ const WindowsWatcher = @This();
|
|||
|
||||
const std = @import("std");
|
||||
const windows = std.os.windows;
|
||||
const fatal = @import("../../../fatal.zig");
|
||||
const Debouncer = @import("../../serve.zig").Debouncer;
|
||||
const Debouncer = @import("Debouncer.zig");
|
||||
|
||||
const log = std.log.scoped(.watcher);
|
||||
|
||||
|
|
@ -40,11 +39,7 @@ pub fn init(
|
|||
gpa: std.mem.Allocator,
|
||||
debouncer: *Debouncer,
|
||||
dir_paths: []const []const u8,
|
||||
) WindowsWatcher {
|
||||
errdefer |err| fatal.msg("error: unable to start the file watcher: {s}", .{
|
||||
@errorName(err),
|
||||
});
|
||||
|
||||
) !WindowsWatcher {
|
||||
var watcher = WindowsWatcher{
|
||||
.debouncer = debouncer,
|
||||
.iocp_port = windows.INVALID_HANDLE_VALUE,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,47 @@
|
|||
const builtin = @import("builtin");
|
||||
|
||||
pub const Watcher = switch (builtin.target.os.tag) {
|
||||
.linux => @import("serve/watcher/LinuxWatcher.zig"),
|
||||
.macos => @import("serve/watcher/MacosWatcher.zig"),
|
||||
.windows => @import("serve/watcher/WindowsWatcher.zig"),
|
||||
.linux => @import("LinuxWatcher.zig"),
|
||||
.macos => @import("MacosWatcher.zig"),
|
||||
.windows => @import("WindowsWatcher.zig"),
|
||||
else => @compileError("unsupported platform"),
|
||||
};
|
||||
|
||||
pub const Debouncer = @import("Debouncer.zig");
|
||||
|
||||
pub const Error = error{
|
||||
OutOfMemory,
|
||||
SystemResources,
|
||||
Unexpected,
|
||||
ProcessFdQuotaExceeded,
|
||||
SystemFdQuotaExceeded,
|
||||
LockedMemoryLimitExceeded,
|
||||
ThreadQuotaExceeded,
|
||||
IsDir,
|
||||
WouldBlock,
|
||||
AccessDenied,
|
||||
ProcessNotFound,
|
||||
PermissionDenied,
|
||||
FileTooBig,
|
||||
NoSpaceLeft,
|
||||
DeviceBusy,
|
||||
NoDevice,
|
||||
SharingViolation,
|
||||
PathAlreadyExists,
|
||||
FileNotFound,
|
||||
PipeBusy,
|
||||
NameTooLong,
|
||||
InvalidUtf8,
|
||||
InvalidWtf8,
|
||||
BadPathName,
|
||||
NetworkNotFound,
|
||||
AntivirusInterference,
|
||||
SymLinkLoop,
|
||||
NotDir,
|
||||
FileLocksNotSupported,
|
||||
FileBusy,
|
||||
UserResourceLimitReached,
|
||||
WatchAlreadyExists,
|
||||
InvalidHandle,
|
||||
QueueFailed,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue