core: remove size limit on preedit length by heap allocating

Fixes #882

We previously had a hardcoded limit of 16 codepoints. In #882, a user
pointed out that in Chinese, is reasonable for a preedit input to be
longer than this.

To avoid any future issues, this commit moves to a heap-allocated
variant. Preedits aren't that common, they aren't high throughput, and
they're generally pretty small, so using a heap allocation is fine. The
memory is owned by the person who set it.
This commit is contained in:
Mitchell Hashimoto
2023-12-03 19:54:26 -08:00
parent e80f974b24
commit 0cdefe8b8b
4 changed files with 60 additions and 25 deletions

View File

@@ -38,11 +38,8 @@ pub const Mouse = struct {
/// The pre-edit state. See Surface.preeditCallback for more information.
pub const Preedit = struct {
/// The codepoints to render as preedit text. We allow up to 16 codepoints
/// as a sort of arbitrary limit. If we experience a realisitic use case
/// where we need more please open an issue.
codepoints: [16]Codepoint = undefined,
len: u8 = 0,
/// The codepoints to render as preedit text.
codepoints: []Codepoint,
/// A single codepoint to render as preedit text.
pub const Codepoint = struct {
@@ -50,10 +47,22 @@ pub const Preedit = struct {
wide: bool = false,
};
/// Deinit this preedit that was cre
pub fn deinit(self: *const Preedit, alloc: Allocator) void {
alloc.free(self.codepoints);
}
/// Allocate a copy of this preedit in the given allocator..
pub fn clone(self: *const Preedit, alloc: Allocator) !Preedit {
return .{
.codepoints = try alloc.dupe(Codepoint, self.codepoints),
};
}
/// The width in cells of all codepoints in the preedit.
pub fn width(self: *const Preedit) usize {
var result: usize = 0;
for (self.codepoints[0..self.len]) |cp| {
for (self.codepoints) |cp| {
result += if (cp.wide) 2 else 1;
}