Fix raw terminal line rendering
This commit is contained in:
+46
-9
@@ -363,15 +363,46 @@ fn readEditorInputAlloc(allocator: std.mem.Allocator, stdin: *std.Io.Reader) !?[
|
||||
fn renderLocalFrame(allocator: std.mem.Allocator, io: std.Io, stdout: std.Io.File, client: *tui.Client, path: []const u8, is_dir: bool, interactive: bool) !void {
|
||||
const frame = try client.render(allocator);
|
||||
defer allocator.free(frame);
|
||||
if (interactive) try stdout.writeStreamingAll(io, "\x1b[H\x1b[2J");
|
||||
try stdout.writeStreamingAll(io, frame);
|
||||
try stdout.writeStreamingAll(io, "\n\n");
|
||||
try stdout.writeStreamingAll(io, "mim opened: ");
|
||||
try stdout.writeStreamingAll(io, path);
|
||||
try stdout.writeStreamingAll(io, if (is_dir)
|
||||
"\nDirectory browser. Space opens commands; o/Enter opens panel items where available; q quits when clean.\n"
|
||||
else
|
||||
"\nEditor starts in insert mode. Esc or Space n enters normal mode; Space commands work in normal mode; Space w saves; Space q quits when clean.\n");
|
||||
if (interactive) {
|
||||
try stdout.writeStreamingAll(io, "\x1b[H\x1b[2J");
|
||||
try writeTerminalText(allocator, io, stdout, frame);
|
||||
try writeTerminalText(allocator, io, stdout, "\n\n");
|
||||
try writeTerminalText(allocator, io, stdout, "mim opened: ");
|
||||
try writeTerminalText(allocator, io, stdout, path);
|
||||
try writeTerminalText(allocator, io, stdout, if (is_dir)
|
||||
"\nDirectory browser. Space opens commands; o/Enter opens panel items where available; q quits when clean.\n"
|
||||
else
|
||||
"\nEditor starts in insert mode. Esc or Space n enters normal mode; Space commands work in normal mode; Space w saves; Space q quits when clean.\n");
|
||||
} else {
|
||||
try stdout.writeStreamingAll(io, frame);
|
||||
try stdout.writeStreamingAll(io, "\n\n");
|
||||
try stdout.writeStreamingAll(io, "mim opened: ");
|
||||
try stdout.writeStreamingAll(io, path);
|
||||
try stdout.writeStreamingAll(io, if (is_dir)
|
||||
"\nDirectory browser. Space opens commands; o/Enter opens panel items where available; q quits when clean.\n"
|
||||
else
|
||||
"\nEditor starts in insert mode. Esc or Space n enters normal mode; Space commands work in normal mode; Space w saves; Space q quits when clean.\n");
|
||||
}
|
||||
}
|
||||
|
||||
fn writeTerminalText(allocator: std.mem.Allocator, io: std.Io, stdout: std.Io.File, bytes: []const u8) !void {
|
||||
const converted = try terminalCrlfAlloc(allocator, bytes);
|
||||
defer allocator.free(converted);
|
||||
try stdout.writeStreamingAll(io, converted);
|
||||
}
|
||||
|
||||
fn terminalCrlfAlloc(allocator: std.mem.Allocator, bytes: []const u8) ![]u8 {
|
||||
var out = std.ArrayList(u8).empty;
|
||||
errdefer out.deinit(allocator);
|
||||
var start: usize = 0;
|
||||
for (bytes, 0..) |byte, i| {
|
||||
if (byte != '\n') continue;
|
||||
if (start < i) try out.appendSlice(allocator, bytes[start..i]);
|
||||
try out.appendSlice(allocator, "\r\n");
|
||||
start = i + 1;
|
||||
}
|
||||
if (start < bytes.len) try out.appendSlice(allocator, bytes[start..]);
|
||||
return out.toOwnedSlice(allocator);
|
||||
}
|
||||
|
||||
fn printLocalContext(allocator: std.mem.Allocator, io: std.Io, args: *std.process.Args.Iterator, stdout: std.Io.File) !void {
|
||||
@@ -568,3 +599,9 @@ test "regular: local editor client exposes save and dirty quit guards" {
|
||||
client.clearQuit();
|
||||
try std.testing.expect(!client.requestedQuit());
|
||||
}
|
||||
|
||||
test "regular: raw terminal output converts newline to carriage-return newline" {
|
||||
const converted = try terminalCrlfAlloc(std.testing.allocator, "a\nb\n");
|
||||
defer std.testing.allocator.free(converted);
|
||||
try std.testing.expectEqualStrings("a\r\nb\r\n", converted);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user