commit 8818b40b5d10f32db1b6454bb8a78a96c7685938
parent 89e4e22d67111a3943171460d2b8d24ecac789a9
Author: Martin Ashby <martin@ashbysoft.com>
Date: Sat, 27 Jan 2024 22:02:06 +0000
Add status line and timeout
Diffstat:
M | src/main.zig | | | 49 | ++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/main.zig b/src/main.zig
@@ -43,6 +43,8 @@ pub fn main() !void {
try editorOpen(&es, args[1]);
}
+ try editorSetStatusMessage(&es, "HELP: ctrl+q = quit", .{});
+
while (true) {
try editorRefreshScreen(&es);
@@ -50,12 +52,18 @@ pub fn main() !void {
error.Quit => return,
else => return e,
};
+
+ try editorProcessTimeouts(&es);
}
}
//// Data
const EditorState = struct {
+ const StatusMsg = struct {
+ msg: []const u8,
+ time: std.time.Instant,
+ };
a: std.mem.Allocator,
screen_buf: std.ArrayListUnmanaged(u8) = .{},
termios_orig: std.os.linux.termios = undefined,
@@ -69,6 +77,7 @@ const EditorState = struct {
coloff: usize = 0,
erow: []ERow = &[_]ERow{},
filename: ?[]const u8 = null,
+ statusmsg: ?StatusMsg = null,
dbglog: std.ArrayList(u8),
@@ -85,6 +94,9 @@ const EditorState = struct {
self.a.free(erow.render);
}
self.a.free(self.erow);
+ if (self.statusmsg) |*statusmsg| {
+ self.a.free(statusmsg.msg);
+ }
const wtr = std.io.getStdOut().writer();
wtr.writeAll(self.dbglog.items) catch {};
@@ -97,6 +109,17 @@ const ERow = struct {
render: []u8,
};
+fn editorProcessTimeouts(es: *EditorState) !void {
+ if (es.statusmsg) |*smg| {
+ const now = try std.time.Instant.now();
+ if (now.since(smg.time) > 5 * std.time.ns_per_s) {
+ const x = smg.msg;
+ es.statusmsg = null;
+ es.a.free(x);
+ }
+ }
+}
+
//// Terminal handling
// Returns the original termios setting for restoring terminal function at exit.
@@ -320,6 +343,7 @@ fn editorRefreshScreen(es: *EditorState) !void {
try wtr.writeAll("\x1b[H"); // Reset cursor (to 1:1)
try editorDrawRows(es, wtr);
try editorDrawStatusBar(es, wtr);
+ try editorDrawMessageBar(es, wtr);
try std.fmt.format(wtr, "\x1b[{};{}H", .{
es.cy - es.rowoff + 1,
es.rx - es.coloff + 1,
@@ -380,6 +404,16 @@ fn editorDrawStatusBar(es: *const EditorState, wtr: anytype) !void {
}
try wtr.writeAll(buf);
try wtr.writeAll("\x1b[m"); // normal colours
+ try wtr.writeAll("\r\n"); // Make another line for input bar
+}
+
+fn editorDrawMessageBar(es: *EditorState, wtr: anytype) !void {
+ try wtr.writeAll("\x1b[K");
+ if (es.statusmsg) |statusmsg| {
+ var tw = truncateWriter(wtr, es.screencols);
+ const wtr2 = tw.writer();
+ try wtr2.writeAll(statusmsg.msg);
+ }
}
fn editorScroll(es: *EditorState) void {
@@ -402,6 +436,19 @@ fn editorScroll(es: *EditorState) void {
}
}
+fn editorSetStatusMessage(es: *EditorState, comptime fmt: []const u8, args: anytype) !void {
+ if (es.statusmsg) |*smg| {
+ const x = smg.msg;
+ es.statusmsg = null;
+ es.a.free(x);
+ }
+ const y: EditorState.StatusMsg = .{
+ .msg = try std.fmt.allocPrint(es.a, fmt, args),
+ .time = try std.time.Instant.now(),
+ };
+ es.statusmsg = y;
+}
+
//// Input
fn editorProcessKeyPress(es: *EditorState) !void {
@@ -483,7 +530,7 @@ fn editorMoveCursor(key: editorKey, es: *EditorState) void {
fn initEditor(es: *EditorState) !void {
const sz = try getWindowSize();
- es.screenrows = sz.rows - 1; // Allow room for status bar
+ es.screenrows = sz.rows - 2; // Allow room for status bar and message bar
es.screencols = sz.cols;
}