Skip to content

Commit e2e210b

Browse files
committed
Load all documents in workspace on start
1 parent 5cb4c2c commit e2e210b

File tree

2 files changed

+65
-19
lines changed

2 files changed

+65
-19
lines changed

src/DocumentStore.zig

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,11 @@ pub fn getOrLoadHandle(store: *DocumentStore, uri: Uri) ?*Handle {
687687

688688
const file_contents = store.readUri(uri) orelse return null;
689689
return store.createAndStoreDocument(uri, file_contents, false) catch |err| {
690+
store.lock.lock();
691+
defer store.lock.unlock();
692+
693+
_ = store.currently_loading_uris.swapRemove(uri);
694+
690695
log.err("failed to store document '{s}': {}", .{ uri, err });
691696
return null;
692697
};
@@ -1366,8 +1371,6 @@ fn createAndStoreDocument(
13661371
self.allocator.destroy(old_handle);
13671372
}
13681373

1369-
try self.loadDependencies(handle.import_uris.items);
1370-
13711374
if (isBuildFile(handle.uri)) {
13721375
log.debug("Opened document '{s}' (build file)", .{handle.uri});
13731376
} else {
@@ -1377,9 +1380,46 @@ fn createAndStoreDocument(
13771380
return handle;
13781381
}
13791382

1380-
fn loadDependencies(store: *DocumentStore, import_uris: []const []const u8) !void {
1381-
var not_currently_loading_uris: std.ArrayListUnmanaged([]const u8) =
1382-
try .initCapacity(store.allocator, import_uris.len);
1383+
pub fn loadDirectoryRecursive(store: *DocumentStore, directory_uri: Uri) !void {
1384+
const workspace_path = try URI.parse(store.allocator, directory_uri);
1385+
defer store.allocator.free(workspace_path);
1386+
1387+
var workspace_dir = try std.fs.openDirAbsolute(workspace_path, .{ .iterate = true });
1388+
defer workspace_dir.close();
1389+
1390+
var walker = try workspace_dir.walk(store.allocator);
1391+
defer walker.deinit();
1392+
1393+
var uris: std.ArrayListUnmanaged([]const u8) = .empty;
1394+
defer uris.deinit(store.allocator);
1395+
1396+
{
1397+
errdefer {
1398+
for (uris.items) |uri| {
1399+
store.allocator.free(uri);
1400+
}
1401+
}
1402+
1403+
while (try walker.next()) |entry| {
1404+
if (std.mem.indexOf(u8, entry.path, std.fs.path.sep_str ++ ".zig-cache" ++ std.fs.path.sep_str) != null) continue;
1405+
if (std.mem.startsWith(u8, entry.path, ".zig-cache" ++ std.fs.path.sep_str)) continue;
1406+
if (!std.mem.eql(u8, std.fs.path.extension(entry.basename), ".zig")) continue;
1407+
1408+
const uri = try std.fs.path.join(store.allocator, &.{ workspace_path, entry.path });
1409+
defer store.allocator.free(uri);
1410+
1411+
_ = try uris.append(store.allocator, try URI.fromPath(store.allocator, uri));
1412+
}
1413+
}
1414+
1415+
try store.loadManyUrisAtOnce(uris.items);
1416+
}
1417+
1418+
/// **Thread safe**
1419+
/// Takes ownership of uris
1420+
fn loadManyUrisAtOnce(store: *DocumentStore, uris: []const Uri) !void {
1421+
var not_currently_loading_uris: std.ArrayListUnmanaged(Uri) =
1422+
try .initCapacity(store.allocator, uris.len);
13831423
defer {
13841424
not_currently_loading_uris.deinit(store.allocator);
13851425
}
@@ -1393,30 +1433,28 @@ fn loadDependencies(store: *DocumentStore, import_uris: []const []const u8) !voi
13931433
store.lock.lockShared();
13941434
defer store.lock.unlockShared();
13951435

1396-
for (import_uris) |import_uri| {
1397-
if (!store.handles.contains(import_uri) and
1398-
!store.currently_loading_uris.contains(import_uri))
1436+
for (uris) |uri| {
1437+
if (!store.handles.contains(uri) and
1438+
!store.currently_loading_uris.contains(uri))
13991439
{
1400-
not_currently_loading_uris.appendAssumeCapacity(
1401-
try store.allocator.dupe(u8, import_uri),
1402-
);
1440+
not_currently_loading_uris.appendAssumeCapacity(uri);
14031441
}
14041442
}
14051443
}
14061444

14071445
errdefer comptime unreachable;
14081446

14091447
const S = struct {
1410-
fn getOrLoadHandleVoid(s: *DocumentStore, duped_import_uri: Uri) void {
1411-
_ = s.getOrLoadHandle(duped_import_uri);
1412-
defer s.allocator.free(duped_import_uri);
1448+
fn getOrLoadHandleVoid(s: *DocumentStore, uri: Uri) void {
1449+
_ = s.getOrLoadHandle(uri);
1450+
defer s.allocator.free(uri);
14131451
}
14141452
};
14151453

1416-
for (not_currently_loading_uris.items) |duped_import_uri| {
1417-
store.thread_pool.spawn(S.getOrLoadHandleVoid, .{ store, duped_import_uri }) catch {
1418-
defer store.allocator.free(duped_import_uri);
1419-
_ = store.getOrLoadHandle(duped_import_uri);
1454+
for (not_currently_loading_uris.items) |uri| {
1455+
store.thread_pool.spawn(S.getOrLoadHandleVoid, .{ store, uri }) catch {
1456+
defer store.allocator.free(uri);
1457+
_ = store.getOrLoadHandle(uri);
14201458
};
14211459
}
14221460
}

src/Server.zig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,14 @@ fn addWorkspace(server: *Server, uri: types.URI) error{OutOfMemory}!void {
861861
.restart = false,
862862
});
863863
}
864+
865+
server.document_store.loadDirectoryRecursive(uri) catch |err| switch (err) {
866+
error.UnsupportedScheme => return,
867+
else => {
868+
log.err("failed to load files in workspace '{s}': {}", .{ uri, err });
869+
return;
870+
},
871+
};
864872
}
865873

866874
fn removeWorkspace(server: *Server, uri: types.URI) void {
@@ -893,7 +901,7 @@ fn didChangeWatchedFilesHandler(server: *Server, arena: std.mem.Allocator, notif
893901
const uri = try Uri.fromPath(arena, file_path);
894902

895903
switch (change.type) {
896-
.Created, .Changed, .Deleted => {
904+
.Created, .Changed => {
897905
const did_update_file = try server.document_store.refreshDocumentFromFileSystem(uri);
898906
updated_files += @intFromBool(did_update_file);
899907
},

0 commit comments

Comments
 (0)