Merge pull request #98 from alexnask/general_improvements
Added zig_exe_path option, use it to detect lib path if none is provided
This commit is contained in:
		
						commit
						3f1d136bb8
					
				@ -55,6 +55,7 @@ The following options are currently available.
 | 
			
		||||
| --- | --- | --- | --- |
 | 
			
		||||
| `enable_snippets` | `bool` | `false` | Enables snippet completion, set to false for compatibility with language clients that do not support snippets (such as ale). |
 | 
			
		||||
| `zig_lib_path` | `?[]const u8` | `null` | zig library path, e.g. `/path/to/zig/lib/zig`, used to analyze std library imports. |
 | 
			
		||||
| `zig_exe_path` | `?[]const u8` | `null` | zig executable path, e.g. `/path/to/zig/bin/zig`, used to run the custom build runner. If `null`, zig is looked up in `PATH`. Will be used to infer the zig standard library path if none is provided. |
 | 
			
		||||
| `warn_style` | `bool` | `false` | Enables warnings for style *guideline* mismatches |
 | 
			
		||||
| `build_runner_path` | `?[]const u8` | `null` | Path to the build_runner.zig file provided by zls. This option must be present in one of the global configuration files to have any effect. `null` is equivalent to `${executable_directory}/build_runner.zig` |
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,10 @@ enable_snippets: bool = false,
 | 
			
		||||
/// zig library path
 | 
			
		||||
zig_lib_path: ?[]const u8 = null,
 | 
			
		||||
 | 
			
		||||
/// zig executable path used to run the custom build runner.
 | 
			
		||||
/// May be used to find a lib path if none is provided.
 | 
			
		||||
zig_exe_path: ?[]const u8 = null,
 | 
			
		||||
 | 
			
		||||
/// Whether to pay attention to style issues. This is opt-in since the style
 | 
			
		||||
/// guide explicitly states that the style info provided is a guideline only.
 | 
			
		||||
warn_style: bool = false,
 | 
			
		||||
 | 
			
		||||
@ -74,7 +74,7 @@ pub const TagStore = struct {
 | 
			
		||||
 | 
			
		||||
allocator: *std.mem.Allocator,
 | 
			
		||||
handles: std.StringHashMap(*Handle),
 | 
			
		||||
has_zig: bool,
 | 
			
		||||
zig_exe_path: ?[]const u8,
 | 
			
		||||
build_files: std.ArrayListUnmanaged(*BuildFile),
 | 
			
		||||
build_runner_path: []const u8,
 | 
			
		||||
 | 
			
		||||
@ -84,12 +84,12 @@ enum_completions: TagStore,
 | 
			
		||||
pub fn init(
 | 
			
		||||
    self: *DocumentStore,
 | 
			
		||||
    allocator: *std.mem.Allocator,
 | 
			
		||||
    has_zig: bool,
 | 
			
		||||
    zig_exe_path: ?[]const u8,
 | 
			
		||||
    build_runner_path: []const u8,
 | 
			
		||||
) !void {
 | 
			
		||||
    self.allocator = allocator;
 | 
			
		||||
    self.handles = std.StringHashMap(*Handle).init(allocator);
 | 
			
		||||
    self.has_zig = has_zig;
 | 
			
		||||
    self.zig_exe_path = zig_exe_path;
 | 
			
		||||
    self.build_files = .{};
 | 
			
		||||
    self.build_runner_path = build_runner_path;
 | 
			
		||||
    self.error_completions = TagStore.init(allocator);
 | 
			
		||||
@ -100,12 +100,14 @@ const LoadPackagesContext = struct {
 | 
			
		||||
    build_file: *BuildFile,
 | 
			
		||||
    allocator: *std.mem.Allocator,
 | 
			
		||||
    build_runner_path: []const u8,
 | 
			
		||||
    zig_exe_path: []const u8,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fn loadPackages(context: LoadPackagesContext) !void {
 | 
			
		||||
    const allocator = context.allocator;
 | 
			
		||||
    const build_file = context.build_file;
 | 
			
		||||
    const build_runner_path = context.build_runner_path;
 | 
			
		||||
    const zig_exe_path = context.zig_exe_path;
 | 
			
		||||
 | 
			
		||||
    const directory_path = try URI.parse(allocator, build_file.uri[0 .. build_file.uri.len - "build.zig".len]);
 | 
			
		||||
    defer allocator.free(directory_path);
 | 
			
		||||
@ -134,7 +136,7 @@ fn loadPackages(context: LoadPackagesContext) !void {
 | 
			
		||||
 | 
			
		||||
    const zig_run_result = try std.ChildProcess.exec(.{
 | 
			
		||||
        .allocator = allocator,
 | 
			
		||||
        .argv = &[_][]const u8{ "zig", "run", "build_runner.zig" },
 | 
			
		||||
        .argv = &[_][]const u8{ zig_exe_path, "run", "build_runner.zig" },
 | 
			
		||||
        .cwd = directory_path,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@ -204,7 +206,7 @@ fn newDocument(self: *DocumentStore, uri: []const u8, text: []u8) anyerror!*Hand
 | 
			
		||||
 | 
			
		||||
    // TODO: Better logic for detecting std or subdirectories?
 | 
			
		||||
    const in_std = std.mem.indexOf(u8, uri, "/std/") != null;
 | 
			
		||||
    if (self.has_zig and std.mem.endsWith(u8, uri, "/build.zig") and !in_std) {
 | 
			
		||||
    if (self.zig_exe_path != null and std.mem.endsWith(u8, uri, "/build.zig") and !in_std) {
 | 
			
		||||
        std.debug.warn("Document is a build file, extracting packages...\n", .{});
 | 
			
		||||
        // This is a build file.
 | 
			
		||||
        var build_file = try self.allocator.create(BuildFile);
 | 
			
		||||
@ -225,10 +227,11 @@ fn newDocument(self: *DocumentStore, uri: []const u8, text: []u8) anyerror!*Hand
 | 
			
		||||
            .build_file = build_file,
 | 
			
		||||
            .allocator = self.allocator,
 | 
			
		||||
            .build_runner_path = self.build_runner_path,
 | 
			
		||||
            .zig_exe_path = self.zig_exe_path.?,
 | 
			
		||||
        }) catch |err| {
 | 
			
		||||
            std.debug.warn("Failed to load packages of build file {} (error: {})\n", .{ build_file.uri, err });
 | 
			
		||||
        };
 | 
			
		||||
    } else if (self.has_zig and !in_std) associate_build_file: {
 | 
			
		||||
    } else if (self.zig_exe_path != null and !in_std) associate_build_file: {
 | 
			
		||||
        // Look into build files to see if we already have one that fits
 | 
			
		||||
        for (self.build_files.items) |build_file| {
 | 
			
		||||
            const build_file_base_uri = build_file.uri[0 .. std.mem.lastIndexOfScalar(u8, build_file.uri, '/').? + 1];
 | 
			
		||||
@ -471,6 +474,7 @@ pub fn applyChanges(
 | 
			
		||||
            .build_file = build_file,
 | 
			
		||||
            .allocator = self.allocator,
 | 
			
		||||
            .build_runner_path = self.build_runner_path,
 | 
			
		||||
            .zig_exe_path = self.zig_exe_path.?,
 | 
			
		||||
        }) catch |err| {
 | 
			
		||||
            std.debug.warn("Failed to load packages of build file {} (error: {})\n", .{ build_file.uri, err });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										39
									
								
								src/main.zig
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								src/main.zig
									
									
									
									
									
								
							@ -533,9 +533,7 @@ fn documentSymbol(id: i64, handle: *DocumentStore.Handle) !void {
 | 
			
		||||
 | 
			
		||||
    try send(types.Response{
 | 
			
		||||
        .id = .{ .Integer = id },
 | 
			
		||||
        .result = .{
 | 
			
		||||
            .DocumentSymbols = try analysis.getDocumentSymbols(&arena.allocator, handle.tree)
 | 
			
		||||
        },
 | 
			
		||||
        .result = .{ .DocumentSymbols = try analysis.getDocumentSymbols(&arena.allocator, handle.tree) },
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -930,11 +928,19 @@ pub fn main() anyerror!void {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Find the zig executable in PATH
 | 
			
		||||
    var has_zig = false;
 | 
			
		||||
    var zig_exe_path: ?[]const u8 = null;
 | 
			
		||||
    defer if (zig_exe_path) |exe_path| allocator.free(exe_path);
 | 
			
		||||
 | 
			
		||||
    // TODO: Should we just spawn a child process that calls "zig version" or something
 | 
			
		||||
    // and check that way?
 | 
			
		||||
    find_zig: {
 | 
			
		||||
        if (config.zig_exe_path) |exe_path| {
 | 
			
		||||
            if (std.fs.path.isAbsolute(exe_path)) {
 | 
			
		||||
                zig_exe_path = try std.mem.dupe(allocator, u8, exe_path);
 | 
			
		||||
                break :find_zig;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            std.debug.warn("zig path `{}` is not absolute, will look in path\n", .{exe_path});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const env_path = std.process.getEnvVarOwned(allocator, "PATH") catch |err| switch (err) {
 | 
			
		||||
            error.EnvironmentVariableNotFound => {
 | 
			
		||||
                std.debug.warn("Could not get PATH.\n", .{});
 | 
			
		||||
@ -957,21 +963,32 @@ pub fn main() anyerror!void {
 | 
			
		||||
            defer allocator.free(full_path);
 | 
			
		||||
 | 
			
		||||
            var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
 | 
			
		||||
            const zig_path = std.os.realpath(full_path, &buf) catch continue;
 | 
			
		||||
            std.debug.warn("Found zig in PATH: {}\n", .{zig_path});
 | 
			
		||||
            has_zig = true;
 | 
			
		||||
            zig_exe_path = std.os.realpath(full_path, &buf) catch continue;
 | 
			
		||||
            std.debug.warn("Found zig in PATH: {}\n", .{zig_exe_path});
 | 
			
		||||
            break :find_zig;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (zig_exe_path) |exe_path| {
 | 
			
		||||
        std.debug.warn("Using zig executable {}\n", .{exe_path});
 | 
			
		||||
        if (config.zig_lib_path == null) {
 | 
			
		||||
            // Set the lib path relative to the executable path.
 | 
			
		||||
            config.zig_lib_path = try std.fs.path.resolve(allocator, &[_][]const u8{
 | 
			
		||||
                std.fs.path.dirname(exe_path).?, "./lib/zig",
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            std.debug.warn("Resolved standard library from executable: {}\n", .{config.zig_lib_path});
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.build_runner_path) |build_runner_path| {
 | 
			
		||||
        try document_store.init(allocator, has_zig, try std.mem.dupe(allocator, u8, build_runner_path));
 | 
			
		||||
        try document_store.init(allocator, zig_exe_path, try std.mem.dupe(allocator, u8, build_runner_path));
 | 
			
		||||
    } else {
 | 
			
		||||
        var exe_dir_bytes: [std.fs.MAX_PATH_BYTES]u8 = undefined;
 | 
			
		||||
        const exe_dir_path = try std.fs.selfExeDirPath(&exe_dir_bytes);
 | 
			
		||||
 | 
			
		||||
        const build_runner_path = try std.fs.path.resolve(allocator, &[_][]const u8{ exe_dir_path, "build_runner.zig" });
 | 
			
		||||
        try document_store.init(allocator, has_zig, build_runner_path);
 | 
			
		||||
        try document_store.init(allocator, zig_exe_path, build_runner_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    defer document_store.deinit();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user