refactor: cache CaseData in Editor

This commit is contained in:
CJ van den Berg 2024-10-15 22:51:46 +02:00
parent 88cf5670aa
commit d10656b433
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9

View file

@ -264,6 +264,8 @@ pub const Editor = struct {
need_save_after_filter: bool = false, need_save_after_filter: bool = false,
case_data: ?CaseData = null,
const WhitespaceMode = enum { visible, indent, none }; const WhitespaceMode = enum { visible, indent, none };
const StyleCache = std.AutoHashMap(u32, ?Widget.Theme.Token); const StyleCache = std.AutoHashMap(u32, ?Widget.Theme.Token);
@ -356,6 +358,7 @@ pub const Editor = struct {
self.handlers.deinit(); self.handlers.deinit();
self.logger.deinit(); self.logger.deinit();
if (self.buffer) |p| p.deinit(); if (self.buffer) |p| p.deinit();
if (self.case_data) |cd| cd.deinit();
} }
fn from_whitespace_mode(whitespace_mode: []const u8) WhitespaceMode { fn from_whitespace_mode(whitespace_mode: []const u8) WhitespaceMode {
@ -371,6 +374,12 @@ pub const Editor = struct {
Widget.need_render(); Widget.need_render();
} }
fn get_case_data(self: *Self) *CaseData {
if (self.case_data) |*cd| return cd;
self.case_data = CaseData.init(self.allocator) catch @panic("CaseData.init");
return &self.case_data.?;
}
fn buf_for_update(self: *Self) !*const Buffer { fn buf_for_update(self: *Self) !*const Buffer {
self.cursels_saved.clearAndFree(); self.cursels_saved.clearAndFree();
self.cursels_saved = try self.cursels.clone(); self.cursels_saved = try self.cursels.clone();
@ -3876,9 +3885,7 @@ pub const Editor = struct {
var sfa = std.heap.stackFallback(4096, self.allocator); var sfa = std.heap.stackFallback(4096, self.allocator);
const cut_text = copy_selection(root, sel.*, sfa.get(), self.metrics) catch return error.Stop; const cut_text = copy_selection(root, sel.*, sfa.get(), self.metrics) catch return error.Stop;
defer allocator.free(cut_text); defer allocator.free(cut_text);
const cd = CaseData.init(allocator) catch return error.Stop; const ucased = self.get_case_data().toUpperStr(allocator, cut_text) catch return error.Stop;
defer cd.deinit();
const ucased = cd.toUpperStr(allocator, cut_text) catch return error.Stop;
defer allocator.free(ucased); defer allocator.free(ucased);
root = try self.delete_selection(root, cursel, allocator); root = try self.delete_selection(root, cursel, allocator);
root = self.insert(root, cursel, ucased, allocator) catch return error.Stop; root = self.insert(root, cursel, ucased, allocator) catch return error.Stop;
@ -3906,9 +3913,7 @@ pub const Editor = struct {
var sfa = std.heap.stackFallback(4096, self.allocator); var sfa = std.heap.stackFallback(4096, self.allocator);
const cut_text = copy_selection(root, sel.*, sfa.get(), self.metrics) catch return error.Stop; const cut_text = copy_selection(root, sel.*, sfa.get(), self.metrics) catch return error.Stop;
defer allocator.free(cut_text); defer allocator.free(cut_text);
const cd = CaseData.init(allocator) catch return error.Stop; const ucased = self.get_case_data().toLowerStr(allocator, cut_text) catch return error.Stop;
defer cd.deinit();
const ucased = cd.toLowerStr(allocator, cut_text) catch return error.Stop;
defer allocator.free(ucased); defer allocator.free(ucased);
root = try self.delete_selection(root, cursel, allocator); root = try self.delete_selection(root, cursel, allocator);
root = self.insert(root, cursel, ucased, allocator) catch return error.Stop; root = self.insert(root, cursel, ucased, allocator) catch return error.Stop;
@ -3933,29 +3938,27 @@ pub const Editor = struct {
saved.cursor = sel.end; saved.cursor = sel.end;
break :ret sel; break :ret sel;
}; };
const cd = CaseData.init(self.allocator) catch return error.Stop;
var result = std.ArrayList(u8).init(self.allocator); var result = std.ArrayList(u8).init(self.allocator);
defer result.deinit(); defer result.deinit();
const writer: struct { const writer: struct {
allocator: Allocator, self_: *Self,
cd: *const CaseData,
result: *std.ArrayList(u8), result: *std.ArrayList(u8),
const Error = (error{ Stop, OutOfMemory } || @typeInfo(@typeInfo(@TypeOf(CaseData.toUpperStr)).Fn.return_type.?).ErrorUnion.error_set); const Error = @typeInfo(@typeInfo(@TypeOf(CaseData.toUpperStr)).Fn.return_type.?).ErrorUnion.error_set;
pub fn write(writer: *@This(), bytes: []const u8) Error!void { pub fn write(writer: *@This(), bytes: []const u8) Error!void {
const flipped = if (writer.cd.isLowerStr(bytes)) const cd = writer.self_.get_case_data();
try writer.cd.toUpperStr(writer.allocator, bytes) const flipped = if (cd.isLowerStr(bytes))
try cd.toUpperStr(writer.self_.allocator, bytes)
else else
try writer.cd.toLowerStr(writer.allocator, bytes); try cd.toLowerStr(writer.self_.allocator, bytes);
defer writer.allocator.free(flipped); defer writer.self_.allocator.free(flipped);
return writer.result.appendSlice(flipped); return writer.result.appendSlice(flipped);
} }
fn map_error(e: anyerror, _: ?*std.builtin.StackTrace) Error { fn map_error(e: anyerror, _: ?*std.builtin.StackTrace) Error {
return @errorCast(e); return @errorCast(e);
} }
} = .{ } = .{
.allocator = self.allocator, .self_ = self,
.cd = &cd,
.result = &result, .result = &result,
}; };
self.write_range(root, sel.*, writer, @TypeOf(writer).map_error, null) catch return error.Stop; self.write_range(root, sel.*, writer, @TypeOf(writer).map_error, null) catch return error.Stop;