75 lines
3 KiB
Zig
75 lines
3 KiB
Zig
pub fn get(project: []const u8, lsp_name: []const u8) ?[]const u8 {
|
|
if (project.len == 0) return get_global(lsp_name);
|
|
if (get_project(project, lsp_name)) |conf| return conf;
|
|
return get_global(lsp_name);
|
|
}
|
|
|
|
fn get_project(project: []const u8, lsp_name: []const u8) ?[]const u8 {
|
|
const file_name = get_config_file_path(project, lsp_name, .project, .no_create) catch return null;
|
|
defer allocator.free(file_name);
|
|
const file: std.fs.File = std.fs.openFileAbsolute(file_name, .{ .mode = .read_only }) catch return null;
|
|
defer file.close();
|
|
return file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch return null;
|
|
}
|
|
|
|
fn get_global(lsp_name: []const u8) ?[]const u8 {
|
|
const file_name = get_config_file_path(&.{}, lsp_name, .global, .no_create) catch return null;
|
|
defer allocator.free(file_name);
|
|
const file: std.fs.File = std.fs.openFileAbsolute(file_name, .{ .mode = .read_only }) catch return null;
|
|
defer file.close();
|
|
return file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch return null;
|
|
}
|
|
|
|
pub fn get_config_file_path(project: ?[]const u8, lsp_name: []const u8, scope: Scope, mode: Mode) ![]u8 {
|
|
const config_dir_path = try get_config_dir_path(project, scope, mode);
|
|
defer allocator.free(config_dir_path);
|
|
var stream: std.Io.Writer.Allocating = .init(allocator);
|
|
defer stream.deinit();
|
|
try stream.writer.print("{s}{s}.json", .{ config_dir_path, lsp_name });
|
|
return stream.toOwnedSlice();
|
|
}
|
|
|
|
fn get_config_dir_path(project: ?[]const u8, scope: Scope, mode: Mode) ![]u8 {
|
|
var stream: std.Io.Writer.Allocating = .init(allocator);
|
|
defer stream.deinit();
|
|
const writer = &stream.writer;
|
|
try writer.writeAll(try root.get_config_dir());
|
|
try writer.writeByte(std.fs.path.sep);
|
|
switch (scope) {
|
|
.project => {
|
|
try writer.writeAll("project");
|
|
try writer.writeByte(std.fs.path.sep);
|
|
if (mode == .mk_parents) std.fs.makeDirAbsolute(stream.written()) catch |e| switch (e) {
|
|
error.PathAlreadyExists => {},
|
|
else => return e,
|
|
};
|
|
if (project) |prj| {
|
|
for (prj) |c| {
|
|
_ = if (std.fs.path.isSep(c))
|
|
try writer.write("__")
|
|
else if (c == ':')
|
|
try writer.write("___")
|
|
else
|
|
try writer.writeByte(c);
|
|
}
|
|
_ = try writer.writeByte(std.fs.path.sep);
|
|
}
|
|
},
|
|
.global => {
|
|
try writer.writeAll("lsp");
|
|
try writer.writeByte(std.fs.path.sep);
|
|
},
|
|
}
|
|
if (mode == .mk_parents) std.fs.makeDirAbsolute(stream.written()) catch |e| switch (e) {
|
|
error.PathAlreadyExists => {},
|
|
else => return e,
|
|
};
|
|
return stream.toOwnedSlice();
|
|
}
|
|
|
|
pub const Scope = enum { project, global };
|
|
pub const Mode = enum { mk_parents, no_create };
|
|
|
|
pub const allocator = std.heap.c_allocator;
|
|
const std = @import("std");
|
|
const root = @import("soft_root").root;
|