fix: watch all directories within the project tree
This commit is contained in:
parent
583344d413
commit
348c2055da
3 changed files with 40 additions and 10 deletions
|
|
@ -587,6 +587,10 @@ pub fn query_recent_files(self: *Self, from: tp.pid_ref, max: usize, query_: []c
|
|||
return @min(max, matches.items.len);
|
||||
}
|
||||
|
||||
fn walk_tree_dir_callback(parent: tp.pid_ref, root_path: []const u8, dir_path: []const u8) error{Exit}!void {
|
||||
try parent.send(.{ "walk_tree_dir", root_path, dir_path });
|
||||
}
|
||||
|
||||
fn walk_tree_entry_callback(parent: tp.pid_ref, root_path: []const u8, file_path: []const u8, mtime_high: i64, mtime_low: i64) error{Exit}!void {
|
||||
const file_type: []const u8, const file_icon: []const u8, const file_color: u24 = guess_file_type(file_path);
|
||||
try parent.send(.{ "walk_tree_entry", root_path, file_path, mtime_high, mtime_low, file_type, file_icon, file_color });
|
||||
|
|
@ -2830,6 +2834,7 @@ fn start_walker(self: *Self) void {
|
|||
.follow_directory_symlinks = tp.env.get().is("follow_directory_symlinks"),
|
||||
.maximum_symlink_depth = @intCast(tp.env.get().num("maximum_symlink_depth")),
|
||||
.log_ignored_links = tp.env.get().is("log_ignored_links"),
|
||||
.dir_callback = walk_tree_dir_callback,
|
||||
}) catch blk: {
|
||||
self.state.walk_tree = .failed;
|
||||
break :blk null;
|
||||
|
|
|
|||
|
|
@ -425,6 +425,10 @@ const Process = struct {
|
|||
|
||||
if (try cbor.match(m.buf, .{ "FW", "change", tp.extract(&path), tp.extract(&event_type) })) {
|
||||
self.handle_file_watch_event(path, event_type);
|
||||
} else if (try cbor.match(m.buf, .{ "walk_tree_dir", tp.extract(&project_directory), tp.extract(&path) })) {
|
||||
var abs_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const abs_path = std.fmt.bufPrint(&abs_buf, "{s}{c}{s}", .{ project_directory, std.fs.path.sep, path }) catch return;
|
||||
file_watcher.watch(abs_path) catch |e| self.logger.err("file_watcher.watch_dir", e);
|
||||
} else if (try cbor.match(m.buf, .{ "walk_tree_entry", tp.extract(&project_directory), tp.more })) {
|
||||
if (self.projects.get(project_directory)) |project|
|
||||
project.walk_tree_entry(m) catch |e| self.logger.err("walk_tree_entry", e);
|
||||
|
|
@ -440,6 +444,15 @@ const Process = struct {
|
|||
} else if (try cbor.match(m.buf, .{ "git", tp.extract(&context), "blame", tp.more })) {
|
||||
const request: *Project.GitBlameRequest = @ptrFromInt(context);
|
||||
request.project.process_git_response(self.parent.ref(), m) catch |e| self.logger.err("git-blame", e);
|
||||
} else if (try cbor.match(m.buf, .{ "git", tp.extract(&context), "workspace_files", tp.extract(&path) })) {
|
||||
const project: *Project = @ptrFromInt(context);
|
||||
const dir_path = std.fs.path.dirname(path) orelse "";
|
||||
if (dir_path.len > 0) blk: {
|
||||
var abs_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const abs_path = std.fmt.bufPrint(&abs_buf, "{s}{c}{s}", .{ project.name, std.fs.path.sep, dir_path }) catch break :blk;
|
||||
file_watcher.watch(abs_path) catch |e| self.logger.err("file_watcher.watch_dir", e);
|
||||
}
|
||||
project.process_git(self.parent.ref(), m) catch {};
|
||||
} else if (try cbor.match(m.buf, .{ "git", tp.extract(&context), tp.more })) {
|
||||
const project: *Project = @ptrFromInt(context);
|
||||
project.process_git(self.parent.ref(), m) catch {};
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ const OutOfMemoryError = error{OutOfMemory};
|
|||
|
||||
pub const EntryCallBack = *const fn (parent: tp.pid_ref, root_path: []const u8, path: []const u8, mtime_high: i64, mtime_low: i64) error{Exit}!void;
|
||||
pub const DoneCallBack = *const fn (parent: tp.pid_ref, root_path: []const u8) error{Exit}!void;
|
||||
pub const DirCallBack = *const fn (parent: tp.pid_ref, root_path: []const u8, path: []const u8) error{Exit}!void;
|
||||
|
||||
pub const Options = struct {
|
||||
follow_directory_symlinks: bool = false,
|
||||
maximum_symlink_depth: usize = 1,
|
||||
log_ignored_links: bool = false,
|
||||
dir_callback: ?DirCallBack = null,
|
||||
};
|
||||
|
||||
pub fn start(a_: std.mem.Allocator, root_path_: []const u8, entry_handler: EntryCallBack, done_handler: DoneCallBack, options: Options) (SpawnError || std.fs.Dir.OpenError)!tp.pid {
|
||||
|
|
@ -78,7 +80,13 @@ pub fn start(a_: std.mem.Allocator, root_path_: []const u8, entry_handler: Entry
|
|||
}
|
||||
|
||||
fn next(self: *tree_walker) !void {
|
||||
if (try self.walker.next()) |path| {
|
||||
if (try self.walker.next()) |entry| {
|
||||
if (entry.kind == .dir) {
|
||||
if (self.options.dir_callback) |cb|
|
||||
cb(self.parent.ref(), self.root_path, entry.path) catch {};
|
||||
return tp.self_pid().send(.{"next"});
|
||||
}
|
||||
const path = entry.path;
|
||||
const stat = self.dir.statFile(path) catch {
|
||||
try self.entry_handler(self.parent.ref(), self.root_path, path, 0, 0);
|
||||
return tp.self_pid().send(.{"next"});
|
||||
|
|
@ -123,6 +131,8 @@ const FilteredWalker = struct {
|
|||
name_buffer: std.ArrayListUnmanaged(u8),
|
||||
options: Options,
|
||||
|
||||
const Kind = enum { file, dir };
|
||||
const Entry = struct { path: []const u8, kind: Kind };
|
||||
const Path = []const u8;
|
||||
|
||||
const StackItem = struct {
|
||||
|
|
@ -160,7 +170,7 @@ const FilteredWalker = struct {
|
|||
self.name_buffer.deinit(self.allocator);
|
||||
}
|
||||
|
||||
fn next(self: *FilteredWalker) OutOfMemoryError!?Path {
|
||||
fn next(self: *FilteredWalker) OutOfMemoryError!?Entry {
|
||||
while (self.stack.items.len != 0) {
|
||||
var top = &self.stack.items[self.stack.items.len - 1];
|
||||
var containing = top;
|
||||
|
|
@ -182,17 +192,17 @@ const FilteredWalker = struct {
|
|||
switch (base.kind) {
|
||||
.directory => {
|
||||
_ = try self.next_directory(&base, &top, &containing, top.symlink_depth);
|
||||
continue;
|
||||
return .{ .path = self.name_buffer.items, .kind = .dir };
|
||||
},
|
||||
.file => return self.name_buffer.items,
|
||||
.file => return .{ .path = self.name_buffer.items, .kind = .file },
|
||||
.sym_link => {
|
||||
if (top.symlink_depth == 0) {
|
||||
if (self.options.log_ignored_links)
|
||||
std.log.warn("TOO MANY LINKS! ignoring symlink: {s}", .{base.name});
|
||||
continue;
|
||||
}
|
||||
if (try self.next_sym_link(&base, &top, &containing, top.symlink_depth -| 1)) |file|
|
||||
return file
|
||||
if (try self.next_sym_link(&base, &top, &containing, top.symlink_depth -| 1)) |entry|
|
||||
return entry
|
||||
else
|
||||
continue;
|
||||
},
|
||||
|
|
@ -229,15 +239,17 @@ const FilteredWalker = struct {
|
|||
return;
|
||||
}
|
||||
|
||||
fn next_sym_link(self: *FilteredWalker, base: *const std.fs.Dir.Entry, top: **StackItem, containing: **StackItem, symlink_depth: usize) !?[]const u8 {
|
||||
fn next_sym_link(self: *FilteredWalker, base: *const std.fs.Dir.Entry, top: **StackItem, containing: **StackItem, symlink_depth: usize) !?Entry {
|
||||
const st = top.*.iter.dir.statFile(base.name) catch return null;
|
||||
switch (st.kind) {
|
||||
.directory => {
|
||||
if (self.options.follow_directory_symlinks)
|
||||
_ = try self.next_directory(base, top, containing, symlink_depth);
|
||||
if (self.options.follow_directory_symlinks) {
|
||||
try self.next_directory(base, top, containing, symlink_depth);
|
||||
return .{ .path = self.name_buffer.items, .kind = .dir };
|
||||
}
|
||||
return null;
|
||||
},
|
||||
.file => return self.name_buffer.items,
|
||||
.file => return .{ .path = self.name_buffer.items, .kind = .file },
|
||||
.sym_link => {
|
||||
if (symlink_depth == 0) {
|
||||
if (self.options.log_ignored_links)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue