diff --git a/src/keybind/builtin/flow.json b/src/keybind/builtin/flow.json index 314f676..339972b 100644 --- a/src/keybind/builtin/flow.json +++ b/src/keybind/builtin/flow.json @@ -328,7 +328,7 @@ ["right_control", "palette_menu_activate_quick"] ] }, - "mini/numeric": { + "mini/goto": { "press": [ ["ctrl+q", "quit"], ["ctrl+v", "system_paste"], @@ -338,7 +338,7 @@ ["ctrl+l", "scroll_view_center_cycle"], ["ctrl+space", "mini_mode_cancel"], ["escape", "mini_mode_cancel"], - ["enter", "mini_mode_select"], + ["enter", "exit_mini_mode"], ["backspace", "mini_mode_delete_backwards"] ] }, diff --git a/src/tui/editor.zig b/src/tui/editor.zig index b9fce38..701626d 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -432,7 +432,6 @@ pub const Editor = struct { tp.extract_cbor(&cursels_cbor), })) return error.RestoreStateMatch; - self.refresh_tab_width(); if (op == .open_file) try self.open(file_path); self.clipboard = if (clipboard.len > 0) try self.allocator.dupe(u8, clipboard) else null; @@ -703,23 +702,6 @@ pub const Editor = struct { return; } - fn refresh_tab_width(self: *Self) void { - self.metrics = self.plane.metrics(self.tab_width); - switch (self.indent_mode) { - .spaces, .auto => {}, - .tabs => self.indent_size = self.tab_width, - } - } - - pub fn set_tab_width(self: *Self, ctx: Context) Result { - var tab_width: usize = 0; - if (!try ctx.args.match(.{tp.extract(&tab_width)})) - return error.InvalidSetTabWidthArgument; - self.tab_width = tab_width; - self.refresh_tab_width(); - } - pub const set_tab_width_meta: Meta = .{ .arguments = &.{.integer} }; - fn close(self: *Self) !void { var meta = std.ArrayListUnmanaged(u8).empty; defer meta.deinit(self.allocator); diff --git a/src/tui/mode/mini/goto.zig b/src/tui/mode/mini/goto.zig index 13abeec..94d5c6d 100644 --- a/src/tui/mode/mini/goto.zig +++ b/src/tui/mode/mini/goto.zig @@ -1,16 +1,140 @@ +const tp = @import("thespian"); + +const key = @import("renderer").input.key; +const mod = @import("renderer").input.modifier; +const event_type = @import("renderer").input.event_type; +const keybind = @import("keybind"); const command = @import("command"); +const EventHandler = @import("EventHandler"); -pub const Type = @import("numeric_input.zig").Create(@This()); -pub const create = Type.create; +const tui = @import("../../tui.zig"); -pub fn name(_: *Type) []const u8 { - return "#goto"; +const Allocator = @import("std").mem.Allocator; +const fmt = @import("std").fmt; + +const Self = @This(); +const name = "#goto"; + +const Commands = command.Collection(cmds); + +allocator: Allocator, +buf: [30]u8 = undefined, +input: ?usize = null, +start: usize, +commands: Commands = undefined, + +pub fn create(allocator: Allocator, _: command.Context) !struct { tui.Mode, tui.MiniMode } { + const editor = tui.get_active_editor() orelse return error.NotFound; + const self = try allocator.create(Self); + errdefer allocator.destroy(self); + self.* = .{ + .allocator = allocator, + .start = editor.get_primary().cursor.row + 1, + }; + try self.commands.init(self); + var mode = try keybind.mode("mini/goto", allocator, .{ + .insert_command = "mini_mode_insert_bytes", + }); + mode.event_handler = EventHandler.to_owned(self); + return .{ mode, .{ .name = name } }; } -pub const preview = goto; -pub const apply = goto; -pub const cancel = goto; +pub fn deinit(self: *Self) void { + self.commands.deinit(); + self.allocator.destroy(self); +} -fn goto(self: *Type) void { +pub fn receive(self: *Self, _: tp.pid_ref, _: tp.message) error{Exit}!bool { + self.update_mini_mode_text(); + return false; +} + +fn update_mini_mode_text(self: *Self) void { + if (tui.mini_mode()) |mini_mode| { + mini_mode.text = if (self.input) |linenum| + (fmt.bufPrint(&self.buf, "{d}", .{linenum}) catch "") + else + ""; + mini_mode.cursor = tui.egc_chunk_width(mini_mode.text, 0, 1); + } +} + +fn goto(self: *Self) void { command.executeName("goto_line", command.fmt(.{self.input orelse self.start})) catch {}; } + +fn insert_char(self: *Self, char: u8) void { + switch (char) { + '0' => { + if (self.input) |linenum| self.input = linenum * 10; + }, + '1'...'9' => { + const digit: usize = @intCast(char - '0'); + self.input = if (self.input) |x| x * 10 + digit else digit; + }, + else => {}, + } +} + +fn insert_bytes(self: *Self, bytes: []const u8) void { + for (bytes) |c| self.insert_char(c); +} + +const cmds = struct { + pub const Target = Self; + const Ctx = command.Context; + const Meta = command.Metadata; + const Result = command.Result; + + pub fn mini_mode_reset(self: *Self, _: Ctx) Result { + self.input = null; + self.update_mini_mode_text(); + } + pub const mini_mode_reset_meta: Meta = .{ .description = "Clear input" }; + + pub fn mini_mode_cancel(self: *Self, _: Ctx) Result { + self.input = null; + self.update_mini_mode_text(); + self.goto(); + command.executeName("exit_mini_mode", .{}) catch {}; + } + pub const mini_mode_cancel_meta: Meta = .{ .description = "Cancel input" }; + + pub fn mini_mode_delete_backwards(self: *Self, _: Ctx) Result { + if (self.input) |linenum| { + const newval = if (linenum < 10) 0 else linenum / 10; + self.input = if (newval == 0) null else newval; + self.update_mini_mode_text(); + self.goto(); + } + } + pub const mini_mode_delete_backwards_meta: Meta = .{ .description = "Delete backwards" }; + + pub fn mini_mode_insert_code_point(self: *Self, ctx: Ctx) Result { + var keypress: usize = 0; + if (!try ctx.args.match(.{tp.extract(&keypress)})) + return error.InvalidGotoInsertCodePointArgument; + switch (keypress) { + '0'...'9' => self.insert_char(@intCast(keypress)), + else => {}, + } + self.update_mini_mode_text(); + self.goto(); + } + pub const mini_mode_insert_code_point_meta: Meta = .{ .arguments = &.{.integer} }; + + pub fn mini_mode_insert_bytes(self: *Self, ctx: Ctx) Result { + var bytes: []const u8 = undefined; + if (!try ctx.args.match(.{tp.extract(&bytes)})) + return error.InvalidGotoInsertBytesArgument; + self.insert_bytes(bytes); + self.update_mini_mode_text(); + self.goto(); + } + pub const mini_mode_insert_bytes_meta: Meta = .{ .arguments = &.{.string} }; + + pub fn mini_mode_paste(self: *Self, ctx: Ctx) Result { + return mini_mode_insert_bytes(self, ctx); + } + pub const mini_mode_paste_meta: Meta = .{ .arguments = &.{.string} }; +}; diff --git a/src/tui/mode/mini/numeric_input.zig b/src/tui/mode/mini/numeric_input.zig deleted file mode 100644 index 2781a45..0000000 --- a/src/tui/mode/mini/numeric_input.zig +++ /dev/null @@ -1,145 +0,0 @@ -const tp = @import("thespian"); - -const key = @import("renderer").input.key; -const mod = @import("renderer").input.modifier; -const event_type = @import("renderer").input.event_type; -const keybind = @import("keybind"); -const command = @import("command"); -const EventHandler = @import("EventHandler"); - -const tui = @import("../../tui.zig"); - -const Allocator = @import("std").mem.Allocator; -const fmt = @import("std").fmt; - -pub fn Create(options: type) type { - return struct { - const Self = @This(); - - const Commands = command.Collection(cmds); - - allocator: Allocator, - buf: [30]u8 = undefined, - input: ?usize = null, - start: usize, - commands: Commands = undefined, - - pub fn create(allocator: Allocator, _: command.Context) !struct { tui.Mode, tui.MiniMode } { - const editor = tui.get_active_editor() orelse return error.NotFound; - const self = try allocator.create(Self); - errdefer allocator.destroy(self); - self.* = .{ - .allocator = allocator, - .start = editor.get_primary().cursor.row + 1, - }; - try self.commands.init(self); - var mode = try keybind.mode("mini/numeric", allocator, .{ - .insert_command = "mini_mode_insert_bytes", - }); - mode.event_handler = EventHandler.to_owned(self); - return .{ mode, .{ .name = options.name(self) } }; - } - - pub fn deinit(self: *Self) void { - self.commands.deinit(); - self.allocator.destroy(self); - } - - pub fn receive(self: *Self, _: tp.pid_ref, _: tp.message) error{Exit}!bool { - self.update_mini_mode_text(); - return false; - } - - fn update_mini_mode_text(self: *Self) void { - if (tui.mini_mode()) |mini_mode| { - mini_mode.text = if (self.input) |linenum| - (fmt.bufPrint(&self.buf, "{d}", .{linenum}) catch "") - else - ""; - mini_mode.cursor = tui.egc_chunk_width(mini_mode.text, 0, 1); - } - } - - fn insert_char(self: *Self, char: u8) void { - switch (char) { - '0' => { - if (self.input) |linenum| self.input = linenum * 10; - }, - '1'...'9' => { - const digit: usize = @intCast(char - '0'); - self.input = if (self.input) |x| x * 10 + digit else digit; - }, - else => {}, - } - } - - fn insert_bytes(self: *Self, bytes: []const u8) void { - for (bytes) |c| self.insert_char(c); - } - - const cmds = struct { - pub const Target = Self; - const Ctx = command.Context; - const Meta = command.Metadata; - const Result = command.Result; - - pub fn mini_mode_reset(self: *Self, _: Ctx) Result { - self.input = null; - self.update_mini_mode_text(); - } - pub const mini_mode_reset_meta: Meta = .{ .description = "Clear input" }; - - pub fn mini_mode_cancel(self: *Self, _: Ctx) Result { - self.input = null; - self.update_mini_mode_text(); - options.cancel(self); - command.executeName("exit_mini_mode", .{}) catch {}; - } - pub const mini_mode_cancel_meta: Meta = .{ .description = "Cancel input" }; - - pub fn mini_mode_delete_backwards(self: *Self, _: Ctx) Result { - if (self.input) |linenum| { - const newval = if (linenum < 10) 0 else linenum / 10; - self.input = if (newval == 0) null else newval; - self.update_mini_mode_text(); - options.preview(self); - } - } - pub const mini_mode_delete_backwards_meta: Meta = .{ .description = "Delete backwards" }; - - pub fn mini_mode_insert_code_point(self: *Self, ctx: Ctx) Result { - var keypress: usize = 0; - if (!try ctx.args.match(.{tp.extract(&keypress)})) - return error.InvalidGotoInsertCodePointArgument; - switch (keypress) { - '0'...'9' => self.insert_char(@intCast(keypress)), - else => {}, - } - self.update_mini_mode_text(); - options.preview(self); - } - pub const mini_mode_insert_code_point_meta: Meta = .{ .arguments = &.{.integer} }; - - pub fn mini_mode_insert_bytes(self: *Self, ctx: Ctx) Result { - var bytes: []const u8 = undefined; - if (!try ctx.args.match(.{tp.extract(&bytes)})) - return error.InvalidGotoInsertBytesArgument; - self.insert_bytes(bytes); - self.update_mini_mode_text(); - options.preview(self); - } - pub const mini_mode_insert_bytes_meta: Meta = .{ .arguments = &.{.string} }; - - pub fn mini_mode_paste(self: *Self, ctx: Ctx) Result { - return mini_mode_insert_bytes(self, ctx); - } - pub const mini_mode_paste_meta: Meta = .{ .arguments = &.{.string} }; - - pub fn mini_mode_select(self: *Self, _: Ctx) Result { - options.apply(self); - command.executeName("exit_mini_mode", .{}) catch {}; - } - pub const mini_mode_select_meta: Meta = .{ .description = "Select" }; - }; - }; -} diff --git a/src/tui/mode/mini/tab_width.zig b/src/tui/mode/mini/tab_width.zig deleted file mode 100644 index a2ca836..0000000 --- a/src/tui/mode/mini/tab_width.zig +++ /dev/null @@ -1,16 +0,0 @@ -const command = @import("command"); - -pub const Type = @import("numeric_input.zig").Create(@This()); -pub const create = Type.create; - -pub fn name(_: *Type) []const u8 { - return " tab size"; -} - -pub const preview = goto; -pub const apply = goto; -pub const cancel = goto; - -fn goto(self: *Type) void { - command.executeName("set_tab_width", command.fmt(.{self.input orelse self.start})) catch {}; -} diff --git a/src/tui/tui.zig b/src/tui/tui.zig index f762102..3a3e7c8 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -744,11 +744,6 @@ const cmds = struct { } pub const force_terminate_meta: Meta = .{ .description = "Force quit without saving" }; - pub fn tab_width(self: *Self, ctx: Ctx) Result { - return enter_mini_mode(self, @import("mode/mini/tab_width.zig"), ctx); - } - pub const tab_width_meta: Meta = .{ .description = "Set tab width" }; - pub fn set_theme(self: *Self, ctx: Ctx) Result { var name: []const u8 = undefined; if (!try ctx.args.match(.{tp.extract(&name)}))