Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A lightweight and cross-platform file watcher for your Zig projects.
You can run the [examples](./examples/) like so:

```sh
zig build run-<filename>
zig build run-<example-filename> -- <file-to-watch>
```

### Usage
Expand Down
11 changes: 10 additions & 1 deletion examples/basic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@ fn watcherThread(watcher: *fzwatch.Watcher) !void {
pub fn main() !void {
const allocator = std.heap.page_allocator;

const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);

if (args.len < 2) {
std.debug.print("Usage: {s} <file-to-watch>\n", .{args[0]});
return error.InvalidArgument;
}
const target_file = args[1];

var watcher = try fzwatch.Watcher.init(allocator);
defer watcher.deinit();

try watcher.addFile("README.md");
try watcher.addFile(target_file);
watcher.setCallback(callback, null);

const thread = try std.Thread.spawn(.{}, watcherThread, .{&watcher});
Expand Down
16 changes: 13 additions & 3 deletions examples/context.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const Object = struct {
}
}

pub fn init(allocator: std.mem.Allocator) !Object {
pub fn init(allocator: std.mem.Allocator, target_file: [:0]u8) !Object {
var watcher = try fzwatch.Watcher.init(allocator);
try watcher.addFile("README.md");
try watcher.addFile(target_file);

return Object{
.allocator = allocator,
Expand All @@ -45,7 +45,17 @@ const Object = struct {

pub fn main() !void {
const allocator = std.heap.page_allocator;
var obj = try Object.init(allocator);

const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);

if (args.len < 2) {
std.debug.print("Usage: {s} <file-to-watch>\n", .{args[0]});
return error.InvalidArgument;
}
const target_file = args[1];

var obj = try Object.init(allocator, target_file);
defer obj.deinit();
try obj.start();

Expand Down
9 changes: 4 additions & 5 deletions src/watchers/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ pub const LinuxWatcher = struct {
}

pub fn addFile(self: *LinuxWatcher, path: []const u8) !void {
try std.fs.cwd().access(path, .{});
_ = try std.posix.inotify_add_watch(
self.inotify.fd,
path,
std.os.linux.IN.MODIFY,
std.os.linux.IN.MODIFY | std.os.linux.IN.CLOSE_WRITE | std.os.linux.IN.ATTRIB | std.os.linux.IN.MOVE_SELF | std.os.linux.IN.DELETE_SELF,
);

try self.paths.append(self.allocator, path);
Expand Down Expand Up @@ -102,14 +103,12 @@ pub const LinuxWatcher = struct {
} else if (ev.wd > self.paths.items.len + self.inotify.offset)
return error.InvalidWatchDescriptor;

if (ev.mask & std.os.linux.IN.IGNORED == 0 and ev.mask & std.os.linux.IN.MODIFY == 0)
continue;

const index = @as(usize, @intCast(@max(0, ev.wd))) - self.inotify.offset;
// Editors like vim create temporary files when saving
// So we have to re-add the file to the watcher
if (ev.mask & std.os.linux.IN.IGNORED != 0)
if (ev.mask & (std.os.linux.IN.DELETE_SELF | std.os.linux.IN.MOVE_SELF | std.os.linux.IN.IGNORED) != 0) {
try self.addFile(self.paths.items[index]);
}
if (self.callback) |callback| callback(self.context, .modified);
}
}
Expand Down