support enums in config_gen (#1072)
* support enum types in config_gen * fix typo
This commit is contained in:
parent
8d86d54c0d
commit
0aacb76743
@ -86,7 +86,7 @@ The following options are currently available.
|
|||||||
| `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/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 |
|
| `zig_exe_path` | `?[]const u8` | `null` | Zig executable path, e.g. `/path/to/zig/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 |
|
||||||
| `build_runner_path` | `?[]const u8` | `null` | Path to the `build_runner.zig` file provided by zls. 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. null is equivalent to `${executable_directory}/build_runner.zig` |
|
||||||
| `global_cache_path` | `?[]const u8` | `null` | Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFloders.Cache}/zls` |
|
| `global_cache_path` | `?[]const u8` | `null` | Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFolders.Cache}/zls` |
|
||||||
| `build_runner_global_cache_path` | `?[]const u8` | `null` | Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env` |
|
| `build_runner_global_cache_path` | `?[]const u8` | `null` | Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env` |
|
||||||
<!-- DO NOT EDIT -->
|
<!-- DO NOT EDIT -->
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
"default": "null"
|
"default": "null"
|
||||||
},
|
},
|
||||||
"global_cache_path": {
|
"global_cache_path": {
|
||||||
"description": "Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFloders.Cache}/zls`",
|
"description": "Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFolders.Cache}/zls`",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "null"
|
"default": "null"
|
||||||
},
|
},
|
||||||
|
@ -76,7 +76,7 @@ zig_exe_path: ?[]const u8 = null,
|
|||||||
/// Path to the `build_runner.zig` file provided by zls. null is equivalent to `${executable_directory}/build_runner.zig`
|
/// Path to the `build_runner.zig` file provided by zls. null is equivalent to `${executable_directory}/build_runner.zig`
|
||||||
build_runner_path: ?[]const u8 = null,
|
build_runner_path: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFloders.Cache}/zls`
|
/// Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFolders.Cache}/zls`
|
||||||
global_cache_path: ?[]const u8 = null,
|
global_cache_path: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env`
|
/// Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env`
|
||||||
|
@ -146,7 +146,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "global_cache_path",
|
"name": "global_cache_path",
|
||||||
"description": "Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFloders.Cache}/zls`",
|
"description": "Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFolders.Cache}/zls`",
|
||||||
"type": "?[]const u8",
|
"type": "?[]const u8",
|
||||||
"default": "null"
|
"default": "null"
|
||||||
},
|
},
|
||||||
|
@ -10,8 +10,70 @@ const ConfigOption = struct {
|
|||||||
description: []const u8,
|
description: []const u8,
|
||||||
/// zig type in string form. e.g "u32", "[]const u8", "?usize"
|
/// zig type in string form. e.g "u32", "[]const u8", "?usize"
|
||||||
type: []const u8,
|
type: []const u8,
|
||||||
|
/// if the zig type should be an enum, this should contain
|
||||||
|
/// a list of enum values and `type`
|
||||||
|
/// If this is set, the value `type` should to be `enum`
|
||||||
|
@"enum": ?[]const []const u8 = null,
|
||||||
/// used in Config.zig as the default initializer
|
/// used in Config.zig as the default initializer
|
||||||
default: []const u8,
|
default: []const u8,
|
||||||
|
|
||||||
|
fn getTypescriptType(self: ConfigOption) error{UnsupportedType}![]const u8 {
|
||||||
|
return if (std.mem.eql(u8, self.type, "?[]const u8"))
|
||||||
|
"string"
|
||||||
|
else if (std.mem.eql(u8, self.type, "bool"))
|
||||||
|
"boolean"
|
||||||
|
else if (std.mem.eql(u8, self.type, "usize"))
|
||||||
|
"integer"
|
||||||
|
else if (std.mem.eql(u8, self.type, "enum"))
|
||||||
|
"string"
|
||||||
|
else
|
||||||
|
error.UnsupportedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn formatZigType(
|
||||||
|
config: ConfigOption,
|
||||||
|
comptime fmt: []const u8,
|
||||||
|
options: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
_ = options;
|
||||||
|
if (fmt.len != 0) return std.fmt.invalidFmtError(fmt, ConfigOption);
|
||||||
|
if (config.@"enum") |enum_members| {
|
||||||
|
try writer.writeAll("enum {");
|
||||||
|
if (enum_members.len > 1) try writer.writeByte(' ');
|
||||||
|
for (enum_members, 0..) |member_name, i| {
|
||||||
|
if (i != 0) try writer.writeAll(", ");
|
||||||
|
try writer.writeAll(member_name);
|
||||||
|
}
|
||||||
|
if (enum_members.len > 1) try writer.writeByte(' ');
|
||||||
|
try writer.writeByte('}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try writer.writeAll(config.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fmtZigType(self: ConfigOption) std.fmt.Formatter(formatZigType) {
|
||||||
|
return .{ .data = self };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn formatDefaultValue(
|
||||||
|
config: ConfigOption,
|
||||||
|
comptime fmt: []const u8,
|
||||||
|
options: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) !void {
|
||||||
|
_ = options;
|
||||||
|
if (fmt.len != 0) return std.fmt.invalidFmtError(fmt, ConfigOption);
|
||||||
|
if (config.@"enum" != null) {
|
||||||
|
try writer.writeByte('.');
|
||||||
|
}
|
||||||
|
const default = std.mem.trim(u8, config.default, &std.ascii.whitespace);
|
||||||
|
try writer.writeAll(default);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fmtDefaultValue(self: ConfigOption) std.fmt.Formatter(formatDefaultValue) {
|
||||||
|
return .{ .data = self };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Config = struct {
|
const Config = struct {
|
||||||
@ -29,20 +91,10 @@ const Schema = struct {
|
|||||||
const SchemaEntry = struct {
|
const SchemaEntry = struct {
|
||||||
description: []const u8,
|
description: []const u8,
|
||||||
type: []const u8,
|
type: []const u8,
|
||||||
|
@"enum": ?[]const []const u8 = null,
|
||||||
default: []const u8,
|
default: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn zigTypeToTypescript(ty: []const u8) ![]const u8 {
|
|
||||||
return if (std.mem.eql(u8, ty, "?[]const u8"))
|
|
||||||
"string"
|
|
||||||
else if (std.mem.eql(u8, ty, "bool"))
|
|
||||||
"boolean"
|
|
||||||
else if (std.mem.eql(u8, ty, "usize"))
|
|
||||||
"integer"
|
|
||||||
else
|
|
||||||
error.UnsupportedType;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generateConfigFile(allocator: std.mem.Allocator, config: Config, path: []const u8) !void {
|
fn generateConfigFile(allocator: std.mem.Allocator, config: Config, path: []const u8) !void {
|
||||||
_ = allocator;
|
_ = allocator;
|
||||||
|
|
||||||
@ -64,13 +116,13 @@ fn generateConfigFile(allocator: std.mem.Allocator, config: Config, path: []cons
|
|||||||
try buff_out.writer().print(
|
try buff_out.writer().print(
|
||||||
\\
|
\\
|
||||||
\\/// {s}
|
\\/// {s}
|
||||||
\\{s}: {s} = {s},
|
\\{}: {} = {},
|
||||||
\\
|
\\
|
||||||
, .{
|
, .{
|
||||||
std.mem.trim(u8, option.description, &std.ascii.whitespace),
|
std.mem.trim(u8, option.description, &std.ascii.whitespace),
|
||||||
std.mem.trim(u8, option.name, &std.ascii.whitespace),
|
std.zig.fmtId(std.mem.trim(u8, option.name, &std.ascii.whitespace)),
|
||||||
std.mem.trim(u8, option.type, &std.ascii.whitespace),
|
option.fmtZigType(),
|
||||||
std.mem.trim(u8, option.default, &std.ascii.whitespace),
|
option.fmtDefaultValue(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +150,8 @@ fn generateSchemaFile(allocator: std.mem.Allocator, config: Config, path: []cons
|
|||||||
for (config.options) |option| {
|
for (config.options) |option| {
|
||||||
properties.putAssumeCapacityNoClobber(option.name, .{
|
properties.putAssumeCapacityNoClobber(option.name, .{
|
||||||
.description = option.description,
|
.description = option.description,
|
||||||
.type = try zigTypeToTypescript(option.type),
|
.type = try option.getTypescriptType(),
|
||||||
|
.@"enum" = option.@"enum",
|
||||||
.default = option.default,
|
.default = option.default,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -116,6 +169,7 @@ fn generateSchemaFile(allocator: std.mem.Allocator, config: Config, path: []cons
|
|||||||
.whitespace = .{
|
.whitespace = .{
|
||||||
.indent_level = 1,
|
.indent_level = 1,
|
||||||
},
|
},
|
||||||
|
.emit_null_optional_fields = false,
|
||||||
}, buff_out.writer());
|
}, buff_out.writer());
|
||||||
|
|
||||||
_ = try buff_out.write("\n}\n");
|
_ = try buff_out.write("\n}\n");
|
||||||
@ -150,12 +204,12 @@ fn updateREADMEFile(allocator: std.mem.Allocator, config: Config, path: []const
|
|||||||
|
|
||||||
for (config.options) |option| {
|
for (config.options) |option| {
|
||||||
try writer.print(
|
try writer.print(
|
||||||
\\| `{s}` | `{s}` | `{s}` | {s} |
|
\\| `{s}` | `{s}` | `{}` | {s} |
|
||||||
\\
|
\\
|
||||||
, .{
|
, .{
|
||||||
std.mem.trim(u8, option.name, &std.ascii.whitespace),
|
std.mem.trim(u8, option.name, &std.ascii.whitespace),
|
||||||
std.mem.trim(u8, option.type, &std.ascii.whitespace),
|
std.mem.trim(u8, option.type, &std.ascii.whitespace),
|
||||||
std.mem.trim(u8, option.default, &std.ascii.whitespace),
|
option.fmtDefaultValue(),
|
||||||
std.mem.trim(u8, option.description, &std.ascii.whitespace),
|
std.mem.trim(u8, option.description, &std.ascii.whitespace),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -209,19 +263,26 @@ fn generateVSCodeConfigFile(allocator: std.mem.Allocator, config: Config, path:
|
|||||||
const snake_case_name = try std.fmt.allocPrint(allocator, "zig.zls.{s}", .{option.name});
|
const snake_case_name = try std.fmt.allocPrint(allocator, "zig.zls.{s}", .{option.name});
|
||||||
defer allocator.free(snake_case_name);
|
defer allocator.free(snake_case_name);
|
||||||
const name = try snakeCaseToCamelCase(allocator, snake_case_name);
|
const name = try snakeCaseToCamelCase(allocator, snake_case_name);
|
||||||
|
errdefer allocator.free(name);
|
||||||
|
|
||||||
var parser = std.json.Parser.init(allocator, false);
|
const default: ?std.json.Value = blk: {
|
||||||
defer parser.deinit();
|
if (option.@"enum" != null) break :blk .{ .String = option.default };
|
||||||
|
|
||||||
var value = try parser.parse(option.default);
|
var parser = std.json.Parser.init(allocator, false);
|
||||||
defer value.deinit();
|
defer parser.deinit();
|
||||||
const default = value.root;
|
|
||||||
|
var value = try parser.parse(option.default);
|
||||||
|
defer value.deinit();
|
||||||
|
|
||||||
|
break :blk if (value.root != .Null) value.root else null;
|
||||||
|
};
|
||||||
|
|
||||||
configuration.putAssumeCapacityNoClobber(name, .{
|
configuration.putAssumeCapacityNoClobber(name, .{
|
||||||
.type = try zigTypeToTypescript(option.type),
|
.type = try option.getTypescriptType(),
|
||||||
.description = option.description,
|
.description = option.description,
|
||||||
|
.@"enum" = option.@"enum",
|
||||||
.format = if (std.mem.indexOf(u8, option.name, "path") != null) "path" else null,
|
.format = if (std.mem.indexOf(u8, option.name, "path") != null) "path" else null,
|
||||||
.default = if (default == .Null) null else default,
|
.default = default,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,7 +1084,7 @@ pub fn main() !void {
|
|||||||
|
|
||||||
try stderr.writeAll(
|
try stderr.writeAll(
|
||||||
\\Changing configuration options may also require editing the `package.json` from zls-vscode at https://github.com/zigtools/zls-vscode/blob/master/package.json
|
\\Changing configuration options may also require editing the `package.json` from zls-vscode at https://github.com/zigtools/zls-vscode/blob/master/package.json
|
||||||
\\You can use `zig build gen -Dvscode-config-path=/path/to/output/file.json` to generate the new configuration properties which you can then copy into `package.json`
|
\\You can use `zig build gen -- --vscode-config-path /path/to/output/file.json` to generate the new configuration properties which you can then copy into `package.json`
|
||||||
\\
|
\\
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user