add: .line core event for line contents in non *raw mode* instead of .key core events
The end of the `.line` event received contents is highlighted by a trailing newline (which cannot occur before, as that triggers the line event itself). Add signal handler for SIGCONT which forces a `.resize` event that should re-draw the contents after continuing a suspended application (i.e. ctrl+z followed by `fg`).
This commit is contained in:
@@ -46,6 +46,7 @@ const Prompt = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE size hint is not required as the `.size = .{ .dim = .{..} }` property is set accordingly which denotes the minimal size
|
||||||
// fn minSize(ctx: *anyopaque, _: *const App.Model, _: zterm.Point) zterm.Point {
|
// fn minSize(ctx: *anyopaque, _: *const App.Model, _: zterm.Point) zterm.Point {
|
||||||
// const this: *@This() = @ptrCast(@alignCast(ctx));
|
// const this: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
// return .{ .x = this.len, .y = 1 };
|
// return .{ .x = this.len, .y = 1 };
|
||||||
@@ -140,9 +141,8 @@ pub fn main() !void {
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
// NOTE maybe I want to decouple the `key`s from the user input too? i.e. this only makes sense if the output is not echoed!
|
// NOTE maybe I want to decouple the `key`s from the user input too? i.e. this only makes sense if the output is not echoed!
|
||||||
// otherwise just use gnu's `readline`?
|
// otherwise just use gnu's `readline`?
|
||||||
.key => |key| {
|
.line => |line| {
|
||||||
// if (key.eql(.{ .cp = 'q' })) app.quit();
|
log.debug("{s}", .{line});
|
||||||
_ = key;
|
|
||||||
},
|
},
|
||||||
// NOTE errors could be displayed in another container in case one was received, etc. to provide the user with feedback
|
// NOTE errors could be displayed in another container in case one was received, etc. to provide the user with feedback
|
||||||
.err => |err| log.err("Received {s} with message: {s}", .{ @errorName(err.err), err.msg }),
|
.err => |err| log.err("Received {s} with message: {s}", .{ @errorName(err.err), err.msg }),
|
||||||
|
|||||||
34
src/app.zig
34
src/app.zig
@@ -30,7 +30,7 @@ pub fn App(comptime M: type, comptime E: type) type {
|
|||||||
thread: ?Thread = null,
|
thread: ?Thread = null,
|
||||||
quit_event: Thread.ResetEvent,
|
quit_event: Thread.ResetEvent,
|
||||||
termios: ?posix.termios = null,
|
termios: ?posix.termios = null,
|
||||||
winch_registered: bool = false,
|
handler_registered: bool = false,
|
||||||
config: TerminalConfiguration,
|
config: TerminalConfiguration,
|
||||||
|
|
||||||
pub const TerminalConfiguration = struct {
|
pub const TerminalConfiguration = struct {
|
||||||
@@ -63,6 +63,13 @@ pub fn App(comptime M: type, comptime E: type) type {
|
|||||||
// -> the signal might not work correctly when hosting the application over ssh!
|
// -> the signal might not work correctly when hosting the application over ssh!
|
||||||
this.postEvent(.resize);
|
this.postEvent(.resize);
|
||||||
}
|
}
|
||||||
|
/// registered CONT handler to force a complete redraw
|
||||||
|
fn handleCont(_: i32) callconv(.c) void {
|
||||||
|
const this: *@This() = @ptrCast(@alignCast(handler_ctx));
|
||||||
|
// NOTE this does not have to be done if in-band resize events are supported
|
||||||
|
// -> the signal might not work correctly when hosting the application over ssh!
|
||||||
|
this.postEvent(.resize);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(io: std.Io, model: Model) @This() {
|
pub fn init(io: std.Io, model: Model) @This() {
|
||||||
return .{
|
return .{
|
||||||
@@ -81,15 +88,19 @@ pub fn App(comptime M: type, comptime E: type) type {
|
|||||||
// post init event (as the very first element to be in the queue - event loop)
|
// post init event (as the very first element to be in the queue - event loop)
|
||||||
this.postEvent(.init);
|
this.postEvent(.init);
|
||||||
|
|
||||||
if (!this.winch_registered) {
|
if (!this.handler_registered) {
|
||||||
handler_ctx = this;
|
handler_ctx = this;
|
||||||
var act = posix.Sigaction{
|
posix.sigaction(posix.SIG.WINCH, &.{
|
||||||
.handler = .{ .handler = handleWinch },
|
.handler = .{ .handler = handleWinch },
|
||||||
.mask = posix.sigemptyset(),
|
.mask = posix.sigemptyset(),
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
};
|
}, null);
|
||||||
posix.sigaction(posix.SIG.WINCH, &act, null);
|
posix.sigaction(posix.SIG.CONT, &.{
|
||||||
this.winch_registered = true;
|
.handler = .{ .handler = handleCont },
|
||||||
|
.mask = posix.sigemptyset(),
|
||||||
|
.flags = 0,
|
||||||
|
}, null);
|
||||||
|
this.handler_registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.quit_event.reset();
|
this.quit_event.reset();
|
||||||
@@ -437,9 +448,14 @@ pub fn App(comptime M: type, comptime E: type) type {
|
|||||||
var len = read_bytes;
|
var len = read_bytes;
|
||||||
while (!std.unicode.utf8ValidateSlice(buf[0..len])) len -= 1;
|
while (!std.unicode.utf8ValidateSlice(buf[0..len])) len -= 1;
|
||||||
remaining_bytes = read_bytes - len;
|
remaining_bytes = read_bytes - len;
|
||||||
var iter: std.unicode.Utf8Iterator = .{ .bytes = buf[0..len], .i = 0 };
|
if (this.config.rawMode) {
|
||||||
while (iter.nextCodepoint()) |cp| this.postEvent(.{ .key = .{ .cp = cp } });
|
var iter: std.unicode.Utf8Iterator = .{ .bytes = buf[0..len], .i = 0 };
|
||||||
continue;
|
while (iter.nextCodepoint()) |cp| this.postEvent(.{ .key = .{ .cp = cp } });
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
this.postEvent(.{ .line = buf[0..len] });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
this.postEvent(.{ .key = key });
|
this.postEvent(.{ .key = key });
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ pub const SystemEvent = union(enum) {
|
|||||||
/// associated error message
|
/// associated error message
|
||||||
msg: []const u8,
|
msg: []const u8,
|
||||||
},
|
},
|
||||||
|
/// Input line event received in non *raw mode* (instead of individual `key` events)
|
||||||
|
line: []const u8,
|
||||||
/// Input key event received from the user
|
/// Input key event received from the user
|
||||||
key: Key,
|
key: Key,
|
||||||
/// Mouse input event
|
/// Mouse input event
|
||||||
|
|||||||
Reference in New Issue
Block a user