feat: add basic reflow command and keybind (alt+q)

This commit is contained in:
CJ van den Berg 2026-01-31 22:07:18 +01:00
parent 9fb9b45c4d
commit 6adc0b5887
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
5 changed files with 82 additions and 0 deletions

View file

@ -13,6 +13,7 @@ const Self = @This();
const max_imbalance = 7;
pub const Root = *const Node;
pub const unicode = @import("unicode.zig");
pub const reflow = @import("reflow.zig").reflow;
pub const Manager = @import("Manager.zig");
pub const Cursor = @import("Cursor.zig");

55
src/buffer/reflow.zig Normal file
View file

@ -0,0 +1,55 @@
pub fn reflow(allocator: std.mem.Allocator, text: []const u8, width: usize) error{ OutOfMemory, WriteFailed }![]u8 {
const prefix = detect_prefix(text);
const words = try split_words(allocator, text, prefix.len);
defer allocator.free(words);
var output: std.Io.Writer.Allocating = .init(allocator);
const writer = &output.writer;
var line_len: usize = 0;
for (words) |word| {
if (line_len == 0) {
try writer.writeAll(prefix);
line_len += prefix.len;
}
if (line_len > prefix.len)
try writer.writeByte(' ');
try writer.writeAll(word);
line_len += word.len;
if (line_len >= width) {
try writer.writeByte('\n');
line_len = 0;
}
}
return output.toOwnedSlice();
}
fn split_words(allocator: std.mem.Allocator, text: []const u8, prefix: usize) error{OutOfMemory}![]const []const u8 {
var words: std.ArrayList([]const u8) = .empty;
var lines = std.mem.splitScalar(u8, text, '\n');
while (lines.next()) |line| {
var it = std.mem.splitAny(u8, line[prefix..], " \t");
while (it.next()) |word| if (word.len > 0) {
(try words.addOne(allocator)).* = word;
};
}
return words.toOwnedSlice(allocator);
}
fn detect_prefix(text: []const u8) []const u8 {
var lines = std.mem.splitScalar(u8, text, '\n');
const line1 = lines.next() orelse return &.{};
var prefix: []const u8 = line1;
while (lines.next()) |line|
prefix = lcp(prefix, line);
return prefix;
}
fn lcp(a: []const u8, b: []const u8) []const u8 {
const len = @min(a.len, b.len);
for (0..len) |i| if (a[i] != b[i])
return a[0..i];
return a[0..len];
}
const std = @import("std");