Added zig_exe_path option, use it to detect lib path if none is provided
This commit is contained in:
parent
c9af33011a
commit
543cb5816c
@ -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). |
|
| `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_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 |
|
| `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` |
|
| `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 library path
|
||||||
zig_lib_path: ?[]const u8 = null,
|
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
|
/// 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.
|
/// guide explicitly states that the style info provided is a guideline only.
|
||||||
warn_style: bool = false,
|
warn_style: bool = false,
|
||||||
|
@ -74,7 +74,7 @@ pub const TagStore = struct {
|
|||||||
|
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
handles: std.StringHashMap(*Handle),
|
handles: std.StringHashMap(*Handle),
|
||||||
has_zig: bool,
|
zig_exe_path: ?[]const u8,
|
||||||
build_files: std.ArrayListUnmanaged(*BuildFile),
|
build_files: std.ArrayListUnmanaged(*BuildFile),
|
||||||
build_runner_path: []const u8,
|
build_runner_path: []const u8,
|
||||||
|
|
||||||
@ -84,12 +84,12 @@ enum_completions: TagStore,
|
|||||||
pub fn init(
|
pub fn init(
|
||||||
self: *DocumentStore,
|
self: *DocumentStore,
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
has_zig: bool,
|
zig_exe_path: ?[]const u8,
|
||||||
build_runner_path: []const u8,
|
build_runner_path: []const u8,
|
||||||
) !void {
|
) !void {
|
||||||
self.allocator = allocator;
|
self.allocator = allocator;
|
||||||
self.handles = std.StringHashMap(*Handle).init(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_files = .{};
|
||||||
self.build_runner_path = build_runner_path;
|
self.build_runner_path = build_runner_path;
|
||||||
self.error_completions = TagStore.init(allocator);
|
self.error_completions = TagStore.init(allocator);
|
||||||
@ -100,12 +100,14 @@ const LoadPackagesContext = struct {
|
|||||||
build_file: *BuildFile,
|
build_file: *BuildFile,
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
build_runner_path: []const u8,
|
build_runner_path: []const u8,
|
||||||
|
zig_exe_path: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn loadPackages(context: LoadPackagesContext) !void {
|
fn loadPackages(context: LoadPackagesContext) !void {
|
||||||
const allocator = context.allocator;
|
const allocator = context.allocator;
|
||||||
const build_file = context.build_file;
|
const build_file = context.build_file;
|
||||||
const build_runner_path = context.build_runner_path;
|
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]);
|
const directory_path = try URI.parse(allocator, build_file.uri[0 .. build_file.uri.len - "build.zig".len]);
|
||||||
defer allocator.free(directory_path);
|
defer allocator.free(directory_path);
|
||||||
@ -134,7 +136,7 @@ fn loadPackages(context: LoadPackagesContext) !void {
|
|||||||
|
|
||||||
const zig_run_result = try std.ChildProcess.exec(.{
|
const zig_run_result = try std.ChildProcess.exec(.{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.argv = &[_][]const u8{ "zig", "run", "build_runner.zig" },
|
.argv = &[_][]const u8{ zig_exe_path, "run", "build_runner.zig" },
|
||||||
.cwd = directory_path,
|
.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?
|
// TODO: Better logic for detecting std or subdirectories?
|
||||||
const in_std = std.mem.indexOf(u8, uri, "/std/") != null;
|
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", .{});
|
std.debug.warn("Document is a build file, extracting packages...\n", .{});
|
||||||
// This is a build file.
|
// This is a build file.
|
||||||
var build_file = try self.allocator.create(BuildFile);
|
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,
|
.build_file = build_file,
|
||||||
.allocator = self.allocator,
|
.allocator = self.allocator,
|
||||||
.build_runner_path = self.build_runner_path,
|
.build_runner_path = self.build_runner_path,
|
||||||
|
.zig_exe_path = self.zig_exe_path.?,
|
||||||
}) catch |err| {
|
}) catch |err| {
|
||||||
std.debug.warn("Failed to load packages of build file {} (error: {})\n", .{ build_file.uri, 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
|
// Look into build files to see if we already have one that fits
|
||||||
for (self.build_files.items) |build_file| {
|
for (self.build_files.items) |build_file| {
|
||||||
const build_file_base_uri = build_file.uri[0 .. std.mem.lastIndexOfScalar(u8, build_file.uri, '/').? + 1];
|
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,
|
.build_file = build_file,
|
||||||
.allocator = self.allocator,
|
.allocator = self.allocator,
|
||||||
.build_runner_path = self.build_runner_path,
|
.build_runner_path = self.build_runner_path,
|
||||||
|
.zig_exe_path = self.zig_exe_path.?,
|
||||||
}) catch |err| {
|
}) catch |err| {
|
||||||
std.debug.warn("Failed to load packages of build file {} (error: {})\n", .{ build_file.uri, 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{
|
try send(types.Response{
|
||||||
.id = .{ .Integer = id },
|
.id = .{ .Integer = id },
|
||||||
.result = .{
|
.result = .{ .DocumentSymbols = try analysis.getDocumentSymbols(&arena.allocator, handle.tree) },
|
||||||
.DocumentSymbols = try analysis.getDocumentSymbols(&arena.allocator, handle.tree)
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,11 +928,19 @@ pub fn main() anyerror!void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the zig executable in PATH
|
// 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: {
|
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) {
|
const env_path = std.process.getEnvVarOwned(allocator, "PATH") catch |err| switch (err) {
|
||||||
error.EnvironmentVariableNotFound => {
|
error.EnvironmentVariableNotFound => {
|
||||||
std.debug.warn("Could not get PATH.\n", .{});
|
std.debug.warn("Could not get PATH.\n", .{});
|
||||||
@ -957,21 +963,32 @@ pub fn main() anyerror!void {
|
|||||||
defer allocator.free(full_path);
|
defer allocator.free(full_path);
|
||||||
|
|
||||||
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||||
const zig_path = std.os.realpath(full_path, &buf) catch continue;
|
zig_exe_path = std.os.realpath(full_path, &buf) catch continue;
|
||||||
std.debug.warn("Found zig in PATH: {}\n", .{zig_path});
|
std.debug.warn("Found zig in PATH: {}\n", .{zig_exe_path});
|
||||||
has_zig = true;
|
|
||||||
break :find_zig;
|
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| {
|
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 {
|
} else {
|
||||||
var exe_dir_bytes: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
var exe_dir_bytes: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||||
const exe_dir_path = try std.fs.selfExeDirPath(&exe_dir_bytes);
|
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" });
|
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();
|
defer document_store.deinit();
|
||||||
|
Loading…
Reference in New Issue
Block a user