feat: dynamically determine available keybind namespaces
This commit is contained in:
parent
85b8ff8bea
commit
264c6ca54b
3 changed files with 63 additions and 10 deletions
|
@ -75,6 +75,30 @@ pub const Mode = struct {
|
||||||
|
|
||||||
const NamespaceMap = std.StringHashMapUnmanaged(Namespace);
|
const NamespaceMap = std.StringHashMapUnmanaged(Namespace);
|
||||||
|
|
||||||
|
pub fn get_namespaces(allocator: std.mem.Allocator) ![]const []const u8 {
|
||||||
|
const namespaces = try root.list_keybind_namespaces(allocator);
|
||||||
|
defer {
|
||||||
|
for (namespaces) |namespace| allocator.free(namespace);
|
||||||
|
allocator.free(namespaces);
|
||||||
|
}
|
||||||
|
var result = std.ArrayList([]const u8).init(allocator);
|
||||||
|
try result.append(try allocator.dupe(u8, "flow"));
|
||||||
|
try result.append(try allocator.dupe(u8, "emacs"));
|
||||||
|
try result.append(try allocator.dupe(u8, "vim"));
|
||||||
|
try result.append(try allocator.dupe(u8, "helix"));
|
||||||
|
for (namespaces) |namespace| {
|
||||||
|
var exists = false;
|
||||||
|
for (result.items) |existing|
|
||||||
|
if (std.mem.eql(u8, namespace, existing)) {
|
||||||
|
exists = true;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
if (!exists)
|
||||||
|
try result.append(try allocator.dupe(u8, namespace));
|
||||||
|
}
|
||||||
|
return result.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_namespace() []const u8 {
|
pub fn get_namespace() []const u8 {
|
||||||
return current_namespace().name;
|
return current_namespace().name;
|
||||||
}
|
}
|
||||||
|
|
30
src/main.zig
30
src/main.zig
|
@ -459,6 +459,20 @@ pub fn write_keybind_namespace(namespace_name: []const u8, content: []const u8)
|
||||||
return file.writeAll(content);
|
return file.writeAll(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_keybind_namespaces(allocator: std.mem.Allocator) ![]const []const u8 {
|
||||||
|
var dir = try std.fs.openDirAbsolute(try get_keybind_namespaces_directory(), .{ .iterate = true });
|
||||||
|
defer dir.close();
|
||||||
|
var result = std.ArrayList([]const u8).init(allocator);
|
||||||
|
var iter = dir.iterateAssumeFirstIteration();
|
||||||
|
while (try iter.next()) |entry| {
|
||||||
|
switch (entry.kind) {
|
||||||
|
.file, .sym_link => try result.append(try allocator.dupe(u8, std.fs.path.stem(entry.name))),
|
||||||
|
else => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_config_dir() ![]const u8 {
|
pub fn get_config_dir() ![]const u8 {
|
||||||
return get_app_config_dir(application_name);
|
return get_app_config_dir(application_name);
|
||||||
}
|
}
|
||||||
|
@ -631,16 +645,24 @@ pub fn get_restore_file_name() ![]const u8 {
|
||||||
|
|
||||||
const keybind_dir = "keys";
|
const keybind_dir = "keys";
|
||||||
|
|
||||||
pub fn get_keybind_namespace_file_name(namespace_name: []const u8) ![]const u8 {
|
pub fn get_keybind_namespaces_directory() ![]const u8 {
|
||||||
const local = struct {
|
const local = struct {
|
||||||
var file_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
var dir_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
||||||
};
|
};
|
||||||
const a = std.heap.c_allocator;
|
const a = std.heap.c_allocator;
|
||||||
if (std.process.getEnvVarOwned(a, "FLOW_KEYS_DIR") catch null) |dir| {
|
if (std.process.getEnvVarOwned(a, "FLOW_KEYS_DIR") catch null) |dir| {
|
||||||
defer a.free(dir);
|
defer a.free(dir);
|
||||||
return try std.fmt.bufPrint(&local.file_buffer, "{s}/{s}.json", .{ dir, namespace_name });
|
return try std.fmt.bufPrint(&local.dir_buffer, "{s}/", .{dir});
|
||||||
}
|
}
|
||||||
return try std.fmt.bufPrint(&local.file_buffer, "{s}/{s}/{s}.json", .{ try get_app_config_dir(application_name), keybind_dir, namespace_name });
|
return try std.fmt.bufPrint(&local.dir_buffer, "{s}/{s}/", .{ try get_app_config_dir(application_name), keybind_dir });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_keybind_namespace_file_name(namespace_name: []const u8) ![]const u8 {
|
||||||
|
const dir = try get_keybind_namespaces_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, namespace_name });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restart() noreturn {
|
fn restart() noreturn {
|
||||||
|
|
|
@ -668,12 +668,19 @@ const cmds = struct {
|
||||||
pub fn toggle_input_mode(self: *Self, _: Ctx) Result {
|
pub fn toggle_input_mode(self: *Self, _: Ctx) Result {
|
||||||
var it = std.mem.splitScalar(u8, self.config.input_mode, '/');
|
var it = std.mem.splitScalar(u8, self.config.input_mode, '/');
|
||||||
self.config.input_mode = it.first();
|
self.config.input_mode = it.first();
|
||||||
self.config.input_mode = if (std.mem.eql(u8, self.config.input_mode, "flow"))
|
|
||||||
"vim"
|
const namespaces = keybind.get_namespaces(self.allocator) catch |e| return tp.exit_error(e, @errorReturnTrace());
|
||||||
else if (std.mem.eql(u8, self.config.input_mode, "vim"))
|
defer {
|
||||||
"helix"
|
for (namespaces) |namespace| self.allocator.free(namespace);
|
||||||
else
|
self.allocator.free(namespaces);
|
||||||
"flow";
|
}
|
||||||
|
var found = false;
|
||||||
|
self.config.input_mode = blk: for (namespaces) |namespace| {
|
||||||
|
if (found) break :blk try self.allocator.dupe(u8, namespace);
|
||||||
|
if (std.mem.eql(u8, namespace, self.config.input_mode))
|
||||||
|
found = true;
|
||||||
|
} else try self.allocator.dupe(u8, namespaces[0]);
|
||||||
|
|
||||||
try self.save_config();
|
try self.save_config();
|
||||||
self.logger.print("input mode {s}", .{self.config.input_mode});
|
self.logger.print("input mode {s}", .{self.config.input_mode});
|
||||||
try keybind.set_namespace(self.config.input_mode);
|
try keybind.set_namespace(self.config.input_mode);
|
||||||
|
|
Loading…
Add table
Reference in a new issue