feat: add support for loading customized flow themes
This commit is contained in:
parent
8f66e855ed
commit
e8dbff76a1
2 changed files with 64 additions and 14 deletions
|
@ -1,5 +1,7 @@
|
|||
const std = @import("std");
|
||||
const cbor = @import("cbor");
|
||||
const Theme = @import("theme");
|
||||
const themes = @import("themes");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const application_name = "flow";
|
||||
|
@ -193,8 +195,6 @@ fn get_app_config_dir(appname: []const u8) ConfigDirError![]const u8 {
|
|||
return config_dir;
|
||||
}
|
||||
|
||||
const theme_dir = "themes";
|
||||
|
||||
fn get_app_config_file_name(appname: []const u8, comptime base_name: []const u8) ConfigDirError![]const u8 {
|
||||
return get_app_config_dir_file_name(appname, base_name ++ ".json");
|
||||
}
|
||||
|
@ -205,3 +205,60 @@ fn get_app_config_dir_file_name(appname: []const u8, comptime config_file_name:
|
|||
};
|
||||
return std.fmt.bufPrint(&local.config_file_buffer, "{s}/{s}", .{ try get_app_config_dir(appname), config_file_name });
|
||||
}
|
||||
|
||||
const theme_dir = "themes";
|
||||
|
||||
fn get_theme_directory() ![]const u8 {
|
||||
const local = struct {
|
||||
var dir_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
||||
};
|
||||
const a = std.heap.c_allocator;
|
||||
if (std.process.getEnvVarOwned(a, "FLOW_THEMES_DIR") catch null) |dir| {
|
||||
defer a.free(dir);
|
||||
return try std.fmt.bufPrint(&local.dir_buffer, "{s}", .{dir});
|
||||
}
|
||||
return try std.fmt.bufPrint(&local.dir_buffer, "{s}/{s}", .{ try get_app_config_dir(application_name), theme_dir });
|
||||
}
|
||||
|
||||
pub fn get_theme_file_name(theme_name: []const u8) ![]const u8 {
|
||||
const dir = try get_theme_directory();
|
||||
const local = struct {
|
||||
var file_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
||||
};
|
||||
return try std.fmt.bufPrint(&local.file_buffer, "{s}/{s}.json", .{ dir, theme_name });
|
||||
}
|
||||
|
||||
fn read_theme(allocator: std.mem.Allocator, theme_name: []const u8) ?[]const u8 {
|
||||
const file_name = get_theme_file_name(theme_name) catch return null;
|
||||
var file = std.fs.openFileAbsolute(file_name, .{ .mode = .read_only }) catch return null;
|
||||
defer file.close();
|
||||
return file.readToEndAlloc(allocator, 64 * 1024) catch null;
|
||||
}
|
||||
|
||||
fn load_theme_file(allocator: std.mem.Allocator, theme_name: []const u8) !?std.json.Parsed(Theme) {
|
||||
return load_theme_file_internal(allocator, theme_name) catch |e| {
|
||||
std.log.err("loaded theme from file failed: {}", .{e});
|
||||
return e;
|
||||
};
|
||||
}
|
||||
|
||||
fn load_theme_file_internal(allocator: std.mem.Allocator, theme_name: []const u8) !?std.json.Parsed(Theme) {
|
||||
_ = std.json.Scanner;
|
||||
const json_str = read_theme(allocator, theme_name) orelse return null;
|
||||
defer allocator.free(json_str);
|
||||
return try std.json.parseFromSlice(Theme, allocator, json_str, .{ .allocate = .alloc_always });
|
||||
}
|
||||
|
||||
pub fn get_theme_by_name(allocator: std.mem.Allocator, name: []const u8) ?struct { Theme, ?std.json.Parsed(Theme) } {
|
||||
if (load_theme_file(allocator, name) catch null) |parsed_theme| {
|
||||
std.log.info("loaded theme from file: {s}", .{name});
|
||||
return .{ parsed_theme.value, parsed_theme };
|
||||
}
|
||||
|
||||
std.log.info("loading theme: {s}", .{name});
|
||||
for (themes.themes) |theme_| {
|
||||
if (std.mem.eql(u8, theme_.name, name))
|
||||
return .{ theme_, null };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
17
src/main.zig
17
src/main.zig
|
@ -94,14 +94,15 @@ pub fn main() !void {
|
|||
}
|
||||
|
||||
if (highlight_line_end < highlight_line_start) {
|
||||
try std.io.getStdErr().writer().print("invalid range\n", .{});
|
||||
std.log.err("invalid range", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const theme = get_theme_by_name(theme_name) orelse {
|
||||
try std.io.getStdErr().writer().print("theme \"{s}\" not found\n", .{theme_name});
|
||||
const theme, const parsed_theme = config_loader.get_theme_by_name(a, theme_name) orelse {
|
||||
std.log.err("theme \"{s}\" not found", .{theme_name});
|
||||
std.process.exit(1);
|
||||
};
|
||||
_ = parsed_theme;
|
||||
|
||||
const set_style: StyleFn = if (res.args.html != 0) set_html_style else set_ansi_style;
|
||||
const unset_style: StyleFn = if (res.args.html != 0) unset_html_style else unset_ansi_style;
|
||||
|
@ -174,7 +175,7 @@ fn get_parser(a: std.mem.Allocator, content: []const u8, file_path: []const u8,
|
|||
}
|
||||
|
||||
fn unknown_file_type(name: []const u8) noreturn {
|
||||
std.io.getStdErr().writer().print("unknown file type \'{s}\'\n", .{name}) catch {};
|
||||
std.log.err("unknown file type \'{s}\'\n", .{name});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
|
@ -391,14 +392,6 @@ pub const fallbacks: []const FallBack = &[_]FallBack{
|
|||
.{ .ts = "field", .tm = "variable" },
|
||||
};
|
||||
|
||||
fn get_theme_by_name(name: []const u8) ?Theme {
|
||||
for (themes.themes) |theme| {
|
||||
if (std.mem.eql(u8, theme.name, name))
|
||||
return theme;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
fn list_themes(writer: Writer) !void {
|
||||
var max_name_len: usize = 0;
|
||||
for (themes.themes) |theme|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue