diff --git a/src/tui/mode/mini/goto.zig b/src/tui/mode/mini/goto.zig index e8bc12a..963ec7f 100644 --- a/src/tui/mode/mini/goto.zig +++ b/src/tui/mode/mini/goto.zig @@ -2,11 +2,16 @@ const fmt = @import("std").fmt; const command = @import("command"); const tui = @import("../../tui.zig"); +const Cursor = @import("../../editor.zig").Cursor; pub const Type = @import("numeric_input.zig").Create(@This()); pub const create = Type.create; -pub const ValueType = @import("../../editor.zig").Cursor; +pub const ValueType = struct { + cursor: Cursor = .{}, + part: enum { row, col } = .row, +}; +pub const Separator = ':'; pub fn name(_: *Type) []const u8 { return "#goto"; @@ -14,35 +19,64 @@ pub fn name(_: *Type) []const u8 { pub fn start(_: *Type) ValueType { const editor = tui.get_active_editor() orelse return .{}; - return editor.get_primary().cursor; + return .{ .cursor = editor.get_primary().cursor }; } pub fn process_digit(self: *Type, digit: u8) void { - switch (digit) { - 0 => { - if (self.input) |*x| x.row = x.row * 10; + const part = if (self.input) |input| input.part else .row; + switch (part) { + .row => switch (digit) { + 0 => { + if (self.input) |*input| input.cursor.row = input.cursor.row * 10; + }, + 1...9 => { + if (self.input) |*input| { + input.cursor.row = input.cursor.row * 10 + digit; + } else { + self.input = .{ .cursor = .{ .row = digit } }; + } + }, + else => unreachable, }, - 1...9 => { - if (self.input) |*x| { - x.row = x.row * 10 + digit; - } else { - self.input = .{ .row = digit }; - } + .col => if (self.input) |*input| { + input.cursor.col = input.cursor.col * 10 + digit; }, - else => unreachable, } } +pub fn process_separator(self: *Type) void { + if (self.input) |*input| switch (input.part) { + .row => input.part = .col, + else => {}, + }; +} + pub fn delete(self: *Type, input: *ValueType) void { - const newval = if (input.row < 10) 0 else input.row / 10; - if (newval == 0) self.input = null else input.row = newval; + switch (input.part) { + .row => { + const newval = if (input.cursor.row < 10) 0 else input.cursor.row / 10; + if (newval == 0) self.input = null else input.cursor.row = newval; + }, + .col => { + const newval = if (input.cursor.col < 10) 0 else input.cursor.col / 10; + if (newval == 0) { + input.part = .row; + input.cursor.col = 0; + } else input.cursor.col = newval; + }, + } } pub fn format_value(_: *Type, input: ?ValueType, buf: []u8) []const u8 { - return if (input) |value| - (fmt.bufPrint(buf, "{d}", .{value.row}) catch "") - else - ""; + return if (input) |value| blk: { + switch (value.part) { + .row => break :blk fmt.bufPrint(buf, "{d}", .{value.cursor.row}) catch "", + .col => if (value.cursor.col == 0) + break :blk fmt.bufPrint(buf, "{d}:", .{value.cursor.row}) catch "" + else + break :blk fmt.bufPrint(buf, "{d}:{d}", .{ value.cursor.row, value.cursor.col }) catch "", + } + } else ""; } pub const preview = goto; @@ -50,9 +84,9 @@ pub const apply = goto; pub const cancel = goto; fn goto(self: *Type, _: command.Context) void { - if (self.input) |input| { - command.executeName("goto_line", command.fmt(.{input.row})) catch {}; - } else { - command.executeName("goto_line_and_column", command.fmt(.{ self.start.row, self.start.col })) catch {}; - } + send_goto(if (self.input) |input| input.cursor else self.start.cursor); +} + +fn send_goto(cursor: Cursor) void { + command.executeName("goto_line_and_column", command.fmt(.{ cursor.row, cursor.col })) catch {}; } diff --git a/src/tui/mode/mini/numeric_input.zig b/src/tui/mode/mini/numeric_input.zig index ad32849..7b6c30f 100644 --- a/src/tui/mode/mini/numeric_input.zig +++ b/src/tui/mode/mini/numeric_input.zig @@ -73,7 +73,7 @@ pub fn Create(options: type) type { const process_digit_ = if (@hasDecl(options, "process_digit")) options.process_digit else process_digit; if (@hasDecl(options, "Separator")) { switch (char) { - '0'...'9' => process_digit_(@intCast(char - '0')), + '0'...'9' => process_digit_(self, @intCast(char - '0')), options.Separator => options.process_separator(self), else => {}, }