diff --git a/build.zig b/build.zig index 6dc1562..70c71d0 100644 --- a/build.zig +++ b/build.zig @@ -88,6 +88,11 @@ pub fn build(b: *std.Build) void { .root_source_file = .{ .path = "src/tracy_noop.zig" }, }); + const zg_dep = b.dependency("zg", .{ + .target = target, + .optimize = dependency_optimize, + }); + const themes_dep = b.dependency("themes", .{}); const syntax_dep = b.dependency("syntax", .{ @@ -224,6 +229,7 @@ pub fn build(b: *std.Build) void { .{ .name = "color", .module = color_mod }, .{ .name = "diff", .module = diff_mod }, .{ .name = "help.md", .module = help_mod }, + .{ .name = "CaseData", .module = zg_dep.module("CaseData") }, }, }); diff --git a/build.zig.zon b/build.zig.zon index 3beb752..61f70ef 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -39,6 +39,10 @@ .url = "git+https://github.com/rockorager/libvaxis#cce22e885013f91b6a226567f20afc3475ca46e0", .hash = "1220f1be979b6df72ff6bc6ed3d6fb0b74d99b75d1f8a86b392c2038702533461696", }, + .zg = .{ + .url = "git+https://codeberg.org/dude_the_builder/zg#16735685fcc3410de361ba3411788ad1fb4fe188", + .hash = "1220fe9ac5cdb41833d327a78745614e67d472469f8666567bd8cf9f5847a52b1c51", + }, }, .paths = .{ "include", diff --git a/src/tui/editor.zig b/src/tui/editor.zig index 7a7d94b..59f8078 100644 --- a/src/tui/editor.zig +++ b/src/tui/editor.zig @@ -9,6 +9,7 @@ const tracy = @import("tracy"); const text_manip = @import("text_manip"); const syntax = @import("syntax"); const project_manager = @import("project_manager"); +const CaseData = @import("CaseData"); const Plane = @import("renderer").Plane; const Cell = @import("renderer").Cell; @@ -3533,6 +3534,64 @@ pub const Editor = struct { if (state.whole_file) |*buf| buf.deinit(); self.filter = null; } + + fn to_upper_cursel(self: *Self, root_: Buffer.Root, cursel: *CurSel, a: Allocator) error{Stop}!Buffer.Root { + var root = root_; + const saved = cursel.*; + const sel = if (cursel.selection) |*sel| sel else ret: { + var sel = cursel.enable_selection(); + move_cursor_word_begin(root, &sel.begin, self.plane) catch return error.Stop; + move_cursor_word_end(root, &sel.end, self.plane) catch return error.Stop; + break :ret sel; + }; + var sfa = std.heap.stackFallback(4096, self.a); + const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop; + defer a.free(cut_text); + const cd = CaseData.init(a) catch return error.Stop; + defer cd.deinit(); + const ucased = cd.toUpperStr(a, cut_text) catch return error.Stop; + defer a.free(ucased); + root = try self.delete_selection(root, cursel, a); + root = self.insert(root, cursel, ucased, a) catch return error.Stop; + cursel.* = saved; + return root; + } + + pub fn to_upper(self: *Self, _: command.Context) tp.result { + const b = self.buf_for_update() catch |e| return tp.exit_error(e); + const root = self.with_cursels_mut(b.root, to_upper_cursel, b.a) catch |e| return tp.exit_error(e); + self.update_buf(root) catch |e| return tp.exit_error(e); + self.clamp(); + } + + fn to_lower_cursel(self: *Self, root_: Buffer.Root, cursel: *CurSel, a: Allocator) error{Stop}!Buffer.Root { + var root = root_; + const saved = cursel.*; + const sel = if (cursel.selection) |*sel| sel else ret: { + var sel = cursel.enable_selection(); + move_cursor_word_begin(root, &sel.begin, self.plane) catch return error.Stop; + move_cursor_word_end(root, &sel.end, self.plane) catch return error.Stop; + break :ret sel; + }; + var sfa = std.heap.stackFallback(4096, self.a); + const cut_text = copy_selection(root, sel.*, sfa.get(), self.plane) catch return error.Stop; + defer a.free(cut_text); + const cd = CaseData.init(a) catch return error.Stop; + defer cd.deinit(); + const ucased = cd.toLowerStr(a, cut_text) catch return error.Stop; + defer a.free(ucased); + root = try self.delete_selection(root, cursel, a); + root = self.insert(root, cursel, ucased, a) catch return error.Stop; + cursel.* = saved; + return root; + } + + pub fn to_lower(self: *Self, _: command.Context) tp.result { + const b = self.buf_for_update() catch |e| return tp.exit_error(e); + const root = self.with_cursels_mut(b.root, to_lower_cursel, b.a) catch |e| return tp.exit_error(e); + self.update_buf(root) catch |e| return tp.exit_error(e); + self.clamp(); + } }; pub fn create(a: Allocator, parent: Widget) !Widget { diff --git a/src/tui/mode/input/flow.zig b/src/tui/mode/input/flow.zig index 44052a2..163df1f 100644 --- a/src/tui/mode/input/flow.zig +++ b/src/tui/mode/input/flow.zig @@ -140,7 +140,8 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_diagnostic", .{}), 'P' => self.cmd("goto_prev_diagnostic", .{}), - 'L' => self.cmd("toggle_logview", .{}), + 'U' => self.cmd("to_upper", .{}), + 'L' => self.cmd("to_lower", .{}), 'I' => self.cmd("toggle_inputview", .{}), 'B' => self.cmd("move_word_left", .{}), 'F' => self.cmd("move_word_right", .{}), diff --git a/src/tui/mode/input/vim/insert.zig b/src/tui/mode/input/vim/insert.zig index 47a00e9..cfd3ae1 100644 --- a/src/tui/mode/input/vim/insert.zig +++ b/src/tui/mode/input/vim/insert.zig @@ -143,7 +143,8 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), - 'L' => self.cmd("toggle_logview", .{}), + 'U' => self.cmd("to_upper", .{}), + 'L' => self.cmd("to_lower", .{}), 'I' => self.cmd("toggle_inputview", .{}), 'B' => self.cmd("move_word_left", .{}), 'F' => self.cmd("move_word_right", .{}), diff --git a/src/tui/mode/input/vim/normal.zig b/src/tui/mode/input/vim/normal.zig index e7487e1..aa91ecc 100644 --- a/src/tui/mode/input/vim/normal.zig +++ b/src/tui/mode/input/vim/normal.zig @@ -146,7 +146,8 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), - 'L' => self.cmd("toggle_logview", .{}), + 'U' => self.cmd("to_upper", .{}), + 'L' => self.cmd("to_lower", .{}), 'I' => self.cmd("toggle_inputview", .{}), 'B' => self.cmd("move_word_left", .{}), 'F' => self.cmd("move_word_right", .{}), diff --git a/src/tui/mode/input/vim/visual.zig b/src/tui/mode/input/vim/visual.zig index 7cb81ba..f2d7eb2 100644 --- a/src/tui/mode/input/vim/visual.zig +++ b/src/tui/mode/input/vim/visual.zig @@ -146,7 +146,8 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result { 'J' => self.cmd("join_next_line", .{}), 'N' => self.cmd("goto_next_match", .{}), 'P' => self.cmd("goto_prev_match", .{}), - 'L' => self.cmd("toggle_logview", .{}), + 'U' => self.cmd("to_upper", .{}), + 'L' => self.cmd("to_lower", .{}), 'I' => self.cmd("toggle_inputview", .{}), 'B' => self.cmd("select_word_left", .{}), 'F' => self.cmd("select_word_right", .{}),