lsp import

This commit is contained in:
agra
2026-02-24 20:05:24 +02:00
parent 06d10541da
commit bfc784734c
4 changed files with 40 additions and 27 deletions

View File

@@ -45,6 +45,8 @@ pub const Document = struct {
pub const DocumentStore = struct {
allocator: std.mem.Allocator,
io: std.Io,
/// Workspace root path (from initialize). Used to absolutify CWD-relative import paths.
root_path: []const u8 = "",
/// All loaded documents keyed by resolved file path.
by_path: std.StringHashMap(*Document),
@@ -56,6 +58,10 @@ pub const DocumentStore = struct {
};
}
fn rootPathOpt(self: *const DocumentStore) ?[]const u8 {
return if (self.root_path.len > 0) self.root_path else null;
}
/// Get or create a document for the given file path. Reads from disk if not yet loaded.
pub fn getOrLoad(self: *DocumentStore, path: []const u8) !*Document {
if (self.by_path.get(path)) |doc| return doc;
@@ -171,17 +177,14 @@ pub const DocumentStore = struct {
const root = doc.root orelse return;
// Extract imports from AST
// Extract imports from AST — uses shared resolution logic from imports.zig
var import_list = std.ArrayList(Import).empty;
const base_dir = sx.imports.dirName(doc.path);
if (root.data == .root) {
for (root.data.root.decls) |decl| {
if (decl.data != .import_decl) continue;
const imp = decl.data.import_decl;
const resolved_path = if (std.mem.eql(u8, base_dir, "."))
imp.path
else
try std.fmt.allocPrint(self.allocator, "{s}/{s}", .{ base_dir, imp.path });
const resolved_path = try sx.imports.resolveImportPath(self.allocator, self.io, base_dir, imp.path, self.rootPathOpt());
try import_list.append(self.allocator, .{
.ns = imp.name,
.path = resolved_path,

View File

@@ -129,6 +129,7 @@ pub const Server = struct {
if (!std.mem.startsWith(u8, root_uri, prefix)) break :chdir;
const root_path = root_uri[prefix.len..];
self.root_path = self.allocator.dupe(u8, root_path) catch break :chdir;
self.documents.root_path = self.root_path;
const path_z = self.allocator.dupeZ(u8, root_path) catch break :chdir;
_ = std.c.chdir(path_z.ptr);
}
@@ -249,13 +250,11 @@ pub const Server = struct {
// 4. #import "path" string → open the file (or directory)
if (findImportPathAtOffset(doc.source, offset)) |import_path| {
const base_dir = sx.imports.dirName(file_path);
const resolved = if (std.mem.eql(u8, base_dir, "."))
import_path
else
try std.fmt.allocPrint(self.allocator, "{s}/{s}", .{ base_dir, import_path });
const rp: ?[]const u8 = if (self.root_path.len > 0) self.root_path else null;
const resolved = try sx.imports.resolveImportPath(self.allocator, self.io, base_dir, import_path, rp);
// For directory imports, try to read as file first
if (std.Io.Dir.readFileAlloc(.cwd(), self.io, resolved, self.allocator, .limited(1))) |_| {
if (std.Io.Dir.readFileAlloc(.cwd(), self.io, resolved, self.allocator, .limited(10 * 1024 * 1024))) |_| {
// It's a file — navigate to it
const target_uri = try std.fmt.allocPrint(self.allocator, "file://{s}", .{resolved});
const range = lsp.Range{